9front - general discussion about 9front
 help / color / mirror / Atom feed
From: igor@9lab.org
To: 9front@9front.org
Subject: Re: [9front] hidpi
Date: Wed, 22 Dec 2021 09:39:14 +0100	[thread overview]
Message-ID: <EB4EE1A4B8CF518C2ADC0A9B72E40509@9lab.org> (raw)
In-Reply-To: <fY4WlDcUa0tGFTLGmEv-NDWLzJwXsUPnq2RK3-w9N1E35Bo3N8nIXTI-BwvNAmMRQtDb_oIH63c0uucUhbK38DilSs3LuWfGeJ1vAluIggw=@protonmail.com>

Quoth Philip Silva <philip.silva@protonmail.com>:
[…]
> - glitches: the borders aren't calculated correctly (3rd patch for rio and acme is very wip)
[…]

By glitches, do you mean issues like the one here:

• https://9lab.org/img/plan9/acid.png

…where there is an issue in computing the column growth ⁽¹⁾ (I think)
manifesting itself as an artefact that looks like a white line at the
bottom of an acme column.  On small res displays this isn't
noticeable, however, on high-res screens it is annoying.

I stopped half way through due to lack of time debugging this
(still on my todo list), and was wondering if you observed the
same glitch.

⁽¹⁾ … https://9lab.org/plan9/debugging-with-acid/

