New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / rom / graphics / text.c
blobe1bb03177c831d31e782db68ba7a16c590cd48f3
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$ $Log
5 Desc: Graphics function Text()
6 Lang: english
7 */
8 #include "graphics_intern.h"
9 #include <graphics/rastport.h>
10 #include <string.h>
11 #define __CYBERGRAPHICS_NOLIBBASE__
12 #include <proto/cybergraphics.h>
13 #include <aros/macros.h>
14 #include <aros/debug.h>
16 #include "gfxfuncsupport.h"
18 void BltTemplateBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
19 struct GfxBase *GfxBase);
21 void BltTemplateAlphaBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
22 struct GfxBase *GfxBase);
24 void ColorFontBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
25 struct GfxBase *GfxBase);
27 /*****************************************************************************
29 NAME */
30 #include <graphics/rastport.h>
31 #include <proto/graphics.h>
33 AROS_LH3(void, Text,
35 /* SYNOPSIS */
36 AROS_LHA(struct RastPort *, rp, A1),
37 AROS_LHA(CONST_STRPTR , string, A0),
38 AROS_LHA(ULONG , count, D0),
40 /* LOCATION */
41 struct GfxBase *, GfxBase, 10, Graphics)
43 /* FUNCTION
45 INPUTS
47 RESULT
49 NOTES
51 EXAMPLE
53 BUGS
55 SEE ALSO
57 INTERNALS
59 HISTORY
60 29-10-95 digulla automatically created from
61 graphics_lib.fd and clib/graphics_protos.h
63 *****************************************************************************/
65 AROS_LIBFUNC_INIT
66 AROS_LIBBASE_EXT_DECL(struct GfxBase *,GfxBase)
68 if (count)
70 struct ColorTextFont *ctf = (struct ColorTextFont *)rp->Font;
71 BOOL antialias;
72 BOOL colorfont;
74 antialias = (ctf->ctf_TF.tf_Style & FSF_COLORFONT) &&
75 ((ctf->ctf_Flags & CT_COLORMASK) == CT_ANTIALIAS) &&
76 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) >= 15);
78 colorfont = (ctf->ctf_TF.tf_Style & FSF_COLORFONT) &&
79 (((ctf->ctf_Flags & CT_COLORMASK) == CT_COLORFONT) || ((ctf->ctf_Flags & CT_COLORMASK) == CT_GREYFONT));
81 if (antialias)
83 BltTemplateAlphaBasedText(rp, string, count, GfxBase);
85 else if (colorfont)
87 ColorFontBasedText(rp, string, count, GfxBase);
89 else if ((rp->DrawMode & INVERSVID) ||
90 (rp->AlgoStyle & (FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED)))
92 BltTemplateBasedText(rp, string, count, GfxBase);
94 else
96 driver_Text (rp, string, count, GfxBase);
100 AROS_LIBFUNC_EXIT
102 } /* Text */
104 /***************************************************************************/
106 void BltTemplateBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
107 struct GfxBase *GfxBase)
109 struct TextExtent te;
110 struct TextFont *tf;
111 WORD raswidth, raswidth16, raswidth_bpr, rasheight, x, y, gx;
112 UBYTE *raster;
113 BOOL is_bold, is_italic;
115 TextExtent(rp, text, len, &te);
117 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
118 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
120 raswidth16 = (raswidth + 15) & ~15;
121 raswidth_bpr = raswidth16 / 8;
123 if ((raster = AllocRaster(raswidth, rasheight)))
125 memset(raster, 0, RASSIZE(raswidth, rasheight));
127 tf = rp->Font;
129 x = -te.te_Extent.MinX;
131 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
132 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
134 while(len--)
136 UBYTE c = *text++;
137 ULONG idx;
138 ULONG charloc;
139 UWORD glyphwidth, glyphpos, bold;
140 UBYTE *glyphdata;
141 UBYTE *dst;
142 ULONG srcmask;
143 ULONG dstmask;
145 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
147 idx = NUMCHARS(tf) - 1;
149 else
151 idx = c - tf->tf_LoChar;
154 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
156 glyphwidth = charloc & 0xFFFF;
157 glyphpos = charloc >> 16;
159 if (tf->tf_CharKern)
161 x += ((WORD *)tf->tf_CharKern)[idx];
165 for(bold = 0; bold <= is_bold; bold++)
167 WORD wx;
168 WORD italicshift, italiccheck = 0;
170 if (is_italic)
172 italiccheck = tf->tf_Baseline;
173 italicshift = italiccheck / 2;
175 else
177 italicshift = 0;
180 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
182 glyphdata = ((UBYTE *)tf->tf_CharData) + glyphpos / 8;
183 dst = raster + wx / 8;
185 for(y = 0; y < rasheight; y++)
187 UBYTE *glyphdatax = glyphdata;
188 UBYTE *dstx = dst;
189 UBYTE srcdata;
191 srcmask = 0x80 >> (glyphpos & 7);
192 dstmask = 0x80 >> (wx & 7);
194 srcdata = *glyphdatax;
196 for(gx = 0; gx < glyphwidth; gx++)
198 if (srcdata & srcmask)
200 *dstx |= dstmask;
203 if (dstmask == 0x1)
205 dstmask = 0x80;
206 dstx++;
208 else
210 dstmask >>= 1;
213 if (srcmask == 0x1)
215 srcmask = 0x80;
216 glyphdatax++;
217 srcdata =*glyphdatax;
219 else
221 srcmask >>= 1;
224 } /* for(gx = 0; gx < glyphwidth; gx++) */
226 glyphdata += tf->tf_Modulo;
227 dst += raswidth_bpr;
229 if (is_italic)
231 italiccheck--;
232 if (italiccheck & 1)
234 italicshift--;
236 wx--;
237 if ((wx & 7) == 7) dst--;
242 } /* for(y = 0; y < rasheight; y++) */
244 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
246 if (tf->tf_CharSpace)
248 x += ((WORD *)tf->tf_CharSpace)[idx];
250 else
252 x += tf->tf_XSize;
255 x += rp->TxSpacing;
257 } /* while(len--) */
259 if (rp->AlgoStyle & FSF_UNDERLINED)
261 UBYTE *dst;
262 ULONG prev_word, act_word = 0, next_word, word;
263 WORD count;
264 LONG underline;
266 underline = rp->TxBaseline + 1;
267 if (underline < rasheight - 1) underline++;
269 if (underline < rasheight)
271 dst = raster + underline * (LONG)raswidth_bpr;
272 next_word = *(UWORD *)dst;
273 #if !AROS_BIG_ENDIAN
274 next_word = AROS_WORD2BE(next_word);
275 #endif
276 count = raswidth16 / 16;
278 while(count--)
280 prev_word = act_word;
281 act_word = next_word;
282 if (count > 1)
284 next_word = ((UWORD *)dst)[1];
286 #if !AROS_BIG_ENDIAN
287 next_word = AROS_WORD2BE(next_word);
288 #endif
290 else
292 next_word = 0;
294 word = ((act_word << 1) & 0xFFFF) + (next_word >> 15);
295 word |= (act_word >> 1) + ((prev_word << 15) & 0xFFFF);
296 word &= ~act_word;
298 word = 0xFFFF &~ word;
299 #if !AROS_BIG_ENDIAN
300 word = AROS_BE2WORD(word);
301 #endif
303 *(UWORD *)dst = word;
304 dst += 2;
306 } /* while(count--) */
308 } /* if (underline < rasheight) */
310 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
312 BltTemplate(raster,
314 raswidth_bpr,
316 rp->cp_x + te.te_Extent.MinX,
317 rp->cp_y - rp->TxBaseline,
318 raswidth,
319 rasheight);
321 FreeRaster(raster, raswidth, rasheight);
323 } /* if ((raster = AllocRaster(raswidth, rasheight))) */
325 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
329 /***************************************************************************/
331 static struct Library *CyberGfxBase = NULL;
333 static AROS_SET_LIBFUNC(CGFX_Expunge, LIBBASETYPE, LIBBASE)
335 if (CyberGfxBase != NULL)
337 CloseLibrary(CyberGfxBase);
338 CyberGfxBase = NULL;
343 /***************************************************************************/
345 void BltTemplateAlphaBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
346 struct GfxBase *GfxBase)
348 struct TextExtent te;
349 struct TextFont *tf;
350 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
351 UBYTE *raster;
352 BOOL is_bold, is_italic;
354 if (!CyberGfxBase)
356 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
357 if (!CyberGfxBase) return;
360 TextExtent(rp, text, len, &te);
362 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
363 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
365 raswidth_bpr = raswidth;
367 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
369 tf = rp->Font;
371 x = -te.te_Extent.MinX;
373 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
374 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
376 while(len--)
378 UBYTE c = *text++;
379 ULONG idx;
380 ULONG charloc;
381 UWORD glyphwidth, glyphpos, bold;
382 UBYTE *glyphdata;
383 UBYTE *dst;
385 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
387 idx = NUMCHARS(tf) - 1;
389 else
391 idx = c - tf->tf_LoChar;
394 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
396 glyphwidth = charloc & 0xFFFF;
397 glyphpos = charloc >> 16;
399 if (tf->tf_CharKern)
401 x += ((WORD *)tf->tf_CharKern)[idx];
405 for(bold = 0; bold <= is_bold; bold++)
407 WORD wx;
408 WORD italicshift, italiccheck = 0;
410 if (is_italic)
412 italiccheck = tf->tf_Baseline;
413 italicshift = italiccheck / 2;
415 else
417 italicshift = 0;
420 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
422 glyphdata = ((UBYTE *)((struct ColorTextFont *)tf)->ctf_CharData[0]) + glyphpos;
423 dst = raster + wx;
425 for(y = 0; y < rasheight; y++)
427 UBYTE *glyphdatax = glyphdata;
428 UBYTE *dstx = dst;
430 for(gx = 0; gx < glyphwidth; gx++)
432 UWORD old = *dstx;
434 old += *glyphdatax++;
435 if (old > 255) old = 255;
436 *dstx++ = old;
439 glyphdata += tf->tf_Modulo * 8;
440 dst += raswidth_bpr;
442 if (is_italic)
444 italiccheck--;
445 if (italiccheck & 1)
447 italicshift--;
448 dst--;
452 } /* for(y = 0; y < rasheight; y++) */
454 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
456 if (tf->tf_CharSpace)
458 x += ((WORD *)tf->tf_CharSpace)[idx];
460 else
462 x += tf->tf_XSize;
465 x += rp->TxSpacing;
467 } /* while(len--) */
469 if (rp->AlgoStyle & FSF_UNDERLINED)
471 UBYTE *dst;
472 UBYTE prev_byte, act_byte = 0, next_byte;
473 WORD count;
474 LONG underline;
476 underline = rp->TxBaseline + 1;
477 if (underline < rasheight - 1) underline++;
479 if (underline < rasheight)
481 dst = raster + underline * (LONG)raswidth_bpr;
482 count = raswidth;
484 next_byte = *dst;
486 while(count--)
488 prev_byte = act_byte;
489 act_byte = next_byte;
490 if (count > 1)
492 next_byte = dst[1];
494 else
496 next_byte = 0;
499 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
501 } /* while(count--) */
503 } /* if (underline < rasheight) */
505 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
507 BltTemplateAlpha(raster,
509 raswidth_bpr,
511 rp->cp_x + te.te_Extent.MinX,
512 rp->cp_y - rp->TxBaseline,
513 raswidth,
514 rasheight);
516 FreeVec(raster);
518 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
520 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
524 /***************************************************************************/
526 void ColorFontBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
527 struct GfxBase *GfxBase)
529 struct TextExtent te;
530 struct TextFont *tf;
531 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
532 UBYTE *raster, *chunky;
533 BOOL is_bold, is_italic;
535 tf = rp->Font;
536 if (!ExtendFont(tf, NULL)) return;
538 chunky = TFE_INTERN(tf->tf_Extension)->hash->chunky_colorfont;
540 TextExtent(rp, text, len, &te);
542 if ((rp->DrawMode & ~INVERSVID) == JAM2)
544 ULONG old_drmd = GetDrMd(rp);
546 SetDrMd(rp, old_drmd ^ INVERSVID);
547 RectFill(rp, rp->cp_x + te.te_Extent.MinX,
548 rp->cp_y + te.te_Extent.MinY,
549 rp->cp_x + te.te_Extent.MaxX,
550 rp->cp_y + te.te_Extent.MaxY);
551 SetDrMd(rp, old_drmd);
555 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
556 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
558 raswidth_bpr = raswidth;
560 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
562 x = -te.te_Extent.MinX;
564 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
565 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
567 while(len--)
569 UBYTE c = *text++;
570 ULONG idx;
571 ULONG charloc;
572 UWORD glyphwidth, glyphpos, bold;
573 UBYTE *glyphdata;
574 UBYTE *dst;
576 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
578 idx = NUMCHARS(tf) - 1;
580 else
582 idx = c - tf->tf_LoChar;
585 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
587 glyphwidth = charloc & 0xFFFF;
588 glyphpos = charloc >> 16;
590 if (tf->tf_CharKern)
592 x += ((WORD *)tf->tf_CharKern)[idx];
596 for(bold = 0; bold <= is_bold; bold++)
598 WORD wx;
599 WORD italicshift, italiccheck = 0;
601 if (is_italic)
603 italiccheck = tf->tf_Baseline;
604 italicshift = italiccheck / 2;
606 else
608 italicshift = 0;
611 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
613 glyphdata = chunky + glyphpos;
614 dst = raster + wx;
616 for(y = 0; y < rasheight; y++)
618 UBYTE *glyphdatax = glyphdata;
619 UBYTE *dstx = dst;
621 for(gx = 0; gx < glyphwidth; gx++)
623 UBYTE p = *glyphdatax++;
625 if (p || !bold) *dstx = p;
627 dstx++;
630 glyphdata += tf->tf_Modulo * 8;
631 dst += raswidth_bpr;
633 if (is_italic)
635 italiccheck--;
636 if (italiccheck & 1)
638 italicshift--;
639 dst--;
643 } /* for(y = 0; y < rasheight; y++) */
645 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
647 if (tf->tf_CharSpace)
649 x += ((WORD *)tf->tf_CharSpace)[idx];
651 else
653 x += tf->tf_XSize;
656 x += rp->TxSpacing;
658 } /* while(len--) */
660 #if 0
661 if (rp->AlgoStyle & FSF_UNDERLINED)
663 UBYTE *dst;
664 UBYTE prev_byte, act_byte = 0, next_byte;
665 WORD count;
666 LONG underline;
668 underline = rp->TxBaseline + 1;
669 if (underline < rasheight - 1) underline++;
671 if (underline < rasheight)
673 dst = raster + underline * (LONG)raswidth_bpr;
674 count = raswidth;
676 next_byte = *dst;
678 while(count--)
680 prev_byte = act_byte;
681 act_byte = next_byte;
682 if (count > 1)
684 next_byte = dst[1];
686 else
688 next_byte = 0;
691 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
693 } /* while(count--) */
695 } /* if (underline < rasheight) */
697 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
699 #endif
702 HIDDT_PixelLUT pixlut;
703 HIDDT_Pixel pixtab[256];
705 pixlut.entries = AROS_PALETTE_SIZE;
706 pixlut.pixels = IS_HIDD_BM(rp->BitMap) ? HIDD_BM_PIXTAB(rp->BitMap) : NULL;
708 if ((rp->Flags & RPF_REMAP_COLORFONTS) &&
709 (CTF(tf)->ctf_ColorFontColors) &&
710 ((CTF(tf)->ctf_Flags & CT_COLORMASK) != CT_GREYFONT) && /* <-- FIX/CHECK/SUPPORT CT_GREYFONT) */
711 IS_HIDD_BM(rp->BitMap) &&
712 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8))
714 UWORD *colortable = CTF(tf)->ctf_ColorFontColors->cfc_ColorTable;
715 WORD i;
717 for(i = 0; i < CTF(tf)->ctf_ColorFontColors->cfc_Count; i++)
719 UWORD rgb12 = *colortable++;
720 HIDDT_Color col;
722 col.red = ((rgb12 >> 8) & 0x0F) * 0x1111;
723 col.green = ((rgb12 >> 4) & 0x0F) * 0x1111;
724 col.blue = ((rgb12 >> 0) & 0x0F) * 0x1111;
726 pixtab[i] = HIDD_BM_MapColor(HIDD_BM_OBJ(rp->BitMap), &col);
729 pixlut.pixels = pixtab;
732 write_transp_pixels_8(rp, raster,raswidth_bpr,
733 rp->cp_x + te.te_Extent.MinX,
734 rp->cp_y - rp->TxBaseline,
735 rp->cp_x + te.te_Extent.MinX + raswidth - 1,
736 rp->cp_y - rp->TxBaseline + rasheight - 1,
737 &pixlut, 0, GfxBase);
741 FreeVec(raster);
743 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
745 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);