Hi Angus,
With the same code as #20, except Text Vertical Alignment is set to tvaTop
, the spacing between bounding rect "top" and the text seems very large, and the space between lines seems very large, too :
program TestDrawText; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Types, Img32, Img32.Vector, Img32.Draw, Img32.Text, Img32.Fmt.PNG; var FontReader: TFontReader; FontCache: TFontCache; I: TImage32; TextRect: TRect; begin try FontReader := TFontReader.Create('Segoe UI'); FontCache := TFontCache.Create(FontReader, 18); I := TImage32.Create(200, 200); I.Clear(clWhite32); TextRect := Rect(0, 0, 150, 200); DrawText(I, TextRect, 'This is a test, my friend', taCenter, tvaTop, FontCache, clBlack32); DrawDashedLine(I, Rectangle(TextRect), [20,10,15,10], nil, 1, clRed32, esPolygon); I.SaveToFile('Text.png'); I.Free; FontCache.Free; FontReader.Free; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.
You will get the image attached. Is it possible to reduce this spacing ?
Thank you very much,
--
Pierre Y.
As an example, in the attached image, the "button" on the left is rendered using TImage32, the one on the right is rendered using Windows GDI.
What's... fun is that "Top" alignment places the text lower than "Bottom" alignment.
Firstly, part of the problem (if it is a problem) is the Segoe UI font seems to have a relatively large ascent (the space between the test baseline and the very top of the tallest text including diacritics - eg Ñ) compared to other fonts.
Having said that, text in Image32 is generally positioned relative to the text's baseline. So, when positioning text relative to its top, it's up to you as the user to decide between using the TFontCache's Ascent property or using
Img32.Vector.GetBounds
to get the height of specific text. With regard toImg32.Text.DrawText
and vtaTop alignment, the text is aligned according to the font's ascent. Again this would look less problematic with another font. Evidently the GDI uses some other metric to position text relative to the top. I'm open to suggestions 😜.Hi Angus,
Thank you for taking time to help me.
As I only target Windows devices... And I want to keep Segoe UI... Could it be possible to use the Windows Text rendering functions to render the text on a 32 bits bitmap (for antialiasing and alpha transparency) and then copy this image at the right place on the final TImage32 ?
-- Pierre
You can draw text onto an opaque bitmap and fairly easily copy that text with the opaque background into a TImage32 object. When doing so however (eg using
Windows.GetBitmapBits
) you'll also need to manually set the alpha channel to 255 (because the GDI leaves the alpha channel completely untouched). That's pretty easy to do usingTImage32.SetAlpha
. Alternatively, you could useTImage32.CopyFromDC
passing the bitmaps' canvas handle but that just hides quite a bit of unnecessary work.If you really want GDI text with a transparent background, that can be done but it's a fiddle - see below,