1*55132Storek /*- 2*55132Storek * Copyright (c) 1991 The Regents of the University of California. 3*55132Storek * All rights reserved. 4*55132Storek * 5*55132Storek * This code is derived from software contributed to the Computer Systems 6*55132Storek * Engineering Group at Lawrence Berkeley Laboratory and to the University 7*55132Storek * of California at Berkeley by Jef Poskanzer. 8*55132Storek * 9*55132Storek * %sccs.include.redist.c% 10*55132Storek * 11*55132Storek * @(#)raster_text.c 7.1 (Berkeley) 07/13/92 12*55132Storek * 13*55132Storek * from: $Header: raster_text.c,v 1.15 92/06/17 08:14:45 torek Exp $ 14*55132Storek */ 15*55132Storek 16*55132Storek /* 17*55132Storek * Text routines for raster library. 18*55132Storek */ 19*55132Storek 20*55132Storek #ifdef KERNEL 21*55132Storek #include "sys/param.h" 22*55132Storek #include "raster.h" 23*55132Storek #ifdef COLORFONT_CACHE 24*55132Storek #include "sys/malloc.h" 25*55132Storek #define NEW(size) malloc(size, M_DEVBUF, M_NOWAIT) 26*55132Storek #endif 27*55132Storek #else 28*55132Storek #include <sys/types.h> 29*55132Storek #include "raster.h" 30*55132Storek #ifdef COLORFONT_CACHE 31*55132Storek #include <malloc.h> 32*55132Storek #define NEW(size) malloc(size) 33*55132Storek #endif 34*55132Storek #endif 35*55132Storek 36*55132Storek 37*55132Storek /* Draws text. Returns 0 on success, -1 on failure. */ 38*55132Storek int 39*55132Storek raster_text( r, x, y, rop, rf, text ) 40*55132Storek register struct raster* r; 41*55132Storek int x, y; 42*55132Storek int rop; 43*55132Storek struct raster_font* rf; 44*55132Storek char* text; 45*55132Storek { 46*55132Storek return raster_textn( r, x, y, rop, rf, text, strlen( text ) ); 47*55132Storek } 48*55132Storek 49*55132Storek /* Draws n characters of text. Returns 0 on success, -1 on failure. */ 50*55132Storek int 51*55132Storek raster_textn( r, x, y, rop, rf, text, n ) 52*55132Storek register struct raster* r; 53*55132Storek int x, y; 54*55132Storek int rop; 55*55132Storek struct raster_font* rf; 56*55132Storek char* text; 57*55132Storek int n; 58*55132Storek { 59*55132Storek int clip; 60*55132Storek int x1, y1; 61*55132Storek struct raster_char* c; 62*55132Storek struct raster* charrast; 63*55132Storek int i; 64*55132Storek register char ch; 65*55132Storek int thisx, thisy; 66*55132Storek int phase; 67*55132Storek 68*55132Storek /* Check whether we can avoid clipping. */ 69*55132Storek clip = 0; 70*55132Storek if ( rf->flags & RASFONT_FIXEDWIDTH && 71*55132Storek rf->flags & RASFONT_NOVERTICALMOVEMENT ) 72*55132Storek { 73*55132Storek /* This font is well-behaved, we can compute the extent cheaply. */ 74*55132Storek c = &(rf->chars['@']); 75*55132Storek charrast = c->r; 76*55132Storek if ( x + c->homex < 0 || y + c->homey < 0 || 77*55132Storek x + c->homex + n * c->nextx > r->width || 78*55132Storek y + c->homey + charrast->height > r->height ) 79*55132Storek clip = 1; 80*55132Storek } 81*55132Storek else 82*55132Storek { 83*55132Storek /* Got to step through the string to compute the extent. */ 84*55132Storek for ( i = 0, x1 = x, y1 = y; 85*55132Storek i < n; 86*55132Storek ++i, x1 += c->nextx, y1 += c->nexty ) 87*55132Storek { 88*55132Storek c = &(rf->chars[text[i]]); 89*55132Storek charrast = c->r; 90*55132Storek if ( charrast != (struct raster*) 0 ) 91*55132Storek { 92*55132Storek if ( x1 + c->homex < 0 || y1 + c->homey < 0 || 93*55132Storek x1 + c->homex + charrast->width > r->width || 94*55132Storek y1 + c->homey + charrast->height > r->height ) 95*55132Storek { 96*55132Storek clip = 1; 97*55132Storek break; 98*55132Storek } 99*55132Storek } 100*55132Storek } 101*55132Storek } 102*55132Storek 103*55132Storek /* Now display the text. */ 104*55132Storek for ( i = 0, x1 = x, y1 = y; 105*55132Storek i < n; 106*55132Storek ++i, x1 += c->nextx, y1 += c->nexty ) 107*55132Storek { 108*55132Storek ch = text[i]; 109*55132Storek c = &(rf->chars[ch]); 110*55132Storek charrast = c->r; 111*55132Storek if ( charrast != (struct raster*) 0 ) 112*55132Storek { 113*55132Storek thisx = x1 + c->homex; 114*55132Storek thisy = y1 + c->homey; 115*55132Storek 116*55132Storek phase = 0; 117*55132Storek #ifdef COLORFONT_CACHE 118*55132Storek if ( r->depth == 8 ) 119*55132Storek { 120*55132Storek /* Initialize color font cache if necessary. */ 121*55132Storek if ( rf->cache == (struct raster_fontcache*) -1 ) 122*55132Storek { 123*55132Storek int c; 124*55132Storek 125*55132Storek rf->cache = (struct raster_fontcache*) 126*55132Storek NEW( sizeof(struct raster_fontcache) ); 127*55132Storek if ( rf->cache != (struct raster_fontcache*) 0 ) 128*55132Storek for ( c = 0; c < 256; ++c ) 129*55132Storek rf->cache->cr[c] = (struct raster*) 0; 130*55132Storek } 131*55132Storek 132*55132Storek if ( rf->cache != (struct raster_fontcache*) 0 ) 133*55132Storek { 134*55132Storek int color; 135*55132Storek struct raster* cr; 136*55132Storek 137*55132Storek color = RAS_GETCOLOR( rop ); 138*55132Storek cr = rf->cache->cr[ch]; 139*55132Storek /* Is this character cached yet? */ 140*55132Storek if ( cr != (struct raster*) 0 ) 141*55132Storek { 142*55132Storek /* Yes, but is it the right color? */ 143*55132Storek if ( rf->cache->color[ch] == color ) 144*55132Storek { 145*55132Storek /* Yes - switch rasters. */ 146*55132Storek charrast = cr; 147*55132Storek } 148*55132Storek else 149*55132Storek { 150*55132Storek /* No, re-draw it. */ 151*55132Storek if ( raster_op_noclip( 152*55132Storek cr, 0, 0, charrast->width, 153*55132Storek charrast->height, rop, charrast, 0, 0 ) == 0 ) 154*55132Storek { 155*55132Storek rf->cache->color[ch] = color; 156*55132Storek charrast = cr; 157*55132Storek } 158*55132Storek } 159*55132Storek } 160*55132Storek else 161*55132Storek { 162*55132Storek /* It's not cached, so cache it. */ 163*55132Storek cr = raster_alloc( 164*55132Storek charrast->width, charrast->height, 8 ); 165*55132Storek if ( cr != (struct raster*) 0 ) 166*55132Storek if ( raster_op_noclip( 167*55132Storek cr, 0, 0, charrast->width, charrast->height, 168*55132Storek rop, charrast, 0, 0 ) == 0 ) 169*55132Storek { 170*55132Storek rf->cache->color[ch] = color; 171*55132Storek charrast = rf->cache->cr[ch] = cr; 172*55132Storek } 173*55132Storek } 174*55132Storek } 175*55132Storek } 176*55132Storek #endif /*COLORFONT_CACHE*/ 177*55132Storek 178*55132Storek if ( clip ) 179*55132Storek { 180*55132Storek if ( raster_op( 181*55132Storek r, thisx, thisy, charrast->width, charrast->height, 182*55132Storek rop, charrast, phase, 0 ) < 0 ) 183*55132Storek return -1; 184*55132Storek } 185*55132Storek else 186*55132Storek { 187*55132Storek if ( raster_op_noclip( 188*55132Storek r, thisx, thisy, charrast->width, charrast->height, 189*55132Storek rop, charrast, phase, 0 ) < 0 ) 190*55132Storek return -1; 191*55132Storek } 192*55132Storek } 193*55132Storek } 194*55132Storek 195*55132Storek return 0; 196*55132Storek } 197*55132Storek 198*55132Storek #ifdef COLORFONT_CACHE 199*55132Storek /* Allocates a raster. Returns (struct raster*) 0 on failure. */ 200*55132Storek struct raster* 201*55132Storek raster_alloc( width, height, depth ) 202*55132Storek int width, height, depth; 203*55132Storek { 204*55132Storek struct raster* r; 205*55132Storek int linelongs; 206*55132Storek 207*55132Storek if ( width <= 0 || height <= 0 || ( depth != 1 && depth != 8 ) ) 208*55132Storek return (struct raster*) 0; 209*55132Storek linelongs = ( ( width * depth + 31 ) >> 5 ); 210*55132Storek r = (struct raster*) 211*55132Storek NEW( sizeof(struct raster) + height * linelongs * sizeof(u_long)); 212*55132Storek if ( r == (struct raster*) 0 ) 213*55132Storek return (struct raster*) 0; 214*55132Storek 215*55132Storek r->width = width; 216*55132Storek r->height = height; 217*55132Storek r->depth = depth; 218*55132Storek r->linelongs = linelongs; 219*55132Storek r->pixels = (u_long*) (r + 1); 220*55132Storek r->data = (caddr_t) 0; 221*55132Storek return r; 222*55132Storek } 223*55132Storek #endif 224