Re: Font Rendering: Multiple FT_Faces and baselines
> I'm aware that when drawing text, all glyphs should be aligned on a > single baseline. The example I've given does not do this; it aligns > the text on different font's baseline, causing the inconsistent > look. This is what I told you in the very beginning: Your logic to position the glyphs vertically is flawed; you actually don't align them correctly – somewhere, you are not using the correct vertical offsets. I suggest that you check the FreeType demo programs for some guidance. https://gitlab.freedesktop.org/freetype/freetype-demos > When I'm talking about "aligning the baselines", I'm referring to > choosing a suitable baseline from different fonts. I use the term > "baseline" loosely as when rendering text from top to bottom, the > ascent value is used. Why not position the baseline for all fonts at position y=0? > Initially, I plan to calculate a global baseline from all the fonts > by averaging their respective baselines. Another way is to pick the > "lowest" baseline (as in the highest ascent value) as the global > baseline. I'm unsure of what strategy to use, so I'm curious about > what approach do other applications use to solve this problem. If I understand you correctly, we have an XY problem here. The real issue seems not to be the alignment on a baseline but rather how to compute the global bounding box of a text string that comprises different fonts. The answer to that was given repeatedly on the mailing list: If you need a bounding box correct to the pixel and you do hinting, you have to make FreeType compute all glyphs, store them somewhere, *then* walk over all individual bounding boxes and take the maximum dimensions to get the global one. Finally, you can render the glyphs with the correct offsets. Werner
Re: Font Rendering: Multiple FT_Faces and baselines
Hi, Sorry for the mess of emails. This is my first time using a mailing list, and I'm still getting the hang of it. I'm aware that when drawing text, all glyphs should be aligned on a single baseline. The example I've given does not do this; it aligns the text on different font's baseline, causing the inconsistent look. When I'm talking about "aligning the baselines", I'm referring to choosing a suitable baseline from different fonts. I use the term "baseline" loosely as when rendering text from top to bottom, the ascent value is used. Initially, I plan to calculate a global baseline from all the fonts by averaging their respective baselines. Another way is to pick the "lowest" baseline (as in the highest ascent value) as the global baseline. I'm unsure of what strategy to use, so I'm curious about what approach do other applications use to solve this problem. Kelvin --- Original Message --- On Thursday, July 20th, 2023 at 11:56, Werner LEMBERG w...@gnu.org wrote: > [It would be nice if you could use a decent e-mail writer that creates > readable plain-text messages (which we prefer on this mailing list), > without completely garbling quoted material.] > > > > This looks like a logic error in your program. If I say `ftdump cjk.otf` > > > I get > > > > > > `ascender: 1160 descender: -288` > > > > > > among other data. > > > > > > The output of `ftdump en.ttf` gives > > > > > > `ascender: 935 descender: -265` > > > > > > This is perfectly fine. [...] > > > > Thank you for pointing it out. I'm unsure about the strategy to > > align the baselines. The simplest would be aligning to the lowest / > > highest baselines, but that may break some faces. > > Uh, oh, please update your knowledge on how fonts are actually working > within the frame of typography. There is no 'lowest' or 'highest' > baseline – there is only the baseline (assuming horizontal > typesetting). It is the very idea of a baseline that all glyphs of > all fonts are by default aligned on that! There exist additional > concepts like superscript or subscript, but this is something else and > not relevant here, as far as I can see. > > Maybe you want to achieve something different, I don't know. Please > educate yourself in advance to use the right technical terms so that > we can actually communicate without misunderstandings. > > You might have a look at > > https://freetype.org/freetype2/docs/glyphs/glyphs-3.html > > as a starter. > > Werner
The COLRv1 hook code (Re: FT_Bitmap and FT_BitmapGlyph life cycles)
Perhaps it is easier just to show you what I have - this is already functional and I can even switch COLRv1 palettes in ftgrid (screenshots the usual place). Basically it works the same ways as svg hooks: the preset slot hook calculates the bound boxes, while the render hook actually draws to the bitmap. In this case, I have a FT_Load_Glyph_Extended() which calls FT_Load_Glyph(), but also call FT_Get_Color_Glyph_ClipBox_Extended(), which is a skia routine which does FT_Get_Color_Glyph_ClipBox() but also if that fails, tries to union all the layers to calculate a skia bound box. I should convert back to override the FT_Load_Glyph() bound values but haven't (yet). Then I have a "FT_Glyph_To_Bitmap_Extended()" which also calls "FT_Glyph_To_Bitmap()", but then overwrite and draws to its bitmap with skia before returning. I'd like to not call "FT_Glyph_To_Bitmap()" but just do 'FT_New_Glyph()' on my own, but that always crashes. why? '...' and '...' are deleted parts too ugly that will hurt your eyes if you see them :-). #include "skia-colrv1-stub.h" #include FT_COLOR_H #include FT_BITMAP_H #include "include/core/SkRect.h" #include "include/core/SkBitmap.h" #include "include/core/SkCanvas.h" #include "freetype/internal/ftobjs.h" #include "skia-src-ports-SkFontHost_FreeType_common_colrv1.h" /* in skia-src-ports-SkFontHost_FreeType_colrv1.cpp */ SkRect FT_Get_Color_Glyph_ClipBox_Extended( FT_Face fFace, FT_UInt base_glyph, FT_ClipBox* clip_box ); FT_Bool isCOLRv1(FT_Face face, FT_UInt glyph_index) { if (FT_IS_SCALABLE(face)) { FT_OpaquePaint opaqueLayerPaint{nullptr, 1}; if (FT_Get_Color_Glyph_Paint(face, glyph_index, FT_COLOR_INCLUDE_ROOT_TRANSFORM, )) { return true; } } return false; } void skia_colr_set_current_palette( FT_Face face, FT_UInt palette_index ) { ... = ... palette_index; } FT_UShort skia_colr_get_current_palette( FT_Face face ) { ... ; } FT_Error FT_Load_Glyph_Extended( FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags ) { if ( isCOLRv1( face, glyph_index) && (load_flags & FT_LOAD_COLOR) ) { FT_ClipBox clipBox; SkRect bounds = FT_Get_Color_Glyph_ClipBox_Extended( face, glyph_index, ); ... keep bounds ... } FT_Error res = FT_Load_Glyph( face, glyph_index, load_flags ); return res; } FT_Error FT_Glyph_To_Bitmap_Extended( FT_Glyph* the_glyph, FT_Render_Moderender_mode, const FT_Vector* origin, FT_Bool destroy ) { ... FT_Error res = FT_Glyph_To_Bitmap( the_glyph, render_mode, origin, destroy ); ... retrieve bounds ... if ( face && bounds ) { FT_UInt glyph_index = face->glyph->glyph_index; /* General variables. */ int width = ceil(bounds->right()) - floor(bounds->left()); //bounds.width(); // fRight minus fLeft int height = ceil(bounds->bottom()) - floor(bounds->top()); //bounds.height(); // fBottom minus fTop int x = floor(bounds->left()); int y = floor(bounds->top()); int size = width * height * 4; FT_Error error; FT_Memory memory = lib->memory; FT_Glyphgbitmap = NULL; if (isCOLRv1(face, glyph_index) && (FT_GLYPH_FORMAT_BITMAP == (*the_glyph)->format)) { FT_BitmapGlyphbitmap = (FT_BitmapGlyph)(*the_glyph); if ((bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) || (bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)) { SkBitmap dstBitmap; dstBitmap.setInfo(SkImageInfo::Make(bitmap->bitmap.width, bitmap->bitmap.rows, ((bitmap->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) ? kBGRA__SkColorType : kGray_8_SkColorType), kPremul_SkAlphaType), bitmap->bitmap.pitch); dstBitmap.setPixels(bitmap->bitmap.buffer); SkCanvas canvas(dstBitmap); canvas.clear(SK_ColorTRANSPARENT); canvas.translate( -x, -y ); bool haveLayers = skia_colrv1_start_glyph(, face, glyph_index, FT_COLOR_INCLUDE_ROOT_TRANSFORM); fprintf(stderr, "**bounds %d %d %d %d - SkRect Max\n", x, -y, width, height); fprintf(stderr, "**bounds %d %d %d %d - Not skia\n", bitmap->left,
Re: Font Rendering: Multiple FT_Faces and baselines
On Thu, 20 Jul 2023 01:03:54 +, takase1121 via FreeType users wrote: > ... calculate an "average" baseline and align to that ... Or align to the midpoints of the overall font glyph boxes (including font ascent and font descent). That may be a suitable compromise.
Re: Adobe's SVG native as ft2 renderer hook (Re: Bug in rsvg+cairo hook with Nabla?
Adobe's SVG native is half way between librsvg and skia's svg rendering. Screenshots of 3 at https://github.com/HinTak/harfbuzz-python-demos/tree/master/skia-adventure And diff against the skia-port code in the ../svg-native/ directory above, and a lot more screenshots. It shouldn't be hard to make a adobe+cairo version from the librsvg+cairo version, if you see the adobe+skia version diff against pure skia (skia+skia svg module).
Re: Font Rendering: Multiple FT_Faces and baselines
Hi, Thank you for pointing it out. I'm unsure about the strategy to align the baselines. The simplest would be aligning to the lowest / highest baselines, but that may break some faces. The other method would be the one I mentioned - calculate an "average" baseline and align to that, but it has the same drawbacks. Are there other methods that I've missed? Original Message On 19 Jul 2023, 20:20, Werner LEMBERG < w...@gnu.org> wrote: >> Thank you for your reply. I attached a example program, test.c > which uses >> SDL2 to render text with the method I mentioned. The > program doesn't take >> any arguments and should produce a file called > result.bmp in the current >> directory. I've also attached two fonts, > cjk.otf and en.ttf as they're the >> font I used. Put everything in > the same directory and it should work. This >> looks like a logic error in your program. If I say `ftdump cjk.otf` I get >> ``` ascender: 1160 descender: -288 ``` among other data. The output of >> `ftdump en.ttf` gives ``` ascender: 935 descender: -265 height: 1200 ``` >> This is perfectly fine. I've attached images of ``` ftgrid -e unic -f 20320 >> cjk.otf ftgrid -e unic -f 70 en.ttf ``` and you can see that the glyphs >> harmonize just fine if you align the baselines of the two fonts. Werner
Re: Font Rendering: Multiple FT_Faces and baselines
[It would be nice if you could use a decent e-mail writer that creates readable plain-text messages (which we prefer on this mailing list), without completely garbling quoted material.] > > This looks like a logic error in your program. If I say `ftdump > > cjk.otf` I get > > > > ``` > > ascender: 1160 > > descender: -288 > > ``` > > > > among other data. > > > > The output of `ftdump en.ttf` gives > > > > ``` > > ascender: 935 > > descender: -265 > > ``` > > > > This is perfectly fine. [...] > > Thank you for pointing it out. I'm unsure about the strategy to > align the baselines. The simplest would be aligning to the lowest / > highest baselines, but that may break some faces. Uh, oh, please update your knowledge on how fonts are actually working within the frame of typography. There is no 'lowest' or 'highest' baseline – there is only *the* baseline (assuming horizontal typesetting). It is the very idea of a baseline that *all* glyphs of *all* fonts are by default aligned on that! There exist additional concepts like superscript or subscript, but this is something else and not relevant here, as far as I can see. Maybe you want to achieve something different, I don't know. Please educate yourself in advance to use the right technical terms so that we can actually communicate without misunderstandings. You might have a look at https://freetype.org/freetype2/docs/glyphs/glyphs-3.html as a starter. Werner
Re: Strange hinting of precomposed character
Yes, all that would be good. I think that Behdad had mentioned it at some point with the fonttools maintainers, but this is all quite a long time ago now. pat On Wed, Jul 19, 2023 at 11:26 PM Werner LEMBERG wrote: > > > > Yep! https://github.com/wenzhuman/fonttools > > Thanks. Unfortunately, this lacks top-level documentation, AFAICS, > describing the changes in comparison to upstream 'fonttools'. > Additionally, the git clone uses the 'master' branch for changes, > which is problematic. > > It would be great if someone could clean this up. BTW, have you ever > contacted the 'fonttools' maintainers and asked them whether they are > interested in the changes? > > > Werner
Adobe's SVG native as ft2 renderer hook (Re: Bug in rsvg+cairo hook with Nabla?
On Wednesday, 19 July 2023 at 05:07:42 BST, Werner LEMBERG wrote: > >> ... please post a link to the report if you do so :-) > https://gitlab.gnome.org/GNOME/librsvg/-/issues/997 > By the way, is there any progress whether Adobe's compact SVG native > viewer library can be used as a FreeType hook? It comes with a Cairo > backend, among others... > https://github.com/adobe/svg-native-viewer The cairo backend was contributed by our Suzuki San (added CC). The answer to your question is yes :-). I chose the skia backend to use (ie dropping skia's own svg parser, but still use skia graphics) as svg renderer hook. I built svg native with dual skia and cairo backends, and run its two backend test programs against the Nabla svg. The results only differ by edges.The result is in the middle of librsvg and skia's own svg renderer.Half of the resulting figure is black. The new Adobe-skia hook code differs from the skia+skiasvg code by only about 5 lines plus header changes. A possible Adobe+cairo code differs from the librsvg+cairo code maybe by similar amount. I'll put some screenshots up online, and you can see what I mean by its being half-black :-).
Re: COLRv1 to gray/alpha question (& color-blindness question)
> > Hin-Tak, > > > This is probably both a spec question & a technical question. What is the > > recommendation for COLRv1 when the rendering target media is not capable of > > color? > > > > Are you asking about RGB to gray conversion? There are multiple specs with > > slightly different formulas and barely noticeable differences, with and > > without gamma correction. I’m is all pretty arbitrary without settled > > consensus. > > > Gray = 0.3R + 0.6G + 0.1B > > > is good enough. > > I am talking about 32-bit RGBA to 8-bit gray conversion, and I gave two > examples/directions - throwing away the RGB part (and use the alpha channel > as a mask on the current foreground colour), or throw away the A part, and > doing 24-bit colour to gray conversion like you suggested (or even just gray > = (r+g+b)/3). Alpha is colorless until blended. Therefore any conversion of RGB to alpha will produce random blending results because assuming black foreground is wrong even on gray surfaces. Hence, the blending should be done in color (on gray surface r=g=b), then the final result can be converted to gray once again for display as above. This is essentially what should happen in ftgrid/ftview if you choose 8-bit display, e.g.,"-d 800x600x8". A.
Re: COLRv1 to gray/alpha question (& color-blindness question)
On Wednesday, 19 July 2023 at 15:27:20 BST, Alexei Podtelezhnikov wrote: > Hin-Tak, > This is probably both a spec question & a technical question. What is the > recommendation for COLRv1 when the rendering target media is not capable of > color? > Are you asking about RGB to gray conversion? There are multiple specs with > slightly different formulas and barely noticeable differences, with and > without gamma correction. I’m is all pretty arbitrary without settled > consensus. > Gray = 0.3R + 0.6G + 0.1B > is good enough. I am talking about 32-bit RGBA to 8-bit gray conversion, and I gave two examples/directions - throwing away the RGB part (and use the alpha channel as a mask on the current foreground colour), or throw away the A part, and doing 24-bit colour to gray conversion like you suggested (or even just gray = (r+g+b)/3). There is probably also a complication in the 2nd case, for layered glyphs - do you throw away the alpha channel first and stack the resulting solid colours/gray on top of one another, or do the full 32-bit rendering, then throw away the alpha channel and collapse the 24-bit? Werner also raised an interesting point - there is provision for palette on dark background vs light background I think, but is there a way of indicating some palettes are colour-blind-friendly? In the western world, it can be as bad as 1 in 30 male Caucasians being colour-blind.
Progress update on adjustment database
The next thing I'm doing for the adjustment database is making combining characters work. Currently, only precomposed characters will be adjusted. If my understanding is correct, this would mean finding any lookups that map a character + combining character onto a glyph, then apply the appropriate adjustments to that glyph. Right now, I'm trying to figure out what features I need to look inside to find these lookups. Should I just search all features? After that, I'm going to tackle the tilde-flattening issue, and any other similar marks that are getting flattened.
Re: COLRv1 to gray/alpha question (& color-blindness question)
Hin-Tak, > This is probably both a spec question & a technical question. What is the > recommendation for COLRv1 when the rendering target media is not capable of > color? Are you asking about RGB to gray conversion? There are multiple specs with slightly different formulas and barely noticeable differences, with and without gamma correction. I’m is all pretty arbitrary without settled consensus. Gray = 0.3R + 0.6G + 0.1B is good enough. A.
Re: [MPEG-OTSPEC] COLRv1 to gray/alpha question (& color-blindness question)
This is far from a complete answer to your question, but please bear in mind that COLRv1 has been proposed and demonstrated as a solution to problems with certain variable monochrome fonts. In particular it can be very convenient to vary the shape of a masking contour using variations, in order to achieve changes in overall form that are simply not possible if one varies only opaque contours. For these fonts, the palette entry 0x is used so as to use "current foreground colour", and that limitation itself could, in theory, trigger certain behaviour in renderers on b/w systems. - Laurence > On 19 Jul 2023, at 05:01, Hin-Tak Leung wrote: > > Hi, > > This is probably both a spec question & a technical question. What is the > recommendation for COLRv1 when the rendering target media is not capable of > color? > > OT-SVG probably has its rules inherited from SVG; or at least, it doesn't > feel too odd to use SVG solely for color output, and glyf/CFF for 8-bit gray > with anti-aliasing. > > With COLRv0, the decisions of solid colours vs gray with anti-aliasing > semi-transparent edges probably isn't too hard either. > > I have finished adding COLRv1-capability to ft2-demos (that potentially means > any FreeType-based system/software is then COLRv1-able), but was faced with > two interesting choices: > > - COLRv1 layers have alpha channels too, so one way of doing it is to throw > away all the colours, and collapse all the alpha layers and draw the > foreground colour (ie black) through the alpha channel. > > - throw away the alpha channels, convert RGB to gray levels. > > The two differ quite significantly if you have dark but transparent colours > vs pale but solid colours. > > In terms of implementation details, some systems might eventually choose to > "lie" about legacy (non-colour) fonts as all having exactly 1 layer with a > default palette of B/W, to simplify and unify APIs of accessing > colour-layered and non-colour fonts? > > A somewhat related question - colour fonts are used beyond emoji's. While > there are 5 kinds of emoji fonts now, and most people are using one of 4... > but if you check Google Fonts, there are 10 colour fonts, one is emoji, but 6 > are Arabic (useful for annotating the Quran...) and 3 are Latin. So there are > intentions for text fonts. A few percents of western male population is > color-blind. Colour-blindness is one of the most common eye problems, after > short-sightedness :-). > > Screenshots at the bottom half of the web page below, and I'll continue the > more technical stuff on freetype-devel. > > > https://github.com/HinTak/harfbuzz-python-demos/tree/master/skia-adventure > ___ > mpeg-otspec mailing list > mpeg-ots...@lists.aau.at > https://lists.aau.at/mailman/listinfo/mpeg-otspec
Re: Strange hinting of precomposed character
> Yep! https://github.com/wenzhuman/fonttools Thanks. Unfortunately, this lacks top-level documentation, AFAICS, describing the changes in comparison to upstream 'fonttools'. Additionally, the git clone uses the 'master' branch for changes, which is problematic. It would be great if someone could clean this up. BTW, have you ever contacted the 'fonttools' maintainers and asked them whether they are interested in the changes? Werner
Re: Strange hinting of precomposed character
There is also a couple of masters theses: https://uwspace.uwaterloo.ca/bitstream/handle/10012/9116/Man_Wenzhu.pdf https://uwspace.uwaterloo.ca/bitstream/handle/10012/14262/Liu_Zeming.pdf?sequence=3=y Happy to answer questions! pat On Wed, Jul 19, 2023, 7:41 PM Brad Neimann wrote: > A long time ago I had some grad students write a compiler > infrastructure for TrueType bytecode. Maybe it's mostly bit-rotted, > but if someone were interested in working on this, I could try to > help. > > > When I get some time, I’d be happy to look into this. I’ve been doing some > compiler-adjacent stuff recently (mostly type inference), and this seems > like a very interesting application of those ideas. > > Regards, > Brad >
Re: Strange hinting of precomposed character
A long time ago I had some grad students write a compiler infrastructure for TrueType bytecode. Maybe it's mostly bit-rotted, but if someone were interested in working on this, I could try to help. When I get some time, I’d be happy to look into this. I’ve been doing some compiler-adjacent stuff recently (mostly type inference), and this seems like a very interesting application of those ideas. Regards, Brad
Re: Strange hinting of precomposed character
Yep! https://github.com/wenzhuman/fonttools On Wed, Jul 19, 2023 at 5:17 PM Werner LEMBERG wrote: > > > > A long time ago I had some grad students write a compiler > > infrastructure for TrueType bytecode. > > Ah, I faintly remember :-) > > > Maybe it's mostly bit-rotted, but if someone were interested in > > working on this, I could try to help. > > Thanks. Is this code available in a public repository? > > > Werner