#ifndef lint static char sccsid[] = "@(#)cg2_shtext.c 9.2 88/01/19 Copyright 1984 Sun Micro"; #endif /* * Copyright (c) 1984 by Sun Microsystems, Inc. */ /*- Paint a string in a cg2 pixrect clipped to a shape, which must be rectangular gensh_text.c, Mon May 13 10:24:35 1985 James Gosling, Sun Microsystems */ #include #ifdef REF #include #include #endif #include "shape.h" #include #include #include #include #include #include "font.h" #define resolution unused,0 extern struct pixrectops mem_ops; extern char pr_reversedst[]; cg2_shapetext(pixrect, op, font, shape, p, n) struct pixrect *pixrect; short op; struct font *font; struct shape *shape; register struct rendering_info *p; { register short temp, sizey; static struct mpr_data data; struct pixrect pix; register struct font *f = font; register struct generic_glyph *ip; short top = 0; short bottom = pixrect->pr_height; short y0 = cfloorfr(p->pos.y) - font->origin.y; short y1 = y0 + font->size.y; short leftedge, rightedge; short inlineclip = 0; short dontclip = op & PIX_DONTCLIP; if (shape == 0) return 0; if (!shape->is_rect) { pst_subdivide_text(pixrect, op, font, shape, shape->trapset, rendering_info, rendering_info_length); return 0; } if (!dontclip) { leftedge = 0; rightedge = pixrect->pr_width; if ((temp = shape->pos.x) > leftedge) leftedge = temp; if ((temp = shape->pos.x + shape->size.x) < rightedge) rightedge = temp; if ((temp = shape->pos.y) > top) top = temp; if ((temp = shape->pos.y + shape->size.y) < bottom) bottom = temp; if (leftedge >= rightedge || y1 <= top || y0 >= bottom) return 0; temp = cfloorfr(p->pos.x) - f->origin.x; if (!f->left_to_right || y0 < top || y1 > bottom) inlineclip = 1; else if (temp >= leftedge && cfloorfr(p[n - 1].pos.x) + f->size.x <= rightedge) dontclip++; if (temp < leftedge) { /* clip off the left */ pix.pr_depth = 1; pix.pr_data = (caddr_t) & data; pix.pr_ops = &mem_ops; while (1) { if (--n < 0) return 0; ip = (struct generic_glyph *) p->g; if (cfloorfr(p->pos.x) + f->size.x - f->origin.x >= leftedge) { if (cfloorfr(p->pos.x) - f->origin.x >= leftedge) { n++; break; /* switch to fast drawing */ } data.md_image = (short *) p->bits; data.md_linebytes = ((ip->h.size.x + 15) >> 3) & ~1; pix.pr_size.x = ip->h.size.x; pix.pr_size.y = ip->h.size.y; pr_shaperop(pixrect, shape, /* (op & (0xF<<1)) == PIX_SRC ? PIX_SRC | PIX_DST : */ op, &pix, cfloorfr(p->pos.x) - ip->h.origin.x, cfloorfr(p->pos.y) - ip->h.origin.y); } p++; } } } { register short linebytes; short xoff = cg2_d(pixrect)->cgpr_offset.x; short yoff = cg2_d(pixrect)->cgpr_offset.y; register struct generic_glyph *ip; /*- static short mrc_lmasktable[] = {0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE}; */ extern short mrc_lmasktable[], mrc_rmasktable[]; short prime; register struct cg2fb *fb = cg2_fbfrompr(pixrect); register struct memropc *ropregs = &fb->ropcontrol[CG2_ALLROP].ropregs; int color; int ma_vert; if ((op & (0xF << 1)) == PIX_NOT(PIX_DST)) { fb->ppmask.reg = 0xFF; ropregs->mrc_op = CG_SRC ^ CG_DEST; } else { color = PIX_OPCOLOR(op); fb->ppmask.reg = color; ropregs->mrc_pattern = -1; fb->ppmask.reg = ~color; ropregs->mrc_pattern = 0; fb->ppmask.reg = ~0; ropregs->mrc_op = CG_SRC & CG_MASK | ~CG_SRC & CG_DEST; } ropregs->mrc_mask2 = 0; fb->status.reg.ropmode = PWWWRD; #define src ((unsigned short *)ip) for (; --n >= 0; p++) { register unsigned char *by; register w; ip = (struct generic_glyph *) p->g; temp = cfloorfr(p->pos.x) - ip->h.origin.x; if (!dontclip && (temp + ip->h.size.x > rightedge || inlineclip && (cfloorfr(p->pos.x) - ip->h.origin.x + ip->h.size.x > rightedge || cfloorfr(p->pos.x) - ip->h.origin.x < leftedge || cfloorfr(p->pos.y) - ip->h.origin.y + ip->h.size.y > bottom || cfloorfr(p->pos.y) - ip->h.origin.y < top))) { pix.pr_depth = 1; pix.pr_data = (caddr_t) & data; pix.pr_ops = &mem_ops; op &= ~PIX_DONTCLIP; if (cfloorfr(p->pos.x) - font->origin.x >= rightedge && font->left_to_right) break; data.md_image = (short *) p->bits; data.md_linebytes = ((ip->h.size.x + 15) >> 3) & ~1; pix.pr_size.x = ip->h.size.x; pix.pr_size.y = ip->h.size.y; pr_shaperop(pixrect, shape, /* (op & (0xF<<1)) == PIX_SRC ? PIX_SRC | PIX_DST : */ op, &pix, cfloorfr(p->pos.x) - ip->h.origin.x, cfloorfr(p->pos.y) - ip->h.origin.y); if ((op & (0xF << 1)) == PIX_NOT(PIX_DST)) { fb->ppmask.reg = 0xFF; ropregs->mrc_op = CG_SRC ^ CG_DEST; } else { color = PIX_OPCOLOR(op); fb->ppmask.reg = color; ropregs->mrc_pattern = -1; fb->ppmask.reg = ~color; ropregs->mrc_pattern = 0; fb->ppmask.reg = ~0; ropregs->mrc_op = CG_SRC & CG_MASK | ~CG_SRC & CG_DEST; } ropregs->mrc_mask2 = 0; fb->status.reg.ropmode = PWWWRD; continue; } temp += xoff; if ((sizey = ip->h.size.y) > 0 && ip->h.size.x > 0) { ma_vert = ((ip->h.size.x + 15) >> 4) << 1; ropregs->mrc_mask1 = mrc_lmasktable[temp & 0xF]; ropregs->mrc_mask2 = mrc_rmasktable[(temp + ip->h.size.x - 1) & 0xF];/*XYZZY*/ w = temp & 0xF; ropregs->mrc_shift = w | (1 << 8); prime = w; w = (ip->h.size.x + w - 1) >> 4; ropregs->mrc_width = w; ropregs->mrc_opcount = w; by = (unsigned char *) &(fb)->ropio.ropplane[0].word [sadd(ssub(cfloorfr(p->pos.y), ip->h.origin.y), yoff)][temp >> 4]; src = p->bits; temp = pr_product(w + 1, sizeof(short)); linebytes = CG2_WIDTH / 8 - temp; ma_vert -= temp; switch (w) { case 0: if (prime <= 0) { assert(ma_vert == 0); while (--sizey != -1) { ropregs->mrc_source1 = *src++; *((short *) by)++ = 0; by += linebytes; } break; } else if (ma_vert) { assert(ma_vert == 0); while (--sizey != -1) { *((short *) by)++ = *src++; by += linebytes; (char *) src += ma_vert; } break; } else { while (--sizey != -1) { *((short *) by)++ = *src++; by += linebytes; } } break; case 1: if (prime <= 0) { /* ma_vert += sizeof(short); */ while (--sizey != -1) { ropregs->mrc_source1 = *src++; *((short *) by)++ = *src++; *((short *) by)++ = 0; by += linebytes; (char *) src += ma_vert; } break; } else if (ma_vert != -2) { assert(ma_vert == 0); while (--sizey != -1) { *((short *) by)++ = *src++; *((short *) by)++ = *src++; by += linebytes; /* (char *) src += ma_vert; */ } break; } else while (--sizey != -1) { *((short *) by)++ = *src++; *((short *) by)++ = 0 /* *src */ ; by += linebytes; } break; default: if (w < 0) break; if (prime <= 0) ma_vert -= sizeof(short); while (--sizey != -1) { if (prime <= 0) ropregs->mrc_source1 = *src++; for (temp = w; --temp != -1;) *((short *) by)++ = *src++; if (prime > 0) *((short *) by)++ = *src++; else { src++; *((short *) by)++ = 0; } by += linebytes; (char *) src += ma_vert; } } } } #undef src } return 0; }