src/fontcache.cpp
branchNewGRF_ports
changeset 6720 35756db7e577
parent 6719 4cc327ad39d5
child 6871 5a9dc001e1ad
equal deleted inserted replaced
6719:4cc327ad39d5 6720:35756db7e577
    12 #include "spritecache.h"
    12 #include "spritecache.h"
    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"
       
    18 #include "blitter/factory.hpp"
    17 
    19 
    18 #ifdef WITH_FREETYPE
    20 #ifdef WITH_FREETYPE
    19 
    21 
    20 #include <ft2build.h>
    22 #include <ft2build.h>
    21 #include FT_FREETYPE_H
    23 #include FT_FREETYPE_H
   359 	DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, size);
   361 	DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, size);
   360 	_glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite;
   362 	_glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite;
   361 	_glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].width  = glyph->width;
   363 	_glyph_ptr[size][GB(key, 8, 8)][GB(key, 0, 8)].width  = glyph->width;
   362 }
   364 }
   363 
   365 
       
   366 void *AllocateFont(size_t size)
       
   367 {
       
   368 	return malloc(size);
       
   369 }
       
   370 
       
   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 
   364 
   386 
   365 const Sprite *GetGlyph(FontSize size, WChar key)
   387 const Sprite *GetGlyph(FontSize size, WChar key)
   366 {
   388 {
   367 	FT_Face face = GetFontFace(size);
   389 	FT_Face face = GetFontFace(size);
   368 	FT_GlyphSlot slot;
   390 	FT_GlyphSlot slot;
   369 	GlyphEntry new_glyph;
   391 	GlyphEntry new_glyph;
   370 	GlyphEntry *glyph;
   392 	GlyphEntry *glyph;
   371 	Sprite *sprite;
   393 	SpriteLoader::Sprite sprite;
   372 	int width;
   394 	int width;
   373 	int height;
   395 	int height;
   374 	int x;
   396 	int x;
   375 	int y;
   397 	int y;
   376 	int y_adj;
   398 	int y_adj;
   388 	glyph = GetGlyphPtr(size, key);
   410 	glyph = GetGlyphPtr(size, key);
   389 	if (glyph != NULL && glyph->sprite != NULL) return glyph->sprite;
   411 	if (glyph != NULL && glyph->sprite != NULL) return glyph->sprite;
   390 
   412 
   391 	slot = face->glyph;
   413 	slot = face->glyph;
   392 
   414 
       
   415 	bool aa = GetFontAAState(size);
       
   416 
   393 	FT_Load_Char(face, key, FT_LOAD_DEFAULT);
   417 	FT_Load_Char(face, key, FT_LOAD_DEFAULT);
   394 	FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
   418 	FT_Render_Glyph(face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
   395 
   419 
   396 	/* 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 */
   397 	width  = max(1, slot->bitmap.width + (size == FS_NORMAL));
   421 	width  = max(1, slot->bitmap.width + (size == FS_NORMAL));
   398 	height = max(1, slot->bitmap.rows  + (size == FS_NORMAL));
   422 	height = max(1, slot->bitmap.rows  + (size == FS_NORMAL));
   399 
   423 
   400 	/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
   424 	/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
   401 	sprite = (Sprite*)calloc(width * height + 8, 1);
   425 	sprite.data = CallocT<SpriteLoader::CommonPixel>(width * height);
   402 	sprite->info   = 1;
   426 	sprite.width = width;
   403 	sprite->width  = width;
   427 	sprite.height = height;
   404 	sprite->height = height;
   428 	sprite.x_offs = slot->bitmap_left;
   405 	sprite->x_offs = slot->bitmap_left;
       
   406 	// XXX 2 should be determined somehow... it's right for the normal face
   429 	// XXX 2 should be determined somehow... it's right for the normal face
   407 	y_adj = (size == FS_NORMAL) ? 2 : 0;
   430 	y_adj = (size == FS_NORMAL) ? 2 : 0;
   408 	sprite->y_offs = GetCharacterHeight(size) - slot->bitmap_top - y_adj;
   431 	sprite.y_offs = GetCharacterHeight(size) - slot->bitmap_top - y_adj;
   409 
   432 
   410 	/* Draw shadow for medium size */
   433 	/* Draw shadow for medium size */
   411 	if (size == FS_NORMAL) {
   434 	if (size == FS_NORMAL) {
   412 		for (y = 0; y < slot->bitmap.rows; y++) {
   435 		for (y = 0; y < slot->bitmap.rows; y++) {
   413 			for (x = 0; x < slot->bitmap.width; x++) {
   436 			for (x = 0; x < slot->bitmap.width; x++) {
   414 				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))) {
   415 					sprite->data[1 + x + (1 + y) * sprite->width] = 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;
   416 				}
   440 				}
   417 			}
   441 			}
   418 		}
   442 		}
   419 	}
   443 	}
   420 
   444 
   421 	for (y = 0; y < slot->bitmap.rows; y++) {
   445 	for (y = 0; y < slot->bitmap.rows; y++) {
   422 		for (x = 0; x < slot->bitmap.width; x++) {
   446 		for (x = 0; x < slot->bitmap.width; x++) {
   423 			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))) {
   424 				sprite->data[x + y * sprite->width] = 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;
   425 			}
   450 			}
   426 		}
   451 		}
   427 	}
   452 	}
   428 
   453 
   429 	new_glyph.sprite = sprite;
   454 	new_glyph.sprite = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, AllocateFont);
       
   455 	free(sprite.data);
   430 	new_glyph.width  = (slot->advance.x >> 6) + (size != FS_NORMAL);
   456 	new_glyph.width  = (slot->advance.x >> 6) + (size != FS_NORMAL);
   431 
   457 
   432 	SetGlyphPtr(size, key, &new_glyph);
   458 	SetGlyphPtr(size, key, &new_glyph);
   433 
   459 
   434 	return sprite;
   460 	return new_glyph.sprite;
   435 }
   461 }
   436 
   462 
   437 
   463 
   438 uint GetGlyphWidth(FontSize size, WChar key)
   464 uint GetGlyphWidth(FontSize size, WChar key)
   439 {
   465 {