Hi everyone,

I have been trying to use FreeType to render emojis. The goal was to see
how FreeType handles CBDT based fonts (by stepping through the code in GDB)
in the hope that it'd give me a better idea of how it'll handle OT-SVG
fonts. However, I couldn't make it work. Following is a description of the
whole issue. The code necessary to reproduce the case is attached.

*What am I trying to do here?*
I am trying to render emojis from a font called `joypixels-android'. You
can get the font file here <https://www.joypixels.com/download>. It's
`JoyPixels 4.5 Free' and I am using the font file that can be found in the
`Android' folder of the zip that you'll download from the site.

*How am I trying to do it?*
You can find the code in `hello.c' and compile it using `Makefile'. After
getting through the boiler plate, all I am doing is using
`FT_Get_First_Char' and `FT_Get_Next_Char' to get all the `charcodes' and
their corresponding `glyph indexes'. For each such pair, I am calling
`FT_Load_Glyph' and then `FT_Render_Glyph'. In the code you'll see that I
am calling `FT_Set_Char_Size' to set the size. Not sure if it makes any
sense with `CBDT' fonts, but I have tried removing it. The problem stays!

*What's the problem?*
If I call `FT_Set_Char_Size' in the program, it returns error code 0x17
which is `Invalid Pixel Size'. Secondly, `FT_Load_Glyph' returns error code
0x24 which is `Invalid Size Handle'. `FT_Load_Glyph' returns the same even
if I don't call `FT_Set_Char_Size' at all.

*Where are the errors coming from?*
The error 0x17, `Invalid Pixel Size' coming from `FT_Set_Char_Size' comes
from the function `FT_Match_Size' which is in `./src/base/ftobjs.c:2924'.
The trace message:
"FT_Match_Size: no matching bitmap strike" also comes up.
The error 0x24, `Invalid Size Handle' comes from `TT_Load_Glyph' which is
in `./src/truetype/ttgload.c:2718'. More specifically from the following
lines:

> 2831     /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
> 2832     if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid
> )
> 2833     {
> 2834       error = FT_THROW( Invalid_Size_Handle );
> 2835       goto Exit;
> 2836     }
> 2837


*My guess, so far?*
Something that really seems suspicious is that the my code doesn't make
into this `if' statement, while the comment indicates it should. The
snippet is from `TT_Load_Glyph' which is in `./src/truetype/ttgload.c:2718':

> 2733     /* try to load embedded bitmap (if any) */
> 2734     if ( size->strike_index != 0xFFFFFFFFUL      &&
> 2735          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
> 2736          IS_DEFAULT_INSTANCE                     )
> 2737     {

The reason why it doesn't do this is `size->strike_index' has the value `0x
0xFFFFFFFFUL'. So I tried to follow the code to see why strike index was
being set to this value. Turns out, it's set to this value at the time when
the `face->size' object is created. My guess is, some code in between
calling `FT_New_Face' and `FT_Load_Glyph' is supposed to set this strike
index. Maybe this should have happened in `FT_Set_Char_Size' but it also
runs into an error before reaching that point, as I have already mentioned.

*Files attached*

   1. *hello.c:* The main code
   2. *Makefile: *The Makefile for linking it to the FreeType I have
   installed on my machine
   3. *Makefile-debug: *The Makefile I am using to link it with a gdb
   debuggable build of FreeType with tracing enabled.
   4. *trace.txt: *Contains a very verbose trace of the program. I have
   removed the last lines because they were simple repetitions (due to the
   while loop).

*Notes:*

   1. I am linking against `FreeType 2.10.0'
   2. I am getting the same issue with any other emoji font I can find.

Please feel free to ask me for more details. :)

