nothings / stb

stb single-file public domain libraries for C/C++
https://twitter.com/nothings
Other
25.8k stars 7.66k forks source link

[stb_truetype] stbtt_FindGlyphIndex, file stb_truetype.h, line 1585. #1511

Open zeromake opened 10 months ago

zeromake commented 10 months ago

Describe the bug use macosx 13 PingFang.ttc stbtt_FindGlyphIndex Assertion failed

Assertion failed: (0), function stbtt_FindGlyphIndex, file stb_truetype.h, line 1585.

To Reproduce demo.c


#include <stdio.h>
#include <stdlib.h>
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

int main()
{
    FILE *fp = 0;
    int dataSize = 0;
    size_t readed;
    unsigned char *data = NULL;
    fp = fopen("PingFang.ttc", "rb");
    if (fp == NULL)
        goto error;
    fseek(fp, 0, SEEK_END);
    dataSize = (int)ftell(fp);
    fseek(fp, 0, SEEK_SET);
    data = (unsigned char *)malloc(dataSize);
    if (data == NULL)
        goto error;
    readed = fread(data, 1, dataSize, fp);
    fclose(fp);
    fp = 0;
    stbtt_fontinfo font;
    int offset = stbtt_GetFontOffsetForIndex(data, 0);
    stbtt_InitFont(&font, data, offset);
    stbtt_FindGlyphIndex(&font, 10);
    return 0;
error:
    if (data)
        free(data);
    if (fp)
        fclose(fp);
    return 1;
}
> ls
PingFang.ttc  demo.c
> curl -OL https://github.com/nothings/stb/raw/master/stb_truetype.h
> gcc demo.c
> ./a.out
Assertion failed: (0), function stbtt_FindGlyphIndex, file stb_truetype.h, line 1585.
fish: Job 1, './a.out' terminated by signal SIGABRT (Abort)

PingFang.ttc

nothings commented 10 months ago

See the line above: https://github.com/nothings/stb/blob/master/stb_truetype.h#L1584

The font doesn't contain a supported unicode-to-glyph mapping table. There are multiple types, and stb_truetype handles all the major types, but apparently this file has one we don't support.

zeromake commented 10 months ago

@nothings

stbtt_uint16 format = ttUSHORT(data + index_map + 0);
// format = 14
nothings commented 10 months ago

Format 14: Unicode Variation Sequences

Subtable format 14 specifies the Unicode Variation Sequences (UVSes) supported by the font. A Variation Sequence, according to the Unicode Standard, comprises a base character followed by a variation selector; e.g. <U+82A6, U+E0101>.

The subtable partitions the UVSes supported by the font into two categories: “default” and “non-default” UVSes. Given a UVS, if the glyph obtained by looking up the base character of that sequence in the Unicode encoding subtable (i.e. the UCS-4 or the BMP encoding subtable) is the glyph to use for that sequence, then the sequence is a “default” UVS; otherwise it is a “non-default” UVS, and the glyph to use for that sequence is specified in the format 14 subtable itself.

The example below shows how a font vendor can use format 14 for a JIS-2004–aware font.

(Note the presence of 24-bit integers in the structures used. The type 14 'cmap' subtable does not keep data aligned to four-byte boundaries. This is also the only 'cmap' subtable which does not stand by itself and is not completely independent of all others; a 'cmap' may not consist of a type 14 subtable alone.)

zeromake commented 10 months ago

Format 14: Unicode Variation Sequences