raster_text.c revision 1.6 1 /* $NetBSD: raster_text.c,v 1.6 2001/11/15 09:48:15 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.6 2001/11/15 09:48:15 lukem Exp $");
48
49 #include <sys/param.h>
50 #ifdef _KERNEL
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 <string.h>
59 #include "raster.h"
60 #ifdef COLORFONT_CACHE
61 #include <malloc.h>
62 #define NEW(size) malloc(size)
63 #endif
64 #endif
65
66 /* Draws text. Returns 0 on success, -1 on failure. */
67 int
68 raster_text( r, x, y, rop, rf, text )
69 struct raster* r;
70 int x, y;
71 int rop;
72 struct raster_font* rf;
73 unsigned char* text;
74 {
75 return raster_textn( r, x, y, rop, rf, text, strlen( text ) );
76 }
77
78 /* Draws n characters of text. Returns 0 on success, -1 on failure. */
79 int
80 raster_textn( r, x, y, rop, rf, text, n )
81 struct raster* r;
82 int x, y;
83 int rop;
84 struct raster_font* rf;
85 unsigned char* text;
86 int n;
87 {
88 int clip;
89 int x1, y1;
90 struct raster_char* c;
91 struct raster* charrast;
92 int i;
93 unsigned char ch;
94 int thisx, thisy;
95 int phase;
96
97 /* Check whether we can avoid clipping. */
98 clip = 0;
99 if ( rf->flags & RASFONT_FIXEDWIDTH &&
100 rf->flags & RASFONT_NOVERTICALMOVEMENT )
101 {
102 /* This font is well-behaved, we can compute the extent cheaply. */
103 c = &(rf->chars['@']);
104 charrast = c->r;
105 if ( x + c->homex < 0 || y + c->homey < 0 ||
106 x + c->homex + n * c->nextx > r->width ||
107 y + c->homey + charrast->height > r->height )
108 clip = 1;
109 }
110 else
111 {
112 /* Got to step through the string to compute the extent. */
113 for ( i = 0, x1 = x, y1 = y;
114 i < n;
115 ++i, x1 += c->nextx, y1 += c->nexty )
116 {
117 c = &(rf->chars[text[i]]);
118 charrast = c->r;
119 if ( charrast != (struct raster*) 0 )
120 {
121 if ( x1 + c->homex < 0 || y1 + c->homey < 0 ||
122 x1 + c->homex + charrast->width > r->width ||
123 y1 + c->homey + charrast->height > r->height )
124 {
125 clip = 1;
126 break;
127 }
128 }
129 }
130 }
131
132 /* Now display the text. */
133 for ( i = 0, x1 = x, y1 = y;
134 i < n;
135 ++i, x1 += c->nextx, y1 += c->nexty )
136 {
137 ch = text[i];
138 c = &(rf->chars[ch]);
139 charrast = c->r;
140 if ( charrast != (struct raster*) 0 )
141 {
142 thisx = x1 + c->homex;
143 thisy = y1 + c->homey;
144
145 phase = 0;
146 #ifdef COLORFONT_CACHE
147 if ( r->depth == 8 )
148 {
149 /* Initialize color font cache if necessary. */
150 if ( rf->cache == (struct raster_fontcache*) -1 )
151 {
152 int c;
153
154 rf->cache = (struct raster_fontcache*)
155 NEW( sizeof(struct raster_fontcache) );
156 if ( rf->cache != (struct raster_fontcache*) 0 )
157 for ( c = 0; c < 256; ++c )
158 rf->cache->cr[c] = (struct raster*) 0;
159 }
160
161 if ( rf->cache != (struct raster_fontcache*) 0 )
162 {
163 int color;
164 struct raster* cr;
165
166 color = RAS_GETCOLOR( rop );
167 cr = rf->cache->cr[ch];
168 /* Is this character cached yet? */
169 if ( cr != (struct raster*) 0 )
170 {
171 /* Yes, but is it the right color? */
172 if ( rf->cache->color[ch] == color )
173 {
174 /* Yes - switch rasters. */
175 charrast = cr;
176 }
177 else
178 {
179 /* No, re-draw it. */
180 if ( raster_op_noclip(
181 cr, 0, 0, charrast->width,
182 charrast->height, rop, charrast, 0, 0 ) == 0 )
183 {
184 rf->cache->color[ch] = color;
185 charrast = cr;
186 }
187 }
188 }
189 else
190 {
191 /* It's not cached, so cache it. */
192 cr = raster_alloc(
193 charrast->width, charrast->height, 8 );
194 if ( cr != (struct raster*) 0 )
195 if ( raster_op_noclip(
196 cr, 0, 0, charrast->width, charrast->height,
197 rop, charrast, 0, 0 ) == 0 )
198 {
199 rf->cache->color[ch] = color;
200 charrast = rf->cache->cr[ch] = cr;
201 }
202 }
203 }
204 }
205 #endif /*COLORFONT_CACHE*/
206
207 if ( clip )
208 {
209 if ( raster_op(
210 r, thisx, thisy, charrast->width, charrast->height,
211 rop, charrast, phase, 0 ) < 0 )
212 return -1;
213 }
214 else
215 {
216 if ( raster_op_noclip(
217 r, thisx, thisy, charrast->width, charrast->height,
218 rop, charrast, phase, 0 ) < 0 )
219 return -1;
220 }
221 }
222 }
223
224 return 0;
225 }
226
227 #ifdef COLORFONT_CACHE
228 /* Allocates a raster. Returns (struct raster*) 0 on failure. */
229 struct raster*
230 raster_alloc( width, height, depth )
231 int width, height, depth;
232 {
233 struct raster* r;
234 int linelongs;
235
236 if ( width <= 0 || height <= 0 || ( depth != 1 && depth != 8 ) )
237 return (struct raster*) 0;
238 linelongs = ( ( width * depth + 31 ) >> 5 );
239 r = (struct raster*)
240 NEW( sizeof(struct raster) + height * linelongs * sizeof(u_int32_t));
241 if ( r == (struct raster*) 0 )
242 return (struct raster*) 0;
243
244 r->width = width;
245 r->height = height;
246 r->depth = depth;
247 r->linelongs = linelongs;
248 r->pixels = (u_int32_t*) (r + 1);
249 r->data = (caddr_t) 0;
250 return r;
251 }
252 #endif
253