Re: Font Rendering: Multiple FT_Faces and baselines

2023-07-19 Thread Werner LEMBERG

> 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

2023-07-19 Thread takase1121
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)

2023-07-19 Thread Hin-Tak Leung
 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

2023-07-19 Thread Lawrence D'Oliveiro
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?

2023-07-19 Thread Hin-Tak Leung
 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

2023-07-19 Thread takase1121 via FreeType users
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

2023-07-19 Thread Werner LEMBERG

[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

2023-07-19 Thread Patrick Lam
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?

2023-07-19 Thread Hin-Tak Leung
 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)

2023-07-19 Thread Alexei Podtelezhnikov
> > 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)

2023-07-19 Thread Hin-Tak Leung
 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

2023-07-19 Thread Craig White
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)

2023-07-19 Thread Alexei Podtelezhnikov
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)

2023-07-19 Thread Laurence Penney
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

2023-07-19 Thread Werner LEMBERG


> 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

2023-07-19 Thread Patrick Lam
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

2023-07-19 Thread Brad Neimann
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

2023-07-19 Thread Patrick Lam
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