|
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 g
Length: 7909 (0x1ee5) Types: TextFile Names: »gxdraw.c«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦ff23ba0e6⟧ »./ghostscript-1.3.tar.Z« └─⟦a24a58cd3⟧ └─⟦this⟧ »gxdraw.c«
/* 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; }