Adding loadRange to Font

This commit is contained in:
MattTuttle
2014-07-30 17:08:16 -05:00
parent 83bb9d9b66
commit 200e953641
6 changed files with 157 additions and 68 deletions

View File

@@ -17,6 +17,7 @@ namespace lime {
typedef struct {
unsigned long codepoint;
unsigned int size;
FT_UInt index;
FT_Pos height;
@@ -29,13 +30,16 @@ namespace lime {
public:
Font (const char *fontFace);
void LoadGlyphs (int size, const char *glyphs);
value createImage (Image *image);
void LoadGlyphs (size_t size, const char *glyphs);
void LoadRange (size_t size, unsigned long start, unsigned long end);
value renderToImage (Image *image);
FT_Face face;
private:
bool InsertCodepoint (unsigned long codepoint, size_t size);
std::list<GlyphInfo> glyphList;

View File

@@ -30,7 +30,6 @@
#include <ui/TouchEvent.h>
#include <ui/Window.h>
#include <ui/WindowEvent.h>
#include <utils/CFFIValue.h>
#include <vm/NekoVM.h>
@@ -168,13 +167,25 @@ namespace lime {
}
value lime_font_load_range (value fontHandle, value size, value start, value end) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
font->LoadRange (val_int (size), val_int (start), val_int (end));
#endif
return alloc_null ();
}
value lime_font_create_image (value fontHandle) {
#ifdef LIME_FREETYPE
Image image;
Font *font = (Font*)(intptr_t)val_float (fontHandle);
value data = alloc_empty_object ();
alloc_field (data, val_id ("glyphs"), font->createImage (&image));
alloc_field (data, val_id ("glyphs"), font->renderToImage (&image));
alloc_field (data, val_id ("image"), image.Value ());
return data;
#else
@@ -207,7 +218,7 @@ namespace lime {
}
value lime_text_from_string (value textHandle, value fontHandle, value textString) {
value lime_text_from_string (value textHandle, value fontHandle, value size, value textString) {
#if defined(LIME_FREETYPE) && defined(LIME_HARFBUZZ)
Image image;
@@ -368,9 +379,10 @@ namespace lime {
DEFINE_PRIM (lime_image_load, 1);
DEFINE_PRIM (lime_font_load, 1);
DEFINE_PRIM (lime_font_load_glyphs, 3);
DEFINE_PRIM (lime_font_load_range, 4);
DEFINE_PRIM (lime_font_create_image, 1);
DEFINE_PRIM (lime_text_create, 3);
DEFINE_PRIM (lime_text_from_string, 3);
DEFINE_PRIM (lime_text_from_string, 4);
DEFINE_PRIM (lime_key_event_manager_register, 2);
DEFINE_PRIM (lime_lzma_encode, 1);
DEFINE_PRIM (lime_lzma_decode, 1);
@@ -395,4 +407,4 @@ extern "C" int lime_register_prims () {
return 0;
}
}

View File

@@ -134,7 +134,7 @@ namespace lime {
bool CompareGlyphCodepoint (const GlyphInfo &a, const GlyphInfo &b) {
return a.codepoint < b.codepoint;
return a.codepoint < b.codepoint || a.size < b.size;
}
@@ -188,8 +188,59 @@ namespace lime {
}
bool Font::InsertCodepoint (unsigned long codepoint, size_t size) {
void Font::LoadGlyphs (int size, const char *glyphs) {
GlyphInfo info;
info.codepoint = codepoint;
// search for duplicates, if any
std::list<GlyphInfo>::iterator first = glyphList.begin ();
first = std::lower_bound (first, glyphList.end (), info, CompareGlyphCodepoint);
// skip duplicates unless they are different sizes
if (codepoint < (*first).codepoint ||
(codepoint == (*first).codepoint && size != (*first).size)) {
info.size = size;
info.index = FT_Get_Char_Index (face, codepoint);
if (FT_Load_Glyph (face, info.index, FT_LOAD_DEFAULT) != 0) return false;
info.height = face->glyph->metrics.height;
glyphList.insert (first, info);
return true;
}
return false;
}
void Font::LoadRange (size_t size, unsigned long start, unsigned long end) {
size_t hdpi = 72;
size_t vdpi = 72;
size_t hres = 100;
FT_Matrix matrix = {
(int)((1.0/hres) * 0x10000L),
(int)((0.0) * 0x10000L),
(int)((0.0) * 0x10000L),
(int)((1.0) * 0x10000L)
};
FT_Set_Char_Size (face, 0, (int)(size*64), (int)(hdpi * hres), vdpi);
FT_Set_Transform (face, &matrix, NULL);
for (unsigned long codepoint = start; codepoint < end; codepoint++) {
InsertCodepoint (codepoint, size);
}
}
void Font::LoadGlyphs (size_t size, const char *glyphs) {
size_t hdpi = 72;
size_t vdpi = 72;
@@ -207,29 +258,13 @@ namespace lime {
char *g = (char*)glyphs;
while (*g != 0) {
GlyphInfo info;
bool found = false;
info.codepoint = readNextChar(g);
std::list<GlyphInfo>::iterator first = glyphList.begin ();
first = std::lower_bound (first, glyphList.end (), info, CompareGlyphCodepoint);
if (info.codepoint < (*first).codepoint) {
info.index = FT_Get_Char_Index (face, info.codepoint);
if (FT_Load_Glyph (face, info.index, FT_LOAD_DEFAULT) != 0) continue;
info.height = face->glyph->metrics.height;
glyphList.insert (first, info);
}
InsertCodepoint (readNextChar(g), size);
}
}
value Font::createImage (Image *image) {
value Font::renderToImage (Image *image) {
if (!init) {
@@ -254,8 +289,22 @@ namespace lime {
value rects = alloc_array (glyphList.size());
int rectsIndex = 0;
size_t hdpi = 72;
size_t vdpi = 72;
size_t hres = 100;
FT_Matrix matrix = {
(int)((1.0/hres) * 0x10000L),
(int)((0.0) * 0x10000L),
(int)((0.0) * 0x10000L),
(int)((1.0) * 0x10000L)
};
for (std::list<GlyphInfo>::iterator it = glyphList.begin(); it != glyphList.end(); it++) {
// recalculate the character size for each glyph since it will vary
FT_Set_Char_Size (face, 0, (int)((*it).size*64), (int)(hdpi * hres), vdpi);
FT_Set_Transform (face, &matrix, NULL);
FT_Load_Glyph (face, (*it).index, FT_LOAD_DEFAULT);
if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL) != 0) continue;