1 /* $NetBSD: raster_text.c,v 1.9 2007/03/04 06:02:39 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to the Computer Systems 8 * Engineering Group at Lawrence Berkeley Laboratory and to the University 9 * of California at Berkeley by Jef Poskanzer. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)raster_text.c 8.1 (Berkeley) 6/11/93 36 */ 37 38 /* 39 * Text routines for raster library. 40 */ 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: raster_text.c,v 1.9 2007/03/04 06:02:39 christos Exp $"); 44 45 #include <sys/param.h> 46 #ifdef _KERNEL 47 #include <sys/systm.h> 48 #include <dev/rcons/raster.h> 49 #ifdef COLORFONT_CACHE 50 #include <sys/malloc.h> 51 #define NEW(size) malloc(size, M_DEVBUF, M_NOWAIT) 52 #endif 53 #else 54 #include <string.h> 55 #include "raster.h" 56 #ifdef COLORFONT_CACHE 57 #include <malloc.h> 58 #define NEW(size) malloc(size) 59 #endif 60 #endif 61 62 /* Draws text. Returns 0 on success, -1 on failure. */ 63 int 64 raster_text( r, x, y, rop, rf, text ) 65 struct raster* r; 66 int x, y; 67 int rop; 68 struct raster_font* rf; 69 unsigned char* text; 70 { 71 return raster_textn( r, x, y, rop, rf, text, strlen( text ) ); 72 } 73 74 /* Draws n characters of text. Returns 0 on success, -1 on failure. */ 75 int 76 raster_textn( r, x, y, rop, rf, text, n ) 77 struct raster* r; 78 int x, y; 79 int rop; 80 struct raster_font* rf; 81 unsigned char* text; 82 int n; 83 { 84 int clip; 85 int x1, y1; 86 struct raster_char* c; 87 struct raster* charrast; 88 int i; 89 unsigned char ch; 90 int thisx, thisy; 91 int phase; 92 93 /* Check whether we can avoid clipping. */ 94 clip = 0; 95 if ( rf->flags & RASFONT_FIXEDWIDTH && 96 rf->flags & RASFONT_NOVERTICALMOVEMENT ) 97 { 98 /* This font is well-behaved, we can compute the extent cheaply. */ 99 c = &(rf->chars['@']); 100 charrast = c->r; 101 if ( x + c->homex < 0 || y + c->homey < 0 || 102 x + c->homex + n * c->nextx > r->width || 103 y + c->homey + charrast->height > r->height ) 104 clip = 1; 105 } 106 else 107 { 108 /* Got to step through the string to compute the extent. */ 109 for ( i = 0, x1 = x, y1 = y; 110 i < n; 111 ++i, x1 += c->nextx, y1 += c->nexty ) 112 { 113 c = &(rf->chars[text[i]]); 114 charrast = c->r; 115 if ( charrast != (struct raster*) 0 ) 116 { 117 if ( x1 + c->homex < 0 || y1 + c->homey < 0 || 118 x1 + c->homex + charrast->width > r->width || 119 y1 + c->homey + charrast->height > r->height ) 120 { 121 clip = 1; 122 break; 123 } 124 } 125 } 126 } 127 128 /* Now display the text. */ 129 for ( i = 0, x1 = x, y1 = y; 130 i < n; 131 ++i, x1 += c->nextx, y1 += c->nexty ) 132 { 133 ch = text[i]; 134 c = &(rf->chars[ch]); 135 charrast = c->r; 136 if ( charrast != (struct raster*) 0 ) 137 { 138 thisx = x1 + c->homex; 139 thisy = y1 + c->homey; 140 141 phase = 0; 142 #ifdef COLORFONT_CACHE 143 if ( r->depth == 8 ) 144 { 145 /* Initialize color font cache if necessary. */ 146 if ( rf->cache == (struct raster_fontcache*) -1 ) 147 { 148 int c; 149 150 rf->cache = (struct raster_fontcache*) 151 NEW( sizeof(struct raster_fontcache) ); 152 if ( rf->cache != (struct raster_fontcache*) 0 ) 153 for ( c = 0; c < 256; ++c ) 154 rf->cache->cr[c] = (struct raster*) 0; 155 } 156 157 if ( rf->cache != (struct raster_fontcache*) 0 ) 158 { 159 int color; 160 struct raster* cr; 161 162 color = RAS_GETCOLOR( rop ); 163 cr = rf->cache->cr[ch]; 164 /* Is this character cached yet? */ 165 if ( cr != (struct raster*) 0 ) 166 { 167 /* Yes, but is it the right color? */ 168 if ( rf->cache->color[ch] == color ) 169 { 170 /* Yes - switch rasters. */ 171 charrast = cr; 172 } 173 else 174 { 175 /* No, re-draw it. */ 176 if ( raster_op_noclip( 177 cr, 0, 0, charrast->width, 178 charrast->height, rop, charrast, 0, 0 ) == 0 ) 179 { 180 rf->cache->color[ch] = color; 181 charrast = cr; 182 } 183 } 184 } 185 else 186 { 187 /* It's not cached, so cache it. */ 188 cr = raster_alloc( 189 charrast->width, charrast->height, 8 ); 190 if ( cr != (struct raster*) 0 ) 191 if ( raster_op_noclip( 192 cr, 0, 0, charrast->width, charrast->height, 193 rop, charrast, 0, 0 ) == 0 ) 194 { 195 rf->cache->color[ch] = color; 196 charrast = rf->cache->cr[ch] = cr; 197 } 198 } 199 } 200 } 201 #endif /*COLORFONT_CACHE*/ 202 203 if ( clip ) 204 { 205 if ( raster_op( 206 r, thisx, thisy, charrast->width, charrast->height, 207 rop, charrast, phase, 0 ) < 0 ) 208 return -1; 209 } 210 else 211 { 212 if ( raster_op_noclip( 213 r, thisx, thisy, charrast->width, charrast->height, 214 rop, charrast, phase, 0 ) < 0 ) 215 return -1; 216 } 217 } 218 } 219 220 return 0; 221 } 222 223 #ifdef COLORFONT_CACHE 224 /* Allocates a raster. Returns (struct raster*) 0 on failure. */ 225 struct raster* 226 raster_alloc( width, height, depth ) 227 int width, height, depth; 228 { 229 struct raster* r; 230 int linelongs; 231 232 if ( width <= 0 || height <= 0 || ( depth != 1 && depth != 8 ) ) 233 return (struct raster*) 0; 234 linelongs = ( ( width * depth + 31 ) >> 5 ); 235 r = (struct raster*) 236 NEW( sizeof(struct raster) + height * linelongs * sizeof(u_int32_t)); 237 if ( r == (struct raster*) 0 ) 238 return (struct raster*) 0; 239 240 r->width = width; 241 r->height = height; 242 r->depth = depth; 243 r->linelongs = linelongs; 244 r->pixels = (u_int32_t*) (r + 1); 245 r->data = (void *) 0; 246 return r; 247 } 248 #endif 249