Commit | Line | Data |
---|---|---|
4fe1e9dd | 1 | /*- |
ad787160 C |
2 | * Copyright (c) 1991, 1993 |
3 | * The Regents of the University of California. All rights reserved. | |
4fe1e9dd CT |
4 | * |
5 | * This code is derived from software contributed to the Computer Systems | |
6 | * Engineering Group at Lawrence Berkeley Laboratory and to the University | |
7 | * of California at Berkeley by Jef Poskanzer. | |
8 | * | |
ad787160 C |
9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | |
17 | * 3. All advertising materials mentioning features or use of this software | |
18 | * must display the following acknowledgement: | |
19 | * This product includes software developed by the University of | |
20 | * California, Berkeley and its contributors. | |
21 | * 4. Neither the name of the University nor the names of its contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
4fe1e9dd | 24 | * |
ad787160 C |
25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
35 | * SUCH DAMAGE. | |
36 | * | |
37 | * @(#)raster_text.c 8.1 (Berkeley) 6/11/93 | |
4fe1e9dd CT |
38 | * |
39 | * from: $Header: raster_text.c,v 1.15 92/06/17 08:14:45 torek Exp $ | |
40 | */ | |
41 | ||
42 | /* | |
43 | * Text routines for raster library. | |
44 | */ | |
45 | ||
46 | #ifdef KERNEL | |
5548a02f KB |
47 | #include <sys/param.h> |
48 | #include <sparc/rcons/raster.h> | |
4fe1e9dd | 49 | #ifdef COLORFONT_CACHE |
5548a02f | 50 | #include <sys/malloc.h> |
4fe1e9dd CT |
51 | #define NEW(size) malloc(size, M_DEVBUF, M_NOWAIT) |
52 | #endif | |
53 | #else | |
54 | #include <sys/types.h> | |
5548a02f | 55 | #include <sparc/rcons/raster.h> |
4fe1e9dd CT |
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 |