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