13 #include "gfx.h" |
13 #include "gfx.h" |
14 #include "string.h" |
14 #include "string.h" |
15 #include "fontcache.h" |
15 #include "fontcache.h" |
16 #include "helpers.hpp" |
16 #include "helpers.hpp" |
17 #include "spriteloader/spriteloader.hpp" |
17 #include "spriteloader/spriteloader.hpp" |
18 #include "blitter/blitter.hpp" |
18 #include "blitter/factory.hpp" |
19 |
19 |
20 #ifdef WITH_FREETYPE |
20 #ifdef WITH_FREETYPE |
21 |
21 |
22 #include <ft2build.h> |
22 #include <ft2build.h> |
23 #include FT_FREETYPE_H |
23 #include FT_FREETYPE_H |
367 { |
367 { |
368 return malloc(size); |
368 return malloc(size); |
369 } |
369 } |
370 |
370 |
371 |
371 |
|
372 /* Check if a glyph should be rendered with antialiasing */ |
|
373 static bool GetFontAAState(FontSize size) |
|
374 { |
|
375 /* AA is only supported for 32 bpp */ |
|
376 if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() != 32) return false; |
|
377 |
|
378 switch (size) { |
|
379 default: NOT_REACHED(); |
|
380 case FS_NORMAL: return _freetype.medium_aa; |
|
381 case FS_SMALL: return _freetype.small_aa; |
|
382 case FS_LARGE: return _freetype.large_aa; |
|
383 } |
|
384 } |
|
385 |
|
386 |
372 const Sprite *GetGlyph(FontSize size, WChar key) |
387 const Sprite *GetGlyph(FontSize size, WChar key) |
373 { |
388 { |
374 FT_Face face = GetFontFace(size); |
389 FT_Face face = GetFontFace(size); |
375 FT_GlyphSlot slot; |
390 FT_GlyphSlot slot; |
376 GlyphEntry new_glyph; |
391 GlyphEntry new_glyph; |
395 glyph = GetGlyphPtr(size, key); |
410 glyph = GetGlyphPtr(size, key); |
396 if (glyph != NULL && glyph->sprite != NULL) return glyph->sprite; |
411 if (glyph != NULL && glyph->sprite != NULL) return glyph->sprite; |
397 |
412 |
398 slot = face->glyph; |
413 slot = face->glyph; |
399 |
414 |
|
415 bool aa = GetFontAAState(size); |
|
416 |
400 FT_Load_Char(face, key, FT_LOAD_DEFAULT); |
417 FT_Load_Char(face, key, FT_LOAD_DEFAULT); |
401 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); |
418 FT_Render_Glyph(face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); |
402 |
419 |
403 /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */ |
420 /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */ |
404 width = max(1, slot->bitmap.width + (size == FS_NORMAL)); |
421 width = max(1, slot->bitmap.width + (size == FS_NORMAL)); |
405 height = max(1, slot->bitmap.rows + (size == FS_NORMAL)); |
422 height = max(1, slot->bitmap.rows + (size == FS_NORMAL)); |
406 |
423 |
415 |
432 |
416 /* Draw shadow for medium size */ |
433 /* Draw shadow for medium size */ |
417 if (size == FS_NORMAL) { |
434 if (size == FS_NORMAL) { |
418 for (y = 0; y < slot->bitmap.rows; y++) { |
435 for (y = 0; y < slot->bitmap.rows; y++) { |
419 for (x = 0; x < slot->bitmap.width; x++) { |
436 for (x = 0; x < slot->bitmap.width; x++) { |
420 if (HASBIT(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { |
437 if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HASBIT(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { |
421 sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR; |
438 sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR; |
|
439 sprite.data[1 + x + (1 + y) * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF; |
422 } |
440 } |
423 } |
441 } |
424 } |
442 } |
425 } |
443 } |
426 |
444 |
427 for (y = 0; y < slot->bitmap.rows; y++) { |
445 for (y = 0; y < slot->bitmap.rows; y++) { |
428 for (x = 0; x < slot->bitmap.width; x++) { |
446 for (x = 0; x < slot->bitmap.width; x++) { |
429 if (HASBIT(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { |
447 if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HASBIT(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { |
430 sprite.data[x + y * sprite.width].m = FACE_COLOUR; |
448 sprite.data[x + y * sprite.width].m = FACE_COLOUR; |
|
449 sprite.data[x + y * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF; |
431 } |
450 } |
432 } |
451 } |
433 } |
452 } |
434 |
453 |
435 new_glyph.sprite = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, AllocateFont); |
454 new_glyph.sprite = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, AllocateFont); |