henesyinit from p9f47575dc5 years agoHistory
398 lines · 11.2 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "system.h"#ifdef Plan9#include <libg.h>#endif#include "stdio.h"#include "defines.h"#include "njerq.h"#include "object.h"#include "comm.h"#include "path.h"#include "graphics.h"#include "cache.h"#include <ctype.h> int fw, fh;struct pspoint forigin; intfindfno(void){	struct object fid, font;	struct cachefont *old;	int i, j; 	if(!msize)return(-1);	old=currentcache;	currentfontOP();	font = pop();	fid = dictget(font.value.v_dict, FID);	for(i=0;i<msize;i++){		if(cachefont[i].cfontid.value.v_fontid.fontno ==		    fid.value.v_fontid.fontno){			for(j=0;j<4;j++){				if(G[j] != cachefont[i].cmatrix[j])break;			}			if(j >= 4){				currentcache = &cachefont[i];				fontchanged = 0;				return(i);			}		}	}	return(-1);} void	 	/*called from setcachedev updates msize to save*/putfcache(int dont, double ury, double urx, double lly, double llx){	struct object font;	struct object fid, fmatrix, BitMaps, CharDict;	struct object fontptr, box, matrix, tmatrix, xmatrix, ascentob;	struct pspoint ur, ll, p1, p2;	int i, width, height, type, istex=0;	static int totalbytes, fontct;	double fwidth, fheight, bx[4], ascent; 	if(msize >= CACHE_MLIMIT){		if(fontct++ < 5)			fprintf(stderr,"hit font limit %d increase CACHE_MLIMIT\n",msize);		dont=1;	}	currentfontOP();	font=pop();	fid = dictget(font.value.v_dict,FID);	tmatrix = dictget(font.value.v_dict,FontMatrix);	box = dictget(font.value.v_dict,FontBBox);	if(box.type == OB_NONE){		pserror("no FontBBox", "putfcache");	}	for(i=0;i<4;i++)		if(box.value.v_array.object[i].type == OB_INT)			bx[i] = (double)I(box,i);		else bx[i] = E(box,i);	BitMaps = dictget(font.value.v_dict,cname("BitMaps"));	/*tex*/	CharDict = dictget(font.value.v_dict, cname("CharDict")); /*Dvilaser*/	if(BitMaps.type != OB_NONE || CharDict.type != OB_NONE)		istex = 1;	tmatrix = dictget(font.value.v_dict,ImageMatrix);	if(tmatrix.type == OB_NONE && current_type==3 && istex){		bx[0] = urx;		bx[1] = ury;		bx[2] = llx;		bx[3] = lly;	}	p1.x=bx[0];p1.y=bx[1];	p1 = dtransform(p1);	p2.x=bx[2]; p2.y=bx[3];	p2 = dtransform(p2);	fheight = p1.y - p2.y;	fwidth = p1.x - p2.x;	if(fwidth < 0.)fwidth = -fwidth;	if(fheight < 0.)fheight = -fheight;	width = (int)ceil(fwidth) + 1;		/*fudge for safety-space too big*/	height = (int)ceil(fheight);					/*don't use narrow char for tex size guess*/					/*was tmatrix.type - BitMaps is better*/	if(istex && current_type == 3){		if(!isalnum(texcode) || texcode == '1' || texcode == 'l' || texcode == 'i' || texcode == 'I'){			dont=1;		}		width = (int)ceil(fwidth);		height = (int)ceil(fheight);		width *= 2;		height *= 2;		if(width <10)width=10;	/*more protection!*/		if(width < height)width = height;	/*wastes space but safe*/		if(width > height)height=width;	/*protect against small 1st char*/	}	fw = width;	fh = height; if(cacheout)fprintf(fpcache,"height %d width %d ",height,width);	if(current_type == 3 && (istex||tmatrix.type != OB_NONE)){		ascentob = dictget(font.value.v_dict,Ascent);		if(ascentob.type != OB_NONE){			ascent = ascentob.value.v_real;			ur.x = 0.;			ur.y = ascent;			ur = dtransform(ur);			forigin.y = ur.y;			if(G[0] < 0. && G[3] < 0. && fabs(G[0])>SMALL && fabs(G[3])>SMALL){				forigin.x = width - fabs(ur.x);				forigin.y = fheight-fabs(ur.y);			}			else if(G[0] <= SMALL && G[3] <= SMALL && G[1] < 0.)				forigin.x = width - fabs(ur.x);			else forigin.x = fabs(ur.x);		}		else forigin.x = forigin.y = 0.;	}	if(width*CACHE_CLIMIT > 32768 || dont){		currentcache = (struct cachefont *)0;		return;	}	cachefont[msize].charbits =cachealloc(Rect(0,0,width*CACHE_CLIMIT,height+3));	if(cachefont[msize].charbits == 0){		if(mdebug)fprintf(stderr,"cachealloc failed\n");		currentcache = (struct cachefont *)0;		return;	}	totalbytes += width*CACHE_CLIMIT*height/8;	cachefont[msize].origin.x = forigin.x;	cachefont[msize].origin.y = forigin.y;	if(istex && current_type == 3)		cachefont[msize].internal = 0;	else if(tmatrix.type == OB_NONE && current_type == 3)		cachefont[msize].internal = 2;	else cachefont[msize].internal = 1;	cachefont[msize].cheight = height;	cachefont[msize].cwidth = width;	if(current_type == 1||cachefont[msize].internal == 2){		cachefont[msize].origin.x=fabs(p1.x);		cachefont[msize].origin.y=fabs(p1.y);		cachefont[msize].upper.y=p2.y;		cachefont[msize].upper.x=p2.x; if(cacheout)fprintf(fpcache,"orig %d %d %d %d ",(int)p1.x,(int)p1.y,(int)p2.x,(int)p2.y);	}	cachefont[msize].cfontid = fid;	cachefont[msize].cfonts = font;	for(i=0;i<4;i++)		cachefont[msize].cmatrix[i] = G[i];	currentcache = &cachefont[msize];	cachefont[msize].charno = 0;	fontchanged = 0;	msize++;}voidmcachechar(void){		/*needs to look for low sequence if at limit*/	struct object font, charno;	struct cachefont *cache;	double adj;	charno = pop();	cache = currentcache;	if(Graphics.device.width == 0){		Graphics.width.x = cache->cachec[cache->charno].gwidth;		Graphics.width.y = cache->cachec[cache->charno].gheight;		return;	}	adj = yadj;	cache->cachec[cache->charno].value = charno.value.v_int;	cache->cachec[cache->charno].lastused = cache->sequence++;	cache->cachec[cache->charno].yadj = yadj;	cache->cachec[cache->charno].xadj = nxadj;	Graphics.width.x = cache->cachec[cache->charno].gwidth;	Graphics.width.y = cache->cachec[cache->charno].gheight;	cache->charno++;} intputcachech(void){	register struct chars *cachechar;	struct object font, charno;	struct cachefont *cache;	double psy, psx;	int i, x, y, delta, gindex;	unsigned char neg=0;	chct++;	charno = pop();	cache = currentcache;	if(cache == (struct cachefont *)0||fontchanged||dontcache)return(0);	for(i=0, cachechar = &cache->cachec[0];i<cache->charno;i++,cachechar++)		if(cachechar->value == 	charno.value.v_int)break;	if(i == cache->charno){		return(0);	}	if(Graphics.device.width == 0)		goto dont;	if(cache->internal){		psy = G[5] + cache->origin.y + cache->cachec[i].yadj;		if(current_type == 3)psx = G[4] - cache->origin.x  +			cache->cachec[i].xadj;		else psx = G[4] + cache->origin.x;		/*was +*/	}	else { psy = G[5] + cache->cheight - cachechar->texy;		psx = G[4] - cache->origin.x  +			cache->cachec[i].xadj;	}	if(Graphics.clipchanged){		clipchar(G[4], psy,		   (double)(cachechar->edges.max.x-cachechar->edges.min.x),		   (double)(cachechar->edges.max.y-cachechar->edges.min.y));		if(Graphics.path.first == NULL){			goto dont;		}	}	else if(psx < Graphics.iminx|| psx + cache->cwidth > Graphics.imaxx ||		psy - cache->cheight < Graphics.iminy|| psy > Graphics.imaxy)		goto dont;	psy = Graphics.device.height - psy + anchor.y;	psx += (double)anchor.x;	if(psy<0)		goto dont;	cachechar->lastused = cache->sequence++;	gindex = floor(currentgray()*((double)GRAYLEVELS-1.)/51.2);	if(gindex < 0)gindex = 0;	if(current_type == 1 || cache->internal == 2){		psy = psy - cache->cheight + 2*cache->origin.y;		if(current_type == 1)		psx = psx - 2*cache->origin.x +			cache->cachec[i].xadj;	/*was- 2**/		if(cache->upper.y<0){			psy -= cache->upper.y;			if(cache->upper.x<0.)				psy -= cache->origin.y;		}		if(cache->upper.x<0){			psx += cache->upper.x;			if(cache->upper.y > 0.)				psx += cache->origin.x;		}		y = (int)floor(psy);	}	else y = (int)floor(psy+.5);	x = (int)floor(psx+.5);/*	if(y<0)goto dont;*/	if(gindex >= 4)		bitblt(&screen, Pt(x, y), cache->charbits,cachechar->edges, DandnotS);	else bitblt(&screen, Pt(x, y), cache->charbits,cachechar->edges, S|D);#ifndef Plan9	ckbdry(x, y);	ckbdry(x+cache->cwidth, y+cache->cheight);#endifdont:	Graphics.width.x = cachechar->gwidth;	Graphics.width.y = cachechar->gheight;	return(1);} intgetbytes(double urx, double  ury, double llx, double lly){	int cwidth, cheight, cbytes;			/*useless since whole fonts are cached except to find big fonts*/	cheight = fabs(ceil(ury-lly));	cwidth = fabs(ceil(urx-llx));	if(cwidth<1)cwidth=1;	if(cheight<1)cheight=1;	cbytes = ((cwidth + 7) >>3)*cheight;	return(cbytes);}voidBuildChar(void){	struct object charname, fontdir, charno, chdata, array, Bheight;	struct object height, width, matrix, chdict, encoding, ascentob;	int gindex;	struct pspoint ur;	double ascent;	charno = pop();	chct++;	fontdir = pop();	encoding = dictget(fontdir.value.v_dict, Encoding);	if(encoding.type == OB_NONE)		pserror("show", "BuildChar no encoding");	push(encoding);	push(charno);	getOP();	charname = pop();	chdict = dictget(fontdir.value.v_dict, Chardata);	if(chdict.type == OB_NONE)		pserror("show", "BuildChar no chardata");	chdata = dictget(chdict.value.v_dict, charname);	if(chdata.type == OB_NONE){		fprintf(stderr,"undefined char \"%s\", using question:line %d:\n",			charname.value.v_string.chars,Line_no);		chdata = dictget(chdict.value.v_dict, blank);		if(chdata.type == OB_NONE)			pserror("BuildChar","can't find question in font");	}	matrix = dictget(fontdir.value.v_dict,ImageMatrix);	if(matrix.type == OB_NONE)		pserror("BuildChar", "ImageMatrix wrong");	matrix.value.v_array.object[4] = chdata.value.v_array.object[3];	matrix.value.v_array.object[5] = chdata.value.v_array.object[4];	Bheight = dictget(fontdir.value.v_dict, BHeight);	if(Bheight.type == OB_NONE)		pserror("BuildChar", "Bheight wrong");	width = chdata.value.v_array.object[0];	height = chdata.value.v_array.object[1];	push(chdata.value.v_array.object[2]);	push(makereal(0.0));					/* char bounding box */	push(chdata.value.v_array.object[3]);	push(makereal(0.0));	push(makereal((double)width.value.v_int));	push(makereal((double)height.value.v_int));	setcachedeviceOP();	push(width);	push(height);/*	gindex = floor(currentgray()*((double)GRAYLEVELS-1.)/51.2);	if(gindex < 0)gindex = 0;	if(gindex == 4)push(false);	else push(true);*/	push(true);	push(matrix);	array = makearray(1, XA_EXECUTABLE);	array.value.v_array.object[0] = chdata.value.v_array.object[5];	push(array);	imagemaskOP();}voidprintmatrix(char *s, struct object matrix){	fprintf(stderr,"%s %f %f %f %f %f %f\n",s,E(matrix,0),E(matrix,1),E(matrix,2),E(matrix,3),E(matrix,4),E(matrix,5));}voidcachestatusOP(void){	push(makeint(bsize));	push(makeint(bmax));	push(makeint(msize));	push(makeint(mmax));	push(makeint(csize));	push(makeint(cmax));	push(makeint(blimit));}voidclipchar(double orx, double ory, double wid, double ht){	newpathOP();	add_element(PA_MOVETO,makepoint(orx,ory));	add_element(PA_LINETO,add_point(makepoint(wid,0.),currentpoint()));	add_element(PA_LINETO,add_point(makepoint(0.,-ht),currentpoint()));	add_element(PA_LINETO,add_point(makepoint(-wid,0.),currentpoint()));	closepathOP();	if(do_clip())		if(smallpath(wid/2.,ht/2.))			Graphics.path.first = NULL;}intsmallpath(double wid, double ht){	struct element *p;	double pmaxx, pminx, pmaxy, pminy;	pminy = pmaxy = Graphics.path.first->ppoint.y;	pminx = pmaxx = Graphics.path.first->ppoint.x;	for(p=Graphics.path.first; p != NULL;p=p->next){		if(p->ppoint.x < pminx)pminx = p->ppoint.x;		else if(p->ppoint.x > pmaxx)pmaxx = p->ppoint.x;		if(p->ppoint.y < pminy)pminy = p->ppoint.y;		else if(p->ppoint.y > pmaxy)pmaxy = p->ppoint.y;	}	if(pmaxx - pminx < wid)return(1);	if(pmaxy - pminy < ht)return(1);	return(0);}#ifdef Plan9Bitmap *cachealloc(Rectangle r){	Bitmap *bx;	bx=balloc(r,0);	return(bx);}#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t