the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 364 lines 14 kB view raw
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}