Minor fixes to comments.
[AROS.git] / rom / graphics / text.c
blobfb55dd75c01a1423df5e2ca310ae4a23dabb8142
1 /*
2 Copyright © 1995-2010, 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 #include <proto/cybergraphics.h>
12 #include <aros/macros.h>
13 #include <aros/debug.h>
15 #include "gfxfuncsupport.h"
17 void BltTemplateBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
18 struct GfxBase *GfxBase);
20 void BltTemplateAlphaBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
21 struct GfxBase *GfxBase);
23 void ColorFontBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
24 struct GfxBase *GfxBase);
26 /*****************************************************************************
28 NAME */
29 #include <graphics/rastport.h>
30 #include <proto/graphics.h>
32 AROS_LH3(void, Text,
34 /* SYNOPSIS */
35 AROS_LHA(struct RastPort *, rp, A1),
36 AROS_LHA(CONST_STRPTR , string, A0),
37 AROS_LHA(ULONG , count, D0),
39 /* LOCATION */
40 struct GfxBase *, GfxBase, 10, Graphics)
42 /* FUNCTION
43 Write text to the rastport at the current position.
44 The current position is updated to a position after the text.
46 INPUTS
47 rp - RastPort
48 string - string to print
49 count - number of characters to print
51 RESULT
53 NOTES
55 EXAMPLE
57 BUGS
59 SEE ALSO
61 INTERNALS
63 HISTORY
64 29-10-95 digulla automatically created from
65 graphics_lib.fd and clib/graphics_protos.h
67 *****************************************************************************/
69 AROS_LIBFUNC_INIT
71 if (count)
73 struct ColorTextFont *ctf = (struct ColorTextFont *)rp->Font;
74 BOOL antialias;
75 BOOL colorfont;
77 antialias = (ctf->ctf_TF.tf_Style & FSF_COLORFONT) &&
78 ((ctf->ctf_Flags & CT_COLORMASK) == CT_ANTIALIAS) &&
79 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) >= 15);
81 colorfont = (ctf->ctf_TF.tf_Style & FSF_COLORFONT) &&
82 (((ctf->ctf_Flags & CT_COLORMASK) == CT_COLORFONT) || ((ctf->ctf_Flags & CT_COLORMASK) == CT_GREYFONT));
84 if (antialias)
86 BltTemplateAlphaBasedText(rp, string, count, GfxBase);
88 else if (colorfont)
90 ColorFontBasedText(rp, string, count, GfxBase);
92 else
94 BltTemplateBasedText(rp, string, count, GfxBase);
98 AROS_LIBFUNC_EXIT
100 } /* Text */
102 /***************************************************************************/
104 void BltTemplateBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
105 struct GfxBase *GfxBase)
107 struct TextExtent te;
108 struct TextFont *tf;
109 WORD raswidth, raswidth16, raswidth_bpr, rasheight, x, y, gx;
110 UBYTE *raster;
111 BOOL is_bold, is_italic;
113 TextExtent(rp, text, len, &te);
115 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
116 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
118 raswidth16 = (raswidth + 15) & ~15;
119 raswidth_bpr = raswidth16 / 8;
121 if ((raster = AllocRaster(raswidth, rasheight)))
123 memset(raster, 0, RASSIZE(raswidth, rasheight));
125 tf = rp->Font;
127 x = -te.te_Extent.MinX;
129 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
130 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
132 while(len--)
134 UBYTE c = *text++;
135 ULONG idx;
136 ULONG charloc;
137 UWORD glyphwidth, glyphpos, bold;
138 UBYTE *glyphdata;
139 UBYTE *dst;
140 ULONG srcmask;
141 ULONG dstmask;
143 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
145 idx = NUMCHARS(tf) - 1;
147 else
149 idx = c - tf->tf_LoChar;
152 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
154 glyphwidth = charloc & 0xFFFF;
155 glyphpos = charloc >> 16;
157 if (tf->tf_CharKern)
159 x += ((WORD *)tf->tf_CharKern)[idx];
163 for(bold = 0; bold <= is_bold; bold++)
165 WORD wx;
166 WORD italicshift, italiccheck = 0;
168 if (is_italic)
170 italiccheck = tf->tf_Baseline;
171 italicshift = italiccheck / 2;
173 else
175 italicshift = 0;
178 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
180 glyphdata = ((UBYTE *)tf->tf_CharData) + glyphpos / 8;
181 dst = raster + wx / 8;
183 for(y = 0; y < rasheight; y++)
185 UBYTE *glyphdatax = glyphdata;
186 UBYTE *dstx = dst;
187 UBYTE srcdata;
189 srcmask = 0x80 >> (glyphpos & 7);
190 dstmask = 0x80 >> (wx & 7);
192 srcdata = *glyphdatax;
194 for(gx = 0; gx < glyphwidth; gx++)
196 if (srcdata & srcmask)
198 *dstx |= dstmask;
201 if (dstmask == 0x1)
203 dstmask = 0x80;
204 dstx++;
206 else
208 dstmask >>= 1;
211 if (srcmask == 0x1)
213 srcmask = 0x80;
214 glyphdatax++;
215 srcdata =*glyphdatax;
217 else
219 srcmask >>= 1;
222 } /* for(gx = 0; gx < glyphwidth; gx++) */
224 glyphdata += tf->tf_Modulo;
225 dst += raswidth_bpr;
227 if (is_italic)
229 italiccheck--;
230 if (italiccheck & 1)
232 italicshift--;
234 wx--;
235 if ((wx & 7) == 7) dst--;
240 } /* for(y = 0; y < rasheight; y++) */
242 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
244 if (tf->tf_CharSpace)
246 x += ((WORD *)tf->tf_CharSpace)[idx];
248 else
250 x += tf->tf_XSize;
253 x += rp->TxSpacing;
255 } /* while(len--) */
257 if (rp->AlgoStyle & FSF_UNDERLINED)
259 UBYTE *dst;
260 ULONG prev_word, act_word = 0, next_word, word;
261 WORD count;
262 LONG underline;
264 underline = rp->TxBaseline + 1;
265 if (underline < rasheight - 1) underline++;
267 if (underline < rasheight)
269 dst = raster + underline * (LONG)raswidth_bpr;
270 next_word = *(UWORD *)dst;
271 #if !AROS_BIG_ENDIAN
272 next_word = AROS_WORD2BE(next_word);
273 #endif
274 count = raswidth16 / 16;
276 while(count--)
278 prev_word = act_word;
279 act_word = next_word;
280 if (count > 1)
282 next_word = ((UWORD *)dst)[1];
284 #if !AROS_BIG_ENDIAN
285 next_word = AROS_WORD2BE(next_word);
286 #endif
288 else
290 next_word = 0;
292 word = ((act_word << 1) & 0xFFFF) + (next_word >> 15);
293 word |= (act_word >> 1) + ((prev_word << 15) & 0xFFFF);
294 word &= ~act_word;
296 word = 0xFFFF &~ word;
297 #if !AROS_BIG_ENDIAN
298 word = AROS_BE2WORD(word);
299 #endif
301 *(UWORD *)dst = word;
302 dst += 2;
304 } /* while(count--) */
306 } /* if (underline < rasheight) */
308 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
310 BltTemplate(raster,
312 raswidth_bpr,
314 rp->cp_x + te.te_Extent.MinX,
315 rp->cp_y - rp->TxBaseline,
316 raswidth,
317 rasheight);
319 FreeRaster(raster, raswidth, rasheight);
321 } /* if ((raster = AllocRaster(raswidth, rasheight))) */
323 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
327 /***************************************************************************/
329 void BltTemplateAlphaBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
330 struct GfxBase *GfxBase)
332 struct TextExtent te;
333 struct TextFont *tf;
334 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
335 UBYTE *raster;
336 BOOL is_bold, is_italic;
338 /* CyberGfxBase is placed inside GfxBase, so it's static */
339 if (!CyberGfxBase)
340 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
341 if (!CyberGfxBase)
342 return;
344 TextExtent(rp, text, len, &te);
346 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
347 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
349 raswidth_bpr = raswidth;
351 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
353 tf = rp->Font;
355 x = -te.te_Extent.MinX;
357 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
358 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
360 while(len--)
362 UBYTE c = *text++;
363 ULONG idx;
364 ULONG charloc;
365 UWORD glyphwidth, glyphpos, bold;
366 UBYTE *glyphdata;
367 UBYTE *dst;
369 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
371 idx = NUMCHARS(tf) - 1;
373 else
375 idx = c - tf->tf_LoChar;
378 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
380 glyphwidth = charloc & 0xFFFF;
381 glyphpos = charloc >> 16;
383 if (tf->tf_CharKern)
385 x += ((WORD *)tf->tf_CharKern)[idx];
389 for(bold = 0; bold <= is_bold; bold++)
391 WORD wx;
392 WORD italicshift, italiccheck = 0;
394 if (is_italic)
396 italiccheck = tf->tf_Baseline;
397 italicshift = italiccheck / 2;
399 else
401 italicshift = 0;
404 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
406 glyphdata = ((UBYTE *)((struct ColorTextFont *)tf)->ctf_CharData[0]) + glyphpos;
407 dst = raster + wx;
409 for(y = 0; y < rasheight; y++)
411 UBYTE *glyphdatax = glyphdata;
412 UBYTE *dstx = dst;
414 for(gx = 0; gx < glyphwidth; gx++)
416 UWORD old = *dstx;
418 old += *glyphdatax++;
419 if (old > 255) old = 255;
420 *dstx++ = old;
423 glyphdata += tf->tf_Modulo * 8;
424 dst += raswidth_bpr;
426 if (is_italic)
428 italiccheck--;
429 if (italiccheck & 1)
431 italicshift--;
432 dst--;
436 } /* for(y = 0; y < rasheight; y++) */
438 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
440 if (tf->tf_CharSpace)
442 x += ((WORD *)tf->tf_CharSpace)[idx];
444 else
446 x += tf->tf_XSize;
449 x += rp->TxSpacing;
451 } /* while(len--) */
453 if (rp->AlgoStyle & FSF_UNDERLINED)
455 UBYTE *dst;
456 UBYTE prev_byte, act_byte = 0, next_byte;
457 WORD count;
458 LONG underline;
460 underline = rp->TxBaseline + 1;
461 if (underline < rasheight - 1) underline++;
463 if (underline < rasheight)
465 dst = raster + underline * (LONG)raswidth_bpr;
466 count = raswidth;
468 next_byte = *dst;
470 while(count--)
472 prev_byte = act_byte;
473 act_byte = next_byte;
474 if (count > 1)
476 next_byte = dst[1];
478 else
480 next_byte = 0;
483 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
485 } /* while(count--) */
487 } /* if (underline < rasheight) */
489 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
491 BltTemplateAlpha(raster,
493 raswidth_bpr,
495 rp->cp_x + te.te_Extent.MinX,
496 rp->cp_y - rp->TxBaseline,
497 raswidth,
498 rasheight);
500 FreeVec(raster);
502 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
504 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
508 /***************************************************************************/
510 void ColorFontBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
511 struct GfxBase *GfxBase)
513 struct TextExtent te;
514 struct TextFont *tf;
515 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
516 UBYTE *raster, *chunky;
517 BOOL is_bold, is_italic;
519 tf = rp->Font;
520 if (!ExtendFont(tf, NULL)) return;
522 chunky = ((struct TextFontExtension_intern *)(tf->tf_Extension))->hash->chunky_colorfont;
524 TextExtent(rp, text, len, &te);
526 if ((rp->DrawMode & ~INVERSVID) == JAM2)
528 ULONG old_drmd = GetDrMd(rp);
530 SetDrMd(rp, old_drmd ^ INVERSVID);
531 RectFill(rp, rp->cp_x + te.te_Extent.MinX,
532 rp->cp_y + te.te_Extent.MinY,
533 rp->cp_x + te.te_Extent.MaxX,
534 rp->cp_y + te.te_Extent.MaxY);
535 SetDrMd(rp, old_drmd);
539 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
540 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
542 raswidth_bpr = raswidth;
544 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
546 x = -te.te_Extent.MinX;
548 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
549 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
551 while(len--)
553 UBYTE c = *text++;
554 ULONG idx;
555 ULONG charloc;
556 UWORD glyphwidth, glyphpos, bold;
557 UBYTE *glyphdata;
558 UBYTE *dst;
560 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
562 idx = NUMCHARS(tf) - 1;
564 else
566 idx = c - tf->tf_LoChar;
569 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
571 glyphwidth = charloc & 0xFFFF;
572 glyphpos = charloc >> 16;
574 if (tf->tf_CharKern)
576 x += ((WORD *)tf->tf_CharKern)[idx];
580 for(bold = 0; bold <= is_bold; bold++)
582 WORD wx;
583 WORD italicshift, italiccheck = 0;
585 if (is_italic)
587 italiccheck = tf->tf_Baseline;
588 italicshift = italiccheck / 2;
590 else
592 italicshift = 0;
595 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
597 glyphdata = chunky + glyphpos;
598 dst = raster + wx;
600 for(y = 0; y < rasheight; y++)
602 UBYTE *glyphdatax = glyphdata;
603 UBYTE *dstx = dst;
605 for(gx = 0; gx < glyphwidth; gx++)
607 UBYTE p = *glyphdatax++;
609 if (p || !bold) *dstx = p;
611 dstx++;
614 glyphdata += tf->tf_Modulo * 8;
615 dst += raswidth_bpr;
617 if (is_italic)
619 italiccheck--;
620 if (italiccheck & 1)
622 italicshift--;
623 dst--;
627 } /* for(y = 0; y < rasheight; y++) */
629 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
631 if (tf->tf_CharSpace)
633 x += ((WORD *)tf->tf_CharSpace)[idx];
635 else
637 x += tf->tf_XSize;
640 x += rp->TxSpacing;
642 } /* while(len--) */
644 #if 0
645 if (rp->AlgoStyle & FSF_UNDERLINED)
647 UBYTE *dst;
648 UBYTE prev_byte, act_byte = 0, next_byte;
649 WORD count;
650 LONG underline;
652 underline = rp->TxBaseline + 1;
653 if (underline < rasheight - 1) underline++;
655 if (underline < rasheight)
657 dst = raster + underline * (LONG)raswidth_bpr;
658 count = raswidth;
660 next_byte = *dst;
662 while(count--)
664 prev_byte = act_byte;
665 act_byte = next_byte;
666 if (count > 1)
668 next_byte = dst[1];
670 else
672 next_byte = 0;
675 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
677 } /* while(count--) */
679 } /* if (underline < rasheight) */
681 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
683 #endif
686 HIDDT_PixelLUT pixlut;
687 HIDDT_Pixel pixtab[256];
689 pixlut.entries = AROS_PALETTE_SIZE;
690 pixlut.pixels = IS_HIDD_BM(rp->BitMap) ? HIDD_BM_PIXTAB(rp->BitMap) : NULL;
692 if ((rp->Flags & RPF_REMAP_COLORFONTS) &&
693 (CTF(tf)->ctf_ColorFontColors) &&
694 ((CTF(tf)->ctf_Flags & CT_COLORMASK) != CT_GREYFONT) && /* <-- FIX/CHECK/SUPPORT CT_GREYFONT) */
695 IS_HIDD_BM(rp->BitMap) &&
696 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8))
698 UWORD *colortable = CTF(tf)->ctf_ColorFontColors->cfc_ColorTable;
699 WORD i;
701 for(i = 0; i < CTF(tf)->ctf_ColorFontColors->cfc_Count; i++)
703 UWORD rgb12 = *colortable++;
704 HIDDT_Color col;
706 col.red = ((rgb12 >> 8) & 0x0F) * 0x1111;
707 col.green = ((rgb12 >> 4) & 0x0F) * 0x1111;
708 col.blue = ((rgb12 >> 0) & 0x0F) * 0x1111;
710 pixtab[i] = HIDD_BM_MapColor(HIDD_BM_OBJ(rp->BitMap), &col);
713 pixlut.pixels = pixtab;
716 write_transp_pixels_8(rp, raster,raswidth_bpr,
717 rp->cp_x + te.te_Extent.MinX,
718 rp->cp_y - rp->TxBaseline,
719 rp->cp_x + te.te_Extent.MinX + raswidth - 1,
720 rp->cp_y - rp->TxBaseline + rasheight - 1,
721 &pixlut, 0, TRUE, GfxBase);
725 FreeVec(raster);
727 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
729 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);