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