Adding loadRange to Font
This commit is contained in:
@@ -27,6 +27,10 @@ typedef GlyphData = {
|
||||
@:autoBuild(lime.Assets.embedFont())
|
||||
class Font {
|
||||
|
||||
|
||||
public var image:Image;
|
||||
public var glyphRects:StringMap<GlyphRect>;
|
||||
|
||||
#if js
|
||||
|
||||
private static var __canvas:CanvasElement;
|
||||
@@ -52,9 +56,54 @@ class Font {
|
||||
|
||||
}
|
||||
|
||||
public function loadGlyphData (size:Int, glyphs:String="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^`'\"/\\&*()[]{}<>|:;_-+=?,. "):GlyphData {
|
||||
public function createImage ():Image {
|
||||
|
||||
var glyphRects = new StringMap<GlyphRect>();
|
||||
glyphRects = new StringMap<GlyphRect>();
|
||||
|
||||
#if (cpp || neko)
|
||||
|
||||
var data = lime_font_create_image (handle);
|
||||
|
||||
if (data == null) {
|
||||
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
||||
for (glyph in cast (data.glyphs, Array<Dynamic>)) {
|
||||
|
||||
glyphRects.set (glyph.char, {
|
||||
x: glyph.x,
|
||||
y: glyph.y,
|
||||
xOffset: glyph.xOffset,
|
||||
yOffset: glyph.yOffset,
|
||||
advance: glyph.advance,
|
||||
width: glyph.width,
|
||||
height: glyph.height,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
glyphRects = data.glyphRects;
|
||||
return new Image (new UInt8Array (data.image.data), data.image.width, data.image.height, data.image.bpp);
|
||||
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
public function loadRange (size:Int, start:Int, end:Int) {
|
||||
|
||||
#if (cpp || neko)
|
||||
|
||||
lime_font_load_range (handle, size, start, end);
|
||||
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
public function loadGlyphs (size:Int, glyphs:String="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^`'\"/\\&*()[]{}<>|:;_-+=?,. ") {
|
||||
|
||||
#if js
|
||||
|
||||
@@ -212,34 +261,6 @@ class Font {
|
||||
#elseif (cpp || neko)
|
||||
|
||||
lime_font_load_glyphs (handle, size, glyphs);
|
||||
var data = lime_font_create_image (handle);
|
||||
|
||||
if (data == null) {
|
||||
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
||||
for (glyph in cast (data.glyphs, Array<Dynamic>)) {
|
||||
|
||||
glyphRects.set (glyph.char, {
|
||||
x: glyph.x,
|
||||
y: glyph.y,
|
||||
xOffset: glyph.xOffset,
|
||||
yOffset: glyph.yOffset,
|
||||
advance: glyph.advance,
|
||||
width: glyph.width,
|
||||
height: glyph.height,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
glyphs: glyphRects,
|
||||
image: new Image (new UInt8Array (data.image.data), data.image.width, data.image.height, data.image.bpp)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
@@ -248,6 +269,7 @@ class Font {
|
||||
#if (cpp || neko)
|
||||
private static var lime_font_load = System.load ("lime", "lime_font_load", 1);
|
||||
private static var lime_font_load_glyphs = System.load ("lime", "lime_font_load_glyphs", 3);
|
||||
private static var lime_font_load_range = System.load ("lime", "lime_font_load_range", 4);
|
||||
private static var lime_font_create_image = System.load ("lime", "lime_font_create_image", 1);
|
||||
#end
|
||||
|
||||
|
||||
@@ -174,11 +174,11 @@ class Text {
|
||||
|
||||
}
|
||||
|
||||
public function fromString (font:Font, text:String) {
|
||||
public function fromString (font:Font, size:Int, text:String) {
|
||||
|
||||
#if (cpp || neko)
|
||||
|
||||
return lime_text_from_string (handle, font.handle, text);
|
||||
return lime_text_from_string (handle, font.handle, size, text);
|
||||
|
||||
#end
|
||||
|
||||
@@ -186,7 +186,7 @@ class Text {
|
||||
|
||||
#if (cpp || neko)
|
||||
private static var lime_text_create = System.load ("lime", "lime_text_create", 3);
|
||||
private static var lime_text_from_string = System.load ("lime", "lime_text_from_string", 3);
|
||||
private static var lime_text_from_string = System.load ("lime", "lime_text_from_string", 4);
|
||||
#end
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -30,21 +30,23 @@ class Main extends Application {
|
||||
|
||||
var text:Text;
|
||||
var font = new Font ("assets/amiri-regular.ttf");
|
||||
font.loadRange (16, 32, 128);
|
||||
font.loadGlyphs (32, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.");
|
||||
font.loadGlyphs (32, "صِفخَلقخودكَمثلالشمسإذبَزَغت—يحظىالضَجيعُبهانَلاءَمِعطار ");
|
||||
var image = font.createImage ();
|
||||
|
||||
text = new Text (RightToLeft, ScriptArabic, "ar");
|
||||
text.fromString (font, "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ");
|
||||
var data = font.loadGlyphData (16, "صِفخَلقخودكَمثلالشمسإذبَزَغت—يحظىالضَجيعُبهانَلاءَمِعطار ");
|
||||
var image = data.image;
|
||||
text.fromString (font, 32, "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ");
|
||||
|
||||
text = new Text (LeftToRight, ScriptLatin, "en");
|
||||
var data = font.loadGlyphData (32, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.");
|
||||
text.fromString (font, "The quick brown fox jumps over the lazy dog.");
|
||||
text.fromString (font, 16, "The quick brown fox jumps over the lazy dog.");
|
||||
|
||||
font = new Font ("assets/fireflysung.ttf");
|
||||
text = new Text (TopToBottom, ScriptHan, "ch");
|
||||
text.fromString (font, "懶惰的姜貓");
|
||||
font.loadGlyphs (32, "懶惰的姜貓");
|
||||
// var image = font.createImage ();
|
||||
|
||||
var chinese = font.loadGlyphData (64, "懶惰的姜貓");
|
||||
text = new Text (TopToBottom, ScriptHan, "ch");
|
||||
text.fromString (font, 32, "懶惰的姜貓");
|
||||
|
||||
switch (context) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user