Thank you,
Moazin
FT_Open_Face: Requesting face 0
FT_Stream_Open: opened `joypixels-android.ttf' (19316880 bytes) successfully
TTF driver
  SFNT driver
sfnt_open_font: synthesize TTC
sfnt_init_face: 0x56509a668ce0 (index 0)
tt_face_load_font_dir: 0x56509a668ce0
FT_Stream_EnterFrame: 8 bytes
FT_Stream_ExitFrame
-- Number of tables:         13
-- Format version:   0x00010000
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 16 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 208 bytes

  tag    offset    length   checksum
  ----------------------------------
  CBDT  0000319c  0125e938  5ce48f7b
  CBLC  01261ad4  00002a34  4d89db91
  GSUB  01264508  0000669a  e1dde4fc
  OS/2  00000158  00000060  760467d7
  cmap  00002090  00000e15  91b90627
  head  000000dc  00000036  0f49bed9
  hhea  00000114  00000024  11640d0f
  hmtx  000001b8  00001ed8  2c020000
  maxp  00000138  00000020  0aa40039
  name  00002ea8  000002d2  3af3706e
  post  0000317c  00000020  fb270084
  vhea  0126aba4  00000024  0e5e04cc
  vmtx  0126abc8  000014c6  13880000
FT_Stream_ExitFrame
table directory loaded

tt_face_lookup_table: 0x56509a668ce0, `fvar' -- could not find table
tt_face_lookup_table: 0x56509a668ce0, `glyf' -- could not find table
tt_face_lookup_table: 0x56509a668ce0, `CFF2' -- could not find table
tt_face_lookup_table: 0x56509a668ce0, `CFF ' -- could not find table
sfnt_load_face: 0x56509a668ce0

tt_face_lookup_table: 0x56509a668ce0, `glyf' -- could not find table
tt_face_lookup_table: 0x56509a668ce0, `CFF ' -- could not find table
tt_face_lookup_table: 0x56509a668ce0, `CFF2' -- could not find table
tt_face_lookup_table: 0x56509a668ce0, `sbix' -- could not find table
`bhed' -->
tt_face_lookup_table: 0x56509a668ce0, `bhed' -- could not find table
missing

`head' -->
tt_face_lookup_table: 0x56509a668ce0, `head' -- found table.
FT_Stream_EnterFrame: 54 bytes
FT_Stream_ExitFrame
Units per EM: 2048
IndexToLoc:      0
loaded

tt_face_lookup_table: 0x56509a668ce0, `CBLC' -- found table.
tt_face_lookup_table: 0x56509a668ce0, `CBDT' -- found table.
`maxp' -->
tt_face_lookup_table: 0x56509a668ce0, `maxp' -- found table.
FT_Stream_EnterFrame: 6 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 26 bytes
FT_Stream_ExitFrame
numGlyphs: 2656
loaded

`cmap' -->
tt_face_lookup_table: 0x56509a668ce0, `cmap' -- found table.
FT_Stream_EnterFrame: 3605 bytes
loaded

`name' -->
tt_face_lookup_table: 0x56509a668ce0, `name' -- found table.
FT_Stream_EnterFrame: 6 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 180 bytes
FT_Stream_ExitFrame
loaded

`post' -->
tt_face_lookup_table: 0x56509a668ce0, `post' -- found table.
FT_Stream_EnterFrame: 32 bytes
FT_Stream_ExitFrame
FormatType:   0x30000
isFixedPitch:     yes
loaded

`hhea' -->
tt_face_lookup_table: 0x56509a668ce0, `hhea' -- found table.
FT_Stream_EnterFrame: 36 bytes
FT_Stream_ExitFrame
Ascender:           1900
Descender:          -500
number_Of_Metrics:  1292
loaded

`hmtx' -->
tt_face_lookup_table: 0x56509a668ce0, `hmtx' -- found table.
loaded

`vertical hhea' -->
tt_face_lookup_table: 0x56509a668ce0, `vhea' -- found table.
FT_Stream_EnterFrame: 36 bytes
FT_Stream_ExitFrame
Ascender:           1275
Descender:         -1275
number_Of_Metrics:     3
loaded

`vertical hmtx' -->
tt_face_lookup_table: 0x56509a668ce0, `vmtx' -- found table.
loaded

`os2' -->
tt_face_lookup_table: 0x56509a668ce0, `OS/2' -- found table.
FT_Stream_EnterFrame: 78 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 8 bytes
FT_Stream_ExitFrame
FT_Stream_EnterFrame: 10 bytes
FT_Stream_ExitFrame
sTypoAscender:  1900
sTypoDescender: -500
usWinAscent:    1900
usWinDescent:    500
fsSelection:    0x40
loaded

`eblc' -->
tt_face_lookup_table: 0x56509a668ce0, `CBLC' -- found table.
FT_Stream_EnterFrame: 10804 bytes
tt_face_load_sbit_strikes: found 1 strikes
tt_face_lookup_table: 0x56509a668ce0, `CBDT' -- found table.
loaded

