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 g

⟦40c285c26⟧ TextFile

    Length: 7909 (0x1ee5)
    Types: TextFile
    Names: »gxdraw.c«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦ff23ba0e6⟧ »./ghostscript-1.3.tar.Z« 
        └─⟦a24a58cd3⟧ 
            └─⟦this⟧ »gxdraw.c« 

TextFile

/* Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
   Distributed by Free Software Foundation, Inc.

This file is part of Ghostscript.

Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.  Refer
to the Ghostscript General Public License for full details.

Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License.  A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities.  It should be in a file named COPYING.  Among other
things, the copyright notice and this notice must be preserved on all
copies.  */

/* gxdraw.c */
/* Primitive drawing routines for GhostScript imaging library */
#include "gx.h"
#include "gxfixed.h"
#include "gxmatrix.h"
#include "gxbitmap.h"
#include "gzstate.h"
#include "gzdevice.h"			/* requires gsstate.h */
#include "gzcolor.h"			/* requires gxdevice.h */

gx_bitmap *gx_tile_expand(P3(int, int, gs_state *));

/* These routines all assume that gx_color_render has been called. */

/* Fill a rectangle. */
int
gz_fill_rectangle(int x, int y, int w, int h, gs_color *pcolor, gs_state *pgs)
{	gx_color_index darker = pcolor->dev_color.color1;
	gx_color_index lighter;
	gx_device *dev = pgs->device->info;
	gx_bitmap *tile;
	int code;
#ifdef DEBUG
if ( gs_debug['q'] )
	printf("[q]x=%d y=%d w=%d h=%d  c1=%ld c2=%ld htl=%d\n",
		x, y, w, h, darker, (long)pcolor->dev_color.color2,
		(long)pcolor->dev_color.halftone_level);
#endif
	if ( color_is_pure(pcolor) )	/* no halftoning */
	   {	(*dev->procs->fill_rectangle)(dev, x, y, w, h, darker);
		return 0;
	   }
	lighter = pcolor->dev_color.color2;
	tile = pcolor->dev_color.tile;
	/* Try to tile the rectangle primitively */
	code = (*dev->procs->tile_rectangle)(dev, tile, x, y, w, h, darker, lighter);
	if ( code < 0 )
	   {	/* Use the default implementation */
		code = gx_default_tile_rectangle(dev, tile, x, y, w, h, darker, lighter);
	   }
	return code;
}

/* Fill a trapezoid.  Requires: wt >= 0, wb >= 0. */
int
gz_fill_trapezoid(int x0, int w0, int y0, int x1, int w1, int h,
  gs_color *pcolor, gs_state *pgs)
{	if ( w0 == 0 && w1 == 0 || h <= 0 ) return 0;
	if ( color_is_pure(pcolor) )
	   {	gx_device *dev = pgs->device->info;
		if ( (*dev->procs->fill_trapezoid)(dev,
			x0, y0, w0, x1, y0 + h, w1,
			pcolor->dev_color.color1) >= 0
		   )
			return 0;
	   }
	   {	int xl, fxl;
		int dxl, dxl1, dxlf = x1 - x0;
		int xr, fxr;
		int dxr, dxr1, dxrf = x1 + w1 - (x0 + w0);
		int y, y1;
		int rxl, rxr, ry;
		/* Compute integer and fractional deltas */
#define reduce_delta(df, d, d1, pos)\
	if ( df >= 0 )\
	   {	if ( df >= h )\
		  d1 = (d = df / h) + 1, df -= d * h;\
		else	/* save the divides */\
		   {	pos();\
			d = 0, d1 = 1;\
		   }\
	   }\
	else			/* df < 0 */\
	   {	if ( df <= -h )\
		  d1 = (d = df / h) - 1, df = d * h - df;\
		else	/* save the divides */\
		  d = 0, d1 = -1, df = -df;\
	   }
#define pos_for_xl()			/* nothing */
		reduce_delta(dxlf, dxl, dxl1, pos_for_xl);
#define pos_for_xr()\
	if ( dxl == 0 && dxlf == 0 && dxrf == 0 )  /* detect rectangle */\
	   {	gz_fill_rectangle(x0, y0, w0, h, pcolor, pgs);\
		return 0;\
	   }
		reduce_delta(dxrf, dxr, dxr1, pos_for_xr);
		xl = x0, fxl = dxlf >> 1;
		xr = x0 + w0, fxr = dxrf >> 1;
		y = y0, y1 = y + h;
		rxl = xl, rxr = xr, ry = y;
		/* Do the fill */
		do
		   {	if ( xl != rxl || xr != rxr )	/* detect rectangles */
			   {	gz_fill_rectangle(rxl, ry, rxr - rxl, y - ry, pcolor, pgs);
				rxl = xl, rxr = xr, ry = y;
			   }
			if ( (fxl += dxlf) >= h ) fxl -= h, xl += dxl1;
			else xl += dxl;
			if ( (fxr += dxrf) >= h ) fxr -= h, xr += dxr1;
			else xr += dxr;
		   }
		while ( ++y < y1 );
		if ( y != ry )
		   {	gz_fill_rectangle(rxl, ry, rxr - rxl, y - ry, pcolor, pgs);
		   }
	   }
	return 0;
}

