shithub: pdffs

Download patch

ref: 5949d53a09a809482abc6fc4e4db6e8c8266afd0
parent: 5de3c66e1b69bc857fd997fe52f5c324bf5f269a
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Aug 11 12:57:30 EDT 2023

this is not Go

--- a/main.c
+++ b/main.c
@@ -24,13 +24,11 @@
 	Page p;
 
 	pageinit(&p, page);
-	ret = pagerender(&p);
-	if(ret){
-		if(text){
-			if(p.buf.sz != 0)
-				fprint(1, "%s", (char*)p.buf.b);
-		}else
+	if((ret = pagerender(&p)) == 0){
+		if(!text)
 			writememimage(1, p.image);
+		else if(p.buf.sz != 0)
+			print("%s", (char*)p.buf.b);
 	}
 	pagefree(&p);
 
--- a/op.c
+++ b/op.c
@@ -71,10 +71,10 @@
 flagless(Op *op)
 {
 	if(op->flags != 0){
-		fprint(2, "Op '%s' expected no flags\n", op->s);
-		return 0;
+		werrstr("op %q: expected no flags", op->s);
+		return -1;
 	}
-	return 1;
+	return 0;
 }
 
 static int
@@ -81,7 +81,7 @@
 cobegin(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -88,16 +88,17 @@
 coend(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
 gspush(Op *op, Page *p)
 {
+	GS *r;
+
 	USED(op);
-	GS *r = realloc(p->GS, sizeof(GS) * (p->nGS + 1));
-	if(r == nil)
-		return 0;
+	if((r = realloc(p->GS, sizeof(GS) * (p->nGS + 1))) == nil)
+		return -1;
 	p->GS = r;
 	p->nGS++;
 	p->GSactive = &p->GS[p->nGS - 1];
@@ -106,11 +107,11 @@
 		p->GSactive->Font.widths = malloc(sizeof(int) * (p->GSactive->Font.last - p->GSactive->Font.first + 1));
 		if(p->GSactive->Font.widths == nil){
 			werrstr("gspush: out of memory allocating space for glyph widths");
-			return 0;
+			return -1;
 		}
 		memcpy(p->GSactive->Font.widths, p->GS[p->nGS - 2].Font.widths, sizeof(int) * (p->GSactive->Font.last - p->GSactive->Font.first + 1));
 	}
-	return 1;
+	return 0;
 }
 
 static int
@@ -120,11 +121,11 @@
 	free(p->GSactive->Font.widths);
 	GS *r = realloc(p->GS, sizeof(GS) * (p->nGS - 1));
 	if(r == nil)
-		return 0;
+		return -1;
 	p->GS = r;
 	p->nGS--;
 	p->GSactive = &p->GS[p->nGS - 1];
-	return 1;
+	return 0;
 }
 
 /* six parameters give the inputs a,b,c,d,e,f for the matrix
@@ -140,6 +141,7 @@
 {
 	double input[6];
 	int i;
+
 	for(i = 0; i < 6; i++)
 		input[i] = arrayget(p->stack, i)->num.d;
 	matmult(input, p->GSactive->CTM, p->GSactive->CTM);
@@ -151,8 +153,8 @@
 {
 	p->GSactive->LW = arrayget(p->stack, 0)->num.d;
 	if(p->GSactive->LW < 0){
-		werrstr("line width cannot be negative: %f", p->GSactive->LW);
-		return 0;
+		werrstr("gswidth: invalid line width: %f", p->GSactive->LW);
+		return -1;
 	}
 	return flagless(op);
 }
@@ -162,8 +164,8 @@
 {
 	p->GSactive->LC = arrayget(p->stack, 0)->num.d;
 	if(p->GSactive->LC > CapEND){
-		werrstr("invalid line cap: %d", p->GSactive->LC);
-		return 0;
+		werrstr("gscap: invalid line cap: %d", p->GSactive->LC);
+		return -1;
 	}
 	return flagless(op);
 }
@@ -173,8 +175,8 @@
 {
 	p->GSactive->LJ = arrayget(p->stack, 0)->num.d;
 	if(p->GSactive->LJ > JoinEND){
-		werrstr("invalid line join: %d", p->GSactive->LJ);
-		return 0;
+		werrstr("gsjoin: invalid line join: %d", p->GSactive->LJ);
+		return -1;
 	}
 	return flagless(op);
 }
@@ -184,8 +186,8 @@
 {
 	p->GSactive->ML = arrayget(p->stack, 0)->num.d;
 	if(p->GSactive->ML < 0){
-		werrstr("miter limit cannot be negative: %f", p->GSactive->ML);
-		return 0;
+		werrstr("gsmiterlim: invalidmiter limit: %f", p->GSactive->ML);
+		return -1;
 	}
 	return flagless(op);
 }
@@ -194,7 +196,7 @@
 gsdash(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -201,7 +203,7 @@
 gsintent(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -218,41 +220,44 @@
 	Object *gs, *o;
 	if((gs = dictget(dictget(dictget(p->obj, "Resources"), "ExtGState"), name)) == &null){
 		werrstr("extgstate dictionary not found: %s", name);
-		return 0;
+		goto err;
 	}
 	if((o = dictget(gs, "Type")) != &null && strcmp(o->name, "ExtGState") != 0){
 		werrstr("invalid type on ExtGState object: %s", o->name);
-		return 0;
+		goto err;
 	}
 	if((o = dictget(gs, "LW")) != &null){
 		if(o->type != Onum){
-			werrstr("line width must be a number, %d", o->type);
-			return 0;
+			werrstr("line width is not a number");
+			goto err;
 		}
 		p->GSactive->LW = o->num.d;
 	}
 	if((o = dictget(gs, "LC")) != &null){
 		if(o->type != Onum){
-			werrstr("line cap must be a number");
-			return 0;
+			werrstr("line cap is not a number");
+			goto err;
 		}
 		p->GSactive->LC = o->num.i;
 	}
 	if((o = dictget(gs, "LJ")) != &null){
 		if(o->type != Onum){
-			werrstr("line join must be a number");
-			return 0;
+			werrstr("line join is not a number");
+			goto err;
 		}
 		p->GSactive->LJ = o->num.i;
 	}
 	if((o = dictget(gs, "ML")) != &null){
 		if(o->type != Onum){
-			werrstr("miter limit must be a number");
-			return 0;
+			werrstr("miter limit is not a number");
+			goto err;
 		}
 		p->GSactive->ML = o->num.d;
 	}
 	return flagless(op);
+err:
+	werrstr("gsstate: %r");
+	return -1;
 }
 
 static int
@@ -259,7 +264,7 @@
 pcmove(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -266,7 +271,7 @@
 pcline(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -273,7 +278,7 @@
 pccurve(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -280,7 +285,7 @@
 pcsubpath(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -287,7 +292,7 @@
 pcrect(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -294,7 +299,7 @@
 ppstroke(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -301,7 +306,7 @@
 ppstrokec(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -308,7 +313,7 @@
 ppfill(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -315,7 +320,7 @@
 ppfills(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -322,7 +327,7 @@
 ppfillcfs(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -329,7 +334,7 @@
 ppc(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -336,11 +341,11 @@
 cpclip(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
-char *colorspacedevices[] = {"DeviceGray", "DeviceRGB", "DeviceCMYK"};
-ColorSpace colorspacechans[] = {
+static char *colorspacedevices[] = {"DeviceGray", "DeviceRGB", "DeviceCMYK"};
+static ColorSpace colorspacechans[] = {
 	[1] = DeviceGray,
 	[3] = DeviceRGB,
 	[4] = DeviceCMYK,
@@ -350,14 +355,15 @@
 iccbasedcspace(Object *icc, ColorSpace *c)
 {
 	Object *o;
+
 	*c = colorspacechans[dictint(icc, "N")];
 	if((o = dictget(icc, "Alternate")) != &null){
 		if(*c > 2 || strcmp(colorspacedevices[*c], o->name) != 0){
-			werrstr("ICCBased cspace: TODO: handle non-device alternate '%s'", o->name);
-			return 0;
+			werrstr("iccbasedcspace: TODO: handle non-device alternate %q", o->name);
+			return -1;
 		}
 	}
-	return 1;
+	return 0;
 }
 
 static int
@@ -368,27 +374,29 @@
 	char *s = arrayget(p->stack, 0)->name;
 	Object *o;
 	int i;
-	for(i = 0; i < 3; i++)
+
+	for(i = 0; i < nelem(colorspacedevices); i++){
 		if(strcmp(s, colorspacedevices[i]) == 0){
 			*c = i;
 			*color = i == 2 ? 0xFF : 0;
-			return 1;
+			return 0;
 		}
+	}
 	if((o = dictget(dictget(p->obj, "Resources"), "ColorSpace")) == &null
 		|| (o = dictget(o, s)) == &null){
-		werrstr("colorspace '%s' not found", s);
-		return 0;
+		werrstr("colorspace not found: %q", s);
+		return -1;
 	}
 	if(strcmp(arrayget(o, 0)->name, "ICCBased") == 0){
 		/* Don't support ICC; fall back to Alternate or default */
 		o = arrayget(o, 1);
 		if(!iccbasedcspace(o, c))
-			return 0;
+			return -1;
 		*color = *c == 2 ? 0xFF : 0;
-		return 1;
+		return 0;
 	}
