shithub: riscv

Download patch

ref: 3273db5a848706ddab027de63089a5406dff6de8
parent: 9e0913fa71697863f3e9ca155e3b1f67a69bdb7c
author: Jacob Moody <moody@posixcafe.org>
date: Thu Jan 2 19:43:05 EST 2025

aux/mnihongo: use memdraw instead of draw

We used to rely on there being a draw(3) there in order to render the
characters in to, this resulted in flashing the rio window white and
made some documents only buildable under a terminal environment.  This
fixes both of those issues.

--- a/sys/src/cmd/aux/mnihongo/mnihongo.c
+++ b/sys/src/cmd/aux/mnihongo/mnihongo.c
@@ -43,6 +43,7 @@
 #include <u.h>
 #include <libc.h>
 #include <draw.h>
+#include <memdraw.h>
 #include <bio.h>
 
 #define hmot(n)	hpos += n
@@ -57,6 +58,7 @@
 char	*fontfile	= "/lib/font/bit/pelm/unicode.9x24.font";
 
 char	*pschar(char *, char *hex, int *wid, int *ht);
+void	memopenfont(char *);
 int	kanji(char *);
 void	Bgetstr(Biobuf *bp, char *s);
 void	Bgetline(Biobuf *bp, char *s);
@@ -63,6 +65,7 @@
 void	Bgetint(Biobuf *bp, int *n);
 
 Biobuf bin, bout;
+Memimage *white;
 
 void
 main(void)
@@ -71,12 +74,15 @@
 	char str[100], *args[10];
 	int jfont, curfont;
 
-	if(initdraw(0, fontfile, 0) < 0){
-		fprint(2, "mnihongo: can't initialize display: %r\n");
-		exits("open");
-	}
 	Binit(&bin, 0, OREAD);
 	Binit(&bout, 1, OWRITE);
+	memimageinit();
+	white = allocmemimage(Rect(0, 0, 1, 1), GREY1);
+	if(white == nil)
+		sysfatal("allocmemimage: %r");
+	memfillcolor(white, DWhite);
+	white->flags |= Frepl;
+	memopenfont(fontfile);
 
 	jfont = -1;
 	curfont = 1;
@@ -177,6 +183,64 @@
 	}
 }
 
+struct {
+	int s, e;
+	char *path;
+	Memsubfont *f;
+} fonts[128];
+static int nfonts;
+
+void memopenfont(char *name)
+{
+	Biobuf *b;
+	int i;
+	char *s, *p, *p2;
+
+	b = Bopen(name, OREAD);
+	for(i = 0; s = Brdline(b, '\n'); i++){
+		if(i == 0)
+			continue;
+		s[Blinelen(b)-1] = '\0';
+		fonts[i].s = strtol(s, &p, 0);
+		if(s == p || *p == '\0')
+			goto Invalid;
+		p++;
+		fonts[i].e = strtol(p, &p2, 0);
+		if(p == p2 || *p2 == '\0')
+			goto Invalid;
+		p = p2 + 1;
+		if(*p == '/')
+			fonts[i].path = strdup(p);
+		else {
+			fonts[i].path = smprint("/lib/font/bit/pelm/%s", p);
+			cleanname(fonts[i].path);
+		}
+	}
+	nfonts = i;
+	if(nfonts == 0){
+Invalid:
+		sysfatal("%s is an invalid font file", name);
+	}
+	Bterm(b);
+}
+
+Memsubfont* memgetfont(Rune r)
+{
+	int i;
+
+	for(i = 0; i < nfonts; i++){
+		if(r >= fonts[i].s && r < fonts[i].e){
+			if(fonts[i].f == nil){
+				fonts[i].f = openmemsubfont(fonts[i].path, fonts[i].s);
+				if(fonts[i].f == nil)
+					sysfatal("failed to open subfont: %r");
+			}
+			return fonts[i].f;
+		}
+	}
+	return nil;	
+}
+
 int kanji(char *s)	/* very special pleading */
 {			/* dump as kanji char if looks like one */
 	Rune r;
@@ -197,22 +261,30 @@
 char *pschar(char *s, char *hex, int *wid, int *ht)
 {
 	Point chpt, spt;
-	Image *b;
+	Memimage *b;
+	Memsubfont *f;
 	uchar rowdata[100];
 	char *hp = hex;
 	int y, i;
+	Rune r;
 
-	chpt = stringsize(font, s);		/* bounding box of char */
+	chartorune(&r, s);
+	f = memgetfont(r);
+	chpt = memsubfontwidth(f, s);		/* bounding box of char */
 	*wid = ((chpt.x+7) / 8) * 8;
 	*ht = chpt.y;
 	/* postscript is backwards to video, so draw white (ones) on black (zeros) */
-	b = allocimage(display, Rpt(ZP, chpt), GREY1, 0, DBlack);	/* place to put it */
-	spt = string(b, Pt(0,0), display->white, ZP, font, s);	/* put it there */
+	white->clipr = Rpt(ZP, chpt);
+	b = allocmemimage(white->clipr, GREY1);
+	if(b == nil)
+		sysfatal("allocmemimage: %r");
+	memfillcolor(b, DBlack);
+	spt = memimagestring(b, Pt(0,0), white, ZP, f, s);	/* put it there */
 /* Bprint(&bout, "chpt %P, spt %P, wid,ht %d,%d\n", chpt, spt, *wid, *ht);
 /* Bflush(&bout); */
 	for (y = 0; y < chpt.y; y++) {	/* read bits a row at a time */
 		memset(rowdata, 0, sizeof rowdata);
-		unloadimage(b, Rect(0, y, chpt.x, y+1), rowdata, sizeof rowdata);
+		unloadmemimage(b, Rect(0, y, chpt.x, y+1), rowdata, sizeof rowdata);
 		for (i = 0; i < spt.x; i += 8) {	/* 8 == byte */
 			sprint(hp, "%2.2x", rowdata[i/8]);
 			hp += 2;
@@ -219,7 +291,7 @@
 		}
 	}
 	*hp = 0;
-	freeimage(b);
+	freememimage(b);
 	return hex;
 }
 
--