> --
> 
> 
> 1st Patch for libdraw and devdraw:
> 
> diff c7dcc82b0be805717efbe77c98eaadf3ee1e31af uncommitted
> --- a/sys/include/ape/draw.h
> +++ b/sys/include/ape/draw.h
> @@ -208,6 +208,7 @@
>  	Image		*windows;
>  	Image		*screenimage;
>  	int			_isnewdisplay;
> +	int			dpi;
>  };
> 
>  struct Image
> --- a/sys/include/draw.h
> +++ b/sys/include/draw.h
> @@ -200,6 +200,7 @@
>  	Image		*windows;
>  	Image		*screenimage;
>  	int		_isnewdisplay;
> +	int		dpi;
>  };
> 
>  struct Image
> --- a/sys/src/9/port/devdraw.c
> +++ b/sys/src/9/port/devdraw.c
> @@ -77,6 +77,8 @@
>  	int		refreshme;
>  	int		infoid;
>  	int		op;
> +	int		displaydpi;
> +	int		forcedpi;
>  };
> 
>  struct Refresh
> @@ -785,6 +789,7 @@
>  	cl->slot = i;
>  	cl->clientid = ++sdraw.clientid;
>  	cl->op = SoverD;
> +	cl->displaydpi=100;
>  	sdraw.client[i] = cl;
>  	return cl;
>  }
> @@ -1396,6 +1401,7 @@
>  	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
>  	uchar *u, *a, refresh;
>  	char *fmt;
> +	Fmt f;
>  	ulong value, chan;
>  	Rectangle r, clipr;
>  	Point p, q, *pp, sp;
> @@ -1643,6 +1649,35 @@
>  			font->nfchar = ni;
>  			font->ascent = a[9];
>  			continue;
> +
> +		/* query: 'Q' n[1] queryspec[n] */
> +		case 'q':
> +			if(n < 2){
> +				error(Eshortdraw);
> +			}
> +			m = 1+1+a[1];
> +			if(n < m){
> +				error(Eshortdraw);
> +			}
> +			fmtstrinit(&f);
> +			for(c=0; c<a[1]; c++){
> +				switch(a[2+c]){
> +				default:
> +					error("unknown query");
> +				case 'd':       /* dpi */
> +					if(client->forcedpi)
> +						fmtprint(&f, "%11d ", client->forcedpi);
> +					else
> +						fmtprint(&f, "%11d ", client->displaydpi);
> +					break;
> +				}
> +			}
> +			client->readdata = (uchar*)fmtstrflush(&f);
> +			if(client->readdata == nil)
> +				error(Enomem);
> +			client->nreaddata = strlen((char*)client->readdata);
> +			continue;
> +
> 
>  		/* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */
>  		case 'l':
> --- a/sys/src/libdraw/init.c
> +++ b/sys/src/libdraw/init.c
> @@ -197,6 +197,7 @@
>  Display*
>  initdisplay(char *dev, char *win, void(*error)(Display*, char*))
>  {
> +	uchar *a;
>  	char buf[128], info[NINFO+1], *t, isnew;
>  	int n, datafd, ctlfd, reffd;
>  	Display *disp;
> @@ -319,6 +320,18 @@
>  	if(dir!=nil && dir->qid.vers==1)	/* other way to tell */
>  		disp->_isnewdisplay = 1;
>  	free(dir);
> +
> +	a = bufimage(disp, 3);
> +	if(a == nil)
> +		goto Error5;
> +	a[0] = 'q';
> +	a[1] = 1;
> +	a[2] = 'd';
> +	disp->dpi = 100;
> +	if(flushimage(disp, 0) >= 0){
> +		if((read(datafd, info, sizeof info)) == 12)
> +			disp->dpi = atoi(info);
> +	}
> 
>  	return disp;
>  }
> 
> --
> 
> 2nd Patch for plan9.ini:
> 
> diff c7dcc82b0be805717efbe77c98eaadf3ee1e31af uncommitted
> --- a/sys/man/8/plan9.ini
> +++ b/sys/man/8/plan9.ini
> @@ -971,6 +971,8 @@
>  .BR off .
>  The first two specify differing levels of power saving;
>  the third turns the monitor off completely.
> +.SS \fL*dpi=\fIvalue\fP
> +This is used to specify the screen dpi.
>  .SS NVRAM
>  .SS \fLnvram=\fIfile\fP
>  .SS \fLnvrlen=\fIlength\fP
> --- a/sys/src/9/port/devdraw.c
> +++ b/sys/src/9/port/devdraw.c
> @@ -765,6 +765,7 @@
>  drawnewclient(void)
>  {
>  	Client *cl, **cp;
> +	char *p;
>  	int i;
> 
>  	for(i=0; i<sdraw.nclient; i++){
> @@ -789,7 +790,9 @@
>  	cl->slot = i;
>  	cl->clientid = ++sdraw.clientid;
>  	cl->op = SoverD;
> -	cl->displaydpi=100;
> +	if((p = getconf("dpi")) == nil || (cl->displaydpi = atoi(p)) == 0){
> +		cl->displaydpi=100;
> +	}
>  	sdraw.client[i] = cl;
>  	return cl;
>  }
> 
> --
> 
> 3rd Patch for rio/acme (proof-of-concept, just to provide an example)
> 
> diff 75d8e460a00505c2b21a0d06ceb4300c93d9c4d6 uncommitted
> --- a/sys/include/ape/draw.h
> +++ b/sys/include/ape/draw.h
> @@ -69,6 +69,7 @@
>  	Displaybufsize	= 8000,
>  	ICOSSCALE	= 1024,
>  	Borderwidth =	4,
> +	DefaultDPI  =	100,
>  };
> 
>  enum
> @@ -358,6 +359,7 @@
>  extern Image*	namedimage(Display*, char*);
>  extern int	nameimage(Image*, char*, int);
>  extern Image* allocimagemix(Display*, ulong, ulong);
> +extern int scalesize(Display*, int);
> 
>  /*
>   * Colors
> --- a/sys/include/draw.h
> +++ b/sys/include/draw.h
> @@ -61,6 +61,7 @@
>  	Displaybufsize	= 8000,
>  	ICOSSCALE	= 1024,
>  	Borderwidth =	4,
> +	DefaultDPI  =	100,
>  };
> 
>  enum
> @@ -354,6 +355,7 @@
>  extern Image*	namedimage(Display*, char*);
>  extern int	nameimage(Image*, char*, int);
>  extern Image* allocimagemix(Display*, ulong, ulong);
> +extern int scalesize(Display*, int);
> 
>  /*
>   * Colors
> --- a/sys/src/cmd/acme/dat.h
> +++ b/sys/src/cmd/acme/dat.h
> @@ -473,11 +473,14 @@
>  	BUFSIZE = Maxblock+IOHDRSZ,	/* size from fbufalloc() */
>  	RBUFSIZE = BUFSIZE/sizeof(Rune),
>  	EVENTSIZE = 256,
> -	Scrollwid = 12,	/* width of scroll bar */
> -	Scrollgap = 4,	/* gap right of scroll bar */
> -	Margin = 4,	/* margin around text */
> -	Border = 2,	/* line between rows, cols, windows */
>  };
> +
> +// like in p9p c96d832
> +#define Scrollwid scalesize(display, 12)	/* width of scroll bar */
> +#define Scrollgap scalesize(display, 4)	/* gap right of scroll bar */
> +#define Margin scalesize(display, 4)	/* margin around text */
> +#define Border scalesize(display, 2)	/* line between rows, cols, windows */
> +#define ButtonBorder scalesize(display, 2)
> 
>  #define	QID(w,q)	((w<<8)|(q))
>  #define	WIN(q)	((((ulong)(q).path)>>8) & 0xFFFFFF)
> --- a/sys/src/cmd/rio/wind.c
> +++ b/sys/src/cmd/rio/wind.c
> @@ -12,6 +12,14 @@
>  #include "dat.h"
>  #include "fns.h"
> 
> +static int
> +wscale(Window *w, int n)
> +{
> +        if(w == nil || w->i == nil)
> +                return n;
> +        return scalesize(w->i->display, n);
> +}
> +
>  Window*
>  wlookid(int id)
>  {
> @@ -308,7 +316,7 @@
>  		else
>  			col = lighttitlecol;
>  	}
> -	border(w->i, w->i->r, Selborder, col, ZP);
> +	border(w->i, w->i->r, wscale(w, Selborder), col, ZP);
>  }
> 
>  static void
> @@ -353,17 +361,17 @@
> 
>  	w->i = i;
>  	w->mc.image = i;
> -	r = insetrect(i->r, Selborder+1);
> +	r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1));
>  	w->scrollr = r;
> -	w->scrollr.max.x = r.min.x+Scrollwid;
> +	w->scrollr.max.x = r.min.x+wscale(w, Scrollwid);
>  	w->lastsr = ZR;
> -	r.min.x += Scrollwid+Scrollgap;
> +	r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap);
>  	frclear(w, FALSE);
>  	frinit(w, r, w->font, w->i, cols);
>  	wsetcols(w, w == input);
>  	w->maxtab = maxtab*stringwidth(w->font, "0");
>  	if(!w->mouseopen || !w->winnameread){
> -		r = insetrect(w->i->r, Selborder);
> +		r = insetrect(w->i->r, wscale(w, Selborder));
>  		draw(w->i, r, cols[BACK], nil, w->entire.min);
>  		wfill(w);
>  		wsetselect(w, w->q0, w->q1);
> @@ -370,7 +378,7 @@
>  		wscrdraw(w);
>  	}
>  	if(w == input)
> -		wborder(w, Selborder);
> +		wborder(w, wscale(w, Selborder));
>  	else
>  		wborder(w, Unselborder);
>  	flushimage(display, 1);
> @@ -390,9 +398,9 @@
>  	if(!w->mouseopen || !w->winnameread)
>  		frredraw(w);
>  	if(w == input)
> -		wborder(w, Selborder);
> +		wborder(w, wscale(w, Selborder));
>  	else
> -		wborder(w, Unselborder);
> +		wborder(w, wscale(w, Unselborder));
>  }
> 
>  static void
> @@ -401,9 +409,9 @@
>  	Rectangle r;
> 
>  	if(w == input)
> -		wborder(w, Selborder);
> +		wborder(w, wscale(w, Selborder));
>  	else
> -		wborder(w, Unselborder);
> +		wborder(w, wscale(w, Unselborder));
>  	r = insetrect(w->i->r, Selborder);
>  	draw(w->i, r, w->cols[BACK], nil, w->entire.min);
>  	wfill(w);
> @@ -1249,7 +1257,7 @@
> 
>  	w = emalloc(sizeof(Window));
>  	w->screenr = i->r;
> -	r = insetrect(i->r, Selborder+1);
> +	r = insetrect(i->r, wscale(w, Selborder)+wscale(w, 1));
>  	w->i = i;
>  	w->mc = *mc;
>  	w->ck = ck;
> @@ -1263,9 +1271,9 @@
>  	w->complete = chancreate(sizeof(Completion*), 0);
>  	w->gone = chancreate(sizeof(char*), 0);
>  	w->scrollr = r;
> -	w->scrollr.max.x = r.min.x+Scrollwid;
> +	w->scrollr.max.x = r.min.x+wscale(w, Scrollwid);
>  	w->lastsr = ZR;
> -	r.min.x += Scrollwid+Scrollgap;
> +	r.min.x += wscale(w, Scrollwid)+wscale(w, Scrollgap);
>  	frinit(w, r, font, i, cols);
>  	w->maxtab = maxtab*stringwidth(font, "0");
>  	w->topped = ++topped;
> @@ -1274,9 +1282,9 @@
>  	w->scrolling = scrolling;
>  	w->dir = estrdup(startdir);
>  	w->label = estrdup("<unnamed>");
> -	r = insetrect(w->i->r, Selborder);
> +	r = insetrect(w->i->r, wscale(w, Selborder));
>  	draw(w->i, r, cols[BACK], nil, w->entire.min);
> -	wborder(w, Selborder);
> +	wborder(w, wscale(w, Selborder));
>  	wscrdraw(w);
>  	incref(w);	/* ref will be removed after mounting; avoids delete before ready to be deleted */
>  	return w;
> --- a/sys/src/libdraw/init.c
> +++ b/sys/src/libdraw/init.c
> @@ -452,5 +465,13 @@
>  	p = d->bufp;
>  	d->bufp += n;
>  	return p;
> +}
> +
> +int
> +scalesize(Display *d, int n)
> +{
> +	if(d == nil || d->dpi <= DefaultDPI)
> +		return n;
> +	return (n*d->dpi+DefaultDPI/2)/DefaultDPI;
>  }
> 
> --
> 
> 4th Patch (drawterm-metal-cocoa - I've been using this most of the time):
> 
> diff 0b7990cf2b84e7a80cf3f3a9e7eadca10d51a2c5 uncommitted
> --- a/include/draw.h
> +++ b/include/draw.h
> @@ -193,6 +193,7 @@
>  	Image		*windows;
>  	Image		*screenimage;
>  	int		_isnewdisplay;
> +	int		dpi;
>  };
> 
>  struct Image
> --- a/kern/devdraw.c
> +++ b/kern/devdraw.c
> @@ -76,6 +76,8 @@
>  	int		refreshme;
>  	int		infoid;
>  	int		op;
> +	int		displaydpi;
> +	int		forcedpi;
>  };
> 
>  struct Refresh
> @@ -166,6 +168,8 @@
>  	Client*		drawclientofpath(ulong);
>  	DImage*	allocdimage(Memimage*);
> 
> +int displaydpi = 200;
> +
>  static	char Enodrawimage[] =	"unknown id for draw image";
>  static	char Enodrawscreen[] =	"unknown id for draw screen";
>  static	char Eshortdraw[] =	"short draw message";
> @@ -783,6 +787,7 @@
>  	cl->slot = i;
>  	cl->clientid = ++sdraw.clientid;
>  	cl->op = SoverD;
> +	cl->displaydpi = displaydpi;
>  	sdraw.client[i] = cl;
>  	return cl;
>  }
> @@ -1408,6 +1413,7 @@
>  	int c, repl, m, y, dstid, scrnid, ni, ci, j, nw, e0, e1, op, ox, oy, oesize, esize, doflush;
>  	uchar *u, *a, refresh;
>  	char *fmt;
> +	Fmt f;
>  	ulong value, chan;
>  	Rectangle r, clipr;
>  	Point p, q, *pp, sp;
> @@ -1654,6 +1660,34 @@
>  			memset(font->fchar, 0, ni*sizeof(FChar));
>  			font->nfchar = ni;
>  			font->ascent = a[9];
> +			continue;
> +
> +		/* query: 'Q' n[1] queryspec[n] */
> +		case 'q':
> +			if(n < 2)
> +				error(Eshortdraw);
> +			m = 1+1+a[1];
> +			if(n < m)
> +				error(Eshortdraw);
> +			fmtstrinit(&f);
> +			for(c=0; c<a[1]; c++){
> +				switch(a[2+c]){
> +				default:
> +					error("unknown query");
> +					break;
> +				case 'd':       /* dpi */
> +					if(client->forcedpi)
> +						fmtprint(&f, "%11d ", client->forcedpi);
> +					else {
> +						fmtprint(&f, "%11d ", client->displaydpi);
> +					}
> +					break;
> +				}
> +			}
> +			client->readdata = (uchar*)fmtstrflush(&f);
> +			if(client->readdata == nil)
> +				error(Enomem);
> +			client->nreaddata = strlen((char*)client->readdata);
>  			continue;
> 
>  		/* load character: 'l' fontid[4] srcid[4] index[2] R[4*4] P[2*4] left[1] width[1] */
> 
> 


  parent reply	other threads:[~2021-12-22  8:47 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-20 16:13 Philip Silva
2021-12-20 16:34 ` hiro
2021-12-20 17:04 ` [9front] hidpi Philip Silva
2021-12-20 17:29   ` hiro
2021-12-20 19:15   ` Noam Preil
2021-12-20 19:34     ` ori
2021-12-20 20:50       ` ori
2021-12-20 21:10         ` hiro
2021-12-20 21:19           ` ori
2021-12-20 22:02             ` sirjofri
2021-12-21  0:29         ` Philip Silva
2021-12-21  8:37           ` hiro
2021-12-20 21:47       ` Noam Preil
2021-12-20 17:59 ` [9front] hidpi igor
2021-12-20 18:28   ` hiro
2021-12-20 19:27     ` Noam Preil
2021-12-20 19:02   ` Philip Silva
2021-12-22  8:39 ` igor [this message]
2021-12-22 11:31   ` Philip Silva
2021-12-23 13:11 igor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=EB4EE1A4B8CF518C2ADC0A9B72E40509@9lab.org \
    --to=igor@9lab.org \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).