From 0a1016331c20944cec1634bd8b615240f93e41dc Mon Sep 17 00:00:00 2001 From: Chris Young Date: Tue, 9 Apr 2019 15:40:04 +0100 Subject: [PATCH 1/5] Add functions to extract SVG glyphs from font. The fucntions are: stbtt_GetCodepointSVG - provides a pointer to the SVG data in the supplied argument, and returns the length of this data stbtt_GetGlyphSVG - As above but takes the glyph index instead of the codepoint Note that the returned data may be deflate compressed. --- stb_truetype.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/stb_truetype.h b/stb_truetype.h index 767f005..2ae1dfe 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -702,7 +702,7 @@ struct stbtt_fontinfo int numGlyphs; // number of glyphs, needed for range checking - int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf int index_map; // a cmap mapping for our chosen character encoding int indexToLocFormat; // format needed to map from glyph index to glyph @@ -829,6 +829,11 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); // frees the data allocated above +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); +// fills svg with the font's SVG data. +// returns data size or 0 if SVG not found. + ////////////////////////////////////////////////////////////////////////////// // // BITMAP RENDERING @@ -1409,6 +1414,14 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in else info->numGlyphs = 0xffff; + t = stbtt__find_table(data, fontstart, "SVG "); + if (t) { + stbtt_uint32 offset = ttULONG(data + t + 2); + info->svg = t + offset; + } else { + info->svg = 0; + } + // find a cmap encoding table we understand *now* to avoid searching // later. (todo: could make this installable) // the same regardless of glyph. @@ -2602,6 +2615,44 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) STBTT_free(v, info->userdata); } +STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) +{ + stbtt_uint8 *data = info->data; + stbtt_uint8 *svg_doc_list = data + info->svg; + + int numEntries = ttUSHORT(svg_doc_list); + stbtt_uint8 *svg_docs = svg_doc_list + 2; + + for(int i=0; i= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) + return svg_doc; + } + return 0; +} + +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg) +{ + stbtt_uint8 *data = info->data; + stbtt_uint8 *svg_doc; + + if(info->svg == 0) + return 0; + + if(svg_doc = stbtt_FindSVGDoc(info, gl)) { + *svg = (void *)data + info->svg + ttULONG(svg_doc + 4); + return ttULONG(svg_doc + 8); + } else { + return 0; + } +} + +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg) +{ + return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg); +} + ////////////////////////////////////////////////////////////////////////////// // // antialiasing software rasterizer From 4e0c494515f6cbe202b7357e6fd2de3f8bc9da62 Mon Sep 17 00:00:00 2001 From: Georgy Macharadze Date: Mon, 22 Apr 2019 14:06:05 +0300 Subject: [PATCH 2/5] stb_image: fixed 'out' nulled but not freed upon failure If realloc fails it returns NULL and out pointer becomes invalid. To fix this it is necessary to store realloc return value in temporary pointer and then compare it with NULL. If it equals NULL then return error and source pointer will still valid. This error was caught by cppcheck: Common realloc mistake: 'out' nulled but not freed upon failure. --- stb_image.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/stb_image.h b/stb_image.h index 8b71060..c1a1938 100644 --- a/stb_image.h +++ b/stb_image.h @@ -6589,7 +6589,15 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, stride = g.w * g.h * 4; if (out) { - out = (stbi_uc*) STBI_REALLOC( out, layers * stride ); + void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride ); + if (NULL == tmp) { + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + return stbi__errpuc("outofmem", "Out of memory"); + } + else + out = tmp; if (delays) { *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); } From f7d1cd581e09fc559cf6d400ec707ab3bc70e0b0 Mon Sep 17 00:00:00 2001 From: Brotcrunsher Date: Tue, 30 Apr 2019 16:30:03 +0200 Subject: [PATCH 3/5] Allowing Compound Glyphs with `numberOfContours < -1` While it is recommended that the numberOfContours are set to -1 for compound glyphs, it is allowed to have any negative value. Source: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html However, I don't know if this happens in practice. --- stb_truetype.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/stb_truetype.h b/stb_truetype.h index 767f005..d6d5f8f 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -1757,7 +1757,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s } } num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - } else if (numberOfContours == -1) { + } else if (numberOfContours < 0) { // Compound shapes. int more = 1; stbtt_uint8 *comp = data + g + 10; @@ -1834,9 +1834,6 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s // More components ? more = flags & (1<<5); } - } else if (numberOfContours < 0) { - // @TODO other compound variations? - STBTT_assert(0); } else { // numberOfCounters == 0, do nothing } From fe6bef23075aaf72a4fd264f25cc9e2cffcb62b5 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 2 Feb 2020 08:14:00 -0800 Subject: [PATCH 4/5] stb_truetype: clean up svg support --- stb_truetype.h | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/stb_truetype.h b/stb_truetype.h index c2c9438..47d8b56 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -833,7 +833,7 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertice STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); -// fills svg with the font's SVG data. +// fills svg with the character's SVG data. // returns data size or 0 if SVG not found. ////////////////////////////////////////////////////////////////////////////// @@ -1337,6 +1337,22 @@ static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) return stbtt__cff_get_index(&cff); } +// since most people won't use this, find this table the first time it's needed +static int stbtt__get_svg(stbtt_fontinfo *info) +{ + stbtt_uint32 t; + if (info->svg < 0) { + t = stbtt__find_table(info->data, info->fontstart, "SVG "); + if (t) { + stbtt_uint32 offset = ttULONG(info->data + t + 2); + info->svg = t + offset; + } else { + info->svg = 0; + } + } + return info->svg; +} + static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) { stbtt_uint32 cmap, t; @@ -1416,14 +1432,8 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in else info->numGlyphs = 0xffff; - t = stbtt__find_table(data, fontstart, "SVG "); - if (t) { - stbtt_uint32 offset = ttULONG(data + t + 2); - info->svg = t + offset; - } else { - info->svg = 0; - } - + info->svg = -1; + // find a cmap encoding table we understand *now* to avoid searching // later. (todo: could make this installable) // the same regardless of glyph. @@ -2618,17 +2628,17 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) { + int i; stbtt_uint8 *data = info->data; - stbtt_uint8 *svg_doc_list = data + info->svg; + stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info); int numEntries = ttUSHORT(svg_doc_list); stbtt_uint8 *svg_docs = svg_doc_list + 2; - for(int i=0; i= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) - return svg_doc; + if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) + return svg_doc; } return 0; } @@ -2642,7 +2652,7 @@ STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char * return 0; if(svg_doc = stbtt_FindSVGDoc(info, gl)) { - *svg = (void *)data + info->svg + ttULONG(svg_doc + 4); + *svg = (char *)data + info->svg + ttULONG(svg_doc + 4); return ttULONG(svg_doc + 8); } else { return 0; From 28cc61a1ff9c65bab78b278b1185dc4fc3359826 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 2 Feb 2020 08:16:58 -0800 Subject: [PATCH 5/5] stb_image: fix previous fix --- stb_image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stb_image.h b/stb_image.h index c02359b..4de0ca1 100644 --- a/stb_image.h +++ b/stb_image.h @@ -6657,7 +6657,7 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, return stbi__errpuc("outofmem", "Out of memory"); } else - out = tmp; + out = (stbi_uc*) tmp; if (delays) { *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); }