#ifndef lint static char sccsid[] = "@(#)tile.c 9.2 88/01/19 Copyright 1985 Sun Micro"; #endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. */ /*- Tile pixrects - infinitly large pixrects that appear as a relicated source. tile.c, Tue Oct 29 10:57:17 1985 James Gosling, Sun Microsystems */ #include #ifdef REF #include #include #endif #include "shape.h" #include "trap_step.h" static tile_rop(); static tile_destroy(); static tile_get(); static struct pixrect *tile_region(); static tile_shaperop(); static tile_error(); struct pixrect * tile_create( /* pr */ ); struct pixrectops tile_ops = {tile_rop, tile_error, /* tile_stencil */ tile_error, /* tile_batchrop */ tile_error, /* tile_nop */ tile_destroy, tile_get, tile_error, /* tile_put */ tile_error, /* tile_vector */ tile_region, tile_error, /* tile_putcolormap */ tile_error, /* tile_getcolormap */ tile_error, /* tile_putattributes */ tile_error, /* tile_getattributes */ tile_error, /* tile_shapetext */ tile_shaperop, tile_error, /* tile_shapecurve */ tile_error, /* tile_shapevector */ generic_replrop, }; static tile_rop(dpr, dx, dy, w, h, op, spr, sx, sy) register struct pixrect *spr; register struct pixrect *dpr; { return (spr == 0 || spr->pr_ops != &tile_ops ? -1 : pr_replrop(dpr, dx, dy, w, h, op, spr->pr_data, sx, sy)); } static tile_error() { return -1; } static tile_destroy(pr) register struct pixrect *pr; { free(pr); return 0; } static tile_get(pr, x, y) register struct pixrect *pr; { register struct pixrect *t = (struct pixrect *) pr->pr_data; return pr_get(t, x % t->pr_width, y % t->pr_height); } static struct pixrect * tile_region(pr, x, y, w, h) register struct pixrect *pr; { return tile_create(pr->pr_data); } static tile_shaperop(dpr, shape, OP, spr, dx, dy) register struct pixrect *spr, *dpr; register struct shape *shape; { struct pr_subregion dst; struct pr_prpos src; struct shape nextshape; if (dpr->pr_ops == &tile_ops || shape == 0) return 0; if (spr == 0 || spr->pr_ops != &tile_ops) return -1; if (shape->is_rect) return pr_replrop(dpr, shape->pos.x, shape->pos.y, shape->size.x, shape->size.y, OP, spr->pr_data, shape->pos.x - dx, shape->pos.y - dy); while (1) { int op = OP; if (shape->size.x < 0) { dst.pos.x = 0; dst.pos.y = 0; dst.size.x = 16000; dst.size.y = 16000; } else { dst.pos.x = shape->pos.x; dst.pos.y = shape->pos.y; dst.size.x = shape->size.x; dst.size.y = shape->size.y; } dst.pr = dpr; if (op & PIX_DONTCLIP) op &= ~PIX_DONTCLIP; else pr_clip(&dst, 0); if (dst.size.x > 0 && dst.size.y > 0) { register y = dst.pos.y; struct fine_trap_state trap; int ylimit = y + dst.size.y; int xlimit = dst.pos.x + dst.size.x; int dstx = dst.pos.x; if (shape->trapset->top > y) { register w; if ((dst.size.y += (w = y - shape->trapset->top)) <= 0) goto Continue; y -= w; } if (shape->trapset->bottom < ylimit && (dst.size.y = (ylimit = shape->trapset->bottom) - y) <= 0) goto Continue; init_fine_trap(&trap, shape->trapset); fast_step_down_trap_to(&trap, y); while (y < ylimit) { register x1 = dstx; register x2 = xlimit; register height; if (trap.x1 > x1) x1 = trap.x1; if (trap.x2 < x2) x2 = trap.x2; height = trap.next.y - y; if (height <= 0) break; if (height + y > ylimit) height = ylimit - y; trap.x1 = trap.next.x1; trap.x2 = trap.next.x2; if (x1 < x2) { pr_replrop(dst.pr, x1, y, x2 - x1, height, OP, spr, x1 - dy, y - dy); } y = trap.next.y; trap.next = *trap.seg++; } } Continue: if (shape->trapset->next) { nextshape = *shape; nextshape.trapset = shape->trapset->next; shape = &nextshape; } else return 0; } } struct pixrect * tile_create(pr) register struct pixrect *pr; { register struct pixrect *ret = (struct pixrect *) snoopalloc("tile.c", sizeof(struct pixrect)); ret->pr_ops = &tile_ops; ret->pr_width = 0x7fffffff; /* maxint */ ret->pr_height = 0x7fffffff; ret->pr_depth = pr->pr_depth; ret->pr_data = (caddr_t) pr; return ret; }