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