155132Storek /*- 255132Storek * Copyright (c) 1991 The Regents of the University of California. 355132Storek * All rights reserved. 455132Storek * 555132Storek * This code is derived from software contributed to the Computer Systems 655132Storek * Engineering Group at Lawrence Berkeley Laboratory and to the University 755132Storek * of California at Berkeley by Jef Poskanzer. 855132Storek * 955132Storek * %sccs.include.redist.c% 1055132Storek * 11*56539Sbostic * @(#)raster_text.c 7.2 (Berkeley) 10/11/92 1255132Storek * 1355132Storek * from: $Header: raster_text.c,v 1.15 92/06/17 08:14:45 torek Exp $ 1455132Storek */ 1555132Storek 1655132Storek /* 1755132Storek * Text routines for raster library. 1855132Storek */ 1955132Storek 2055132Storek #ifdef KERNEL 21*56539Sbostic #include <sys/param.h> 22*56539Sbostic #include <sparc/rcons/raster.h> 2355132Storek #ifdef COLORFONT_CACHE 24*56539Sbostic #include <sys/malloc.h> 2555132Storek #define NEW(size) malloc(size, M_DEVBUF, M_NOWAIT) 2655132Storek #endif 2755132Storek #else 2855132Storek #include <sys/types.h> 29*56539Sbostic #include <sparc/rcons/raster.h> 3055132Storek #ifdef COLORFONT_CACHE 3155132Storek #include <malloc.h> 3255132Storek #define NEW(size) malloc(size) 3355132Storek #endif 3455132Storek #endif 3555132Storek 3655132Storek 3755132Storek /* Draws text. Returns 0 on success, -1 on failure. */ 3855132Storek int 3955132Storek raster_text( r, x, y, rop, rf, text ) 4055132Storek register struct raster* r; 4155132Storek int x, y; 4255132Storek int rop; 4355132Storek struct raster_font* rf; 4455132Storek char* text; 4555132Storek { 4655132Storek return raster_textn( r, x, y, rop, rf, text, strlen( text ) ); 4755132Storek } 4855132Storek 4955132Storek /* Draws n characters of text. Returns 0 on success, -1 on failure. */ 5055132Storek int 5155132Storek raster_textn( r, x, y, rop, rf, text, n ) 5255132Storek register struct raster* r; 5355132Storek int x, y; 5455132Storek int rop; 5555132Storek struct raster_font* rf; 5655132Storek char* text; 5755132Storek int n; 5855132Storek { 5955132Storek int clip; 6055132Storek int x1, y1; 6155132Storek struct raster_char* c; 6255132Storek struct raster* charrast; 6355132Storek int i; 6455132Storek register char ch; 6555132Storek int thisx, thisy; 6655132Storek int phase; 6755132Storek 6855132Storek /* Check whether we can avoid clipping. */ 6955132Storek clip = 0; 7055132Storek if ( rf->flags & RASFONT_FIXEDWIDTH && 7155132Storek rf->flags & RASFONT_NOVERTICALMOVEMENT ) 7255132Storek { 7355132Storek /* This font is well-behaved, we can compute the extent cheaply. */ 7455132Storek c = &(rf->chars['@']); 7555132Storek charrast = c->r; 7655132Storek if ( x + c->homex < 0 || y + c->homey < 0 || 7755132Storek x + c->homex + n * c->nextx > r->width || 7855132Storek y + c->homey + charrast->height > r->height ) 7955132Storek clip = 1; 8055132Storek } 8155132Storek else 8255132Storek { 8355132Storek /* Got to step through the string to compute the extent. */ 8455132Storek for ( i = 0, x1 = x, y1 = y; 8555132Storek i < n; 8655132Storek ++i, x1 += c->nextx, y1 += c->nexty ) 8755132Storek { 8855132Storek c = &(rf->chars[text[i]]); 8955132Storek charrast = c->r; 9055132Storek if ( charrast != (struct raster*) 0 ) 9155132Storek { 9255132Storek if ( x1 + c->homex < 0 || y1 + c->homey < 0 || 9355132Storek x1 + c->homex + charrast->width > r->width || 9455132Storek y1 + c->homey + charrast->height > r->height ) 9555132Storek { 9655132Storek clip = 1; 9755132Storek break; 9855132Storek } 9955132Storek } 10055132Storek } 10155132Storek } 10255132Storek 10355132Storek /* Now display the text. */ 10455132Storek for ( i = 0, x1 = x, y1 = y; 10555132Storek i < n; 10655132Storek ++i, x1 += c->nextx, y1 += c->nexty ) 10755132Storek { 10855132Storek ch = text[i]; 10955132Storek c = &(rf->chars[ch]); 11055132Storek charrast = c->r; 11155132Storek if ( charrast != (struct raster*) 0 ) 11255132Storek { 11355132Storek thisx = x1 + c->homex; 11455132Storek thisy = y1 + c->homey; 11555132Storek 11655132Storek phase = 0; 11755132Storek #ifdef COLORFONT_CACHE 11855132Storek if ( r->depth == 8 ) 11955132Storek { 12055132Storek /* Initialize color font cache if necessary. */ 12155132Storek if ( rf->cache == (struct raster_fontcache*) -1 ) 12255132Storek { 12355132Storek int c; 12455132Storek 12555132Storek rf->cache = (struct raster_fontcache*) 12655132Storek NEW( sizeof(struct raster_fontcache) ); 12755132Storek if ( rf->cache != (struct raster_fontcache*) 0 ) 12855132Storek for ( c = 0; c < 256; ++c ) 12955132Storek rf->cache->cr[c] = (struct raster*) 0; 13055132Storek } 13155132Storek 13255132Storek if ( rf->cache != (struct raster_fontcache*) 0 ) 13355132Storek { 13455132Storek int color; 13555132Storek struct raster* cr; 13655132Storek 13755132Storek color = RAS_GETCOLOR( rop ); 13855132Storek cr = rf->cache->cr[ch]; 13955132Storek /* Is this character cached yet? */ 14055132Storek if ( cr != (struct raster*) 0 ) 14155132Storek { 14255132Storek /* Yes, but is it the right color? */ 14355132Storek if ( rf->cache->color[ch] == color ) 14455132Storek { 14555132Storek /* Yes - switch rasters. */ 14655132Storek charrast = cr; 14755132Storek } 14855132Storek else 14955132Storek { 15055132Storek /* No, re-draw it. */ 15155132Storek if ( raster_op_noclip( 15255132Storek cr, 0, 0, charrast->width, 15355132Storek charrast->height, rop, charrast, 0, 0 ) == 0 ) 15455132Storek { 15555132Storek rf->cache->color[ch] = color; 15655132Storek charrast = cr; 15755132Storek } 15855132Storek } 15955132Storek } 16055132Storek else 16155132Storek { 16255132Storek /* It's not cached, so cache it. */ 16355132Storek cr = raster_alloc( 16455132Storek charrast->width, charrast->height, 8 ); 16555132Storek if ( cr != (struct raster*) 0 ) 16655132Storek if ( raster_op_noclip( 16755132Storek cr, 0, 0, charrast->width, charrast->height, 16855132Storek rop, charrast, 0, 0 ) == 0 ) 16955132Storek { 17055132Storek rf->cache->color[ch] = color; 17155132Storek charrast = rf->cache->cr[ch] = cr; 17255132Storek } 17355132Storek } 17455132Storek } 17555132Storek } 17655132Storek #endif /*COLORFONT_CACHE*/ 17755132Storek 17855132Storek if ( clip ) 17955132Storek { 18055132Storek if ( raster_op( 18155132Storek r, thisx, thisy, charrast->width, charrast->height, 18255132Storek rop, charrast, phase, 0 ) < 0 ) 18355132Storek return -1; 18455132Storek } 18555132Storek else 18655132Storek { 18755132Storek if ( raster_op_noclip( 18855132Storek r, thisx, thisy, charrast->width, charrast->height, 18955132Storek rop, charrast, phase, 0 ) < 0 ) 19055132Storek return -1; 19155132Storek } 19255132Storek } 19355132Storek } 19455132Storek 19555132Storek return 0; 19655132Storek } 19755132Storek 19855132Storek #ifdef COLORFONT_CACHE 19955132Storek /* Allocates a raster. Returns (struct raster*) 0 on failure. */ 20055132Storek struct raster* 20155132Storek raster_alloc( width, height, depth ) 20255132Storek int width, height, depth; 20355132Storek { 20455132Storek struct raster* r; 20555132Storek int linelongs; 20655132Storek 20755132Storek if ( width <= 0 || height <= 0 || ( depth != 1 && depth != 8 ) ) 20855132Storek return (struct raster*) 0; 20955132Storek linelongs = ( ( width * depth + 31 ) >> 5 ); 21055132Storek r = (struct raster*) 21155132Storek NEW( sizeof(struct raster) + height * linelongs * sizeof(u_long)); 21255132Storek if ( r == (struct raster*) 0 ) 21355132Storek return (struct raster*) 0; 21455132Storek 21555132Storek r->width = width; 21655132Storek r->height = height; 21755132Storek r->depth = depth; 21855132Storek r->linelongs = linelongs; 21955132Storek r->pixels = (u_long*) (r + 1); 22055132Storek r->data = (caddr_t) 0; 22155132Storek return r; 22255132Storek } 22355132Storek #endif 224