Enable transparency with TSVG2ImageList on VCL

There was a little bug in the package which prevented the proper rendering of images with transparency on the VCL TButton, so I uploaded a new fix which corrects this. After download of the fixed package you should rebuild the packages. The demo packages are update also.

In this post I would like to show how you can set properties on the TSVG2ImageList to enable transparency.

First there is the question what type of button you should select from the Tool Palette in the Delphi IDE. There is a TButton, a TBitBtn and a TSpeedButton.

It turns out that the TBitBtn and TSpeedButton are legacy controls and you should avoid using these in new applications. The illustration below shows why:

TSVG2ImageList1

There is  a Fuchsia color border on the TBitBtn and TSpeedButton control, that is because it uses the old windows method of simulating transparency by using the left (or right, not sure) bottom pixel as a transparency color. Before it copies the image from the image list, it clears the target area with color Fuchsia. On the pixels that should be semi transparent this Fuchsia color seeps through.

So TBitBtn and TSpeedButton should be avoided, the TButton, shows the correct image.

In this test application linked the image list to the ActionManager1 and added a couple of actions. On each action I set the ImageIndex of the corresponding image in the SVG2ImageList. Next linked one of the Actions to TButton.

On the TButton you also have to set the “Images” property to link to an image list. Then you have the option to set a number of image index properties on the TButton to show different images depending on the state of the button.

Finally here are the properties of the TSVG2ImageList to enable transparency:

TSVG2ImageList2

All color settings, especially “BkColor” should be set to “clNone” and “ColorDepth” should be set to “cd32Bit”.

SVG Font example for SVG package

The new version 2.1 of the SVG package supports SVG Fonts.

The previous versions of the package used only system fonts and converted these to glyphs, but this would not always give accurate results. Could be that the specified font is not installed and also, in Delphi it is not easy to find out wat the exact glyph metrics are.

With SVG fonts you have more control over the final result.

Here is an example how SVG fonts can be used with the package. I have created a test application that looks like this:

FontExample1

The memo control contains the SVG content and with the button “Apply”, I can apply the SVG content to the SVG2Image control.

There are two ways to apply SVG content to SVG controls, I could set the “SVG” property of the TSVG2Image controls like so:

procedure TForm1.bApplyClick(Sender: TObject);
begin
  SVG2Image1.SVG.Assign(Memo1.Lines);
  SVG2Image1.Repaint;
end;

The advantage of this method is dat the SVG content is saved in the form file and in the excutable file so you don’t have to supply the SVG as a seperate file to the excutable.

The other method is to specify a reference to a file in the “Filename” property of the TSVG2Image control. In that case we first have to save the content of the Memo control to file.

procedure TForm1.bApplyClick(Sender: TObject);
begin
  Memo1.Lines.SaveToFile(Edit1.Text);
  SVG2Image1.Filename := Edit1.Text;
  SVG2Image1.NeedsParse := True;
  SVG2Image1.Repaint;
end;

The advantage of the second method is that, if a reference to an external file is used from within the SVG content, the parser will know where to find it.

So in this example we want to specify an external SVG file containing the SVG font, so we use the second method.

The statement:  “SVG2Image1.NeedsParse := True” will force the control to reparse the SVG content, even though the filename stays the same.

For this example I have put this SVG content in the Memo:

<?xml version="1.0" standalone="no"?>
<svg width="10cm" height="3cm" viewBox="0 0 1000 300" xmlns="http://www.w3.org/2000/svg" version="1.1">

  <g font-family="Roboto" font-size="45" >
    <text x="200" y="150" fill="blue" >You are <tspan font-weight="bold" fill="red" >not </tspan>a banana.</text>
  </g>

  <rect x="1" y="1" width="998" height="298" fill="none" stroke="blue" stroke-width="2" />
</svg>

Now when I run the application it will save the SVG content to the location I have specified in the Edit control and render the SVG in the TSVG2Image control.

FontExample2

Now we need an SVG file containg an SVG font. You can use the Batik SVG Font converter to create such a file out of a any “True type font”. So as an example I have converted the Great Vibes  font to “GreatVibes.svg” and I have saved this file relative to the referencing SVG in folder “\Fonts”.

Now I have to change the SVG content to make it use the new font, there are several ways to do that.

You can use the SVG FontFace functionality like so:


<?xml version="1.0" standalone="no"?>
<svg
version="1.1"
width="10cm" height="3cm"
viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<defs>
<font-face font-family="Great Vibes" unicode-range="U+0-7F">
<font-face-src>
<font-face-uri xlink:href="Fonts/GreatVibes.svg#Font"/>
</font-face-src>
</font-face>
</defs>

<g font-family="Great Vibes" font-size="80" >
<text x="200" y="150" fill="blue" >You are <tspan font-weight="bold" fill="red" >not </tspan>a banana.</text>
</g>

<rect x="1" y="1" width="998" height="298"  fill="none" stroke="blue" stroke-width="2" />
</svg>

The “font-face-uri” element specifies an external SVG document containing a font element with id=”Font”. Note that I had to add the namespace declaration xmlns:xlink=”http://www.w3.org/1999/xlink” in the SVG element because the font-face-uri uses the xlink:href attribute!

Another method would be using CSS like so:


<?xml version="1.0" standalone="no"?>
<svg
version="1.1"
width="10cm" height="3cm"
viewBox="0 0 1000 300"
xmlns="http://www.w3.org/2000/svg">

<defs>
<style type="text/css">
@font-face {
font-family: 'Great Vibes';
font-weight: normal;
font-style: normal;
src: url("Fonts/GreatVibes.svg#Font") format("svg")
}
</style>
</defs>

<g font-family="Great Vibes" font-size="80" >
<text x="200" y="150" fill="blue" >You are <tspan font-weight="bold" fill="red" >not </tspan>a banana.</text>
</g>

<rect x="1" y="1" width="998" height="298"  fill="none" stroke="blue" stroke-width="2" />
</svg>

The end result should look like this:

FontExample3