DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦dff042bd5⟧ TextFile

    Length: 11089 (0x2b51)
    Types: TextFile
    Names: »pixrops.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z« 
        └─⟦036c765ac⟧ 
            └─⟦this⟧ »TeX3.0/MFcontrib/fonttool/pixrops.c« 
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./tex82/MFcontrib/fonttool/pixrops.c« 
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦63303ae94⟧ »unix3.14/TeX3.14.tar.Z« 
        └─⟦c58930e5c⟧ 
            └─⟦this⟧ »TeX3.14/MFcontrib/fonttool/pixrops.c« 

TextFile

/*
 * File:
 *
 *	pixrops.c
 *
 * Author:
 *
 *	Brad Rullman
 *	Department of Computer Science  FR-35
 *	University of Washington
 *	Seattle, Washington  98155
 *	email: ecola@cs.washington.edu
 *
 *	Copyright @ March, 1987 - This program, or any subset of the functions
 *	herein, is not to be redistributed, or used for personal or commercial
 *	gain in the form of fame, fortune, or shorter working hours, without
 *	the consent of the author.
 *
 * Function:
 *
 *	A file of functions that manipulate the contents of pixrects.
 *
 * Contents:
 *
 *   Public:
 *
 *	ResetRect		Initialize a rect.
 *	ExpandRect		Expand a rect to include another pixel.
 *	DrawRefPoint		Draw the reference point in the PaintSW.
 *	DisplayPR		Display changes to the view pixrect on screen.
 *	RedisplayPRs		Redisplay view and paint subwindows.
 *	ResizePRs		Change pixrects to hold a larger character.
 * 
 *   Private Internal:
 *
 *	scalePRUp		Magnify a true-size pixrect.
 *	centerPRinPR		Centers and copies one PR into another.
 */

#include "global.h"



/*
 * scalePRUp
 *
 * Input:
 *	srcPR	  : pointer to the pixrect to be scaled.
 *	srcX, srcY: origin of bounding box to scale up.
 *	srcW, srcH: dimensions of the bounding box to scale up.
 *	dstPR	  : pointer to the pixrect to hold the magnified image.
 * Output:
 *	none.
 * Action:
 *	Magnifies each pixel in the specified bounding box of srcPR and
 *	writes it to the corresponding magnified coordinate position in
 *	dstPR using the RasterOp function pr_rop.  Note that if the
 *	"Write-Black" option or the "White-White" option is in effect,
 *	we must take into consideration the cells immediately surrounding
 *	the bounding box too, since each cell is actually a circle that
 *	encloses a larger area than a simple square cell, i.e. the cells
 *	now can overlap each other in the PaintSW.
 */
static void
scalePRUp(srcPR, srcX, srcY, srcW, srcH, dstPR)
struct pixrect *srcPR, *dstPR;
int srcX, srcY, srcW, srcH;
{
    register int sx, sy;	/* steps through the source PR */
    register sxMax = srcX + srcW;	/* upper bound of sx */
    register syMax = srcY + srcH;	/* upper bound of sy */
    int cellWidth = Magnification + 2*CellOffset;

    if ( (CellType == CELLNORMAL) || (Magnification < 4) ) {
	/*
	 * Clear the affected region.
	 */
	pr_rop(dstPR, SCALEUP(srcX), SCALEUP(srcY),
	       SCALEUP(srcW), SCALEUP(srcH),
	       PIX_CLR, (struct pixrect *) NULL, 0, 0);
	/*
	 * Paint the cells in the PaintSW that correspond to the "on"
	 * cells in the ViewSW.
	 */
	for (sy = srcY; sy < syMax; ++sy) {
	    for (sx = srcX; sx < sxMax; ++sx) {
		if (pr_get(srcPR, sx, sy) == 1) {
		    pr_rop(dstPR, SCALEUP(sx), SCALEUP(sy), 
			   Magnification, Magnification,
			   PIX_SET, (struct pixrect *) NULL, 0, 0);
		}
	    }
	}
    }
    else if (CellType == CELLWRITEBLACK) {
	/*
	 * Clear the affected region.
	 */
	pr_rop(dstPR, SCALEUP(srcX)-CellOffset, SCALEUP(srcY)-CellOffset,
	       SCALEUP(srcW)+2*CellOffset, SCALEUP(srcH)+2*CellOffset,
	       PIX_CLR, (struct pixrect *) NULL, 0, 0);
	/*
	 * Paint the cells in the PaintSW that correspond to the "on"
	 * cells in the ViewSW.
	 */
	srcX--; srcY--; sxMax++; syMax++;
	for (sy = srcY; sy < syMax; ++sy) {
	    for (sx = srcX; sx < sxMax; ++sx) {
		if (pr_get(srcPR, sx, sy) == 1) {
		    pr_rop(dstPR, 
			   SCALEUP(sx)-CellOffset, SCALEUP(sy)-CellOffset,
			   cellWidth, cellWidth,
			   PIX_DST | PIX_SRC, CellMask, 0, 0);
		}
	    }
	}
    }
    else if (CellType == CELLWRITEWHITE) {
	/*
	 * Set the affected region.
	 */
	pr_rop(dstPR, SCALEUP(srcX)-CellOffset, SCALEUP(srcY)-CellOffset,
	       SCALEUP(srcW)+4, SCALEUP(srcH)+4,
	       PIX_SET, (struct pixrect *) NULL, 0, 0);
	/*
	 * Erase the cells in the PaintSW that correspond to the "off"
	 * cells in the ViewSW.
	 */
	srcX--; srcY--; sxMax++; syMax++;
	for (sy = srcY; sy < syMax; ++sy) {
	    for (sx = srcX; sx < sxMax; ++sx) {
		if (pr_get(srcPR, sx, sy) == 0) {
		    pr_rop(dstPR,
			   SCALEUP(sx)-CellOffset, SCALEUP(sy)-CellOffset,
			   cellWidth, cellWidth,
			   PIX_DST & PIX_NOT(PIX_SRC), CellMask, 0, 0);
		}
	    }
	}
    }
}