/* Default implementation of tile_rectangle */
int
gx_default_tile_rectangle(gx_device *dev, register gx_bitmap *tile,
  int x, int y, int w, int h, gx_color_index color0, gx_color_index color1)
{	/* Fill the rectangle in chunks */
	int width = tile->width;
	int raster = tile->raster;
	int ex = x + w, ey = y + h;
	int fex = ex - width, fey = ey - tile->height;
	int irx = ((width & (width - 1)) == 0 ?	/* power of 2 */
		x & (width - 1) :
		x % width);
	int ry = y % tile->height;
	int icw = width - irx;
	int ch = tile->height - ry;
	byte *row = tile->data + ry * raster;
	int (*proc)(P10(gx_device *, byte *, int, int, int, int, int, int, gx_color_index, gx_color_index)) = dev->procs->copy_mono;
	int cx, cy;
#ifdef DEBUG
if ( gs_debug['t'] )
   {	int ptx, pty;
	byte *ptp = tile->data;
	printf("[t]tile w=%d h=%d raster=%d; x=%d y=%d w=%d h=%d\n",
		tile->width, tile->height, tile->raster, x, y, w, h);
	for ( pty = 0; pty < tile->height; pty++ )
	   {	printf("   ");
		for ( ptx = 0; ptx < tile->raster; ptx++ )
			printf("%3x", *ptp++);
	   }
	printf("\n");
   }
#endif
	if ( icw > w ) icw = w;
	if ( ch > h ) ch = h;
#define real_copy_tile(sourcex, tx, tw)\
  (*proc)(dev, row, sourcex, raster, tx, cy, tw, ch, color0, color1)
#ifdef DEBUG
#define copy_tile(sx, tx, tw)\
  if ( gs_debug['t'] )\
	printf("   copy sx=%d x=%d y=%d w=%d h=%d\n",\
		sx, tx, cy, tw, ch);\
  real_copy_tile(sx, tx, tw)
#else
#define copy_tile(sx, tx, tw)\
  real_copy_tile(sx, tx, tw)
#endif
	for ( cy = y; cy < ey; )
	   {	copy_tile(irx, x, icw);
		cx = x + icw;
		while ( cx <= fex )
		   {	copy_tile(0, cx, width);
			cx += width;
		   }
		if ( cx < ex )
		   {	copy_tile(0, cx, ex - cx);
		   }
		cy += ch;
		ch = (cy > fey ? ey - cy : tile->height);
		row = tile->data;
	   }
#undef copy_tile
#undef real_copy_tile
	return 0;
}

/* Draw a one-pixel-wide line. */
int
gz_draw_line(int ix, int iy, int itox, int itoy,
  gs_color *pcolor, gs_state *pgs)
{	int h = itoy - iy;
	if ( h == 0 )		/* horizontal line */
	   {	int w = itox - ix;
		/* The iy - 1 looks funny, but that's what's consistent */
		/* with the rest of the half-open interval story. */
		if ( w <= 0 )
			gz_fill_rectangle(itox, iy - 1, - w, 1, pcolor, pgs);
		else
			gz_fill_rectangle(ix, iy - 1, w, 1, pcolor, pgs);
	   }
	else
	   {	int h = itoy - iy;
		int abs_w;
		gx_device *dev = pgs->device->info;
		if ( h < 0 )
		   {	/* Fill primitive requires h > 0 */
			int tix = ix;
			ix = itox, iy = itoy;
			itox = tix;	/* itoy isn't used again */
			h = - h;
		   }
		if ( color_is_pure(pcolor) &&
		    (*dev->procs->draw_line)(dev, ix, iy, itox, iy + h,
					     pcolor->dev_color.color1) >= 0 )
		  return 0;
		abs_w = abs(itox - ix);
		if ( abs_w <= h )
			gz_fill_trapezoid(ix, 1, iy, itox, 1, h, pcolor, pgs);
		else
		   {	/* If the line is more horizontal than vertical, */
			/* we have to fill it a little differently */
			/* to make sure all the pixels get colored. */
			int ux = (itox > ix ? abs_w : -abs_w) / h;
			int upos, uneg, uabs;
			if ( ux > 0 ) upos = ux, uneg = 0, uabs = ux;
			else upos = 0, uneg = ux, uabs = -ux;
			gz_fill_trapezoid(ix, 0, iy, ix+uneg, uabs, 1,
				pcolor, pgs);
			gz_fill_trapezoid(ix+uneg, uabs, iy+1, itox-upos, uabs, h-1,
				pcolor, pgs);
			gz_fill_trapezoid(itox-upos, uabs, iy+h-1, itox, 0, 1,
				pcolor, pgs);
		   }
	   }
	return 0;
}

/****** STUBS ******/
int
gx_default_draw_line(gx_device *dev,
  int x0, int y0, int x1, int y1, gx_color_index color)
{	return -1;
}
int
gx_default_fill_trapezoid(gx_device *dev,
  int x0, int y0, int width0, int x1, int y1, int width1,
  gx_color_index color)
{	return -1;
}
int
gx_default_tile_trapezoid(gx_device *dev, gx_bitmap *tile,
  int x0, int y0, int width0, int x1, int y1, int width1,
  gx_color_index color0, gx_color_index color1)
{	return -1;
}