shithub: fnt

Download patch

ref: 9377e269215159537789b955e0743755c1bd2cef
parent: e3ee7778d1321c57f818466f7fc1672dec56f283
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Sep 2 15:34:22 EDT 2024

otfglyf: correctly handle outlines vs bitmaps, don't search for "glyf" table more than once

--- a/otf.c.in
+++ b/otf.c.in
@@ -772,6 +772,7 @@
 Glyf *
 otfglyf(Otf *o, int index, RasterOpts *opts)
 {
+	static TableRecord noGlyf;
 	int off, len, i;
 	Glyf *g;
 
@@ -779,15 +780,10 @@
 		werrstr("index out of range");
 		return nil;
 	}
-	g = nil;
 	if(o->td.head == nil){
 		werrstr("no head table");
-		goto err;
+		return nil;
 	}
-	if(o->td.loca == nil){
-		werrstr("no loca table");
-		goto err;
-	}
 	if((g = calloc(1, sizeof(*g))) == nil){
 		werrstr("no memory");
 		return nil;
@@ -801,48 +797,42 @@
 				break;
 			}
 		}
-		if(o->glyf == nil){
-			werrstr("no glyf table");
-			goto err;
-		}
+		if(o->glyf == nil)
+			o->glyf = &noGlyf;
 	}
-	if(o->indexToLocFormat == 0){
-		off = (int)o->td.loca->shortOffsets[index]*2;
-		len = (int)o->td.loca->shortOffsets[index+1]*2 - off;
-	}else{
-		off = o->td.loca->longOffsets[index];
-		len = o->td.loca->longOffsets[index+1] - off;
-	}
-	if(len < 1) /* no outlines */
-		return g;
+	if(o->glyf != &noGlyf && o->td.loca != nil){
+		if(o->indexToLocFormat == 0){
+			off = (int)o->td.loca->shortOffsets[index]*2;
+			len = (int)o->td.loca->shortOffsets[index+1]*2 - off;
+		}else{
+			off = o->td.loca->longOffsets[index];
+			len = o->td.loca->longOffsets[index+1] - off;
+		}
 
-	if(otfpushrange(o, o->glyf->offset, o->glyf->length) < 0)
-		goto err;
-	if(otfpushrange(o, off, len) < 0)
-		goto err;
-	if(read_Glyf(o, g) < 0){
-		free(g);
-		g = nil;
-	}
-	otfpoprange(o);
-	otfpoprange(o);
-
-	return g;
+		if(len > 0){
+			if(otfpushrange(o, o->glyf->offset, o->glyf->length) < 0){
 err:
-	free(g);
-	g = nil;
-	otfpopranges(o);
-
-	if(o->td.eblc != nil && o->td.ebdt != nil){
-		if((g = calloc(1, sizeof(*g))) == nil){
-			werrstr("no memory");
-			goto err;
+				free(g);
+				otfpopranges(o);
+				return nil;
+			}
+			if(otfpushrange(o, off, len) < 0)
+				goto err;
+			if(read_Glyf(o, g) < 0)
+				goto err;
+			otfpoprange(o);
+			otfpoprange(o);
+			return g;
 		}
-		g->index = index;
-		g = bitglyf(o, g, opts);
+		if(o->td.eblc == nil && o->td.ebdt == nil)
+			return g;
 	}
 
-	return g;
+	if(o->td.eblc != nil && o->td.ebdt != nil)
+		return bitglyf(o, g, opts);
+
+	free(g);
+	return nil;
 }
 
 int
--- a/plan9/otf.c
+++ b/plan9/otf.c
@@ -773,6 +773,7 @@
 Glyf *
 otfglyf(Otf *o, int index, RasterOpts *opts)
 {
+	static TableRecord noGlyf;
 	int off, len, i;
 	Glyf *g;
 
@@ -780,15 +781,10 @@
 		werrstr("index out of range");
 		return nil;
 	}
-	g = nil;
 	if(o->td.head == nil){
 		werrstr("no head table");
-		goto err;
+		return nil;
 	}
-	if(o->td.loca == nil){
-		werrstr("no loca table");
-		goto err;
-	}
 	if((g = calloc(1, sizeof(*g))) == nil){
 		werrstr("no memory");
 		return nil;
@@ -802,48 +798,42 @@
 				break;
 			}
 		}
-		if(o->glyf == nil){
-			werrstr("no glyf table");
-			goto err;
-		}
+		if(o->glyf == nil)
+			o->glyf = &noGlyf;
 	}
-	if(o->indexToLocFormat == 0){
-		off = (int)o->td.loca->shortOffsets[index]*2;
-		len = (int)o->td.loca->shortOffsets[index+1]*2 - off;
-	}else{
-		off = o->td.loca->longOffsets[index];
-		len = o->td.loca->longOffsets[index+1] - off;
-	}
-	if(len < 1) /* no outlines */
-		return g;
+	if(o->glyf != &noGlyf && o->td.loca != nil){
+		if(o->indexToLocFormat == 0){
+			off = (int)o->td.loca->shortOffsets[index]*2;
+			len = (int)o->td.loca->shortOffsets[index+1]*2 - off;
+		}else{
+			off = o->td.loca->longOffsets[index];
+			len = o->td.loca->longOffsets[index+1] - off;
+		}
 
-	if(otfpushrange(o, o->glyf->offset, o->glyf->length) < 0)
-		goto err;
-	if(otfpushrange(o, off, len) < 0)
-		goto err;
-	if(read_Glyf(o, g) < 0){
-		free(g);
-		g = nil;
-	}
-	otfpoprange(o);
-	otfpoprange(o);
-
-	return g;
+		if(len > 0){
+			if(otfpushrange(o, o->glyf->offset, o->glyf->length) < 0){
 err:
-	free(g);
-	g = nil;
-	otfpopranges(o);
-
-	if(o->td.eblc != nil && o->td.ebdt != nil){
-		if((g = calloc(1, sizeof(*g))) == nil){
-			werrstr("no memory");
-			goto err;
+				free(g);
+				otfpopranges(o);
+				return nil;
+			}
+			if(otfpushrange(o, off, len) < 0)
+				goto err;
+			if(read_Glyf(o, g) < 0)
+				goto err;
+			otfpoprange(o);
+			otfpoprange(o);
+			return g;
 		}
-		g->index = index;
-		g = bitglyf(o, g, opts);
+		if(o->td.eblc == nil && o->td.ebdt == nil)
+			return g;
 	}
 
-	return g;
+	if(o->td.eblc != nil && o->td.ebdt != nil)
+		return bitglyf(o, g, opts);
+
+	free(g);
+	return nil;
 }
 
 int
--