question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

GlyphMetrics - width, leaftBearing, rightBearing ?

See original GitHub issue

I’m having a mental crisis looking at SixLabors.Fonts… I need to replace the pinvokes for GetCharABCWidthsFloat and GetCharABCWidthsFloat. (for work with PDF and TIFF)

Now I thought I could do font.GetGlyph('c').LeftBearing/RightBearing/Width

Instead of properties or fields, it just has a method BoundingBox, which requires a location… Now of course I could pass location (0,0) but what’s the point ? The width/height of a glyph doesn’t depend on its location. And where’s LeftBearing(A)/RightBearing©/B(lack) ? I suppose font.GetGlyph(‘c’).BoundingBox( (0,0), dpi ).Width is = A + B + C ?

And then glyph takes a character as argument, makes it an integer, and then makes a character from the codepoint again ? What about VB.NET users where char is not convertible into codepoint ? Makes little sense.

Also, I saw a leftBearing inside horizontalMetricsTable, but it’s not accessible, and then there’s no rightBearing ?

Looking at QFontMetrics->inFont https://doc.qt.io/archives/qt-4.8/qfontmetrics.html there’s also no way to determine if a glyph is in the font ? What happens if it isn’t in the font ?

[System.Runtime.InteropServices.DllImport("GDI32", SetLastError = true)]
internal static extern int GetCharABCWidthsFloat(System.IntPtr hdc, uint iFirstChar, uint iLastChar, [System.Runtime.InteropServices.In] [System.Runtime.InteropServices.Out] ABCFloat[] lpABCF);

[System.Runtime.InteropServices.DllImport("GDI32", SetLastError = true)]
internal static extern int GetCharABCWidthsFloat(Win32DCSafeHandle hdc, uint iFirstChar, uint iLastChar, [System.Runtime.InteropServices.In] [System.Runtime.InteropServices.Out] ABCFloat[] lpABCF);

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
ststeigercommented, Feb 21, 2020

And another question: why does font.GetGlyph(‘c’); give me BoundingBox method, while font.FontInstance.GetGlyph(‘c’) gives me actual useful information ? Isn’t font already an instance ? Why font.FontInstance ? And if font has FontInstance, why does Glyph not have GlyphInstance ? Takes only appx 3 hours of dwelling through the source code…

var fg = font.FontInstance.GetGlyph('c');
ushort AplusBplusC = fg.AdvanceWidth;
// fg.Index
// fg.Height

And if GlyphInstance exposes horiAdvance (aka “Width”) and vertAdvance (aka “Height”), why not expose

width
height
horiBearingX
horiBearingY
vertBearingX
vertBearingY

Also, is it correct that it doesn’t differentiate between text-direction horizontal, and text-direction vertical ? Horizontal Vertical as in freetype ?

And while both FreeType and SixLabors.Fonts are horrible, it only took me 10 minutes to figure out how to get the FreeType (SharpFont) metrics.

1reaction
ststeigercommented, Jul 23, 2021

@JimBobSquarePants: Sorry for the unpleasant tone, I know this is a spare-time-project, and you put great effort into it.

It’s just that … when it comes to font and imaging, all APIs, ms or not, fall short of everything … System.Drawing.Font can enumerate the fonts, but doesn’t expose the file path. SixLabors.Fonts doesn’t read fontconfig, but can read a font given the file path. Yupii. System.Drawing can read and write gifs on Windows, but it doesn’t work on Linux. Windows-APIs like GetCharABCWidthsFloat and fontmetrics don’t document where they get the data from, you can find hints in the source-code of wine (if there isn’t a E_NOT_IMPLEMENTED). Neither SixLabors.Fonts nor System.Drawing.Fonts can create a font-package (for embedding fonts in PDFs, but only the glyphs used to save space). SixLabors.Fonts reads the font-metrics-data in question, but doesn’t in any way expose it (well…). FreeType with C# binding has a f*ing native dependency that would require typedef in C#, unless you wanna patch the windows-executable, which is a pain-in-the-a** to compile.

And there I sit and want to replace some WinAPI calls to get PDF-rendering working on Linux, render a svg-text to a path, and write some text on a moving gif, but I can’t do any of these things because I first need to read the true-type-font-specification, then dig trough the freetype documentation to understand what the values are, then read to Wine-Source-Code to figure out how to get the license-info of a ttf-file, then open issues with Microsoft for libgdiplus only to have them close it as “won’t fix”. Then dig through the sixlabors source-code to figure out how to get the metrics I need. Read through wine-code again to figure out what microsoft adds, never mind the why. Not to mention if you want to do something as simple as having support for listing the fonts on MacOS without adding platform libraries 100 of megabytes in size, you might as well shoot yourselfs in the head instead. Then put it all on shelf because it takes too long.

Then take some source code a year later when you have some time again and try to get on, half the APIs of sixlabors have changed, google around for a few hours to get the things I had working working again, and, and, and …

Then write an issue here, and then, when you still haven’t done any of the stuff you wanted to do; only to here and there have people complain about how the issues I write are not written in a friendly fashion/tone, even when I already went out of my way to be nice wile writing them - you would get cranky, too. Not that it necessarely is okay to vent all of it here. My apologies for that. By the way, if you ever want to render a text to a SVG-path: https://github.com/ststeiger/SvgRenderer (just don’t think that you could specify the font by font-family name as in the svg-text-tag - because the fonts can’t be found that way, and while System.Drawing.FontFontFamily will find the font, it won’t return the path, so you can’t read the font-file, which renders the excercise utterly futile…)

<svg viewBox="0 0 200 30" xmlns="http://www.w3.org/2000/svg">
  <text y="20" font-family="Arial, Helvetica, sans-serif">Sans serif</text>
</svg>
Read more comments on GitHub >

github_iconTop Results From Across the Web

QFontMetrics Class | Qt GUI 6.5.2
Returns the minimum right bearing of the font. This is the smallest rightBearing(char) of all characters in the font. Note that this function...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found