|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 11089 (0x2b51)
Types: TextFile
Names: »pixrops.c«
└─⟦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«
/*
* 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);
}
}