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: 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: 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