Charles.Forsyth20060303a828770d19 years agoHistory
511 lines · 12.4 KB · Brainfuck
RawDownload
implement Paginate; include "common.m";include "print.m";include "paginate.m"; sys: Sys;print: Print;L: Layout;D: Draw; Frame, Lay, Line, Control: import Layout;Docinfo: import Build;Image, Display, Rect, Point: import D;Item: import Build;MaskedImage: import CharonUtils; disp: ref Display;p0: Point;nulimg: ref Image; DPI: con 110; init(layout: Layout, draw: Draw, display: ref Draw->Display): string{	sys = load Sys Sys->PATH;	L = layout;	D = draw;	disp = display;	if (L == nil || D == nil || disp == nil)		return "bad args";	print = load Print Print->PATH;	if (print == nil)		return sys->sprint("cannot load module %s: %r", Print->PATH);	print->init();#nullfd := sys->open("/dev/null", Sys->OWRITE);#print->set_printfd(nullfd);	p0 = Point(0, 0);	nulimg = disp.newimage(((0, 0), (1, 1)), 3, 0, 0);	return nil;} paginate(frame: ref Layout->Frame, orient: int, pnums, cancel: chan of int, result: chan of (string, ref Pageset)){	pidc := chan of int;	spawn watchdog(pidc, cancel, nil, sys->pctl(0, nil));	watchpid := <- pidc; 	if (frame.kids != nil) {		result <-= ("cannot print frameset", nil);		kill(watchpid);		return;	} 	defp := print->get_defprinter();	if (defp == nil) {		result <-= ("no default printer", nil);		kill(watchpid);		return;	} 	# assuming printer's X & Y resolution are the same	if (orient == PORTRAIT)		defp.popt.orientation = Print->PORTRAIT;	else		defp.popt.orientation = Print->LANDSCAPE;	(dpi, pagew, pageh) := print->get_size(defp);	pagew = (DPI * pagew)/dpi;	pageh = (DPI * pageh)/dpi; 	pfr := copyframe(frame);	pr := Rect(p0, (pagew, pageh));	pfr.r = pr;	pfr.cr = pr;	pfr.viewr = pr;	l := pfr.layout;	L->relayout(pfr, l, pagew, l.just);	maxy := l.height + l.margin; # don't include bottom margin	prctxt := ref Layout->Printcontext;	pfr.prctxt = prctxt;	pfr.cim = nulimg;	pnum := 1;	startys : list of int; 	for (y := 0; y < maxy;) {		startys = y :: startys;		pnums <-= pnum++;		endy := y + pageh;		prctxt.endy = pageh;		pfr.viewr.min.y = y;		pfr.viewr.max.y = endy;		L->drawall(pfr);		y += prctxt.endy;	} 	# startys are in reverse order	ys : list of int;	for (; startys != nil; startys = tl startys)		ys = hd startys :: ys; 	pageset := ref Pageset(defp, pfr, ys);	result <-= (nil, pageset);	kill(watchpid);} printpageset(pset: ref Pageset, pnums, cancel: chan of int){	pidc := chan of int;	stopdog := chan of int;	spawn watchdog(pidc, cancel, stopdog, sys->pctl(0, nil));	watchpid := <- pidc; 	frame := pset.frame;	pageh := frame.cr.dy();	white := disp.rgb2cmap(255, 255, 255);	prctxt := frame.prctxt;	l := frame.layout;	maxy := l.height + l.margin; # don't include bottom margin	maxy = max(maxy, pageh);	pnum := 1; 	for (pages := pset.pages; pages != nil; pages = tl pages) {		y := hd pages;		if (y + pageh > maxy)			pageh = maxy - y;		frame.cr.max.y = pageh;		frame.cim = disp.newimage(frame.cr, 3, 0, white);		if (frame.cim == nil) {			pnums <-= -1;			kill(watchpid);			return;		}		pnums <-= pnum++;		endy := y + pageh;		prctxt.endy = pageh;		frame.viewr.min.y = y;		frame.viewr.max.y = endy;		L->drawall(frame);		stopdog <-= 1;#start := sys->millisec();		if (print->print_image(pset.printer, disp, frame.cim, 100, cancel) == -1) {			# cancelled			kill(watchpid);			return;		}		stopdog <-= 1;#sys->print("PAGE %d: %dms\n", pnum -1, sys->millisec()-start);	}	pnums <-= -1;	kill(watchpid);} watchdog(pidc, cancel, pause: chan of int, pid: int){	pidc <-= sys->pctl(0, nil);	if (pause == nil)		pause = chan of int;	for (;;) alt {	<- cancel =>		kill(pid);		return;	<- pause =>		<- pause;	}} kill(pid: int){	sys->fprint(sys->open("/prog/" + string pid +"/ctl", Sys->OWRITE), "kill");} killgrp(pid: int){	sys->fprint(sys->open("/prog/" + string pid +"/ctl", Sys->OWRITE), "killgrp");} max(a, b: int): int{	if (a > b)		return a;	return b;} copyframe(f: ref Frame): ref Frame{ 	zr := Draw->Rect(p0, p0);	newf := ref Frame(		-1,			# id		nil,			# doc		nil,			# src		" PRINT FRAME ",	# name		f.marginw,	# marginw		f.marginh,	# marginh		0,			# framebd		Build->FRnoscroll,	# flags		nil,			# layout - filled in below, needs this frame ref		nil,			# sublays - filled in by geometry code		0,			# sublayid		nil,			# controls - filled in below, needs this frame ref		0,			# controlid - filled in below		nil,			# cim		zr,			# r		zr,			# cr		zr,			# totalr		zr,			# viewr		nil,			# vscr		nil,			# hscr		nil,			# parent		nil,			# kids		0,			# animpid		nil			# prctxt	); 	newf.doc = copydoc(f, newf, f.doc);	controls := array [len f.controls] of ref Control;	for (i := 0; i < len controls; i++)		controls[i] = copycontrol(f, newf, f.controls[i]);	newf.layout = copylay(f, newf, f.layout);	newf.controls = controls;	newf.controlid = len controls; 	return newf;} copysublay(oldf, f: ref Frame, oldid:int): int{	if (oldid < 0)		return -1;	if (f.sublayid >= len f.sublays)		f.sublays = (array [len f.sublays + 30] of ref Lay)[:] = f.sublays;	id := f.sublayid++;	lay := copylay(oldf, f, oldf.sublays[oldid]);	f.sublays[id] = lay;	return id;} copydoc(oldf, f : ref Frame, doc: ref Build->Docinfo): ref Docinfo{	background := copybackground(oldf, f, doc.background);	newdoc := ref Build->Docinfo(		nil,		#src		nil,		#base		nil,		#referrer		nil,		#doctitle		background,		nil,		#backgrounditem		doc.text, doc.link, doc.vlink, doc.alink,		nil,		#target		nil,		#refresh		nil,		#chset		nil,		#lastModified		0,		#scripttype		0,		#hasscripts		nil,		#events		0,		#evmask		nil,		#kidinfo		0,		#frameid		nil,		#anchors		nil,		#dests		nil,		#forms		nil,		#tables		nil,		#maps		nil		#images	);	return newdoc;} copylay(oldf, f: ref Frame, l: ref Lay): ref Lay{	start := copyline(oldf, f, nil, l.start);	end := start;	for (line := l.start.next; line != nil; line = line.next)		end = copyline(oldf, f, end, line); 	newl := ref Lay(		start,		end,		l.targetwidth,		# targetwidth		l.width,		# width		l.height,		# height		l.margin,	# margin		nil,		# floats - filled in by geometry code		copybackground(oldf, f, l.background),		l.just,		Layout->Lchanged	);	start.flags = end.flags = byte 0;	return newl;} copycontrol(oldf, f: ref Frame, ctl: ref Control): ref Control{	if (ctl == nil)		return nil; 	pick c := ctl {	Cbutton =>		return ref Control.Cbutton(f, nil, c.r, c.flags, nil, c.pic, c.picmask, c.dpic, c.dpicmask, c.label, c.dorelief);	Centry =>		scr := copycontrol(oldf, f, c.scr);		return ref Control.Centry(f, nil, c.r, c.flags, nil, scr, c.s, c.sel, c.left, c.linewrap, 0);	Ccheckbox=>		return ref Control.Ccheckbox(f, nil, c.r, c.flags, nil, c.isradio);	Cselect =>		scr := copycontrol(oldf, f, c.scr);		options := (array [len c.options] of Build->Option)[:] = c.options;		return ref Control.Cselect(f, nil, c.r, c.flags, nil, nil, scr, c.nvis, c.first, options);	Clistbox =>		hscr := copycontrol(oldf, f, c.hscr);		vscr := copycontrol(oldf, f, c.vscr);		options := (array [len c.options] of Build->Option)[:] = c.options;		return ref Control.Clistbox(f, nil, c.r, c.flags, nil, hscr, vscr, c.nvis, c.first, c.start, c.maxcol, options, nil);	Cscrollbar =>		# do not copy ctl as this is set by those associated controls		return ref Control.Cscrollbar(f, nil, c.r, c.flags, nil, c.top, c.bot, c.mindelta, c.deltaval, nil, c.holdstate);	Canimimage =>		bg := copybackground(oldf, f, c.bg);		return ref Control.Canimimage(f, nil, c.r, c.flags, nil, c.cim, 0, 0, big 0, bg);	Clabel =>		return ref Control.Clabel(f, nil, c.r, c.flags, nil, c.s);	* =>		return nil;	}} copyline(oldf, f: ref Frame, prev, l: ref Line): ref Line{	if (l == nil)		return nil;	cp := ref *l;	items := copyitems(oldf, f, l.items);	newl := ref Line (items, nil, prev, l.pos, l.width, l.height, l.ascent, Layout->Lchanged);	if (prev != nil)		prev.next = newl;	return newl;} copyitems(oldf, f: ref Frame, items: ref Item): ref Item{	if (items == nil)		return nil;	item := copyitem(oldf, f, items);	end := item;	for (items = items.next; items != nil; items = items.next) {		end.next = copyitem(oldf, f, items);		end = end.next;	}	return item;} copyitem(oldf, f : ref Frame, item: ref Item): ref Item{	if (item == nil)		return nil;	pick it := item {	Itext =>		return ref Item.Itext(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			it.s, it.fnt, it.fg, it.voff, it.ul);	Irule =>		return ref Item.Irule(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			it.align, it.noshade, it.size, it.wspec);	Iimage =>		# need to copy the image to prevent		# ongoing image fetches from messing up our layout		ci := copycimage(it.ci);		return ref Item.Iimage(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			it.imageid, ci, it.imwidth, it.imheight, it.altrep,			nil, it.name, -1, it.align, it.hspace, it.vspace, it.border);	Iformfield =>		return ref Item.Iformfield(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			copyformfield(oldf, f, it.formfield)		);	Itable =>		return ref Item.Itable(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			copytable(oldf, f, it.table));	Ifloat =>		items := copyitem(oldf, f, it.item);		return ref Item.Ifloat(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			items, it.x, it.y, it.side, byte 0);	Ispacer =>		return ref Item.Ispacer(			nil, it.width, it.height, it.ascent, 0, it.state, nil,			it.spkind, it.fnt);	* =>		return nil;	}} copycimage(ci: ref CharonUtils->CImage): ref CharonUtils->CImage{	if (ci == nil)		return nil;	mims : array of ref MaskedImage;	if (len ci.mims > 0)		# if len> 1 then animated, but we only want first frame		mims = array [1] of {0 => ci.mims[0]};	return ref CharonUtils->CImage(nil, nil, nil, 0, ci.width, ci.height, nil, mims, 0);} copyformfield(oldf, f: ref Frame, ff: ref Build->Formfield): ref Build->Formfield{	image := copyitem(oldf, f, ff.image);	# should be safe to reference Option list	newff := ref Build->Formfield(		ff.ftype, 0, nil, ff.name, ff.value, ff.size, ff.maxlength, ff.rows,		ff.cols, ff.flags, ff.options, image, ff.ctlid, nil, 0	);	return newff;} copytable(oldf, f: ref Frame, tbl: ref Build->Table): ref Build->Table{	nrow := tbl.nrow;	ncol := tbl.ncol;	caption_lay := copysublay(oldf, f, tbl.caption_lay);	cols := (array [ncol] of Build->Tablecol)[:] = tbl.cols;	rows := array [nrow] of ref Build->Tablerow;	for (i := 0; i < nrow; i++) {		r := tbl.rows[i];		rows[i] = ref Build->Tablerow(nil, r.height, r.ascent, r.align, r.background, r.pos, r.flags);	} 	cells : list of ref Build->Tablecell;	grid := array [nrow] of {* => array [ncol] of ref Build->Tablecell};	for (rix := 0; rix < nrow; rix++) {		rowcells: list of ref Build->Tablecell = nil;		for (colix := 0; colix < ncol; colix++) {			cell := copytablecell(oldf, f, tbl.grid[rix][colix]);			if (cell == nil)				continue;			grid[rix][colix] = cell;			cells = cell :: cells;			rowcells = cell :: rowcells;		}		# reverse the row cells;		rcells : list of ref Build->Tablecell = nil;		for (; rowcells != nil; rowcells = tl rowcells)			rcells = hd rowcells :: rcells;		rows[rix].cells = rcells;	} 	# reverse the cells	sllec: list of ref Build->Tablecell;	for (; cells != nil; cells = tl cells)		sllec = hd cells :: sllec;	cells = sllec; 	return ref Build->Table(		tbl.tableid,	# tableid		nrow,		# nrow		ncol,			# ncol		len cells,		# ncell		tbl.align,		# align		tbl.width,		# width		tbl.border,	# border		tbl.cellspacing,	# cellspacing		tbl.cellpadding,	# cellpadding		tbl.background,	# background		nil,			# caption		tbl.caption_place,	# caption_place		caption_lay,	# caption_lay		nil,			# currows		cols,			# cols		rows,		# rows		cells,		# cells		tbl.totw,		# totw		tbl.toth,		# toth		tbl.caph,		# caph		tbl.availw,	# availw		grid,			# grid		nil,			# tabletok		Layout->Lchanged		# flags	);} copytablecell(oldf, f: ref Frame, cell: ref Build->Tablecell): ref Build->Tablecell{	if (cell == nil)		return nil; 	layid := copysublay(oldf, f, cell.layid);	background := copybackground(oldf, f, cell.background);	newcell := ref Build->Tablecell(		cell.cellid,		nil,	# content		layid,		cell.rowspan, cell.colspan, cell.align,		cell.flags, cell.wspec, cell.hspec,		background, cell.minw, cell.maxw,		cell.ascent, cell.row, cell.col, cell.pos);	return newcell;} 

Lines 1–500 of 511.

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