`cpal' -->
tt_face_lookup_table: 0x56509a668ce0, `CPAL' -- could not find table
missing

`colr' -->
failed to load

`pclt' -->
tt_face_lookup_table: 0x56509a668ce0, `PCLT' -- could not find table
missing

`gasp' -->
tt_face_lookup_table: 0x56509a668ce0, `gasp' -- could not find table
missing

`kern' -->
tt_face_lookup_table: 0x56509a668ce0, `kern' -- could not find table
missing

sfnt_load_face: done
tt_face_lookup_table: 0x56509a668ce0, `hdmx' -- could not find table
FT_Open_Face: New face object, adding to list
FT_Open_Face: Creating glyph slot
FT_New_GlyphSlot: Creating new slot object
FT_New_GlyphSlot: Return 0x0
FT_Open_Face: Creating size object
FT_Open_Face: Return 0x0
FT_Match_Size: no matching bitmap strike
FT_Request_Size (truetype driver):
  x scale: 65536 (1.000000)
  y scale: 65536 (1.000000)
  ascender: 0.000000
  descender: 0.000000
  height: 0.000000
  max advance: 0.000000
  x ppem: 0
  y ppem: 0
TT_Load_Glyph: glyph index 1
  failed (error code 0x24)
TT_Load_Glyph: glyph index 2
  failed (error code 0x24)
TT_Load_Glyph: glyph index 3
  failed (error code 0x24)
TT_Load_Glyph: glyph index 4
  failed (error code 0x24)
TT_Load_Glyph: glyph index 5
  failed (error code 0x24)
TT_Load_Glyph: glyph index 6
  failed (error code 0x24)
TT_Load_Glyph: glyph index 7
  failed (error code 0x24)
TT_Load_Glyph: glyph index 8
  failed (error code 0x24)
TT_Load_Glyph: glyph index 9
  failed (error code 0x24)
TT_Load_Glyph: glyph index 10
  failed (error code 0x24)
[...]

Attachment: Makefile
Description: Binary data

Attachment: Makefile-debug
Description: Binary data

#include <stdio.h>
#include <string.h>
#include <ft2build.h>
#include FT_FREETYPE_H

int main(void){
    FT_Library ft;
    if(FT_Init_FreeType(&ft)){
        printf("Error");
        return 1;
    }
    FT_Face face;
    if(FT_New_Face(ft, "joypixels-android.ttf", 0, &face)) {
        printf("Error");
	return 1;
    }
    FT_Error err = FT_Set_Char_Size(face, 0, 16*64, 300, 300);
    printf("%d\n", err);
    FT_ULong charcode;
    FT_UInt gindex;
    charcode = FT_Get_First_Char(face, &gindex);
    while(gindex != 0){
        printf("(%lu, %u)\n", charcode, gindex);
        FT_Error err = FT_Load_Glyph(face, gindex, FT_LOAD_DEFAULT|FT_LOAD_COLOR);
        printf("%d\n", err);
        FT_GlyphSlot g = face->glyph;
        err = FT_Render_Glyph(g, FT_RENDER_MODE_NORMAL);
        /* Do everything with the glyph here */         
        charcode = FT_Get_Next_Char(face, charcode, &gindex);
    }

    return 0;
}
_______________________________________________
Freetype-devel mailing list
Freetype-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/freetype-devel

Reply via email to