aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fontsrv
diff options
context:
space:
mode:
authorFazlul Shahriar <fshahriar@gmail.com>2018-06-22 16:43:17 -0400
committerDavid du Colombier <0intro@gmail.com>2018-10-05 23:38:31 +0200
commit48da9bd71ddae0c51f8aff4c0d6806a8e32c4e23 (patch)
tree47af35532b23f284a3f84588f08eb442b8701889 /src/cmd/fontsrv
parentdb27122d3942ebec4471c260403d87cdd6541add (diff)
downloadplan9port-48da9bd71ddae0c51f8aff4c0d6806a8e32c4e23.tar.gz
plan9port-48da9bd71ddae0c51f8aff4c0d6806a8e32c4e23.tar.bz2
plan9port-48da9bd71ddae0c51f8aff4c0d6806a8e32c4e23.zip
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 (limited to 'src/cmd/fontsrv')
-rw-r--r--src/cmd/fontsrv/x11.c81
1 files changed, 43 insertions, 38 deletions
diff --git a/src/cmd/fontsrv/x11.c b/src/cmd/fontsrv/x11.c
index a097ca4d..455e8126 100644
--- 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