some fixes to accented characters
[tangerine.git] / rom / graphics / text.c
blob35d9d6a92f26a83e4bcb13d3d0a8364090a4922f
1 /*
2 Copyright © 1995-2007, 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
44 Write text to the rastport at the current position.
45 The current position is updated to a position after the text.
47 INPUTS
48 rp - RastPort
49 string - string to print
50 count - number of characters to print
52 RESULT
54 NOTES
56 EXAMPLE
58 BUGS
60 SEE ALSO
62 INTERNALS
64 HISTORY
65 29-10-95 digulla automatically created from
66 graphics_lib.fd and clib/graphics_protos.h
68 *****************************************************************************/
70 AROS_LIBFUNC_INIT
72 if (count)
74 struct ColorTextFont *ctf = (struct ColorTextFont *)rp->Font;
75 BOOL antialias;
76 BOOL colorfont;
78 antialias = (ctf->ctf_TF.tf_Style & FSF_COLORFONT) &&
79 ((ctf->ctf_Flags & CT_COLORMASK) == CT_ANTIALIAS) &&
80 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) >= 15);
82 colorfont = (ctf->ctf_TF.tf_Style & FSF_COLORFONT) &&
83 (((ctf->ctf_Flags & CT_COLORMASK) == CT_COLORFONT) || ((ctf->ctf_Flags & CT_COLORMASK) == CT_GREYFONT));
85 if (antialias)
87 BltTemplateAlphaBasedText(rp, string, count, GfxBase);
89 else if (colorfont)
91 ColorFontBasedText(rp, string, count, GfxBase);
93 else if ((rp->DrawMode & INVERSVID) ||
94 (rp->AlgoStyle & (FSF_BOLD | FSF_ITALIC | FSF_UNDERLINED)))
96 BltTemplateBasedText(rp, string, count, GfxBase);
98 else
100 driver_Text (rp, string, count, GfxBase);
104 AROS_LIBFUNC_EXIT
106 } /* Text */
108 /***************************************************************************/
110 void BltTemplateBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
111 struct GfxBase *GfxBase)
113 struct TextExtent te;
114 struct TextFont *tf;
115 WORD raswidth, raswidth16, raswidth_bpr, rasheight, x, y, gx;
116 UBYTE *raster;
117 BOOL is_bold, is_italic;
119 TextExtent(rp, text, len, &te);
121 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
122 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
124 raswidth16 = (raswidth + 15) & ~15;
125 raswidth_bpr = raswidth16 / 8;
127 if ((raster = AllocRaster(raswidth, rasheight)))
129 memset(raster, 0, RASSIZE(raswidth, rasheight));
131 tf = rp->Font;
133 x = -te.te_Extent.MinX;
135 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
136 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
138 while(len--)
140 UBYTE c = *text++;
141 ULONG idx;
142 ULONG charloc;
143 UWORD glyphwidth, glyphpos, bold;
144 UBYTE *glyphdata;
145 UBYTE *dst;
146 ULONG srcmask;
147 ULONG dstmask;
149 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
151 idx = NUMCHARS(tf) - 1;
153 else
155 idx = c - tf->tf_LoChar;
158 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
160 glyphwidth = charloc & 0xFFFF;
161 glyphpos = charloc >> 16;
163 if (tf->tf_CharKern)
165 x += ((WORD *)tf->tf_CharKern)[idx];
169 for(bold = 0; bold <= is_bold; bold++)
171 WORD wx;
172 WORD italicshift, italiccheck = 0;
174 if (is_italic)
176 italiccheck = tf->tf_Baseline;
177 italicshift = italiccheck / 2;
179 else
181 italicshift = 0;
184 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
186 glyphdata = ((UBYTE *)tf->tf_CharData) + glyphpos / 8;
187 dst = raster + wx / 8;
189 for(y = 0; y < rasheight; y++)
191 UBYTE *glyphdatax = glyphdata;
192 UBYTE *dstx = dst;
193 UBYTE srcdata;
195 srcmask = 0x80 >> (glyphpos & 7);
196 dstmask = 0x80 >> (wx & 7);
198 srcdata = *glyphdatax;
200 for(gx = 0; gx < glyphwidth; gx++)
202 if (srcdata & srcmask)
204 *dstx |= dstmask;
207 if (dstmask == 0x1)
209 dstmask = 0x80;
210 dstx++;
212 else
214 dstmask >>= 1;
217 if (srcmask == 0x1)
219 srcmask = 0x80;
220 glyphdatax++;
221 srcdata =*glyphdatax;
223 else
225 srcmask >>= 1;
228 } /* for(gx = 0; gx < glyphwidth; gx++) */
230 glyphdata += tf->tf_Modulo;
231 dst += raswidth_bpr;
233 if (is_italic)
235 italiccheck--;
236 if (italiccheck & 1)
238 italicshift--;
240 wx--;
241 if ((wx & 7) == 7) dst--;
246 } /* for(y = 0; y < rasheight; y++) */
248 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
250 if (tf->tf_CharSpace)
252 x += ((WORD *)tf->tf_CharSpace)[idx];
254 else
256 x += tf->tf_XSize;
259 x += rp->TxSpacing;
261 } /* while(len--) */
263 if (rp->AlgoStyle & FSF_UNDERLINED)
265 UBYTE *dst;
266 ULONG prev_word, act_word = 0, next_word, word;
267 WORD count;
268 LONG underline;
270 underline = rp->TxBaseline + 1;
271 if (underline < rasheight - 1) underline++;
273 if (underline < rasheight)
275 dst = raster + underline * (LONG)raswidth_bpr;
276 next_word = *(UWORD *)dst;
277 #if !AROS_BIG_ENDIAN
278 next_word = AROS_WORD2BE(next_word);
279 #endif
280 count = raswidth16 / 16;
282 while(count--)
284 prev_word = act_word;
285 act_word = next_word;
286 if (count > 1)
288 next_word = ((UWORD *)dst)[1];
290 #if !AROS_BIG_ENDIAN
291 next_word = AROS_WORD2BE(next_word);
292 #endif
294 else
296 next_word = 0;
298 word = ((act_word << 1) & 0xFFFF) + (next_word >> 15);
299 word |= (act_word >> 1) + ((prev_word << 15) & 0xFFFF);
300 word &= ~act_word;
302 word = 0xFFFF &~ word;
303 #if !AROS_BIG_ENDIAN
304 word = AROS_BE2WORD(word);
305 #endif
307 *(UWORD *)dst = word;
308 dst += 2;
310 } /* while(count--) */
312 } /* if (underline < rasheight) */
314 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
316 BltTemplate(raster,
318 raswidth_bpr,
320 rp->cp_x + te.te_Extent.MinX,
321 rp->cp_y - rp->TxBaseline,
322 raswidth,
323 rasheight);
325 FreeRaster(raster, raswidth, rasheight);
327 } /* if ((raster = AllocRaster(raswidth, rasheight))) */
329 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
333 /***************************************************************************/
335 static struct Library *CyberGfxBase = NULL;
337 static AROS_SET_LIBFUNC(CGFX_Expunge, LIBBASETYPE, LIBBASE)
339 if (CyberGfxBase != NULL)
341 CloseLibrary(CyberGfxBase);
342 CyberGfxBase = NULL;
347 /***************************************************************************/
349 void BltTemplateAlphaBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
350 struct GfxBase *GfxBase)
352 struct TextExtent te;
353 struct TextFont *tf;
354 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
355 UBYTE *raster;
356 BOOL is_bold, is_italic;
358 if (!CyberGfxBase)
360 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
361 if (!CyberGfxBase) return;
364 TextExtent(rp, text, len, &te);
366 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
367 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
369 raswidth_bpr = raswidth;
371 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
373 tf = rp->Font;
375 x = -te.te_Extent.MinX;
377 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
378 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
380 while(len--)
382 UBYTE c = *text++;
383 ULONG idx;
384 ULONG charloc;
385 UWORD glyphwidth, glyphpos, bold;
386 UBYTE *glyphdata;
387 UBYTE *dst;
389 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
391 idx = NUMCHARS(tf) - 1;
393 else
395 idx = c - tf->tf_LoChar;
398 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
400 glyphwidth = charloc & 0xFFFF;
401 glyphpos = charloc >> 16;
403 if (tf->tf_CharKern)
405 x += ((WORD *)tf->tf_CharKern)[idx];
409 for(bold = 0; bold <= is_bold; bold++)
411 WORD wx;
412 WORD italicshift, italiccheck = 0;
414 if (is_italic)
416 italiccheck = tf->tf_Baseline;
417 italicshift = italiccheck / 2;
419 else
421 italicshift = 0;
424 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
426 glyphdata = ((UBYTE *)((struct ColorTextFont *)tf)->ctf_CharData[0]) + glyphpos;
427 dst = raster + wx;
429 for(y = 0; y < rasheight; y++)
431 UBYTE *glyphdatax = glyphdata;
432 UBYTE *dstx = dst;
434 for(gx = 0; gx < glyphwidth; gx++)
436 UWORD old = *dstx;
438 old += *glyphdatax++;
439 if (old > 255) old = 255;
440 *dstx++ = old;
443 glyphdata += tf->tf_Modulo * 8;
444 dst += raswidth_bpr;
446 if (is_italic)
448 italiccheck--;
449 if (italiccheck & 1)
451 italicshift--;
452 dst--;
456 } /* for(y = 0; y < rasheight; y++) */
458 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
460 if (tf->tf_CharSpace)
462 x += ((WORD *)tf->tf_CharSpace)[idx];
464 else
466 x += tf->tf_XSize;
469 x += rp->TxSpacing;
471 } /* while(len--) */
473 if (rp->AlgoStyle & FSF_UNDERLINED)
475 UBYTE *dst;
476 UBYTE prev_byte, act_byte = 0, next_byte;
477 WORD count;
478 LONG underline;
480 underline = rp->TxBaseline + 1;
481 if (underline < rasheight - 1) underline++;
483 if (underline < rasheight)
485 dst = raster + underline * (LONG)raswidth_bpr;
486 count = raswidth;
488 next_byte = *dst;
490 while(count--)
492 prev_byte = act_byte;
493 act_byte = next_byte;
494 if (count > 1)
496 next_byte = dst[1];
498 else
500 next_byte = 0;
503 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
505 } /* while(count--) */
507 } /* if (underline < rasheight) */
509 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
511 BltTemplateAlpha(raster,
513 raswidth_bpr,
515 rp->cp_x + te.te_Extent.MinX,
516 rp->cp_y - rp->TxBaseline,
517 raswidth,
518 rasheight);
520 FreeVec(raster);
522 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
524 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
528 /***************************************************************************/
530 void ColorFontBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
531 struct GfxBase *GfxBase)
533 struct TextExtent te;
534 struct TextFont *tf;
535 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
536 UBYTE *raster, *chunky;
537 BOOL is_bold, is_italic;
539 tf = rp->Font;
540 if (!ExtendFont(tf, NULL)) return;
542 chunky = ((struct TextFontExtension_intern *)(tf->tf_Extension))->hash->chunky_colorfont;
544 TextExtent(rp, text, len, &te);
546 if ((rp->DrawMode & ~INVERSVID) == JAM2)
548 ULONG old_drmd = GetDrMd(rp);
550 SetDrMd(rp, old_drmd ^ INVERSVID);
551 RectFill(rp, rp->cp_x + te.te_Extent.MinX,
552 rp->cp_y + te.te_Extent.MinY,
553 rp->cp_x + te.te_Extent.MaxX,
554 rp->cp_y + te.te_Extent.MaxY);
555 SetDrMd(rp, old_drmd);
559 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
560 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
562 raswidth_bpr = raswidth;
564 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
566 x = -te.te_Extent.MinX;
568 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
569 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
571 while(len--)
573 UBYTE c = *text++;
574 ULONG idx;
575 ULONG charloc;
576 UWORD glyphwidth, glyphpos, bold;
577 UBYTE *glyphdata;
578 UBYTE *dst;
580 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
582 idx = NUMCHARS(tf) - 1;
584 else
586 idx = c - tf->tf_LoChar;
589 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
591 glyphwidth = charloc & 0xFFFF;
592 glyphpos = charloc >> 16;
594 if (tf->tf_CharKern)
596 x += ((WORD *)tf->tf_CharKern)[idx];
600 for(bold = 0; bold <= is_bold; bold++)
602 WORD wx;
603 WORD italicshift, italiccheck = 0;
605 if (is_italic)
607 italiccheck = tf->tf_Baseline;
608 italicshift = italiccheck / 2;
610 else
612 italicshift = 0;
615 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
617 glyphdata = chunky + glyphpos;
618 dst = raster + wx;
620 for(y = 0; y < rasheight; y++)
622 UBYTE *glyphdatax = glyphdata;
623 UBYTE *dstx = dst;
625 for(gx = 0; gx < glyphwidth; gx++)
627 UBYTE p = *glyphdatax++;
629 if (p || !bold) *dstx = p;
631 dstx++;
634 glyphdata += tf->tf_Modulo * 8;
635 dst += raswidth_bpr;
637 if (is_italic)
639 italiccheck--;
640 if (italiccheck & 1)
642 italicshift--;
643 dst--;
647 } /* for(y = 0; y < rasheight; y++) */
649 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
651 if (tf->tf_CharSpace)
653 x += ((WORD *)tf->tf_CharSpace)[idx];
655 else
657 x += tf->tf_XSize;
660 x += rp->TxSpacing;
662 } /* while(len--) */
664 #if 0
665 if (rp->AlgoStyle & FSF_UNDERLINED)
667 UBYTE *dst;
668 UBYTE prev_byte, act_byte = 0, next_byte;
669 WORD count;
670 LONG underline;
672 underline = rp->TxBaseline + 1;
673 if (underline < rasheight - 1) underline++;
675 if (underline < rasheight)
677 dst = raster + underline * (LONG)raswidth_bpr;
678 count = raswidth;
680 next_byte = *dst;
682 while(count--)
684 prev_byte = act_byte;
685 act_byte = next_byte;
686 if (count > 1)
688 next_byte = dst[1];
690 else
692 next_byte = 0;
695 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
697 } /* while(count--) */
699 } /* if (underline < rasheight) */
701 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
703 #endif
706 HIDDT_PixelLUT pixlut;
707 HIDDT_Pixel pixtab[256];
709 pixlut.entries = AROS_PALETTE_SIZE;
710 pixlut.pixels = IS_HIDD_BM(rp->BitMap) ? HIDD_BM_PIXTAB(rp->BitMap) : NULL;
712 if ((rp->Flags & RPF_REMAP_COLORFONTS) &&
713 (CTF(tf)->ctf_ColorFontColors) &&
714 ((CTF(tf)->ctf_Flags & CT_COLORMASK) != CT_GREYFONT) && /* <-- FIX/CHECK/SUPPORT CT_GREYFONT) */
715 IS_HIDD_BM(rp->BitMap) &&
716 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8))
718 UWORD *colortable = CTF(tf)->ctf_ColorFontColors->cfc_ColorTable;
719 WORD i;
721 for(i = 0; i < CTF(tf)->ctf_ColorFontColors->cfc_Count; i++)
723 UWORD rgb12 = *colortable++;
724 HIDDT_Color col;
726 col.red = ((rgb12 >> 8) & 0x0F) * 0x1111;
727 col.green = ((rgb12 >> 4) & 0x0F) * 0x1111;
728 col.blue = ((rgb12 >> 0) & 0x0F) * 0x1111;
730 pixtab[i] = HIDD_BM_MapColor(HIDD_BM_OBJ(rp->BitMap), &col);
733 pixlut.pixels = pixtab;
736 write_transp_pixels_8(rp, raster,raswidth_bpr,
737 rp->cp_x + te.te_Extent.MinX,
738 rp->cp_y - rp->TxBaseline,
739 rp->cp_x + te.te_Extent.MinX + raswidth - 1,
740 rp->cp_y - rp->TxBaseline + rasheight - 1,
741 &pixlut, 0, GfxBase);
745 FreeVec(raster);
747 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
749 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);