/*
 * ResetRect
 *
 * Input:
 *	rectp: pointer to the rect to be initialized.
 *	x, y : origin of rect (top-left corner).
 *	w, h : width and height of rect.
 * Output:
 *	none.
 * Action:
 *	Resets the given rect to the given location and dimensions.
 */
void
ResetRect(rectp, x, y, w, h)
Rect *rectp;
int x, y, w, h;
{
    rectp->r_left = x;
    rectp->r_top = y;
    rectp->r_width = w;
    rectp->r_height = h;
}



/*
 * ExpandRect
 *
 * Input:
 *	rectp: pointer to the rect to be expanded.
 *	x, y : origin of pixel to be included in rect.
 * Output:
 *	none.
 * Action:
 *	If necessary, expands the given rect to include the given pixel.
 *	Useful in place of ResetRect when two points defining
 *	the new rect are not immediately known, e.g. when we already have
 *	a rect defined and want it to include an arbitrary point which may
 *	lie inside or outside.
 */
void
ExpandRect(rectp, x, y)
Rect *rectp;
int x, y;
{
    if (x < rectp->r_left) {	/* x is to left of rect */
	rectp->r_width += rectp->r_left - x;
	rectp->r_left = x;
    }
    else if (x > (rectp->r_left + rectp->r_width - 1)) {  /* x is to right */
	rectp->r_width = x - rectp->r_left + 1;
    }
    if (y < rectp->r_top) {	/* y is above rect */
	rectp->r_height += rectp->r_top - y;
	rectp->r_top = y;
    }
    else if (y > (rectp->r_top + rectp->r_height - 1)) {  /* y is below */
	rectp->r_height = y - rectp->r_top + 1;
    }
}



/*
 * DrawRefPoint
 *
 * Input:
 *	none.
 * Output:
 *	none.
 * Action:
 *	Draws the reference point at the proper magnification in the 
 *	PaintSW at the coordinates specified by ReferenceXY.
 */
void
DrawRefPoint()
{
    if (pw_write(PaintPW, ReferenceXY.x, ReferenceXY.y,
		 Magnification, Magnification, (PIX_SRC ^ PIX_DST),
	 	 ReferencePoint, (MAXMAG-Magnification)/2,
		 (MAXMAG-Magnification)/2) != 0) {
	AbortWithError("DrawRefPoint: Failed write to pixwin.\n");
    }
}



/*
 * DisplayPR
 *
 * Input:
 *	x, y: origin of a bounding box in the view pixrect.
 *	w, h: width and height of the bounding box -- i.e. the area
 *	      of the view pixrect to be drawn.
 * Output:
 *	none.
 * Action:
 *	Magnifies the ViewPR region inside the given bounding box and
 *	writes it to the paint subwindow pixwin. Writes the unmagnified
 *	version to the view subwindow pixwin. The bounding box is given by
 *	(x,y) (x+w, y+h). The reference point is redrawn in the PaintSW if
 *	it lies	within the bounding box.
 */
void
DisplayPR(x, y, w, h)
int x, y;
int w, h;
{
    int magX, magY, magW, magH;

    if ( (CellType == CELLNORMAL) || (Magnification < 4) ) {
	magX = SCALEUP(x); magY = SCALEUP(y);
	magW = SCALEUP(w); magH = SCALEUP(h);
    }
    else {
    /*
     * Since we are simulating a dot-writing output device (CellType
     * is writeBlack or writeWhite), expand the bounding box 
     * on each of its sides, since CellMask is actually larger than one
     * normal cell (one Magnification-by-Magnification square).
     */
	magX = SCALEUP(x-1); magY = SCALEUP(y-1);
	magW = SCALEUP(w+2); magH = SCALEUP(h+2);
    }

    if (Magnification > 1) {
	scalePRUp(ViewPR, x, y, w, h, PaintPR);
    }
    else {	/* save some time and do it directly */
	pr_rop(PaintPR, magX, magY, magW, magH, PIX_SRC, ViewPR, x, y);
    }

    /*
     * Make the changes to the destination pixwin.
     */
    if (pw_write(PaintPW, magX, magY, magW, magH, PIX_SRC,
		 PaintPR, magX, magY) != 0) {
	AbortWithError("DisplayPR: Failed write to pixwin.\n");
    }

    /*
     * Re-display the reference point if it lies within the region that
     * has just been written to the screen.
     */
    if ( (ReferenceXY.x >= magX) && (ReferenceXY.y >= magY) &&
	 (ReferenceXY.x < (magX+magW)) && (ReferenceXY.y < (magY+magH)) ) {
	DrawRefPoint();
    }

    pw_write(ViewPW, x, y, w, h, PIX_SRC, ViewPR, x, y);
}



