Fixed Arabic text rendering using Harfbuzz. Updated TextRendering sample.

This commit is contained in:
Daniel Uranga
2015-01-23 12:18:52 -03:00
committed by MattTuttle
parent 11008a1214
commit 5b2287a374
4 changed files with 26 additions and 11 deletions

View File

@@ -57,6 +57,7 @@ namespace lime {
void LoadRange (unsigned long start, unsigned long end); void LoadRange (unsigned long start, unsigned long end);
value RenderToImage (ImageBuffer *image); value RenderToImage (ImageBuffer *image);
void SetSize (size_t size); void SetSize (size_t size);
bool InsertCodepointFromIndex (unsigned long codepoint);
#ifdef LIME_FREETYPE #ifdef LIME_FREETYPE
FT_Face face; FT_Face face;
@@ -67,6 +68,7 @@ namespace lime {
private: private:
bool InsertCodepoint (unsigned long codepoint); bool InsertCodepoint (unsigned long codepoint);
bool InsertCodepoint (unsigned long codepoint, bool b);
std::list<GlyphInfo> glyphList; std::list<GlyphInfo> glyphList;
size_t mSize; size_t mSize;

View File

@@ -529,7 +529,15 @@ namespace lime {
} }
bool Font::InsertCodepointFromIndex (unsigned long codepoint) {
return InsertCodepoint(codepoint, false);
}
bool Font::InsertCodepoint (unsigned long codepoint) { bool Font::InsertCodepoint (unsigned long codepoint) {
return InsertCodepoint(codepoint, true);
}
bool Font::InsertCodepoint (unsigned long codepoint, bool b) {
GlyphInfo info; GlyphInfo info;
info.codepoint = codepoint; info.codepoint = codepoint;
@@ -543,8 +551,12 @@ namespace lime {
// if (codepoint < (*first).codepoint || // if (codepoint < (*first).codepoint ||
// (codepoint == (*first).codepoint && mSize != (*first).size)) { // (codepoint == (*first).codepoint && mSize != (*first).size)) {
info.index = FT_Get_Char_Index (face, codepoint);
if (b) {
info.index = FT_Get_Char_Index (face, codepoint);
} else {
info.index = codepoint;
}
if (FT_Load_Glyph (face, info.index, FT_LOAD_DEFAULT) != 0) return false; if (FT_Load_Glyph (face, info.index, FT_LOAD_DEFAULT) != 0) return false;
info.height = face->glyph->metrics.height; info.height = face->glyph->metrics.height;

View File

@@ -11,7 +11,8 @@ namespace lime {
if (strlen(script) != 4) return; if (strlen(script) != 4) return;
hb_script_t tag = (hb_script_t)HB_TAG (script[0], script[1], script[2], script[3]); //hb_script_t tag = (hb_script_t)HB_TAG (script[0], script[1], script[2], script[3]);
hb_script_t tag = hb_script_from_string (script, -1);
buffer = hb_buffer_create (); buffer = hb_buffer_create ();
hb_buffer_set_direction (buffer, (hb_direction_t)direction); hb_buffer_set_direction (buffer, (hb_direction_t)direction);
@@ -48,6 +49,7 @@ namespace lime {
for (int i = 0; i < glyph_count; i++) { for (int i = 0; i < glyph_count; i++) {
font->InsertCodepointFromIndex(glyph_info[i].codepoint);
hb_glyph_position_t pos = glyph_pos[i]; hb_glyph_position_t pos = glyph_pos[i];
value obj = alloc_empty_object (); value obj = alloc_empty_object ();

View File

@@ -18,10 +18,11 @@ class TextField {
private var size:Int; private var size:Int;
private var text:String; private var text:String;
private var image:ImageBuffer; private var image:ImageBuffer;
private var points:Array<TextFormat.PosInfo>;
public function new (text:String, size:Int, textFormat:TextFormat, font:Font, context:RenderContext, x:Float=0, y:Float=0) { public function new (text:String, size:Int, textFormat:TextFormat, font:Font, context:RenderContext, x:Float=0, y:Float=0) {
points = textFormat.fromString (font, size, text);
font.loadGlyphs (size, text); font.loadGlyphs (size, text);
image = font.createImage (); image = font.createImage ();
this.text = text; this.text = text;
@@ -34,8 +35,6 @@ class TextField {
public function init (context:RenderContext, textFormat:TextFormat, font:Font, x:Float, y:Float) { public function init (context:RenderContext, textFormat:TextFormat, font:Font, x:Float, y:Float) {
var points = textFormat.fromString (font, size, text);
switch (context) { switch (context) {
// case CANVAS (context): // case CANVAS (context):
@@ -202,20 +201,20 @@ class Main extends Application {
public override function init (context:RenderContext):Void { public override function init (context:RenderContext):Void {
textFields.push(new TextField ("صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ", 24, textFields.push(new TextField ("صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ", 16,
new TextFormat (RightToLeft, ScriptArabic, "ar"), new TextFormat (RightToLeft, ScriptArabic, "ar"),
new Font ("assets/amiri-regular.ttf"), Font.fromFile ("assets/amiri-regular.ttf"),
context, window.width - 20, 100)); context, window.width, 80));
textFields.push(new TextField ("The quick brown fox jumps over the lazy dog.", 16, textFields.push(new TextField ("The quick brown fox jumps over the lazy dog.", 16,
new TextFormat (LeftToRight, ScriptLatin, "en"), new TextFormat (LeftToRight, ScriptLatin, "en"),
new Font ("assets/amiri-regular.ttf"), Font.fromFile ("assets/amiri-regular.ttf"),
context, 20, 20)); context, 20, 20));
textFields.push(new TextField ("", 32, textFields.push(new TextField ("", 32,
new TextFormat (TopToBottom, ScriptHan, "zh"), new TextFormat (TopToBottom, ScriptHan, "zh"),
new Font ("assets/fireflysung.ttf"), Font.fromFile ("assets/fireflysung.ttf"),
context, 50, 150)); context, 50, 170));
switch (context) { switch (context) {