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