Adding loadRange to Font
This commit is contained in:
@@ -27,6 +27,10 @@ typedef GlyphData = {
|
|||||||
@:autoBuild(lime.Assets.embedFont())
|
@:autoBuild(lime.Assets.embedFont())
|
||||||
class Font {
|
class Font {
|
||||||
|
|
||||||
|
|
||||||
|
public var image:Image;
|
||||||
|
public var glyphRects:StringMap<GlyphRect>;
|
||||||
|
|
||||||
#if js
|
#if js
|
||||||
|
|
||||||
private static var __canvas:CanvasElement;
|
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
|
#if js
|
||||||
|
|
||||||
@@ -212,34 +261,6 @@ class Font {
|
|||||||
#elseif (cpp || neko)
|
#elseif (cpp || neko)
|
||||||
|
|
||||||
lime_font_load_glyphs (handle, size, glyphs);
|
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
|
#end
|
||||||
|
|
||||||
@@ -248,6 +269,7 @@ class Font {
|
|||||||
#if (cpp || neko)
|
#if (cpp || neko)
|
||||||
private static var lime_font_load = System.load ("lime", "lime_font_load", 1);
|
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_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);
|
private static var lime_font_create_image = System.load ("lime", "lime_font_create_image", 1);
|
||||||
#end
|
#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)
|
#if (cpp || neko)
|
||||||
|
|
||||||
return lime_text_from_string (handle, font.handle, text);
|
return lime_text_from_string (handle, font.handle, size, text);
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ class Text {
|
|||||||
|
|
||||||
#if (cpp || neko)
|
#if (cpp || neko)
|
||||||
private static var lime_text_create = System.load ("lime", "lime_text_create", 3);
|
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
|
#end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace lime {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
unsigned long codepoint;
|
unsigned long codepoint;
|
||||||
|
unsigned int size;
|
||||||
FT_UInt index;
|
FT_UInt index;
|
||||||
FT_Pos height;
|
FT_Pos height;
|
||||||
|
|
||||||
@@ -29,13 +30,16 @@ namespace lime {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Font (const char *fontFace);
|
Font (const char *fontFace);
|
||||||
void LoadGlyphs (int size, const char *glyphs);
|
void LoadGlyphs (size_t size, const char *glyphs);
|
||||||
value createImage (Image *image);
|
void LoadRange (size_t size, unsigned long start, unsigned long end);
|
||||||
|
value renderToImage (Image *image);
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool InsertCodepoint (unsigned long codepoint, size_t size);
|
||||||
|
|
||||||
std::list<GlyphInfo> glyphList;
|
std::list<GlyphInfo> glyphList;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include <ui/TouchEvent.h>
|
#include <ui/TouchEvent.h>
|
||||||
#include <ui/Window.h>
|
#include <ui/Window.h>
|
||||||
#include <ui/WindowEvent.h>
|
#include <ui/WindowEvent.h>
|
||||||
#include <utils/CFFIValue.h>
|
|
||||||
#include <vm/NekoVM.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) {
|
value lime_font_create_image (value fontHandle) {
|
||||||
|
|
||||||
#ifdef LIME_FREETYPE
|
#ifdef LIME_FREETYPE
|
||||||
Image image;
|
Image image;
|
||||||
Font *font = (Font*)(intptr_t)val_float (fontHandle);
|
Font *font = (Font*)(intptr_t)val_float (fontHandle);
|
||||||
value data = alloc_empty_object ();
|
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 ());
|
alloc_field (data, val_id ("image"), image.Value ());
|
||||||
return data;
|
return data;
|
||||||
#else
|
#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)
|
#if defined(LIME_FREETYPE) && defined(LIME_HARFBUZZ)
|
||||||
Image image;
|
Image image;
|
||||||
@@ -368,9 +379,10 @@ namespace lime {
|
|||||||
DEFINE_PRIM (lime_image_load, 1);
|
DEFINE_PRIM (lime_image_load, 1);
|
||||||
DEFINE_PRIM (lime_font_load, 1);
|
DEFINE_PRIM (lime_font_load, 1);
|
||||||
DEFINE_PRIM (lime_font_load_glyphs, 3);
|
DEFINE_PRIM (lime_font_load_glyphs, 3);
|
||||||
|
DEFINE_PRIM (lime_font_load_range, 4);
|
||||||
DEFINE_PRIM (lime_font_create_image, 1);
|
DEFINE_PRIM (lime_font_create_image, 1);
|
||||||
DEFINE_PRIM (lime_text_create, 3);
|
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_key_event_manager_register, 2);
|
||||||
DEFINE_PRIM (lime_lzma_encode, 1);
|
DEFINE_PRIM (lime_lzma_encode, 1);
|
||||||
DEFINE_PRIM (lime_lzma_decode, 1);
|
DEFINE_PRIM (lime_lzma_decode, 1);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ namespace lime {
|
|||||||
|
|
||||||
bool CompareGlyphCodepoint (const GlyphInfo &a, const GlyphInfo &b) {
|
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 hdpi = 72;
|
||||||
size_t vdpi = 72;
|
size_t vdpi = 72;
|
||||||
@@ -207,29 +258,13 @@ namespace lime {
|
|||||||
char *g = (char*)glyphs;
|
char *g = (char*)glyphs;
|
||||||
while (*g != 0) {
|
while (*g != 0) {
|
||||||
|
|
||||||
GlyphInfo info;
|
InsertCodepoint (readNextChar(g), size);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value Font::createImage (Image *image) {
|
value Font::renderToImage (Image *image) {
|
||||||
|
|
||||||
if (!init) {
|
if (!init) {
|
||||||
|
|
||||||
@@ -254,8 +289,22 @@ namespace lime {
|
|||||||
value rects = alloc_array (glyphList.size());
|
value rects = alloc_array (glyphList.size());
|
||||||
int rectsIndex = 0;
|
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++) {
|
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);
|
FT_Load_Glyph (face, (*it).index, FT_LOAD_DEFAULT);
|
||||||
|
|
||||||
if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL) != 0) continue;
|
if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL) != 0) continue;
|
||||||
|
|||||||
@@ -30,21 +30,23 @@ class Main extends Application {
|
|||||||
|
|
||||||
var text:Text;
|
var text:Text;
|
||||||
var font = new Font ("assets/amiri-regular.ttf");
|
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 = new Text (RightToLeft, ScriptArabic, "ar");
|
||||||
text.fromString (font, "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ");
|
text.fromString (font, 32, "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ");
|
||||||
var data = font.loadGlyphData (16, "صِفخَلقخودكَمثلالشمسإذبَزَغت—يحظىالضَجيعُبهانَلاءَمِعطار ");
|
|
||||||
var image = data.image;
|
|
||||||
|
|
||||||
text = new Text (LeftToRight, ScriptLatin, "en");
|
text = new Text (LeftToRight, ScriptLatin, "en");
|
||||||
var data = font.loadGlyphData (32, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.");
|
text.fromString (font, 16, "The quick brown fox jumps over the lazy dog.");
|
||||||
text.fromString (font, "The quick brown fox jumps over the lazy dog.");
|
|
||||||
|
|
||||||
font = new Font ("assets/fireflysung.ttf");
|
font = new Font ("assets/fireflysung.ttf");
|
||||||
text = new Text (TopToBottom, ScriptHan, "ch");
|
font.loadGlyphs (32, "懶惰的姜貓");
|
||||||
text.fromString (font, "懶惰的姜貓");
|
// var image = font.createImage ();
|
||||||
|
|
||||||
var chinese = font.loadGlyphData (64, "懶惰的姜貓");
|
text = new Text (TopToBottom, ScriptHan, "ch");
|
||||||
|
text.fromString (font, 32, "懶惰的姜貓");
|
||||||
|
|
||||||
switch (context) {
|
switch (context) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user