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