Skip to content

Commit

Permalink
Merge pull request #6324 from Sokigo-GLS/branch-allow-missing-glyph
Browse files Browse the repository at this point in the history
Try to fallback to using a question mark if a glyph is missing in a font
  • Loading branch information
rouault committed May 25, 2021
2 parents 67115b3 + a72d95c commit 8204b17
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
16 changes: 14 additions & 2 deletions fontcache.c
Expand Up @@ -287,8 +287,14 @@ glyph_element* msGetGlyphByIndex(face_element *face, unsigned int size, unsigned
FT_Set_Pixel_Sizes(face->face,0,MS_NINT(size * 96/72.0));
}
error = FT_Load_Glyph(face->face,key.codepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
if (error) {
msDebug("Unable to load glyph %u for font \"%s\". Using ? as fallback.\n", key.codepoint, face->font);
// If we can't find a glyph then try to fallback to a question mark.
unsigned int fallbackCodepoint = msGetGlyphIndex(face, 0x3F);
error = FT_Load_Glyph(face->face,fallbackCodepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
}
if(error) {
msSetError(MS_MISCERR, "unable to load glyph %ud for font \"%s\"", "msGetGlyphByIndex()",key.codepoint, face->font);
msSetError(MS_MISCERR, "unable to load glyph %u for font \"%s\"", "msGetGlyphByIndex()",key.codepoint, face->font);
free(gc);
#ifdef USE_THREAD
if (use_global_ft_cache)
Expand Down Expand Up @@ -335,8 +341,14 @@ outline_element* msGetGlyphOutline(face_element *face, glyph_element *glyph) {
pen.x = pen.y = 0;
FT_Set_Transform(face->face, &matrix, &pen);
error = FT_Load_Glyph(face->face,glyph->key.codepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP/*|FT_LOAD_IGNORE_TRANSFORM*/|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
if (error) {
msDebug("Unable to load glyph %u for font \"%s\". Using ? as fallback.\n", glyph->key.codepoint, face->font);
// If we can't find a glyph then try to fallback to a question mark.
unsigned int fallbackCodepoint = msGetGlyphIndex(face, 0x3F);
error = FT_Load_Glyph(face->face,fallbackCodepoint,FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP/*|FT_LOAD_IGNORE_TRANSFORM*/|FT_LOAD_NO_HINTING|FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
}
if(error) {
msSetError(MS_MISCERR, "unable to load glyph %ud for font \"%s\"", "msGetGlyphByIndex()",glyph->key.codepoint, face->font);
msSetError(MS_MISCERR, "unable to load glyph %u for font \"%s\"", "msGetGlyphOutline()",glyph->key.codepoint, face->font);
#ifdef USE_THREAD
if (use_global_ft_cache)
msReleaseLock(TLOCK_TTF);
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions msautotest/renderers/font-fail.map
@@ -1,5 +1,6 @@
# RUN_PARMS: font-fail-key.txt [MAPSERV] QUERY_STRING="map=[MAPFILE]&mode=map&layer=l1" > [RESULT_DEVERSION]
# RUN_PARMS: font-fail-file.txt [MAPSERV] QUERY_STRING="map=[MAPFILE]&mode=map&layer=l2" > [RESULT_DEVERSION]
# RUN_PARMS: font-fail-missing-glyph.png [SHP2IMG] -m [MAPFILE] -l missing_glyph -i png -o [RESULT]

MAP

Expand Down Expand Up @@ -41,4 +42,21 @@ LAYER
FEATURE POINTS 50 50 END END
END

LAYER
NAME "missing_glyph"
STATUS ON
TYPE POLYGON
FEATURE
POINTS 0 0 400 0 400 300 0 300 0 0 END
END
CLASS
LABEL
TEXT 'this is a test: это проверка'
TYPE truetype
SIZE 8
FONT "default"
END
END
END

END
13 changes: 10 additions & 3 deletions textlayout.c
Expand Up @@ -242,7 +242,7 @@ static hb_position_t _ms_get_glyph_v_advance_func (hb_font_t *font, void *font_d
}
#endif

int WARN_UNUSED check_single_font(fontSetObj *fontset, char *fontkey, text_run *run, TextInfo *glyphs, int ignore_missing) {
static int check_single_font(fontSetObj *fontset, char *fontkey, text_run *run, TextInfo *glyphs, int ignore_missing) {
int i;
face_element *fcache = NULL;
if(fontset && fontkey) {
Expand All @@ -256,16 +256,23 @@ int WARN_UNUSED check_single_font(fontSetObj *fontset, char *fontkey, text_run *
run->face = fcache;
if(MS_UNLIKELY(!fcache)) return MS_FAILURE;
for(i=0; i<run->length; i++) {
int codepoint = msGetGlyphIndex(fcache, glyphs->unicodes[run->offset+i]);
unsigned int codepoint = msGetGlyphIndex(fcache, glyphs->unicodes[run->offset+i]);
if(codepoint || ignore_missing)
{
if( codepoint == 0 )
{
msDebug("Unable to find glyph for codepoint %u. Using ? as fallback.\n", glyphs->unicodes[run->offset+i]);
codepoint = msGetGlyphIndex(fcache, '?');
}
glyphs->codepoints[run->offset+i] = codepoint;
}
else
return MS_FAILURE;
}
return MS_SUCCESS;
}

int WARN_UNUSED get_face_for_run(fontSetObj *fontset, char *fontlist, text_run *run, TextInfo *glyphs) {
static int get_face_for_run(fontSetObj *fontset, char *fontlist, text_run *run, TextInfo *glyphs) {
char *startfont, *endfont;
#if defined(USE_HARFBUZZ) && defined(USE_FRIBIDI)
const char *prefix = NULL;
Expand Down

0 comments on commit 8204b17

Please sign in to comment.