-	werrstr("cspace: TODO: %s color space", arrayget(o, 0)->name);
-	return 0;
+	werrstr("cspace: TODO: color space %q", arrayget(o, 0)->name);
+	return -1;
 }
 
 static int
@@ -396,11 +404,12 @@
 {
 	ColorSpace c = op->flags & Nonstroking ? p->GSactive->NSCS : p->GSactive->SCS;
 	u32int *color = op->flags & Nonstroking ? &p->GSactive->NSC : &p->GSactive->SC;
+
 	if(c == DeviceRGB){
 		*color = ((u8int)(255 * arrayget(p->stack, 0)->num.d)) << 24 | ((u8int)(255 * arrayget(p->stack, 1)->num.d)) << 16 | ((u8int)(255 * arrayget(p->stack, 2)->num.d)) << 8 | 0xff;
-		return 1;
+		return 0;
 	}
-	return 0;
+	return -1;
 }
 
 static int
@@ -409,7 +418,7 @@
 	ColorSpace c = op->flags & Nonstroking ? p->GSactive->NSCS : p->GSactive->SCS;
 	if(c < 3)
 		return ccolour(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -416,12 +425,13 @@
 cgray(Op *op, Page *p)
 {
 	int value = 255 * arrayget(p->stack, 0)->num.d;
-	int i;
 	u32int *color;
+	int i;
+
 	if(op->flags & Nonstroking){
 		color = &p->GSactive->NSC;
 		p->GSactive->NSCS = DeviceGray;
-	} else{
+	}else{
 		color = &p->GSactive->SC;
 		p->GSactive->SCS = DeviceGray;
 	}
@@ -429,7 +439,7 @@
 	for(i = 0; i < 3; i++)
 		*color = (*color | value) << 8;
 	*color |= 255;
-	return 1;
+	return 0;
 }
 
 static int
@@ -436,7 +446,7 @@
 crgb(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -443,7 +453,7 @@
 ccmyk(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -450,7 +460,7 @@
 sshade(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -457,7 +467,7 @@
 eoobject(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -464,7 +474,7 @@
 iibegin(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -471,7 +481,7 @@
 iidata(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -478,7 +488,7 @@
 iiend(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -486,7 +496,7 @@
 {
 	USED(op);
 	p->TS.Tc = arrayget(p->stack, 0)->num.d;
-	return 1;
+	return 0;
 }
 
 static int
@@ -494,7 +504,7 @@
 {
 	USED(op);
 	p->TS.Tw = arrayget(p->stack, 0)->num.d;
-	return 1;
+	return 0;
 }
 
 static int
@@ -501,7 +511,7 @@
 tshscale(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -516,26 +526,30 @@
 {
 	Object *o;
 	int i;
+
 	if(p->GSactive->Font.widths != nil)
 		free(p->GSactive->Font.widths);
+	p->GSactive->Font.widths = nil;
+	p->GSactive->Font.first = -1;
+	p->GSactive->Font.last = -1;
 	o = dictget(p->GSactive->Font.font, "FirstChar");
 	if(o == nil)
-		return 1;
+		return -1;
 	p->GSactive->Font.first = o->num.i;
 	p->GSactive->Font.last = dictget(p->GSactive->Font.font, "LastChar")->num.i;
 	p->GSactive->Font.widths = malloc(sizeof(int) * (p->GSactive->Font.last - p->GSactive->Font.first + 1));
 	if(p->GSactive->Font.widths == nil){
-		print("Failed to allocate for (%d, %d): %d\n", p->GSactive->Font.first, p->GSactive->Font.last, p->GSactive->Font.last - p->GSactive->Font.first + 1);
-		return 1;
+		werrstr("memory");
+		return -1;
 	}
 	o = dictget(p->GSactive->Font.font, "Widths");
 	if(o == nil)
-		return 0;
+		return -1;
 	for(i = 0; i < arraylen(o); i++)
 		p->GSactive->Font.widths[i] = arrayget(o, i)->num.i;
 	o = dictget(p->GSactive->Font.font, "FontDescriptor");
 	p->GSactive->Font.defwidth = dictget(o, "MissingWidth")->num.i;
-	return 1;
+	return 0;
 }
 
 static int
@@ -544,14 +558,14 @@
 	char *name = arrayget(p->stack, 0)->name;
 	p->GSactive->Font.font = dictget(dictget(dictget(p->obj, "Resources"), "Font"), name);
 	if(p->GSactive->Font.font == nil){
-		werrstr("Font not found: '%s'", name);
-		return 0;
+		werrstr("font not found: %q", name);
+		return -1;
 	}
 	p->GSactive->Font.enc = dictget(p->GSactive->Font.font, "Encoding");
 	if(p->GSactive->Font.enc)
 		p->GSactive->Font.enc = dictget(p->GSactive->Font.enc, "Differences");
 	p->GSactive->Font.size = arrayget(p->stack, 1)->num.d;
-	return fontwidths(p) && flagless(op);
+	return (fontwidths(p) == 0 && flagless(op) == 0) ? 0 : -1;
 }
 
 static int
@@ -558,7 +572,7 @@
 tsrendmode(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -565,7 +579,7 @@
 tsrise(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -572,8 +586,8 @@
 tobegin(Op *op, Page *p)
 {
 	if(p->TS.inobj){
-		werrstr("Text objects must not be nested");
-		return 0;
+		werrstr("tobegin: text objects must not be nested");
+		return -1;
 	}
 	p->TS.inobj = 1;
 	p->GSactive->Font.font = nil;
@@ -586,8 +600,8 @@
 toend(Op *op, Page *p)
 {
 	if(!p->TS.inobj){
-		werrstr("ET found without BT");
-		return 0;
+		werrstr("toend: ET without BT");
+		return -1;
 	}
 	p->TS.inobj = 0;
 	return flagless(op);
@@ -597,6 +611,7 @@
 tmove(Page *p, double x, double y, int tlm)
 {
 	double *mat = tlm ? p->TS.Tlm : p->TS.Tm;
+
 	mattrans(mat, x, y, mat);
 	if(tlm)
 		memcpy(p->TS.Tm, p->TS.Tlm, sizeof(double) * 6);
@@ -606,12 +621,13 @@
 tpmove(Op *op, Page *p)
 {
 	Object *x, *y;
+
 	x = arrayget(p->stack, 0);
 	y = arrayget(p->stack, 1);
 	if(op->flags & Leading)
 		p->TS.TL = -y->num.d;
 	tmove(p, x->num.d, y->num.d, 1);
-	return 1;
+	return 0;
 }
 
 static int
@@ -618,6 +634,7 @@
 tpmatrix(Op *op, Page *p)
 {
 	int i;
+
 	for(i = 0; i < 6; i++){
 		p->TS.Tm[i] = arrayget(p->stack, i)->num.d;
 		p->TS.Tlm[i] = p->TS.Tm[i];
@@ -638,6 +655,7 @@
 {
 	int i, len, d = 0;
 	Object *o;
+
 	if(p->GSactive->Font.enc != nil){
 		len = arraylen(p->GSactive->Font.enc);
 		for(i = 0; i < len; i++){
@@ -714,11 +732,11 @@
 				if(strcmp(o->name, "arrowright") == 0)
 					return bufput(&p->buf, (uchar*)"→", strlen("→")) == strlen("→");
 				break;
-			} else
+			}else
 				d++;
 		}
 	}
-	return bufput(&p->buf, (uchar*)&c, 1) == 1;
+	return bufput(&p->buf, (uchar*)&c, 1);
 }
 
 // Returns glyph width in TEXT SPACE units.
@@ -753,6 +771,7 @@
 	Memimage *ink;
 	double tx;
 	int i;
+
 	/* Text rendering matrix converts coordinates from font space to device space */
 	matscale(p->TS.Tm, Tfs, Tfs, Trm);
 	matmult(Trm, p->GSactive->CTM, Trm);
@@ -761,22 +780,22 @@
 		if(p->TS.y != Trm[5]){
 			for(i = 0; i < (int)((Trm[5] - p->TS.y) / p->GSactive->Font.size / 1.5) && i < 2; i++)
 				if(bufput(&p->buf, (uchar*)"\n", 1) != 1)
-					return 0;
-		} else if(Trm[4] - p->TS.x > 5) {
+					return -1;
+		}else if(Trm[4] - p->TS.x > 5){
 			if(bufput(&p->buf, (uchar*)" ", 1) != 1)
-				return 0;
+				return -1;
 		}
 	}
 	usize oend = p->buf.sz;
 	if(!writepatched(p, c)){
 		werrstr("tchar: failed to write character: %r");
- 		return 0;
+ 		return -1;
 	}
 	if(p->buf.b != nil){
 		ink = allocmemimage(Rect(0,0,1,1),RGB24);
 		if(ink == nil){
 			werrstr("failed to allocate ink");
-			return 0;
+			return -1;
 		}
 		ink->flags |= Frepl;
 		ink->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
@@ -788,7 +807,7 @@
 	mattrans(p->TS.Tm, tx, 0, p->TS.Tm);
 	p->TS.x = Trm[4] + tx;
 	p->TS.y = Trm[5];
-	return 1;
+	return 0;
 }
 
 static int
@@ -797,8 +816,8 @@
 	ulong i;
 	for(i = 0; i < len; i++)
 		if(!tchar(p, str[i]))
-			return 0;
-	return 1;
+			return -1;
+	return 0;
 }
 
 static int
@@ -806,14 +825,14 @@
 {
 	if(op->flags & TwTc){
 		werrstr("TODO thshow TwTc");
-		return 0;
+		return -1;
 	}
 	if(op->flags & Nextline)
 		tmove(p, 0, 0 - p->TS.TL, 1);
 	Object *o = arrayget(p->stack, 0);
 	if(!tstr(p, o->str, o->len))
-		return 0;
-	return 1;
+		return -1;
+	return 0;
 }
 
 static int
@@ -821,13 +840,13 @@
 {
 	Object *o, *arr = arrayget(p->stack, 0);
 	int i;
+
 	for(i = 0; i < arraylen(arr); i++){
 		o = arrayget(arr, i);
 		if(o->type == Ostr){
 			if(!tstr(p, o->str, o->len))
 				return 0;
-		}
-		else {
+		}else{
 			mattrans(p->TS.Tm, 0 - (p->GSactive->Font.size * o->num.d / 1000), 0, p->TS.Tm);
 		}
 	}
@@ -838,7 +857,7 @@
 t3width(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -845,7 +864,7 @@
 t3widthbb(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -859,7 +878,7 @@
 	s->num.d = x;
 	s->num.i = x;
 */
-	return 0;
+	return -1;
 }
 
 static int
@@ -873,7 +892,7 @@
 	s->num.d = x;
 	s->num.i = x;
 */
-	return 0;
+	return -1;
 }
 
 static int
@@ -888,7 +907,7 @@
 	s->num.d = x;
 	s->num.i = x;
 */
-	return 0;
+	return -1;
 }
 
 static int
@@ -903,7 +922,7 @@
 	s->num.d = x;
 	s->num.i = x;
 */
-	return 0;
+	return -1;
 }
 
 static int
@@ -910,7 +929,7 @@
 t4idiv(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -917,7 +936,7 @@
 t4mod(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -924,7 +943,7 @@
 t4neg(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -931,7 +950,7 @@
 t4abs(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -938,7 +957,7 @@
 t4ceiling(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -945,7 +964,7 @@
 t4floor(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -952,7 +971,7 @@
 t4round(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -959,7 +978,7 @@
 t4truncate(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -966,7 +985,7 @@
 t4sqrt(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -973,7 +992,7 @@
 t4sin(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -980,7 +999,7 @@
 t4cos(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -987,7 +1006,7 @@
 t4atan(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -994,7 +1013,7 @@
 t4exp(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1001,7 +1020,7 @@
 t4ln(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1008,7 +1027,7 @@
 t4log(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1015,7 +1034,7 @@
 t4cvi(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1022,7 +1041,7 @@
 t4cvr(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1029,7 +1048,7 @@
 t4eq(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1036,7 +1055,7 @@
 t4ne(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1043,7 +1062,7 @@
 t4gt(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1050,7 +1069,7 @@
 t4ge(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1057,7 +1076,7 @@
 t4lt(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1064,7 +1083,7 @@
 t4le(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1071,7 +1090,7 @@
 t4and(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1078,7 +1097,7 @@
 t4or(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1085,7 +1104,7 @@
 t4xor(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1092,7 +1111,7 @@
 t4not(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1099,7 +1118,7 @@
 t4bitshift(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1106,7 +1125,7 @@
 t4true(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1113,7 +1132,7 @@
 t4false(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1120,7 +1139,7 @@
 t4if(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1127,7 +1146,7 @@
 t4ifelse(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1134,7 +1153,7 @@
 t4pop(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1141,7 +1160,7 @@
 t4exch(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1148,7 +1167,7 @@
 t4dup(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1155,7 +1174,7 @@
 t4copy(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1162,7 +1181,7 @@
 t4index(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1169,7 +1188,7 @@
 t4roll(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static int
@@ -1176,7 +1195,7 @@
 opignore(Op *op, Page *p)
 {
 	USED(op, p);
-	return 0;
+	return -1;
 }
 
 static Op ops[] = {
@@ -1426,6 +1445,7 @@
 pagegsclean(Page *p)
 {
 	int i;
+
 	if(p->GSactive != nil){
 		p->GSactive = nil;
 		for(i = 0; i < p->nGS; i++)
@@ -1441,7 +1461,7 @@
 {
 	pdfobjfree(p->stack);
 	p->stack = arraynew(p->obj->pdf);
-	return p->stack != nil;
+	return p->stack != nil ? 0 : -1;
 }
 
 void
@@ -1458,14 +1478,15 @@
 	Stream *s;
 	Object *o;
 	Op *op;
-	s = Sopen(content);
-	if(s == nil){
-		fprint(2, "%O\n", content);
-		sysfatal("%r");
+
+	o = nil;
+	if((s = Sopen(content)) == nil){
+		werrstr("content: %O", content);
+		goto err;
 	}
 	p->stack = arraynew(content->pdf);
 	if(p->stack == nil)
-		return 0;
+		goto err;
 	while(s->buf.off != s->buf.sz){
 		while(isws(s->buf.b[s->buf.off]) && s->buf.off != s->buf.sz)
 			s->buf.off++;
@@ -1473,36 +1494,38 @@
 			break;
 		o = pdfobj(content->pdf, s, 0);
 		if(o == nil){
-			werrstr("pagerendercontent: failed to parse op: %r");
-			return 0;
+			werrstr("failed to parse op: %r");
+			goto err;
 		}
 		if(o->type == Oop){
 			op = opfind(o->str);
+			pdfobjfree(o);
+			o = nil;
 			if(op == nil){
-				fprint(2, "Unknown op: %s\n", o->str);
-				pdfobjfree(o);
-				return 0;
+				werrstr("unknown op: %s\n", o->str);
+				goto err;
 			}
-			pdfobjfree(o);
-			werrstr("unimplemented or error not reported properly");
-			if(!op->f(op, p)){
-				werrstr("renderer: %s failed: %r", op->s);
-				fprint(2, "%r\n");
-			//	return 0;
+			if(op->f(op, p) != 0){
+				werrstr("%s failed: %r", op->s);
+				goto err;
 			}
-			if(!stackreset(p))
-				return 0;
-		} else{
-			if(!arrayadd(p->stack, o)){
-				fprint(2, "Failed to push operand to stack: %r\n");
-				return 0;
-			}
+			if(stackreset(p) != 0)
+				goto err;
+		}else{
+			if(arrayadd(p->stack, o) != 0)
+				goto err;
 		}
 	}
-	if(bufput(&p->buf, (uchar*)"\n\0", 2) != 2)
-		return 0;
+	if(bufput(&p->buf, (uchar*)"\n", 2) != 2)
+		goto err;
 	Sclose(s);
-	return 1;
+
+	return 0;
+err:
+	werrstr("pagerendercontent: %r");
+	pdfobjfree(o);
+	Sclose(s);
+	return -1;
 }
 
 int
@@ -1510,29 +1533,32 @@
 {
 	Object *content;
 	int i;
+
 	p->nGS = 1;
-	p->GS = malloc(sizeof(GS));
+	p->GS = malloc(sizeof(*p->GS));
 	if(p->GS == nil){
-		werrstr("Out of memory");
-		return 0;
+		werrstr("memory");
+		goto err;
 	}
 	p->GSactive = p->GS;
 	gsinit(p, p->GS);
 	if((p->image = allocmemimage(Rect(0,0,1100,1300), strtochan("r8g8b8"))) == nil){
-		werrstr("unable to allocate image: %r");
-		pagegsclean(p);
-		return 0;
+		werrstr("allocmemimage: %r");
+		goto err;
 	}
-	memfillcolor(p->image, 0xFFFFFFFF);
+	memfillcolor(p->image, DWhite);
 	content = dictget(p->obj, "Contents");
 	if(content->type == Oarray){
-		for(i = 0; i < arraylen(content); i++)
-			if(!pagerendercontent(p, arrayget(content, i)))
-				return 0;
-	}
-	else if(content->type != Onull)
-		if(!pagerendercontent(p, content))
-			return 0;
+		for(i = 0; i < arraylen(content); i++){
+			if(pagerendercontent(p, arrayget(content, i)) != 0)
+				goto err;
+		}
+	}else if(content->type != Onull && pagerendercontent(p, content) != 0)
+		goto err;
 	pagegsclean(p);
-	return 1;
+
+	return 0;
+err:
+	pagegsclean(p);
+	return -1;
 }