Added more controller IDs.
[AROS.git] / rom / graphics / text.c
blobcee226d5ef54133deb3b0a6c59f1645d2cf27933
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 #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
95 BltTemplateBasedText(rp, string, count, GfxBase);
99 AROS_LIBFUNC_EXIT
101 } /* Text */
103 /***************************************************************************/
105 void BltTemplateBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
106 struct GfxBase *GfxBase)
108 struct TextExtent te;
109 struct TextFont *tf;
110 WORD raswidth, raswidth16, raswidth_bpr, rasheight, x, y, gx;
111 UBYTE *raster;
112 BOOL is_bold, is_italic;
114 TextExtent(rp, text, len, &te);
116 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
117 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
119 raswidth16 = (raswidth + 15) & ~15;
120 raswidth_bpr = raswidth16 / 8;
122 if ((raster = AllocRaster(raswidth, rasheight)))
124 memset(raster, 0, RASSIZE(raswidth, rasheight));
126 tf = rp->Font;
128 x = -te.te_Extent.MinX;
130 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
131 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
133 while(len--)
135 UBYTE c = *text++;
136 ULONG idx;
137 ULONG charloc;
138 UWORD glyphwidth, glyphpos, bold;
139 UBYTE *glyphdata;
140 UBYTE *dst;
141 ULONG srcmask;
142 ULONG dstmask;
144 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
146 idx = NUMCHARS(tf) - 1;
148 else
150 idx = c - tf->tf_LoChar;
153 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
155 glyphwidth = charloc & 0xFFFF;
156 glyphpos = charloc >> 16;
158 if (tf->tf_CharKern)
160 x += ((WORD *)tf->tf_CharKern)[idx];
164 for(bold = 0; bold <= is_bold; bold++)
166 WORD wx;
167 WORD italicshift, italiccheck = 0;
169 if (is_italic)
171 italiccheck = tf->tf_Baseline;
172 italicshift = italiccheck / 2;
174 else
176 italicshift = 0;
179 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
181 glyphdata = ((UBYTE *)tf->tf_CharData) + glyphpos / 8;
182 dst = raster + wx / 8;
184 for(y = 0; y < rasheight; y++)
186 UBYTE *glyphdatax = glyphdata;
187 UBYTE *dstx = dst;
188 UBYTE srcdata;
190 srcmask = 0x80 >> (glyphpos & 7);
191 dstmask = 0x80 >> (wx & 7);
193 srcdata = *glyphdatax;
195 for(gx = 0; gx < glyphwidth; gx++)
197 if (srcdata & srcmask)
199 *dstx |= dstmask;
202 if (dstmask == 0x1)
204 dstmask = 0x80;
205 dstx++;
207 else
209 dstmask >>= 1;
212 if (srcmask == 0x1)
214 srcmask = 0x80;
215 glyphdatax++;
216 srcdata =*glyphdatax;
218 else
220 srcmask >>= 1;
223 } /* for(gx = 0; gx < glyphwidth; gx++) */
225 glyphdata += tf->tf_Modulo;
226 dst += raswidth_bpr;
228 if (is_italic)
230 italiccheck--;
231 if (italiccheck & 1)
233 italicshift--;
235 wx--;
236 if ((wx & 7) == 7) dst--;
241 } /* for(y = 0; y < rasheight; y++) */
243 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
245 if (tf->tf_CharSpace)
247 x += ((WORD *)tf->tf_CharSpace)[idx];
249 else
251 x += tf->tf_XSize;
254 x += rp->TxSpacing;
256 } /* while(len--) */
258 if (rp->AlgoStyle & FSF_UNDERLINED)
260 UBYTE *dst;
261 ULONG prev_word, act_word = 0, next_word, word;
262 WORD count;
263 LONG underline;
265 underline = rp->TxBaseline + 1;
266 if (underline < rasheight - 1) underline++;
268 if (underline < rasheight)
270 dst = raster + underline * (LONG)raswidth_bpr;
271 next_word = *(UWORD *)dst;
272 #if !AROS_BIG_ENDIAN
273 next_word = AROS_WORD2BE(next_word);
274 #endif
275 count = raswidth16 / 16;
277 while(count--)
279 prev_word = act_word;
280 act_word = next_word;
281 if (count > 1)
283 next_word = ((UWORD *)dst)[1];
285 #if !AROS_BIG_ENDIAN
286 next_word = AROS_WORD2BE(next_word);
287 #endif
289 else
291 next_word = 0;
293 word = ((act_word << 1) & 0xFFFF) + (next_word >> 15);
294 word |= (act_word >> 1) + ((prev_word << 15) & 0xFFFF);
295 word &= ~act_word;
297 word = 0xFFFF &~ word;
298 #if !AROS_BIG_ENDIAN
299 word = AROS_BE2WORD(word);
300 #endif
302 *(UWORD *)dst = word;
303 dst += 2;
305 } /* while(count--) */
307 } /* if (underline < rasheight) */
309 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
311 BltTemplate(raster,
313 raswidth_bpr,
315 rp->cp_x + te.te_Extent.MinX,
316 rp->cp_y - rp->TxBaseline,
317 raswidth,
318 rasheight);
320 FreeRaster(raster, raswidth, rasheight);
322 } /* if ((raster = AllocRaster(raswidth, rasheight))) */
324 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
328 /***************************************************************************/
330 void BltTemplateAlphaBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
331 struct GfxBase *GfxBase)
333 struct TextExtent te;
334 struct TextFont *tf;
335 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
336 UBYTE *raster;
337 BOOL is_bold, is_italic;
339 /* CyberGfxBase is placed inside GfxBase, so it's static */
340 if (!CyberGfxBase)
341 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
342 if (!CyberGfxBase)
343 return;
345 TextExtent(rp, text, len, &te);
347 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
348 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
350 raswidth_bpr = raswidth;
352 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
354 tf = rp->Font;
356 x = -te.te_Extent.MinX;
358 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
359 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
361 while(len--)
363 UBYTE c = *text++;
364 ULONG idx;
365 ULONG charloc;
366 UWORD glyphwidth, glyphpos, bold;
367 UBYTE *glyphdata;
368 UBYTE *dst;
370 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
372 idx = NUMCHARS(tf) - 1;
374 else
376 idx = c - tf->tf_LoChar;
379 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
381 glyphwidth = charloc & 0xFFFF;
382 glyphpos = charloc >> 16;
384 if (tf->tf_CharKern)
386 x += ((WORD *)tf->tf_CharKern)[idx];
390 for(bold = 0; bold <= is_bold; bold++)
392 WORD wx;
393 WORD italicshift, italiccheck = 0;
395 if (is_italic)
397 italiccheck = tf->tf_Baseline;
398 italicshift = italiccheck / 2;
400 else
402 italicshift = 0;
405 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
407 glyphdata = ((UBYTE *)((struct ColorTextFont *)tf)->ctf_CharData[0]) + glyphpos;
408 dst = raster + wx;
410 for(y = 0; y < rasheight; y++)
412 UBYTE *glyphdatax = glyphdata;
413 UBYTE *dstx = dst;
415 for(gx = 0; gx < glyphwidth; gx++)
417 UWORD old = *dstx;
419 old += *glyphdatax++;
420 if (old > 255) old = 255;
421 *dstx++ = old;
424 glyphdata += tf->tf_Modulo * 8;
425 dst += raswidth_bpr;
427 if (is_italic)
429 italiccheck--;
430 if (italiccheck & 1)
432 italicshift--;
433 dst--;
437 } /* for(y = 0; y < rasheight; y++) */
439 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
441 if (tf->tf_CharSpace)
443 x += ((WORD *)tf->tf_CharSpace)[idx];
445 else
447 x += tf->tf_XSize;
450 x += rp->TxSpacing;
452 } /* while(len--) */
454 if (rp->AlgoStyle & FSF_UNDERLINED)
456 UBYTE *dst;
457 UBYTE prev_byte, act_byte = 0, next_byte;
458 WORD count;
459 LONG underline;
461 underline = rp->TxBaseline + 1;
462 if (underline < rasheight - 1) underline++;
464 if (underline < rasheight)
466 dst = raster + underline * (LONG)raswidth_bpr;
467 count = raswidth;
469 next_byte = *dst;
471 while(count--)
473 prev_byte = act_byte;
474 act_byte = next_byte;
475 if (count > 1)
477 next_byte = dst[1];
479 else
481 next_byte = 0;
484 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
486 } /* while(count--) */
488 } /* if (underline < rasheight) */
490 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
492 BltTemplateAlpha(raster,
494 raswidth_bpr,
496 rp->cp_x + te.te_Extent.MinX,
497 rp->cp_y - rp->TxBaseline,
498 raswidth,
499 rasheight);
501 FreeVec(raster);
503 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
505 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);
509 /***************************************************************************/
511 void ColorFontBasedText(struct RastPort *rp, CONST_STRPTR text, ULONG len,
512 struct GfxBase *GfxBase)
514 struct TextExtent te;
515 struct TextFont *tf;
516 WORD raswidth, raswidth_bpr, rasheight, x, y, gx;
517 UBYTE *raster, *chunky;
518 BOOL is_bold, is_italic;
520 tf = rp->Font;
521 if (!ExtendFont(tf, NULL)) return;
523 chunky = ((struct TextFontExtension_intern *)(tf->tf_Extension))->hash->chunky_colorfont;
525 TextExtent(rp, text, len, &te);
527 if ((rp->DrawMode & ~INVERSVID) == JAM2)
529 ULONG old_drmd = GetDrMd(rp);
531 SetDrMd(rp, old_drmd ^ INVERSVID);
532 RectFill(rp, rp->cp_x + te.te_Extent.MinX,
533 rp->cp_y + te.te_Extent.MinY,
534 rp->cp_x + te.te_Extent.MaxX,
535 rp->cp_y + te.te_Extent.MaxY);
536 SetDrMd(rp, old_drmd);
540 raswidth = te.te_Extent.MaxX - te.te_Extent.MinX + 1;
541 rasheight = te.te_Extent.MaxY - te.te_Extent.MinY + 1;
543 raswidth_bpr = raswidth;
545 if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR)))
547 x = -te.te_Extent.MinX;
549 is_bold = (rp->AlgoStyle & FSF_BOLD) != 0;
550 is_italic = (rp->AlgoStyle & FSF_ITALIC) != 0;
552 while(len--)
554 UBYTE c = *text++;
555 ULONG idx;
556 ULONG charloc;
557 UWORD glyphwidth, glyphpos, bold;
558 UBYTE *glyphdata;
559 UBYTE *dst;
561 if (c < tf->tf_LoChar || c > tf->tf_HiChar)
563 idx = NUMCHARS(tf) - 1;
565 else
567 idx = c - tf->tf_LoChar;
570 charloc = ((ULONG *)tf->tf_CharLoc)[idx];
572 glyphwidth = charloc & 0xFFFF;
573 glyphpos = charloc >> 16;
575 if (tf->tf_CharKern)
577 x += ((WORD *)tf->tf_CharKern)[idx];
581 for(bold = 0; bold <= is_bold; bold++)
583 WORD wx;
584 WORD italicshift, italiccheck = 0;
586 if (is_italic)
588 italiccheck = tf->tf_Baseline;
589 italicshift = italiccheck / 2;
591 else
593 italicshift = 0;
596 wx = x + italicshift + (bold ? tf->tf_BoldSmear : 0);
598 glyphdata = chunky + glyphpos;
599 dst = raster + wx;
601 for(y = 0; y < rasheight; y++)
603 UBYTE *glyphdatax = glyphdata;
604 UBYTE *dstx = dst;
606 for(gx = 0; gx < glyphwidth; gx++)
608 UBYTE p = *glyphdatax++;
610 if (p || !bold) *dstx = p;
612 dstx++;
615 glyphdata += tf->tf_Modulo * 8;
616 dst += raswidth_bpr;
618 if (is_italic)
620 italiccheck--;
621 if (italiccheck & 1)
623 italicshift--;
624 dst--;
628 } /* for(y = 0; y < rasheight; y++) */
630 } /* for(bold = 0; bold < ((rp->AlgoStyle & FSF_BOLD) ? 2 : 1); bold++) */
632 if (tf->tf_CharSpace)
634 x += ((WORD *)tf->tf_CharSpace)[idx];
636 else
638 x += tf->tf_XSize;
641 x += rp->TxSpacing;
643 } /* while(len--) */
645 #if 0
646 if (rp->AlgoStyle & FSF_UNDERLINED)
648 UBYTE *dst;
649 UBYTE prev_byte, act_byte = 0, next_byte;
650 WORD count;
651 LONG underline;
653 underline = rp->TxBaseline + 1;
654 if (underline < rasheight - 1) underline++;
656 if (underline < rasheight)
658 dst = raster + underline * (LONG)raswidth_bpr;
659 count = raswidth;
661 next_byte = *dst;
663 while(count--)
665 prev_byte = act_byte;
666 act_byte = next_byte;
667 if (count > 1)
669 next_byte = dst[1];
671 else
673 next_byte = 0;
676 *dst++ = (act_byte || (!prev_byte && !next_byte)) ? 255 : 0;
678 } /* while(count--) */
680 } /* if (underline < rasheight) */
682 } /* if (rp->AlgoStyle & FSF_UNDERLINED) */
684 #endif
687 HIDDT_PixelLUT pixlut;
688 HIDDT_Pixel pixtab[256];
690 pixlut.entries = AROS_PALETTE_SIZE;
691 pixlut.pixels = IS_HIDD_BM(rp->BitMap) ? HIDD_BM_PIXTAB(rp->BitMap) : NULL;
693 if ((rp->Flags & RPF_REMAP_COLORFONTS) &&
694 (CTF(tf)->ctf_ColorFontColors) &&
695 ((CTF(tf)->ctf_Flags & CT_COLORMASK) != CT_GREYFONT) && /* <-- FIX/CHECK/SUPPORT CT_GREYFONT) */
696 IS_HIDD_BM(rp->BitMap) &&
697 (GetBitMapAttr(rp->BitMap, BMA_DEPTH) > 8))
699 UWORD *colortable = CTF(tf)->ctf_ColorFontColors->cfc_ColorTable;
700 WORD i;
702 for(i = 0; i < CTF(tf)->ctf_ColorFontColors->cfc_Count; i++)
704 UWORD rgb12 = *colortable++;
705 HIDDT_Color col;
707 col.red = ((rgb12 >> 8) & 0x0F) * 0x1111;
708 col.green = ((rgb12 >> 4) & 0x0F) * 0x1111;
709 col.blue = ((rgb12 >> 0) & 0x0F) * 0x1111;
711 pixtab[i] = HIDD_BM_MapColor(HIDD_BM_OBJ(rp->BitMap), &col);
714 pixlut.pixels = pixtab;
717 write_transp_pixels_8(rp, raster,raswidth_bpr,
718 rp->cp_x + te.te_Extent.MinX,
719 rp->cp_y - rp->TxBaseline,
720 rp->cp_x + te.te_Extent.MinX + raswidth - 1,
721 rp->cp_y - rp->TxBaseline + rasheight - 1,
722 &pixlut, 0, TRUE, GfxBase);
726 FreeVec(raster);
728 } /* if ((raster = AllocVec(raswidth * rasheight, MEMF_CLEAR))) */
730 Move(rp, rp->cp_x + te.te_Width, rp->cp_y);