some fixes to accented characters
[tangerine.git] / rom / graphics / textextent.c
blobd8a0e91f8f9dd534ea3965943201730a6dcb98c0
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Calculate the size a text needs in a specific rastport.
6 Lang: english
7 */
8 #include "graphics_intern.h"
9 #include <graphics/rastport.h>
11 /*****************************************************************************
13 NAME */
14 #include <graphics/rastport.h>
15 #include <graphics/text.h>
16 #include <proto/graphics.h>
18 AROS_LH4(void, TextExtent,
20 /* SYNOPSIS */
21 AROS_LHA(struct RastPort *, rp, A1),
22 AROS_LHA(CONST_STRPTR , string, A0),
23 AROS_LHA(ULONG , count, D0),
24 AROS_LHA(struct TextExtent *, textExtent, A2),
26 /* LOCATION */
27 struct GfxBase *, GfxBase, 115, Graphics)
29 /* FUNCTION
30 This function determines the metric of the space
31 that a text string would render into.
33 INPUTS
34 rp - RastPort
35 string - address of string
36 count - number of characters
37 textExtent - storing place for the result
38 te_Width - same as TextLength() result: the rp_cp_x
39 advance that rendering this text would cause.
40 te_Height - same as tf_YSize. The height of the
41 font.
42 te_Extent.MinX - the offset to the left side of the
43 rectangle this would render into. Often zero.
44 te_Extent.MinY - same as -tf_Baseline. The offset
45 from the baseline to the top of the rectangle
46 this would render into.
47 te_Extent.MaxX - the offset of the left side of the
48 rectangle this would render into. Often the
49 same as te_Width-1.
50 te_Extent.MaxY - same as tf_YSize-tf_Baseline-1.
51 The offset from the baseline to the bottom of
52 the rectangle this would render into.
54 RESULT
56 NOTES
58 EXAMPLE
60 BUGS
62 SEE ALSO
64 INTERNALS
66 HISTORY
67 29-10-95 digulla automatically created from
68 graphics_lib.fd and clib/graphics_protos.h
70 *****************************************************************************/
72 AROS_LIBFUNC_INIT
74 struct TextFont *tf = rp->Font;
76 textExtent->te_Width = TextLength(rp, string, count);
77 textExtent->te_Height = tf->tf_YSize;
78 textExtent->te_Extent.MinY = -tf->tf_Baseline;
79 textExtent->te_Extent.MaxY = textExtent->te_Height - 1 - tf->tf_Baseline;
81 /* MinX/MaxX can be a bit more complicated if there are kerning/space tables */
83 if ((tf->tf_Flags & FPF_PROPORTIONAL) || tf->tf_CharKern || tf->tf_CharSpace)
85 WORD idx;
86 WORD defaultidx = NUMCHARS(tf) - 1; /* Last glyph is the default glyph */
87 WORD x, x2;
88 UBYTE c;
90 textExtent->te_Extent.MinX = 0;
91 textExtent->te_Extent.MaxX = 0;
92 x = 0;
94 if (count)
96 while(count--)
98 c = *string++;
100 if ( c < tf->tf_LoChar || c > tf->tf_HiChar)
102 idx = defaultidx;
104 else
106 idx = c - tf->tf_LoChar;
109 #define CHECK_MINMAX(x) \
110 if ((x) < textExtent->te_Extent.MinX) textExtent->te_Extent.MinX = (x); \
111 if ((x) > textExtent->te_Extent.MaxX) textExtent->te_Extent.MaxX = (x);
113 x += ((WORD *)tf->tf_CharKern)[idx];
114 CHECK_MINMAX(x);
116 x2 = x + ( ( ((ULONG *)tf->tf_CharLoc)[idx] ) & 0xFFFF);
117 CHECK_MINMAX(x2);
119 x += ((WORD *)tf->tf_CharSpace)[idx];
120 CHECK_MINMAX(x);
122 x += rp->TxSpacing;
123 CHECK_MINMAX(x);
125 } /* while(count--) */
127 textExtent->te_Extent.MaxX--;
129 } /* if (count) */
131 } /* if ((tf->tf_Flags & FPF_PROPORTIONAL) || tf->tf_CharKern || tf->tf_CharSpace) */
132 else
134 /* Normal non-proportional Font */
135 textExtent->te_Extent.MinX = 0;
136 textExtent->te_Extent.MaxX = textExtent->te_Width - 1;
139 if (rp->AlgoStyle & FSF_BOLD)
141 textExtent->te_Extent.MaxX += tf->tf_BoldSmear;
144 if (rp->AlgoStyle & FSF_ITALIC)
146 /* ###### ######
147 ** ## ## ## ##
148 ** ## ## ## ##
149 ** ## ## ===> ## ##
150 ** ## ## ## ##
151 **..##..##.. ..##..##..
152 ** ## ## ## ##
153 ** ###### ######
156 textExtent->te_Extent.MaxX += tf->tf_Baseline / 2;
157 textExtent->te_Extent.MinX -= (tf->tf_YSize - tf->tf_Baseline) / 2;
160 AROS_LIBFUNC_EXIT
162 } /* TextExtent */