Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / graphics / textextent.c
blobe3186a4ff7247d57dac95846c48bdeea056375d8
1 /*
2 Copyright © 1995-2012, 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 that a text string
31 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.
44 Often zero.
45 te_Extent.MinY - same as -tf_Baseline. The offset
46 from the baseline to the top of the
47 rectangle this would render into.
48 te_Extent.MaxX - the offset of the left side of the
49 rectangle this would render into.
50 Often the same as te_Width-1.
51 te_Extent.MaxY - same as tf_YSize-tf_Baseline-1.
52 The offset from the baseline to the
53 bottom of the rectangle this would
54 render into.
56 RESULT
58 NOTES
60 EXAMPLE
62 BUGS
64 SEE ALSO
66 INTERNALS
68 *****************************************************************************/
70 AROS_LIBFUNC_INIT
72 struct TextFont *tf = rp->Font;
74 textExtent->te_Width = TextLength(rp, string, count);
75 textExtent->te_Height = tf->tf_YSize;
76 textExtent->te_Extent.MinY = -tf->tf_Baseline;
77 textExtent->te_Extent.MaxY = textExtent->te_Height - 1 - tf->tf_Baseline;
79 /* MinX/MaxX can be a bit more complicated if there are kerning/space
80 * tables */
82 if ((tf->tf_Flags & FPF_PROPORTIONAL) || tf->tf_CharKern
83 || tf->tf_CharSpace)
85 WORD idx;
86 WORD defaultidx = NUMCHARS(tf) - 1; /* Last glyph is 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) \
111 textExtent->te_Extent.MinX = (x); \
112 if ((x) > textExtent->te_Extent.MaxX) \
113 textExtent->te_Extent.MaxX = (x);
115 x += ((WORD *)tf->tf_CharKern)[idx];
116 CHECK_MINMAX(x);
118 x2 = x + ( ( ((ULONG *)tf->tf_CharLoc)[idx] ) & 0xFFFF);
119 CHECK_MINMAX(x2);
121 x += ((WORD *)tf->tf_CharSpace)[idx];
122 CHECK_MINMAX(x);
124 x += rp->TxSpacing;
125 CHECK_MINMAX(x);
127 } /* while(count--) */
129 textExtent->te_Extent.MaxX--;
131 } /* if (count) */
133 } /* if ((tf->tf_Flags & FPF_PROPORTIONAL) || tf->tf_CharKern
134 * || tf->tf_CharSpace) */
135 else
137 /* Normal non-proportional Font */
138 textExtent->te_Extent.MinX = 0;
139 textExtent->te_Extent.MaxX = textExtent->te_Width - 1;
142 if (rp->AlgoStyle & FSF_BOLD)
144 textExtent->te_Extent.MaxX += tf->tf_BoldSmear;
147 if (rp->AlgoStyle & FSF_ITALIC)
149 /* ###### ######
150 ** ## ## ## ##
151 ** ## ## ## ##
152 ** ## ## ===> ## ##
153 ** ## ## ## ##
154 **..##..##.. ..##..##..
155 ** ## ## ## ##
156 ** ###### ######
159 textExtent->te_Extent.MaxX += tf->tf_Baseline / 2;
160 textExtent->te_Extent.MinX -= (tf->tf_YSize - tf->tf_Baseline) / 2;
163 AROS_LIBFUNC_EXIT
165 } /* TextExtent */