plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

commit 48da9bd71ddae0c51f8aff4c0d6806a8e32c4e23
parent db27122d3942ebec4471c260403d87cdd6541add
Author: Fazlul Shahriar <fshahriar@gmail.com>
Date:   Fri, 22 Jun 2018 16:43:17 -0400

fontsrv: copy some fixes from OS X to X11

* Avoid allocating empty images by adding 1 to width/height. This was
  crashing fontsrv. The total width of the subfont image can be zero
  even if the characters are present in the font. For example, all the
  characters in x0300.bit (part of "Combining Diacritical Marks" Unicode
  block) have zero width.
* Make sure U+0000 is always present in the font, otherwise libdraw
  complains with: "stringwidth: bad character set for rune 0x0000 in ..."
* Use the same fallback glyph (pjw face) as OS X. This also fixes a bug
  where advance was set to the total width of subfont instead of the
  character.

Update #125 (most likely fixes the crash if in X11)

Change-Id: Icdc2b641b8b0c08644569006e91cf613b4d5477f

Diffstat:
Msrc/cmd/fontsrv/x11.c | 81++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 43 insertions(+), 38 deletions(-)

diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c @@ -66,19 +66,16 @@ load(XFont *f) return; e = FT_New_Face(lib, f->fontfile, f->index, &face); - if(e){ fprint(2, "load failed for %s (%s) index:%d\n", f->name, f->fontfile, f->index); return; } - if(!FT_IS_SCALABLE(face)) { fprint(2, "%s is a non scalable font, skipping\n", f->name); FT_Done_Face(face); - f->loaded = 1; + f->loaded = 1; return; } - f->unit = face->units_per_EM; f->height = (int)((face->ascender - face->descender) * 1.2); f->originy = face->descender; // bbox.yMin (or descender) is negative, becase the baseline is y-coord 0 @@ -96,7 +93,11 @@ load(XFont *f) f->nrange++; } } - + // libdraw expects U+0000 to be present + if(!f->range[0]) { + f->range[0] = 1; + f->nrange++; + } FT_Done_Face(face); f->loaded = 1; } @@ -108,14 +109,13 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) FT_Error e; Memimage *m, *mc, *m1; double pixel_size; - int x, y, y0; + int w, x, y, y0; int i; Fontchar *fc, *fc0; Memsubfont *sf; //Point rect_points[4]; e = FT_New_Face(lib, xf->fontfile, xf->index, &face); - if(e){ fprint(2, "load failed for %s (%s) index:%d\n", xf->name, xf->fontfile, xf->index); return nil; @@ -129,16 +129,16 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) } pixel_size = (dpi*size)/72.0; - x = (int)((face->max_advance_width) * pixel_size/xf->unit + 0.99999999); + w = x = (int)((face->max_advance_width) * pixel_size/xf->unit + 0.99999999); y = (int)((face->ascender - face->descender) * pixel_size/xf->unit + 0.99999999); y0 = (int)(-face->descender * pixel_size/xf->unit + 0.99999999); - m = allocmemimage(Rect(0, 0, x*(hi+1-lo), y), antialias ? GREY8 : GREY1); + m = allocmemimage(Rect(0, 0, x*(hi+1-lo)+1, y+1), antialias ? GREY8 : GREY1); if(m == nil) { FT_Done_Face(face); return nil; } - mc = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1); + mc = allocmemimage(Rect(0, 0, x+1, y+1), antialias ? GREY8 : GREY1); if(mc == nil) { freememimage(m); FT_Done_Face(face); @@ -165,41 +165,42 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) x = 0; for(i=lo; i<=hi; i++, fc++) { - int r; + int k, r; int advance; memfillcolor(mc, DBlack); - e = FT_Load_Char(face, i, FT_LOAD_RENDER|FT_LOAD_NO_HINTING|(antialias ? 0:FT_LOAD_TARGET_MONO)); - if(e){ - fprint(2, "FT_Load_Char failed for %d\n", i); - //mempoly(mc, rect_points, 4, Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, m->r.min, Pt(m->r.max.x, m->r.min.y), Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, m->r.min, Pt(m->r.min.x, m->r.max.y), Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, Pt(m->r.max.x, m->r.min.y), m->r.max, Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, Pt(m->r.min.x, m->r.max.y), m->r.max, Endsquare, Endsquare, 0, memopaque, ZP, S); - memimageline(mc, m->r.min, m->r.max, Endsquare, Endsquare, 0, memopaque, ZP, S); - advance = Dx(m->r); - - memimagedraw(m, Rect(x, 0, x + advance, y), mc, ZP, memopaque, ZP, S); - } else { - FT_Bitmap *bitmap = &face->glyph->bitmap; - uchar *base = byteaddr(mc, mc->r.min); - advance = (face->glyph->advance.x+32) >> 6; - - for(r=0; r < bitmap->rows; r++) - memmove(base + r*mc->width*sizeof(u32int), bitmap->buffer + r*bitmap->pitch, bitmap->pitch); - - memimagedraw(m, Rect(x, 0, x + advance, y), mc, - Pt(-face->glyph->bitmap_left, -(y - y0 - face->glyph->bitmap_top)), - memopaque, ZP, S); - } - fc->x = x; fc->top = 0; - fc->bottom = y; - fc->left = 0; + fc->bottom = Dy(m->r); + e = 1; + k = FT_Get_Char_Index(face, i); + if(k != 0) { + e = FT_Load_Glyph(face, k, FT_LOAD_RENDER|FT_LOAD_NO_HINTING|(antialias ? 0:FT_LOAD_TARGET_MONO)); + } + if(e || face->glyph->advance.x <= 0) { + fc->width = 0; + fc->left = 0; + if(i == 0) { + drawpjw(m, fc, x, w, y, y - y0); + x += fc->width; + } + continue; + } + + FT_Bitmap *bitmap = &face->glyph->bitmap; + uchar *base = byteaddr(mc, mc->r.min); + advance = (face->glyph->advance.x+32) >> 6; + + for(r=0; r < bitmap->rows; r++) + memmove(base + r*mc->width*sizeof(u32int), bitmap->buffer + r*bitmap->pitch, bitmap->pitch); + + memimagedraw(m, Rect(x, 0, x + advance, y), mc, + Pt(-face->glyph->bitmap_left, -(y - y0 - face->glyph->bitmap_top)), + memopaque, ZP, S); + fc->width = advance; + fc->left = 0; x += advance; #ifdef DEBUG_FT_BITMAP @@ -229,6 +230,10 @@ mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias) // round up to 32-bit boundary // so that in-memory data is same // layout as in-file data. + if(x == 0) + x = 1; + if(y == 0) + y = 1; if(antialias) x += -x & 3; else