FireBirdLib - Topfield TMS PVR TAP Programming Library
FMUC_PutStringAA.c
Go to the documentation of this file.
1#include <stdlib.h>
2#include <string.h>
3#include "FBLib_FontManager.h"
4
5void FMUC_PutStringAA(word rgn, dword x, dword y, dword maxX, const char *str, dword fcolor, dword bcolor, tFontDataUC *FontData, byte bDot, byte align, float AntiAliasFactor)
6{
8
9 int XEnd, YEnd;
10 dword *PixelData;
11 byte *FontBitmap;
12 byte *p, *pEnd;
13 dword X, Y;
14 dword CX, CY, CW, CH;
15 dword SaveBoxX;
16 dword dotWidth;
17 char *newstr;
18 int width = 0, newstrlen;
19 dword LastBackgroundPixel = 0;
20 byte LastForegroundPixel = 0;
21 dword LastPixel = 0;
22 byte Grey;
23 tGlyphCacheUC *GlyphData;
24 byte BytesPerChar;
25 bool hasAnsiChars, hasUTFChars;
26
27 //Remember the last position for diacritical marks
28 bool isDiacriticalMark;
29 int LastCC, NextCX;
30
31 if(!str || !str[0] || !FontData || (maxX <= x))
32 {
33 TRACEEXIT();
34 return;
35 }
36
37 if(GetOSDRegionWidth(rgn) && GetOSDRegionWidth(rgn) <= maxX) maxX = GetOSDRegionWidth(rgn) - 1;
38
39 //Convert to UTF8 if necessary
40 GetStringEncoding(str, &hasAnsiChars, &hasUTFChars);
41 if(hasAnsiChars && !hasUTFChars)
42 {
43 newstr = TAP_MemAlloc((strlen(str) << 2) + 20);
44 if(newstr == NULL)
45 {
46 TRACEEXIT();
47 return;
48 }
49
50 StrToUTF8(str, newstr, 9);
51 }
52 else
53 {
54 newstrlen = strlen(str) + 20;
55 newstr = TAP_MemAlloc(newstrlen);
56 if(newstr == NULL)
57 {
58 TRACEEXIT();
59 return;
60 }
61
62 strncpy(newstr, str, newstrlen);
63 newstr[newstrlen - 1] = '\0';
64 }
66
67 XEnd = x + FMUC_GetStringWidth(newstr, FontData) - 1;
68 dotWidth = 0;
69
70 switch(bDot)
71 {
72 case 0:
73 {
74 char *p;
75
76 if(XEnd > (int)maxX)
77 {
78 newstrlen = strlen(newstr);
79 p = FMUC_FindUTF8Start(&newstr[newstrlen - 1]);
80
81 do
82 {
83 GlyphData = FMUC_GetGlyphData(FontData, p, NULL);
84 if(GlyphData)
85 {
86 width = GlyphData->Width;
87 XEnd -= width;
88 *p = '\0';
89 }
90 p = FMUC_FindUTF8Start(p - 1);
91 newstrlen--;
92 } while((XEnd > (int)maxX) && (width != 0) && (newstrlen > 0) && (p > newstr));
93 }
94 break;
95 }
96
97 case 1:
98 {
99 char *p;
100
101 if(XEnd > (int)maxX)
102 {
103 dotWidth = FMUC_GetStringWidth("… ", FontData);
104 XEnd += dotWidth;
105
106 newstrlen = strlen(newstr);
107 p = FMUC_FindUTF8Start(&newstr[newstrlen - 1]);
108 do
109 {
110 GlyphData = FMUC_GetGlyphData(FontData, p, NULL);
111 if(GlyphData)
112 {
113 width = GlyphData->Width;
114 XEnd -= width;
115 *p = '\0';
116 }
117 p = FMUC_FindUTF8Start(p - 1);
118 newstrlen--;
119 } while((XEnd > (int)maxX) && (width != 0) && (newstrlen > 0) && (p > newstr));
120 strcat(newstr, "…");
121 }
122 break;
123 }
124
125 case 2:
126 {
127 char *p;
128
129 p = newstr;
130 if(XEnd > (int)maxX)
131 {
132 dotWidth = FMUC_GetStringWidth("…", FontData);
133 XEnd += dotWidth;
134 newstrlen = strlen(newstr);
135 do
136 {
137 GlyphData = FMUC_GetGlyphData(FontData, p, NULL);
138 if(GlyphData)
139 {
140 width = GlyphData->Width;
141 XEnd -= width;
142 }
143 p = FMUC_FindNextUTF8(p);
144 newstrlen--;
145 } while((XEnd > (int)maxX) && (width != 0) && (newstrlen > 0));
146
147 DeleteAt(newstr, 0, (int)(p - newstr));
148 InsertAt(newstr, 0, "…");
149 }
150 break;
151 }
152 }
153
154 if(XEnd > (int)maxX)
155 {
156 TAP_MemFree(newstr);
157
158 TRACEEXIT();
159 return;
160 }
161
162 YEnd = y + FMUC_GetStringHeight(newstr, FontData) - 1;
163
164 switch(align)
165 {
166 case ALIGN_LEFT:
167 {
168 SaveBoxX = x;
169 break;
170 }
171
172 case ALIGN_CENTER:
173 {
174 SaveBoxX = x + ((maxX - XEnd) >> 1);
175 break;
176 }
177
178 case ALIGN_RIGHT:
179 {
180 SaveBoxX = maxX - (XEnd - x);
181 break;
182 }
183
184 default:
185 SaveBoxX = x;
186 break;
187 }
188
189 if(bcolor & 0xff000000)
190 {
191 TAP_Osd_FillBox(rgn, x, y, maxX - x + 1, YEnd - y + 1, bcolor);
192 FM_InitAlphaLUT(fcolor, bcolor, AntiAliasFactor);
193 }
194
195 PixelData = (dword*) TAP_Osd_SaveBox(rgn, SaveBoxX, y, XEnd - x + 1, YEnd - y + 1);
196 if(PixelData)
197 {
198 CX = 0;
199 LastCC = 0;
200 NextCX = 0;
201 p = newstr;
202 pEnd = p + strlen(p);
203
204 while(p < pEnd)
205 {
206 GlyphData = FMUC_GetGlyphData(FontData, p, &BytesPerChar);
207 if(GlyphData)
208 {
209 isDiacriticalMark = FMUC_IsDiacriticalMark(GlyphData->Unicode);
210
211 if(isDiacriticalMark)
212 {
213 //Jump back to the position of the last character based on the width of both glyphs
214 NextCX = CX;
215 CX = LastCC - (GlyphData->Width >> 1);
216 }
217
218 FontBitmap = GlyphData->GlyphData;
219 CW = GlyphData->Width;
220 CH = GlyphData->Height;
221
222 for(Y = 0; Y < CH; Y++)
223 {
224 CY = (XEnd - x + 1) * Y;
225
226 dword *pd = &PixelData[CX + CY];
227
228 for(X = 0; X < CW; X++)
229 {
230 Grey = *FontBitmap++;
231 if(Grey != 0x00)
232 {
233 if(Grey == 0xff)
234 {
235 *pd = fcolor;
236 }
237 else
238 {
239 if(bcolor & 0xff000000)
240 {
241 *pd = (fcolor & 0xff000000) | (AlphaLUT[Grey].r << 16) | (AlphaLUT[Grey].g << 8) | AlphaLUT[Grey].b;
242 }
243 else
244 {
245 if((LastForegroundPixel != Grey) || (LastBackgroundPixel != *pd))
246 {
247 LastBackgroundPixel = *pd;
248 LastForegroundPixel = Grey;
249 LastPixel = (fcolor & 0xff000000) | FM_AlphaBlendRGB(Grey, fcolor, LastBackgroundPixel, AntiAliasFactor);
250 }
251
252 *pd = LastPixel;
253 }
254 }
255 }
256 pd++;
257 }
258 }
259
260 if(isDiacriticalMark)
261 {
262 CX = NextCX;
263 }
264 else
265 {
266 //Calculate the center of the character
267 LastCC = CX + (CW >> 1);
268 CX += CW;
269 }
270 }
271 p += BytesPerChar;
272 }
273
274 TAP_Osd_RestoreBox(rgn, SaveBoxX, y, XEnd - x + 1, YEnd - y + 1, PixelData);
275 TAP_MemFree(PixelData);
276 }
277
278 TAP_MemFree(newstr);
279
280 TRACEEXIT();
281}
byte * FMUC_FindNextUTF8(byte *p)
byte * FMUC_FindUTF8Start(byte *p)
tAlphaLUT AlphaLUT[256]
void FM_InitAlphaLUT(dword fgColor, dword bgColor, float AntiAliasFactor)
tGlyphCacheUC * FMUC_GetGlyphData(tFontDataUC *FontData, const byte *UTF8Character, byte *BytesPerChar)
dword FM_AlphaBlendRGB(byte Alpha, dword FG, dword BG, float AntiAliasFactor)
bool FMUC_IsDiacriticalMark(dword Character)
dword FMUC_GetStringHeight(const char *Text, tFontDataUC *FontData)
dword FMUC_GetStringWidth(const char *Text, tFontDataUC *FontData)
void FMUC_PutStringAA(word rgn, dword x, dword y, dword maxX, const char *str, dword fcolor, dword bcolor, tFontDataUC *FontData, byte bDot, byte align, float AntiAliasFactor)
word GetOSDRegionWidth(word Region)
@ LFChars
Definition: libFireBird.h:2505
@ ControlChars
Definition: libFireBird.h:2504
#define TRACEEXIT()
Definition: libFireBird.h:1244
void GetStringEncoding(const char *Text, bool *hasAnsiChars, bool *hasUTFChars)
@ Y
Definition: libFireBird.h:291
@ X
Definition: libFireBird.h:290
void MakeValidFileName(char *strName, eRemoveChars ControlCharacters)
bool StrToUTF8(const byte *SourceString, byte *DestString, byte DefaultISO8859CharSet)
Definition: StrToUTF8.c:146
#define TRACEENTER()
Definition: libFireBird.h:1243
void InsertAt(const char *SourceString, int Pos, char *NewString)
Definition: InsertAt.c:4
void DeleteAt(char *SourceString, int Pos, int Len)
Definition: DeleteAt.c:4
byte * GlyphData
Definition: libFireBird.h:1843