/*
 * RedisplayPRs
 *
 * Input:
 *	none.
 * Output:
 *	none.
 * Action:
 *	This routine is called only in case of damage to some subset of
 *	the FontTool windows.  It redisplays the entire paint and view
 *	pixrects in the appropriate subwindows, and redisplays the 
 *	reference point in the paint subwindow.
 */
void
RedisplayPRs()
{
    if (pw_write(PaintPW, 0, 0, PaintPR->pr_size.x, PaintPR->pr_size.y,
		 PIX_SRC, PaintPR, 0, 0) != 0) {
	AbortWithError("RedisplayPRs: Failed write to pixwin.\n");
    }
    DrawRefPoint();
    pw_write(ViewPW, 0, 0, ViewPR->pr_size.x, ViewPR->pr_size.y,
	     PIX_SRC, ViewPR, 0, 0);
}



/*
 * ResizePRs
 *
 * Input:
 *	width, height: new dimensions of FontTool's underlying pixrect
 *		       structures.
 *	saveContents: 1 if the current contents of the pixrect structures
 *		      are to be preserved, 0 otherwise.
 * Output:
 *	none.
 * Action:
 *	Changes the sizes of the ViewPR and the UndoPR to the given
 *	dimensions.  The pixrects are cleared unless saveContents is 1,
 *	in which case the contents of the old are centered in the new.
 *	Then all subwindows are resized accordingly and redisplayed.
 */
void
ResizePRs(width, height, saveContents)
int width, height;
{
    struct pixrect *tempPR;
    int xTranslation = (width - ViewPR->pr_size.x)/2;
    int yTranslation = (height - ViewPR->pr_size.y)/2;
    static void centerPRinPR();

    if (saveContents) {
	tempPR = ViewPR;
	ViewPR = mem_create(width, height, 1);
	centerPRinPR(tempPR, ViewPR);
	pr_destroy(tempPR);
	ReferenceXY.x += SCALEUP(xTranslation);
	ReferenceXY.y += SCALEUP(yTranslation);

	tempPR = UndoPR;
	UndoPR = mem_create(width, height, 1);
	centerPRinPR(tempPR, UndoPR);
	pr_destroy(tempPR);
	UndoRect.r_left += xTranslation;
	UndoRect.r_top += yTranslation;
    }
    else {
	pr_destroy(ViewPR);
	ViewPR = mem_create(width, height, 1);
	pr_destroy(UndoPR);
	UndoPR = mem_create(ViewPR->pr_size.x, ViewPR->pr_size.y, 1);
    }

    pr_destroy(PaintPR);
    PaintPR = mem_create(ViewPR->pr_size.x * MAXMAG,
			 ViewPR->pr_size.y * MAXMAG, 1);
    ViewRect.r_width = ViewPR->pr_size.x;
    ViewRect.r_height = ViewPR->pr_size.y;
    FixSubwindows();
    RedisplayFrame();
    UpdateViewFields();
}



/*
 * centerPRinPR
 * 
 * Input:
 *	srcPR, dstPR: the source and destination pixrects.
 * Output:
 *	none.
 * Action:
 *	Centers and copies the contents of the source pixrect into the
 *	destination pixrect.  Assumes that either: one or both dimensions
 *	of dstPR are LARGER than those of srcPR, or that one or both
 *	dimensions of dstPR are SMALLER than those of srcPR; not a 
 *	combination of the two.
 */
static void
centerPRinPR(srcPR, dstPR)
struct pixrect *srcPR, *dstPR;
{
    int changeInWidth = dstPR->pr_size.x - srcPR->pr_size.x;
    int changeInHeight = dstPR->pr_size.y - srcPR->pr_size.y;

    if ( (changeInWidth > 0) || (changeInHeight > 0) ) {
	pr_rop(dstPR, changeInWidth/2, changeInHeight/2,
	       srcPR->pr_size.x, srcPR->pr_size.y, PIX_SRC, srcPR, 0, 0);
    }
    else {
	pr_rop(dstPR, 0, 0, srcPR->pr_size.x, srcPR->pr_size.y, PIX_SRC,
	       srcPR, abs(changeInWidth)/2, abs(changeInHeight)/2);
    }
}