comparison mde/font/FontTexture.d @ 137:9f035cd139c6

BIG commit. Major change: old Options class is gone, all content values are loaded and saved automatically. All options updated to reflect this, some changed. Content restrutured a lot: New IContent module, Content module includes more functionality. New ContentLoader module to manage content loading/saving/translation. Translation module moved to content dir and cut down to reflect current usage. File format unchanged except renames: FontOptions -> Font, VideoOptions -> Screen. Font render mode and LCD filter options are now enums. GUI loading needs to create content (and set type for enums), but doesn't save/load value. Some setup of mainSchedule moved to mde.mainLoop. Content callbacks are called on content change now. ContentLists are set up implicitly from content symbols. Not as fast but much easier! Bug-fix in the new MTTagReader. Renamed MT *Reader maker functions to avoid confusion in paths.d. New mde.setup.logger module to allow logger setup before any other module's static this().
author Diggory Hardy <diggory.hardy@gmail.com>
date Sat, 07 Feb 2009 12:46:03 +0000
parents ee209602770d
children e45226d3deae
comparison
equal deleted inserted replaced
136:4084f07f2c7a 137:9f035cd139c6
23 * coords are cartesian (i.e. y increases upwards), although largely this is too abstract to 23 * coords are cartesian (i.e. y increases upwards), although largely this is too abstract to
24 * matter. However, for the model/world coords, y increases downwards. */ 24 * matter. However, for the model/world coords, y increases downwards. */
25 module mde.font.FontTexture; 25 module mde.font.FontTexture;
26 26
27 import mde.types.Colour; 27 import mde.types.Colour;
28 import mde.lookup.Options; 28 import mde.content.AStringContent;
29 import mde.font.exception; 29 import mde.font.exception;
30 30
31 import derelict.freetype.ft; 31 import derelict.freetype.ft;
32 import derelict.opengl.gl; 32 import derelict.opengl.gl;
33 33
238 logger.error ("FontTexture.addGlyph failed!"); 238 logger.error ("FontTexture.addGlyph failed!");
239 239
240 auto gi = FT_Get_Char_Index (face, chr); 240 auto gi = FT_Get_Char_Index (face, chr);
241 auto g = face.glyph; 241 auto g = face.glyph;
242 242
243 // Use renderMode from options, masking bits which are allowable: 243 if (FT_Load_Glyph (face, gi, FT_LOAD_RENDER | fontOpts.modeFlag))
244 if (FT_Load_Glyph (face, gi, FT_LOAD_RENDER | (fontOpts.renderMode() & 0xF0000)))
245 throw new fontGlyphException ("Unable to render glyph"); 244 throw new fontGlyphException ("Unable to render glyph");
246 245
247 auto b = g.bitmap; 246 auto b = g.bitmap;
248 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 247 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
249 //glPixelStorei (GL_UNPACK_ROW_LENGTH, b.pitch); 248 //glPixelStorei (GL_UNPACK_ROW_LENGTH, b.pitch);
290 buffer[i*b.width + j + 0] = b.buffer[i*b.pitch + j + 0]; 289 buffer[i*b.width + j + 0] = b.buffer[i*b.pitch + j + 0];
291 buffer[i*b.width + j + 1] = b.buffer[i*b.pitch + j + 1]; 290 buffer[i*b.width + j + 1] = b.buffer[i*b.pitch + j + 1];
292 buffer[i*b.width + j + 2] = b.buffer[i*b.pitch + j + 2]; 291 buffer[i*b.width + j + 2] = b.buffer[i*b.pitch + j + 2];
293 } 292 }
294 293
295 format = (fontOpts.renderMode() & RENDER_LCD_BGR) ? GL_BGR : GL_RGB; 294 format = (fontOpts.mode() >= 4) ? GL_BGR : GL_RGB;
296 } else if (b.pixel_mode == FT_Pixel_Mode.FT_PIXEL_MODE_LCD_V) { 295 } else if (b.pixel_mode == FT_Pixel_Mode.FT_PIXEL_MODE_LCD_V) {
297 // NOTE: Notes above apply. But in this case converting the buffers seems essential. 296 // NOTE: Notes above apply. But in this case converting the buffers seems essential.
298 buffer = new ubyte[b.width*b.rows]; 297 buffer = new ubyte[b.width*b.rows];
299 for (uint i = 0; i < b.rows; ++i) 298 for (uint i = 0; i < b.rows; ++i)
300 for (uint j = 0; j < b.width; ++j) 299 for (uint j = 0; j < b.width; ++j)
302 // i/3 is the "real" row, b.width*3 is our width (with subpixels), j is column, 301 // i/3 is the "real" row, b.width*3 is our width (with subpixels), j is column,
303 // i%3 is sub-pixel (R/G/B). i/3*3 necessary to round to multiple of 3 302 // i%3 is sub-pixel (R/G/B). i/3*3 necessary to round to multiple of 3
304 buffer[i/3*b.width*3 + 3*j + i%3] = b.buffer[i*b.pitch + j]; 303 buffer[i/3*b.width*3 + 3*j + i%3] = b.buffer[i*b.pitch + j];
305 } 304 }
306 305
307 format = (fontOpts.renderMode() & RENDER_LCD_BGR) ? GL_BGR : GL_RGB; 306 format = (fontOpts.mode() >= 4) ? GL_BGR : GL_RGB;
308 } else 307 } else
309 throw new fontGlyphException ("Unsupported freetype bitmap format"); 308 throw new fontGlyphException ("Unsupported freetype bitmap format");
310 309
311 glTexSubImage2D(GL_TEXTURE_2D, 0, 310 glTexSubImage2D(GL_TEXTURE_2D, 0,
312 ga.x, ga.y, 311 ga.x, ga.y,
443 } 442 }
444 Line[] lines; 443 Line[] lines;
445 int nextYPos = 0; // y position for next created line (0 for first line) 444 int nextYPos = 0; // y position for next created line (0 for first line)
446 } 445 }
447 446
448 // this bit of renderMode, if set, means read glyph as BGR not RGB when using LCD rendering 447 struct fontOpts {
449 enum { RENDER_LCD_BGR = 1 << 30 } 448 static:
450 FontOptions fontOpts; 449 EnumContent mode;
451 class FontOptions : Options { 450 int modeFlag;
452 /* renderMode have one of the following values, possibly with bit 31 set (see RENDER_LCD_BGR): 451 /* lcdFilter should come from enum FT_LcdFilter:
453 * FT_LOAD_TARGET_NORMAL (0x00000) 452 * FT_LCD_FILTER_NONE (0), FT_LCD_FILTER_DEFAULT (1), FT_LCD_FILTER_LIGHT (2) */
454 * FT_LOAD_TARGET_LIGHT (0x10000) 453 EnumContent lcdFilter;
455 * FT_LOAD_TARGET_LCD (0x30000) 454 IntContent defaultSize;
456 * FT_LOAD_TARGET_LCD_V (0x40000) 455 StringContent defaultFont;
457 * The mode FT_LOAD_TARGET_MONO (0x20000) is unsupported.
458 *
459 * lcdFilter should come from enum FT_LcdFilter:
460 * FT_LCD_FILTER_NONE (0), FT_LCD_FILTER_DEFAULT (1), FT_LCD_FILTER_LIGHT (2) */
461 mixin (impl!("int renderMode, lcdFilter, defaultSize; char[] defaultFont;"));
462
463 void validate() {
464 }
465 456
466 static this() { 457 static this() {
467 fontOpts = new FontOptions ("FontOptions"); 458 mode = new EnumContent ("Font.mode", ["normal"[],"light","lcd","lcd_v","lcd_bgr","lcd_bgr_v"]);
459 lcdFilter = new EnumContent ("Font.lcdFilter", ["none"[],"default","light"]);
460 defaultSize = new IntContent ("Font.defaultSize");
461 defaultFont = new StringContent ("Font.defaultFont");
462 mode.addCallback (delegate void(Content) {
463 /* modeFlag should have one of the following values:
464 * FT_LOAD_TARGET_NORMAL (0x00000)
465 * FT_LOAD_TARGET_LIGHT (0x10000)
466 * FT_LOAD_TARGET_LCD (0x30000)
467 * FT_LOAD_TARGET_LCD_V (0x40000)
468 * The mode FT_LOAD_TARGET_MONO (0x20000) is unsupported. */
469 modeFlag = fontOpts.mode();
470 if (modeFlag == 2 || modeFlag == 4) modeFlag = 0x30000;
471 else if (modeFlag == 3 || modeFlag == 5) modeFlag = 0x40000;
472 else modeFlag <<= 16;
473 });
468 } 474 }
469 } 475 }
470 476
471 struct GlyphAttribs { 477 struct GlyphAttribs {
472 int x, y; // position within texture 478 int x, y; // position within texture