the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2
3#include "BufferedImage.h"
4#include "UIFontData.h"
5
6#include <unordered_set>
7
8#include "UIBitmapFont.h"
9
10
11/////////////////////////////
12// UI Abstract Bitmap Font //
13/////////////////////////////
14
15UIAbstractBitmapFont::~UIAbstractBitmapFont()
16{
17 if (m_registered) IggyFontRemoveUTF8( m_fontname.c_str(),-1,IGGY_FONTFLAG_none );
18 delete m_bitmapFontProvider;
19}
20
21
22UIAbstractBitmapFont::UIAbstractBitmapFont(const string &fontname)
23{
24 m_fontname = fontname;
25
26 m_registered = false;
27
28 m_bitmapFontProvider = new IggyBitmapFontProvider();
29 m_bitmapFontProvider->get_font_metrics = &UIAbstractBitmapFont::GetFontMetrics_Callback;
30 m_bitmapFontProvider->get_glyph_for_codepoint = &UIAbstractBitmapFont::GetCodepointGlyph_Callback;
31 m_bitmapFontProvider->get_glyph_metrics = &UIAbstractBitmapFont::GetGlyphMetrics_Callback;
32 m_bitmapFontProvider->is_empty = &UIAbstractBitmapFont::IsGlyphEmpty_Callback;
33 m_bitmapFontProvider->get_kerning = &UIAbstractBitmapFont::GetKerningForGlyphPair_Callback;
34 m_bitmapFontProvider->can_bitmap = &UIAbstractBitmapFont::CanProvideBitmap_Callback;
35 m_bitmapFontProvider->get_bitmap = &UIAbstractBitmapFont::GetGlyphBitmap_Callback;
36 m_bitmapFontProvider->free_bitmap = &UIAbstractBitmapFont::FreeGlyphBitmap_Callback;
37 m_bitmapFontProvider->userdata = this;
38}
39
40void UIAbstractBitmapFont::registerFont()
41{
42 if (!m_registered)
43 {
44 // 4J-JEV: These only need registering the once when we first use this font in Iggy.
45 m_bitmapFontProvider->num_glyphs = m_numGlyphs;
46 IggyFontInstallBitmapUTF8( m_bitmapFontProvider, m_fontname.c_str(), -1, IGGY_FONTFLAG_none );
47 m_registered = true;
48 }
49
50 // 4J-JEV: Reset the font redirect to these fonts (we must do this everytime in-case we switched away elsewhere).
51 IggyFontSetIndirectUTF8( m_fontname.c_str(), -1, IGGY_FONTFLAG_all, m_fontname.c_str(), -1, IGGY_FONTFLAG_none );
52}
53
54IggyFontMetrics * RADLINK UIAbstractBitmapFont::GetFontMetrics_Callback(void *user_context,IggyFontMetrics *metrics)
55{
56 return ((UIAbstractBitmapFont *) user_context)->GetFontMetrics(metrics);
57}
58
59S32 RADLINK UIAbstractBitmapFont::GetCodepointGlyph_Callback(void *user_context,U32 codepoint)
60{
61 return ((UIAbstractBitmapFont *) user_context)->GetCodepointGlyph(codepoint);
62}
63
64IggyGlyphMetrics * RADLINK UIAbstractBitmapFont::GetGlyphMetrics_Callback(void *user_context,S32 glyph,IggyGlyphMetrics *metrics)
65{
66 return ((UIAbstractBitmapFont *) user_context)->GetGlyphMetrics(glyph,metrics);
67}
68
69rrbool RADLINK UIAbstractBitmapFont::IsGlyphEmpty_Callback(void *user_context,S32 glyph)
70{
71 return ((UIAbstractBitmapFont *) user_context)->IsGlyphEmpty(glyph);
72}
73
74F32 RADLINK UIAbstractBitmapFont::GetKerningForGlyphPair_Callback(void *user_context,S32 first_glyph,S32 second_glyph)
75{
76 return ((UIAbstractBitmapFont *) user_context)->GetKerningForGlyphPair(first_glyph,second_glyph);
77}
78
79rrbool RADLINK UIAbstractBitmapFont::CanProvideBitmap_Callback(void *user_context,S32 glyph,F32 pixel_scale)
80{
81 return ((UIAbstractBitmapFont *) user_context)->CanProvideBitmap(glyph,pixel_scale);
82}
83
84rrbool RADLINK UIAbstractBitmapFont::GetGlyphBitmap_Callback(void *user_context,S32 glyph,F32 pixel_scale,IggyBitmapCharacter *bitmap)
85{
86 return ((UIAbstractBitmapFont *) user_context)->GetGlyphBitmap(glyph,pixel_scale,bitmap);
87}
88
89void RADLINK UIAbstractBitmapFont::FreeGlyphBitmap_Callback(void *user_context,S32 glyph,F32 pixel_scale,IggyBitmapCharacter *bitmap)
90{
91 return ((UIAbstractBitmapFont *) user_context)->FreeGlyphBitmap(glyph,pixel_scale,bitmap);
92}
93
94UIBitmapFont::UIBitmapFont( SFontData &sfontdata )
95 : UIAbstractBitmapFont( sfontdata.m_strFontName )
96{
97 m_numGlyphs = sfontdata.m_uiGlyphCount;
98
99 BufferedImage bimg(sfontdata.m_wstrFilename);
100 int *bimgData = bimg.getData();
101
102 m_cFontData = new CFontData(sfontdata, bimgData);
103
104 //delete [] bimgData;
105}
106
107UIBitmapFont::~UIBitmapFont()
108{
109 m_cFontData->release();
110}
111
112//Callback function type for returning vertical font metrics
113IggyFontMetrics *UIBitmapFont::GetFontMetrics(IggyFontMetrics *metrics)
114{
115 //Description
116 // Vertical metrics for a font
117 //Members
118 // ascent - extent of characters above baseline (positive)
119 // descent - extent of characters below baseline (positive)
120 // line_gap - spacing between one row's descent and the next line's ascent
121 // average_glyph_width_for_tab_stops - spacing of "average" character for computing default tab stops
122 // largest_glyph_bbox_y1 - lowest point below baseline of any character in the font
123
124 metrics->ascent = m_cFontData->getFontData()->m_fAscent;
125 metrics->descent = m_cFontData->getFontData()->m_fDescent;
126
127 metrics->average_glyph_width_for_tab_stops = 8.0f;
128
129 // This is my best guess, there's no reference to a specific glyph here
130 // so aren't these just exactly the same.
131 metrics->largest_glyph_bbox_y1 = metrics->descent;
132
133 // metrics->line_gap; // 4J-JEV: Sean said this does nothing.
134
135 return metrics;
136}
137
138//Callback function type for mapping 32-bit unicode code point to internal font glyph number; use IGGY_GLYPH_INVALID to mean "invalid character"
139S32 UIBitmapFont::GetCodepointGlyph(U32 codepoint)
140{
141 // 4J-JEV: Change "right single quotation marks" to apostrophies.
142 if (codepoint == 0x2019) codepoint = 0x27;
143
144 return m_cFontData->getGlyphId(codepoint);
145}
146
147//Callback function type for returning horizontal metrics for each glyph
148IggyGlyphMetrics * UIBitmapFont::GetGlyphMetrics(S32 glyph,IggyGlyphMetrics *metrics)
149{
150 // 4J-JEV: Information about 'Glyph Metrics'.
151 // http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-3.html - Overview.
152 // http://en.wikipedia.org/wiki/Kerning#Kerning_values - 'Font Units'
153
154 //Description
155 // Horizontal metrics for a glyph
156 //Members
157 // x0 y0 x1 y1 - bounding box
158 // advance - horizontal distance to move character origin after drawing this glyph
159
160
161 /* 4J-JEV: *IMPORTANT*
162 *
163 * I believe these are measured wrt the scale mentioned in GetGlyphBitmap
164 * i.e. 1.0f == pixel_scale,
165 *
166 * However we do not have that information here, then all these values need to be
167 * the same for every scale in this font.
168 *
169 * We have 2 scales of bitmap glyph, and we can only scale these up by powers of 2
170 * otherwise the fonts will become blurry. The appropriate glyph is chosen in
171 * 'GetGlyphBitmap' however we need to set the horizontal sizes here.
172 */
173
174 float glyphAdvance = m_cFontData->getAdvance(glyph);
175
176 // 4J-JEV: Anything outside this measurement will be
177 // cut off if it's at the start or end of the row.
178 metrics->x0 = 0.0f;
179
180 if ( m_cFontData->glyphIsWhitespace(glyph) )
181 metrics->x1 = 0.0f;
182 else
183 metrics->x1 = glyphAdvance;
184
185 // The next Glyph just starts right after this one.
186 metrics->advance = glyphAdvance;
187
188 //app.DebugPrintf("[UIBitmapFont] GetGlyphMetrics:\n\tmetrics->advance == %f,\n", metrics->advance);
189
190 // These don't do anything either.
191 metrics->y0 = 0.0f; metrics->y1 = 1.0f;
192
193 return metrics;
194}
195
196//Callback function type that should return true iff the glyph has no visible elements
197rrbool UIBitmapFont::IsGlyphEmpty (S32 glyph)
198{
199 if (m_cFontData->glyphIsWhitespace(glyph)) return true;
200 return false;//app.DebugPrintf("Is glyph %d empty? %s\n",glyph,isEmpty?"TRUE":"FALSE");
201}
202
203//Callback function type for returning the kerning amount for a given pair of glyphs
204F32 UIBitmapFont::GetKerningForGlyphPair(S32 first_glyph,S32 second_glyph)
205{
206 //UIBitmapFont *uiFont = (UIBitmapFont *) user_context;
207 //app.DebugPrintf("Get kerning for glyph pair %d,%d\n",first_glyph,second_glyph);
208
209 // 4J-JEV: Yet another field that doesn't do anything.
210 // Only set out of paranoia.
211 return 0.0f;
212}
213
214//Callback function type used for reporting whether a bitmap supports a given glyph at the given scale
215rrbool UIBitmapFont::CanProvideBitmap(S32 glyph,F32 pixel_scale)
216{
217 //app.DebugPrintf("Can provide bitmap for glyph %d at scale %f? %s\n",glyph,pixel_scale,canProvideBitmap?"TRUE":"FALSE");
218 return true;
219}
220
221// Description
222// Callback function type used for getting the bitmap for a given glyph
223// Parameters
224// glyph The glyph to compute/get the bitmap for
225// pixel_scale The scale factor (pseudo point size) requested by the textfield,adjusted for display resolution
226// bitmap The structure to store the bitmap into
227rrbool UIBitmapFont::GetGlyphBitmap(S32 glyph,F32 pixel_scale,IggyBitmapCharacter *bitmap)
228{
229 //Description
230 // Data structure used to return to Iggy the bitmap to use for a glyph
231 //Members
232 // pixels_one_per_byte - pixels startin with the top-left-most; 0 is transparent and 255 is opaque
233 // width_in_pixels - this is the width of the bitmap data
234 // height_in_pixels - this is the height of the bitmap data
235 // stride_in_bytes - the distance from one row to the next
236 // oversample - this is the amount of oversampling (0 or 1 = not oversample,2 = 2x oversampled,4 = 4x oversampled)
237 // point_sample - if true,the bitmap will be drawn with point sampling; if false,it will be drawn with bilinear
238 // top_left_x - the offset of the top left corner from the character origin
239 // top_left_y - the offset of the top left corner from the character origin
240 // pixel_scale_correct - the pixel_scale at which this character should be displayed at displayed_width_in_pixels
241 // pixel_scale_min - the smallest pixel_scale to allow using this character (scaled down)
242 // pixel_scale_max - the largest pixels cale to allow using this character (scaled up)
243 // user_context_for_free - you can use this to store data to access on the corresponding free call
244
245 int row = 0,col = 0;
246 m_cFontData->getPos(glyph,row,col);
247
248 // Skip to glyph start.
249 bitmap->pixels_one_per_byte = m_cFontData->topLeftPixel(row,col);
250
251 // Choose a reasonable glyph scale.
252 float glyphScale = 1.0f, truePixelScale = 1.0f / m_cFontData->getFontData()->m_fAdvPerPixel;
253 F32 targetPixelScale = pixel_scale;
254 //if(!RenderManager.IsWidescreen())
255 //{
256 // // Fix for different scales in 480
257 // targetPixelScale = pixel_scale*2/3;
258 //}
259 while ( (0.5f + glyphScale) * truePixelScale < targetPixelScale)
260 glyphScale++;
261
262 // 4J-JEV: Debug code to check which font sizes are being used.
263#if (!defined _CONTENT_PACKAGE) && (VERBOSE_FONT_OUTPUT > 0)
264
265 struct DebugData
266 {
267 string name;
268 long scale;
269 long mul;
270
271 bool operator==(const DebugData& dd) const
272 {
273 if ( name.compare(dd.name) != 0 ) return false;
274 else if (scale != dd.scale) return false;
275 else if (mul != dd.mul) return false;
276 else return true;
277 }
278 };
279
280 static long long lastPrint = System::currentTimeMillis();
281 static unordered_set<DebugData> debug_fontSizesRequested;
282
283 {
284 DebugData dData = { m_cFontData->getFontName(), (long) pixel_scale, (long) glyphScale };
285 debug_fontSizesRequested.insert(dData);
286
287 if ( (lastPrint - System::currentTimeMillis()) > VERBOSE_FONT_OUTPUT )
288 {
289 app.DebugPrintf("<UIBitmapFont> Requested font/sizes:\n");
290
291 unordered_set<DebugData>::iterator itr;
292 for ( itr = debug_fontSizesRequested.begin();
293 itr != debug_fontSizesRequested.end();
294 itr++
295 )
296 {
297 app.DebugPrintf("<UIBitmapFont>\t- %s:%i\t(x%i)\n", itr->name.c_str(), itr->scale, itr->mul);
298 }
299
300 lastPrint = System::currentTimeMillis();
301 debug_fontSizesRequested.clear();
302 }
303 }
304#endif
305
306 //app.DebugPrintf("Request glyph_%d (U+%.4X) at %f, converted to %f (%f)\n",
307 // glyph, GetUnicode(glyph), pixel_scale, targetPixelScale, glyphScale);
308
309 // It is not necessary to shrink the glyph width here
310 // as its already been done in 'GetGlyphMetrics' by:
311 // > metrics->x1 = m_kerningTable[glyph] * ratio;
312 bitmap->width_in_pixels = m_cFontData->getFontData()->m_uiGlyphWidth;
313 bitmap->height_in_pixels = m_cFontData->getFontData()->m_uiGlyphHeight;
314
315 /* 4J-JEV: This is to do with glyph placement,
316 * and not the position in the archive.
317 * I don't know why the 0.65 is needed, or what it represents,
318 * although it doesn't look like its the baseline.
319 */
320 bitmap->top_left_x = 0;
321
322 // 4J-PB - this was chopping off the top of the characters, so accented ones were losing a couple of pixels at the top
323 // DaveK has reduced the height of the accented capitalised characters, and we've dropped this from 0.65 to 0.64
324 bitmap->top_left_y = -((S32) m_cFontData->getFontData()->m_uiGlyphHeight) * m_cFontData->getFontData()->m_fAscent;
325
326 bitmap->oversample = 0;
327 bitmap->point_sample = true;
328
329 // 4J-JEV:
330 // pixel_scale == font size chosen in flash.
331 // bitmap->pixel_scale_correct = (float) m_glyphHeight; // Scales the glyph to desired size.
332 // bitmap->pixel_scale_correct = pixel_scale; // Always the same size (not desired size).
333 // bitmap->pixel_scale_correct = pixel_scale * 0.5; // Doubles original size.
334 // bitmap->pixel_scale_correct = pixel_scale * 2; // Halves original size.
335
336 // Actual scale, and possible range of scales.
337 bitmap->pixel_scale_correct = pixel_scale / glyphScale;
338 bitmap->pixel_scale_max = 99.0f;
339 bitmap->pixel_scale_min = 0.0f;
340
341 /* 4J-JEV: Some of Sean's code.
342 int glyphScaleMin = 1;
343 int glyphScaleMax = 3;
344 float actualScale = pixel_scale / glyphScale;
345 bitmap->pixel_scale_correct = actualScale;
346 bitmap->pixel_scale_min = actualScale * glyphScaleMin * 0.999f;
347 bitmap->pixel_scale_max = actualScale * glyphScaleMax * 1.001f; */
348
349 // 4J-JEV: Nothing to do with glyph placement,
350 // entirely to do with cropping your glyph out of an archive.
351 bitmap->stride_in_bytes = m_cFontData->getFontData()->m_uiGlyphMapX;
352
353 // 4J-JEV: Additional information needed to release memory afterwards.
354 bitmap->user_context_for_free = NULL;
355
356 return true;
357}
358
359//Callback function type for freeing a bitmap shape returned by GetGlyphBitmap
360void UIBitmapFont::FreeGlyphBitmap(S32 glyph,F32 pixel_scale,IggyBitmapCharacter *bitmap)
361{
362 // We don't need to free anything,it just comes from the archive.
363 //app.DebugPrintf("Free bitmap for glyph %d at scale %f\n",glyph,pixel_scale);
364}