xref: /original-bsd/sys/sparc/rcons/raster_text.c (revision 30928eff)
1 /*-
2  * Copyright (c) 1991 The Regents of the University of California.
3  * All rights reserved.
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  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)raster_text.c	7.2 (Berkeley) 10/11/92
12  *
13  * from: $Header: raster_text.c,v 1.15 92/06/17 08:14:45 torek Exp $
14  */
15 
16 /*
17  * Text routines for raster library.
18  */
19 
20 #ifdef KERNEL
21 #include <sys/param.h>
22 #include <sparc/rcons/raster.h>
23 #ifdef COLORFONT_CACHE
24 #include <sys/malloc.h>
25 #define NEW(size) malloc(size, M_DEVBUF, M_NOWAIT)
26 #endif
27 #else
28 #include <sys/types.h>
29 #include <sparc/rcons/raster.h>
30 #ifdef COLORFONT_CACHE
31 #include <malloc.h>
32 #define NEW(size) malloc(size)
33 #endif
34 #endif
35 
36 
37 /* Draws text.  Returns 0 on success, -1 on failure. */
38 int
39 raster_text( r, x, y, rop, rf, text )
40     register struct raster* r;
41     int x, y;
42     int rop;
43     struct raster_font* rf;
44     char* text;
45     {
46     return raster_textn( r, x, y, rop, rf, text, strlen( text ) );
47     }
48 
49 /* Draws n characters of text.  Returns 0 on success, -1 on failure. */
50 int
51 raster_textn( r, x, y, rop, rf, text, n )
52     register struct raster* r;
53     int x, y;
54     int rop;
55     struct raster_font* rf;
56     char* text;
57     int n;
58     {
59     int clip;
60     int x1, y1;
61     struct raster_char* c;
62     struct raster* charrast;
63     int i;
64     register char ch;
65     int thisx, thisy;
66     int phase;
67 
68     /* Check whether we can avoid clipping. */
69     clip = 0;
70     if ( rf->flags & RASFONT_FIXEDWIDTH &&
71 	 rf->flags & RASFONT_NOVERTICALMOVEMENT )
72 	{
73 	/* This font is well-behaved, we can compute the extent cheaply. */
74 	c = &(rf->chars['@']);
75 	charrast = c->r;
76 	if ( x + c->homex < 0 || y + c->homey < 0 ||
77 	     x + c->homex + n * c->nextx > r->width ||
78 	     y + c->homey + charrast->height > r->height )
79 	    clip = 1;
80 	}
81     else
82 	{
83 	/* Got to step through the string to compute the extent. */
84 	for ( i = 0, x1 = x, y1 = y;
85 	      i < n;
86 	      ++i, x1 += c->nextx, y1 += c->nexty )
87 	    {
88 	    c = &(rf->chars[text[i]]);
89 	    charrast = c->r;
90 	    if ( charrast != (struct raster*) 0 )
91 		{
92 		if ( x1 + c->homex < 0 || y1 + c->homey < 0 ||
93 		     x1 + c->homex + charrast->width > r->width ||
94 		     y1 + c->homey + charrast->height > r->height )
95 		    {
96 		    clip = 1;
97 		    break;
98 		    }
99 		}
100 	    }
101 	}
102 
103     /* Now display the text. */
104     for ( i = 0, x1 = x, y1 = y;
105 	  i < n;
106 	  ++i, x1 += c->nextx, y1 += c->nexty )
107 	{
108 	ch = text[i];
109 	c = &(rf->chars[ch]);
110 	charrast = c->r;
111 	if ( charrast != (struct raster*) 0 )
112 	    {
113 	    thisx = x1 + c->homex;
114 	    thisy = y1 + c->homey;
115 
116 	    phase = 0;
117 #ifdef COLORFONT_CACHE
118 	    if ( r->depth == 8 )
119 		{
120 		/* Initialize color font cache if necessary. */
121 		if ( rf->cache == (struct raster_fontcache*) -1 )
122 		    {
123 		    int c;
124 
125 		    rf->cache = (struct raster_fontcache*)
126 			NEW( sizeof(struct raster_fontcache) );
127 		    if ( rf->cache != (struct raster_fontcache*) 0 )
128 			for ( c = 0; c < 256; ++c )
129 			    rf->cache->cr[c] = (struct raster*) 0;
130 		    }
131 
132 		if ( rf->cache != (struct raster_fontcache*) 0 )
133 		    {
134 		    int color;
135 		    struct raster* cr;
136 
137 		    color = RAS_GETCOLOR( rop );
138 		    cr = rf->cache->cr[ch];
139 		    /* Is this character cached yet? */
140 		    if ( cr != (struct raster*) 0 )
141 			{
142 			/* Yes, but is it the right color? */
143 			if ( rf->cache->color[ch] == color )
144 			    {
145 			    /* Yes - switch rasters. */
146 			    charrast = cr;
147 			    }
148 			else
149 			    {
150 			    /* No, re-draw it. */
151 			    if ( raster_op_noclip(
152 				 cr, 0, 0, charrast->width,
153 				 charrast->height, rop, charrast, 0, 0 ) == 0 )
154 				{
155 				rf->cache->color[ch] = color;
156 				charrast = cr;
157 				}
158 			    }
159 			}
160 		    else
161 			{
162 			/* It's not cached, so cache it. */
163 			cr = raster_alloc(
164 			    charrast->width, charrast->height, 8 );
165 			if ( cr != (struct raster*) 0 )
166 			    if ( raster_op_noclip(
167 				 cr, 0, 0, charrast->width, charrast->height,
168 				 rop, charrast, 0, 0 ) == 0 )
169 				{
170 				rf->cache->color[ch] = color;
171 				charrast = rf->cache->cr[ch] = cr;
172 				}
173 			}
174 		    }
175 		}
176 #endif /*COLORFONT_CACHE*/
177 
178 	    if ( clip )
179 		{
180 		if ( raster_op(
181 			 r, thisx, thisy, charrast->width, charrast->height,
182 			 rop, charrast, phase, 0 ) < 0 )
183 		    return -1;
184 		}
185 	    else
186 		{
187 		if ( raster_op_noclip(
188 			 r, thisx, thisy, charrast->width, charrast->height,
189 			 rop, charrast, phase, 0 ) < 0 )
190 		    return -1;
191 		}
192 	    }
193 	}
194 
195     return 0;
196     }
197 
198 #ifdef COLORFONT_CACHE
199 /* Allocates a raster.  Returns (struct raster*) 0 on failure. */
200 struct raster*
201 raster_alloc( width, height, depth )
202     int width, height, depth;
203     {
204     struct raster* r;
205     int linelongs;
206 
207     if ( width <= 0 || height <= 0 || ( depth != 1 && depth != 8 ) )
208 	return (struct raster*) 0;
209     linelongs = ( ( width * depth + 31 ) >> 5 );
210     r = (struct raster*)
211 	NEW( sizeof(struct raster) + height * linelongs * sizeof(u_long));
212     if ( r == (struct raster*) 0 )
213 	return (struct raster*) 0;
214 
215     r->width = width;
216     r->height = height;
217     r->depth = depth;
218     r->linelongs = linelongs;
219     r->pixels = (u_long*) (r + 1);
220     r->data = (caddr_t) 0;
221     return r;
222     }
223 #endif
224