Add more Font details, fix @:font embedding

This commit is contained in:
Joshua Granick
2015-03-09 04:57:13 -07:00
parent 9804f1970a
commit a406401848
10 changed files with 350 additions and 678 deletions

View File

@@ -5,8 +5,8 @@ package lime;
import haxe.Json;
import haxe.Unserializer;
import lime.audio.AudioBuffer;
import lime.graphics.Font;
import lime.graphics.Image;
import lime.text.Font;
import lime.utils.ByteArray;
@:access(lime.AssetLibrary)
@@ -1450,11 +1450,7 @@ class Assets {
super();
#if openfl_html5_dom
nmeFromBytes (haxe.Resource.getBytes (resourceName));
#else
__fromBytes (haxe.Resource.getBytes (resourceName));
#end
__fromBytes (lime.utils.ByteArray.fromBytes (haxe.Resource.getBytes (resourceName)));
};
@@ -1519,9 +1515,9 @@ class Assets {
var constructor = macro {
super();
super ();
fontName = resourceName;
__fromBytes (lime.utils.ByteArray.fromBytes (haxe.Resource.getBytes (resourceName)));
};
@@ -1542,7 +1538,7 @@ class Assets {
if (fields != null) {
#if (!html5) // CFFILoader.h(248) : NOT Implemented:api_buffer_data
#if (openfl && !html5) // CFFILoader.h(248) : NOT Implemented:api_buffer_data
var constructor = macro {

View File

@@ -1,383 +0,0 @@
package lime.graphics;
import lime.graphics.Image;
import lime.utils.ByteArray;
import lime.utils.UInt8Array;
import lime.system.System;
#if (js && html5)
import js.html.CanvasElement;
import js.html.CanvasRenderingContext2D;
#end
@:autoBuild(lime.Assets.embedFont())
class Font {
public var fontName (default, null):String;
public var image:Image;
public var glyphs:Map<Int, Map<Int, GlyphRect>>;
@:noCompletion private var __fontPath:String;
@:noCompletion private var __handle:Dynamic;
public function new (fontName:String = null) {
this.fontName = fontName;
this.glyphs = new Map<Int, Map<Int, GlyphRect>>();
}
public function createImage ():ImageBuffer {
glyphs = new Map<Int, Map<Int, GlyphRect>>();
#if (js && html5)
/*
if (__canvas == null) {
__canvas = cast js.Browser.document.createElement ("canvas");
__context = cast __canvas.getContext ("2d");
}
__canvas.width = __canvas.height = 128;
__context.fillStyle = "#000000";
__context.textBaseline = "top";
__context.textAlign = "left";
__context.font = size + "px " + fontFace;
// canvas doesn't give the appropriate metrics so the values have to be padded...
var padding = size / 4;
var x = 0.0, y = 0.0, i = 0;
var height = size + padding;
while (i < glyphs.length) {
var c = glyphs.charAt(i++);
var metrics = __context.measureText (c);
var width = metrics.width + 4; // fudge because of incorrect text metrics
if (x + width > __canvas.width) {
y += height + 1;
x = 0;
}
if (y + height > __canvas.height) {
if (__canvas.width < __canvas.height) {
__canvas.width *= 2;
} else {
__canvas.height *= 2;
}
__context.clearRect (0, 0, __canvas.width, __canvas.height);
__context.textBaseline = "top";
__context.textAlign = "left";
__context.fillStyle = "#000000";
__context.font = size + "px " + fontFace;
glyphRects = new IntMap<GlyphRect>();
x = y = i = 0;
continue;
}
__context.fillText (c, x + 2, y);
glyphRects.set(c, new GlyphRect(x, y, width, height, Std.int(width)));
x += width;
}
var image = new js.html.Image ();
image.src = __canvas.toDataURL();
return new Image (image, __canvas.width, __canvas.height);*/
#elseif flash
/*var bd = new flash.display.BitmapData(128, 128, true, 0);
var tf = new flash.text.TextField ();
var format = new flash.text.TextFormat ();
format.size = size;
format.font = fontFace;
tf.defaultTextFormat = format;
// tf.embedFonts = true;
var mat = new flash.geom.Matrix ();
var i = 0, x = 0.0, y = 0.0, maxHeight = 0.0;
while (i < glyphs.length) {
var c = glyphs.charAt(i++);
tf.text = c;
if (x + tf.textWidth > bd.width) {
y += maxHeight + 1;
x = maxHeight = 0;
}
if (y + tf.textHeight > bd.height) {
if (bd.width < bd.height) {
bd = new flash.display.BitmapData(bd.width * 2, bd.height, true, 0);
} else {
bd = new flash.display.BitmapData(bd.width, bd.height * 2, true, 0);
}
glyphRects = new IntMap<GlyphRect>();
x = y = maxHeight = i = 0;
continue;
}
mat.identity ();
mat.translate (x, y);
bd.draw (tf, mat);
glyphRects.set(c, new GlyphRect (x, y, tf.textWidth + 2, tf.textHeight + 2, Std.int(tf.textWidth + 2)));
x += tf.textWidth + 4;
if (tf.textHeight + 4 > maxHeight) {
maxHeight = tf.textHeight + 4;
}
}
return new ImageBuffer (bd, bd.width, bd.height);*/
#elseif (cpp || neko || nodejs)
if (__handle==null) throw "Uninitialized font handle.";
var data = lime_font_create_image (__handle);
if (data == null) {
return null;
} else {
var glyphRects:Map<Int, GlyphRect>;
for (glyph in cast (data.glyphs, Array<Dynamic>)) {
if (glyphs.exists (glyph.size)) {
glyphRects = glyphs.get (glyph.size);
} else {
glyphRects = new Map<Int, GlyphRect>();
glyphs.set (glyph.size, glyphRects);
}
glyphRects.set (glyph.codepoint, new GlyphRect (glyph.x, glyph.y, glyph.width, glyph.height, glyph.offset.x, glyph.offset.y));
}
return new ImageBuffer (new UInt8Array (data.image.data), data.image.width, data.image.height, data.image.bpp);
}
#end
return null;
}
public function decompose ():NativeFontData {
#if (cpp || neko || nodejs)
if (__handle==null) throw "Uninitialized font handle.";
return lime_font_outline_decompose (__handle, 1024 * 20);
#else
return null;
#end
}
public static function fromBytes (bytes:ByteArray):Font {
var font = new Font ();
// TODO font.__fromBytes (bytes);
return font;
}
public static function fromFile (path:String):Font {
var font = new Font ();
font.__fromFile (path);
return font;
}
public function loadRange (size:Int, start:Int, end:Int) {
#if (flash || js)
// this.glyphs = glyphs;
#elseif (cpp || neko || nodejs)
if (__handle==null) throw "Uninitialized font handle.";
lime_font_load_range (__handle, size, start, end);
#end
}
public function loadGlyphs (size:Int, glyphs:String=null) {
if (glyphs == null) {
glyphs = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^`'\"/\\&*()[]{}<>|:;_-+=?,. ";
}
#if (flash || js)
//this.glyphs = glyphs;
#elseif (cpp || neko || nodejs)
if (__handle==null) throw "Uninitialized font handle.";
lime_font_load_glyphs (__handle, size, glyphs);
#end
}
@:noCompletion private function __fromFile (path:String):Void {
__fontPath = path;
#if (cpp || neko || nodejs)
__handle = lime_font_load (__fontPath);
if (__handle != null) {
fontName = lime_font_get_family_name (__handle);
}
#end
}
#if (cpp || neko || nodejs)
private static var lime_font_get_family_name = System.load ("lime", "lime_font_get_family_name", 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_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_outline_decompose = System.load ("lime", "lime_font_outline_decompose", 2);
#end
}
class GlyphRect {
public var x:Float;
public var y:Float;
public var width:Float;
public var height:Float;
public var xOffset:Int;
public var yOffset:Int;
public function new (x:Float, y:Float, width:Float, height:Float, xOffset:Int=0, yOffset:Int=0) {
this.x = x;
this.y = y;
this.xOffset = xOffset;
this.yOffset = yOffset;
this.width = width;
this.height = height;
}
}
typedef NativeFontData = {
var has_kerning:Bool;
var is_fixed_width:Bool;
var has_glyph_names:Bool;
var is_italic:Bool;
var is_bold:Bool;
var num_glyphs:Int;
var family_name:String;
var style_name:String;
var em_size:Int;
var ascend:Int;
var descend:Int;
var height:Int;
var glyphs:Array<NativeGlyphData>;
var kerning:Array<NativeKerningData>;
}
typedef NativeGlyphData = {
var char_code:Int;
var advance:Int;
var min_x:Int;
var max_x:Int;
var min_y:Int;
var max_y:Int;
var points:Array<Int>;
}
typedef NativeKerningData = {
var left_glyph:Int;
var right_glyph:Int;
var x:Int;
var y:Int;
}

View File

@@ -1,216 +0,0 @@
package lime.graphics;
import lime.system.System;
@:enum abstract TextDirection(Int) to (Int) {
var Invalid = 0;
var LeftToRight = 4;
var RightToLeft = 5;
var TopToBottom = 6;
var BottomToTop = 7;
}
@:enum abstract TextScript(String) to (String) {
var ScriptCommon = "Zyyy";
var ScriptInherited = "Zinh";
var ScriptUnknown = "Zzzz";
var ScriptArabic = "Arab";
var ScriptArmenian = "Armn";
var ScriptBengali = "Beng";
var ScriptCyrillic = "Cyrl";
var ScriptDevanagari = "Deva";
var ScriptGeorgian = "Geor";
var ScriptGreek = "Grek";
var ScriptGujarati = "Gujr";
var ScriptGurmukhi = "Guru";
var ScriptHangul = "Hang";
var ScriptHan = "Hani";
var ScriptHebrew = "Hebr";
var ScriptHiragana = "Hira";
var ScriptKannada = "Knda";
var ScriptKatakana = "Kana";
var ScriptLao = "Laoo";
var ScriptLatin = "Latn";
var ScriptMalayalam = "Mlym";
var ScriptOriya = "Orya";
var ScriptTamil = "Taml";
var ScriptTelugu = "Telu";
var ScriptThai = "Thai";
var ScriptTibetan = "Tibt";
var ScriptBopomofo = "Bopo";
var ScriptBraille = "Brai";
var ScriptCanadianSyllabics = "Cans";
var ScriptCherokee = "Cher";
var ScriptEthiopic = "Ethi";
var ScriptKhmer = "Khmr";
var ScriptMongolian = "Mong";
var ScriptMyanmar = "Mymr";
var ScriptOgham = "Ogam";
var ScriptRunic = "Runr";
var ScriptSinhala = "Sinh";
var ScriptSyriac = "Syrc";
var ScriptThaana = "Thaa";
var ScriptYi = "Yiii";
var ScriptDeseret = "Dsrt";
var ScriptGothic = "Goth";
var ScriptOldItalic = "Ital";
var ScriptBuhid = "Buhd";
var ScriptHanunoo = "Hano";
var ScriptTagalog = "Tglg";
var ScriptTagbanwa = "Tagb";
var ScriptCypriot = "Cprt";
var ScriptLimbu = "Limb";
var ScriptLinearB = "Linb";
var ScriptOsmanya = "Osma";
var ScriptShavian = "Shaw";
var ScriptTaiLe = "Tale";
var ScriptUgaritic = "Ugar";
var ScriptBuginese = "Bugi";
var ScriptCoptic = "Copt";
var ScriptGlagolitic = "Glag";
var ScriptKharoshthi = "Khar";
var ScriptNewTaiLue = "Talu";
var ScriptOldPersian = "Xpeo";
var ScriptSylotiNagri = "Sylo";
var ScriptTifinagh = "Tfng";
var ScriptBalinese = "Bali";
var ScriptCuneiform = "Xsux";
var ScriptNko = "Nkoo";
var ScriptPhagsPa = "Phag";
var ScriptPhoenician = "Phnx";
var ScriptCarian = "Cari";
var ScriptCham = "Cham";
var ScriptKayahLi = "Kali";
var ScriptLepcha = "Lepc";
var ScriptLycian = "Lyci";
var ScriptLydian = "Lydi";
var ScriptOlChiki = "Olck";
var ScriptRejang = "Rjng";
var ScriptSaurashtra = "Saur";
var ScriptSundanese = "Sund";
var ScriptVai = "Vaii";
var ScriptAvestan = "Avst";
var ScriptBamum = "Bamu";
var ScriptEgyptianHieroglyphs = "Egyp";
var ScriptImperialAramaic = "Armi";
// var ScriptInvar scriptionalPahlavi = "Phli";
// var ScriptInvar scriptionalParthian = "Prti";
var ScriptJavanese = "Java";
var ScriptKaithi = "Kthi";
var ScriptLisu = "Lisu";
var ScriptMeeteiMayek = "Mtei";
var ScriptOldSouthArabian = "Sarb";
var ScriptOldTurkic = "Orkh";
var ScriptSamaritan = "Samr";
var ScriptTaiTham = "Lana";
var ScriptTaiViet = "Tavt";
var ScriptBatak = "Batk";
var ScriptBrahmi = "Brah";
var ScriptMandaic = "Mand";
var ScriptChakma = "Cakm";
var ScriptMeroiticCursive = "Merc";
var ScriptMeroiticHieroglyphs = "Mero";
var ScriptMiao = "Plrd";
var ScriptSharada = "Shrd";
var ScriptSoraSompeng = "Sora";
var ScriptTakri = "Takr";
var ScriptBassaVah = "Bass";
var ScriptCaucasianAlbanian = "Aghb";
var ScriptDuployan = "Dupl";
var ScriptElbasan = "Elba";
var ScriptGrantha = "Gran";
var ScriptKhojki = "Khoj";
var ScriptKhudawadi = "Sind";
var ScriptLinearA = "Lina";
var ScriptMahajani = "Mahj";
var ScriptManichaean = "Mani";
var ScriptMendeKikakui = "Mend";
var ScriptModi = "Modi";
var ScriptMro = "Mroo";
var ScriptNabataean = "Nbat";
var ScriptOldNorthArabian = "Narb";
var ScriptOldPermic = "Perm";
var ScriptPahawhHmong = "Hmng";
var ScriptPalmyrene = "Palm";
var ScriptPauCinHau = "Pauc";
var ScriptPsalterPahlavi = "Phlp";
var ScriptSiddham = "Sidd";
var ScriptTirhuta = "Tirh";
var ScriptWarangCiti = "Wara";
}
typedef Point = {
var x:Float;
var y:Float;
};
typedef PosInfo = {
var codepoint:UInt;
var advance:Point;
var offset:Point;
};
class TextFormat {
public var direction(default, null):TextDirection;
#if (cpp || neko || nodejs)
public var handle:Dynamic;
#end
public function new (direction:TextDirection, script:TextScript, language:String) {
#if (cpp || neko || nodejs)
handle = lime_text_create (direction, script, language);
#end
this.direction = direction;
}
@:access(lime.graphics.Font)
public function fromString (font:Font, size:Int, text:String):Array<PosInfo> {
#if (cpp || neko || nodejs)
if (font.__handle==null) throw "Uninitialized font handle.";
return lime_text_from_string (handle, font.__handle, size, text);
#else
return null;
#end
}
#if (cpp || neko || nodejs)
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", 4);
#end
}

View File

@@ -18,9 +18,9 @@ import sys.FileSystem;
import sys.io.File;
#if (lime && !lime_legacy)
import lime.text.Font;
import lime.tools.helpers.FileHelper;
import lime.tools.helpers.ProcessHelper;
import lime.graphics.Font;
import sys.io.Process;
@:access(lime.graphics.Font)
#end
@@ -920,7 +920,7 @@ class HXProject {
try {
var font = Font.fromFile (asset.sourcePath);
embeddedAsset.fontName = font.fontName;
embeddedAsset.fontName = font.name;
} catch (e:Dynamic) {}

View File

@@ -18,7 +18,17 @@ import js.html.CanvasRenderingContext2D;
class Font {
public var fontName (default, null):String;
public var ascender (get, null):Int;
public var descender (get, null):Int;
public var height (get, null):Int;
public var name (default, null):String;
public var numGlyphs (get, null):Int;
public var underlinePosition (get, null):Int;
public var underlineThickness (get, null):Int;
public var unitsPerEM (get, null):Int;
public var image:Image;
public var glyphs:Map<Int, Map<Int, GlyphRect>>;
@@ -26,9 +36,9 @@ class Font {
@:noCompletion private var __handle:Dynamic;
public function new (fontName:String = null) {
public function new (name:String = null) {
this.fontName = fontName;
this.name = name;
this.glyphs = new Map<Int, Map<Int, GlyphRect>> ();
}
@@ -293,7 +303,7 @@ class Font {
if (__handle != null) {
fontName = lime_font_get_family_name (__handle);
name = lime_font_get_family_name (__handle);
}
@@ -312,7 +322,7 @@ class Font {
if (__handle != null) {
fontName = lime_font_get_family_name (__handle);
name = lime_font_get_family_name (__handle);
}
@@ -321,8 +331,106 @@ class Font {
}
// Get & Set Methods
private function get_ascender ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_ascender (__handle);
#else
return 0;
#end
}
private function get_descender ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_descender (__handle);
#else
return 0;
#end
}
private function get_height ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_height (__handle);
#else
return 0;
#end
}
private function get_numGlyphs ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_num_glyphs (__handle);
#else
return 0;
#end
}
private function get_underlinePosition ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_underline_position (__handle);
#else
return 0;
#end
}
private function get_underlineThickness ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_underline_thickness (__handle);
#else
return 0;
#end
}
private function get_unitsPerEM ():Int {
#if (cpp || neko || nodejs)
return lime_font_get_units_per_em (__handle);
#else
return 0;
#end
}
// Native Methods
#if (cpp || neko || nodejs)
private static var lime_font_get_ascender = System.load ("lime", "lime_font_get_ascender", 1);
private static var lime_font_get_descender = System.load ("lime", "lime_font_get_descender", 1);
private static var lime_font_get_family_name = System.load ("lime", "lime_font_get_family_name", 1);
private static var lime_font_get_height = System.load ("lime", "lime_font_get_height", 1);
private static var lime_font_get_num_glyphs = System.load ("lime", "lime_font_get_num_glyphs", 1);
private static var lime_font_get_underline_position = System.load ("lime", "lime_font_get_underline_position", 1);
private static var lime_font_get_underline_thickness = System.load ("lime", "lime_font_get_underline_thickness", 1);
private static var lime_font_get_units_per_em = System.load ("lime", "lime_font_get_units_per_em", 1);
private static var lime_font_load:Dynamic = 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);

View File

@@ -5,13 +5,13 @@ package lime.tools.helpers;
//import openfl.utils.ByteArray;
import haxe.io.Bytes;
import haxe.io.Path;
import lime.tools.helpers.LogHelper;
import lime.tools.helpers.ProcessHelper;
import lime.graphics.Font;
import lime.project.Asset;
import lime.project.AssetEncoding;
import lime.project.AssetType;
import lime.project.HXProject;
import lime.text.Font;
import lime.tools.helpers.LogHelper;
import lime.tools.helpers.ProcessHelper;
import sys.io.File;
import sys.FileSystem;
import sys.io.FileSeek;

View File

@@ -34,7 +34,14 @@ namespace lime {
~Font ();
value Decompose (int em);
int GetAscender ();
int GetDescender ();
wchar_t *GetFamilyName ();
int GetHeight ();
int GetNumGlyphs ();
int GetUnderlinePosition ();
int GetUnderlineThickness ();
int GetUnitsPerEM ();
bool InsertCodepointFromIndex (unsigned long codepoint);
void LoadGlyphs (const char *glyphs);
void LoadRange (unsigned long start, unsigned long end);

View File

@@ -144,6 +144,30 @@ namespace lime {
}
value lime_font_get_ascender (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetAscender ());
#else
return alloc_null ();
#endif
}
value lime_font_get_descender (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetDescender ());
#else
return alloc_null ();
#endif
}
value lime_font_get_family_name (value fontHandle) {
#ifdef LIME_FREETYPE
@@ -156,6 +180,66 @@ namespace lime {
}
value lime_font_get_height (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetHeight ());
#else
return alloc_null ();
#endif
}
value lime_font_get_num_glyphs (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetNumGlyphs ());
#else
return alloc_null ();
#endif
}
value lime_font_get_underline_position (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetUnderlinePosition ());
#else
return alloc_null ();
#endif
}
value lime_font_get_underline_thickness (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetUnderlineThickness ());
#else
return alloc_null ();
#endif
}
value lime_font_get_units_per_em (value fontHandle) {
#ifdef LIME_FREETYPE
Font *font = (Font*)(intptr_t)val_float (fontHandle);
return alloc_int (font->GetUnitsPerEM ());
#else
return alloc_null ();
#endif
}
value lime_font_load (value data) {
#ifdef LIME_FREETYPE
@@ -552,7 +636,14 @@ namespace lime {
DEFINE_PRIM (lime_application_update, 1);
DEFINE_PRIM (lime_audio_load, 1);
DEFINE_PRIM (lime_font_create_image, 1);
DEFINE_PRIM (lime_font_get_ascender, 1);
DEFINE_PRIM (lime_font_get_descender, 1);
DEFINE_PRIM (lime_font_get_family_name, 1);
DEFINE_PRIM (lime_font_get_height, 1);
DEFINE_PRIM (lime_font_get_num_glyphs, 1);
DEFINE_PRIM (lime_font_get_underline_position, 1);
DEFINE_PRIM (lime_font_get_underline_thickness, 1);
DEFINE_PRIM (lime_font_get_units_per_em, 1);
DEFINE_PRIM (lime_font_load, 1);
DEFINE_PRIM (lime_font_load_glyphs, 3);
DEFINE_PRIM (lime_font_load_range, 4);

View File

@@ -131,116 +131,136 @@ namespace {
enum {
PT_MOVE = 1,
PT_LINE = 2,
PT_CURVE = 3
};
struct point {
int x, y;
unsigned char type;
point() { }
point(int x, int y, unsigned char type) : x(x), y(y), type(type) { }
int x, y;
unsigned char type;
point () { }
point (int x, int y, unsigned char type) : x (x), y (y), type (type) { }
};
struct glyph {
FT_ULong char_code;
FT_Vector advance;
FT_Glyph_Metrics metrics;
int index, x, y;
std::vector<int> pts;
FT_ULong char_code;
FT_Vector advance;
FT_Glyph_Metrics metrics;
int index, x, y;
std::vector<int> pts;
glyph(): x(0), y(0) { }
glyph () : x (0), y (0) { }
};
struct kerning {
int l_glyph, r_glyph;
int x, y;
kerning() { }
kerning(int l, int r, int x, int y): l_glyph(l), r_glyph(r), x(x), y(y) { }
int l_glyph, r_glyph;
int x, y;
kerning () { }
kerning (int l, int r, int x, int y) : l_glyph (l), r_glyph (r), x (x), y (y) { }
};
struct glyph_sort_predicate {
bool operator()(const glyph* g1, const glyph* g2) const {
return g1->char_code < g2->char_code;
bool operator () (const glyph* g1, const glyph* g2) const {
return g1->char_code < g2->char_code;
}
};
typedef const FT_Vector *FVecPtr;
int outline_move_to(FVecPtr to, void *user) {
glyph *g = static_cast<glyph*>(user);
g->pts.push_back(PT_MOVE);
g->pts.push_back(to->x);
g->pts.push_back(to->y);
g->x = to->x;
g->y = to->y;
int outline_move_to (FVecPtr to, void *user) {
return 0;
}
int outline_line_to(FVecPtr to, void *user) {
glyph *g = static_cast<glyph*>(user);
g->pts.push_back(PT_LINE);
g->pts.push_back(to->x - g->x);
g->pts.push_back(to->y - g->y);
glyph *g = static_cast<glyph*> (user);
g->pts.push_back (PT_MOVE);
g->pts.push_back (to->x);
g->pts.push_back (to->y);
g->x = to->x;
g->y = to->y;
return 0;
}
int outline_conic_to(FVecPtr ctl, FVecPtr to, void *user) {
glyph *g = static_cast<glyph*>(user);
g->pts.push_back(PT_CURVE);
g->pts.push_back(ctl->x - g->x);
g->pts.push_back(ctl->y - g->y);
g->pts.push_back(to->x - ctl->x);
g->pts.push_back(to->y - ctl->y);
g->x = to->x;
g->y = to->y;
return 0;
}
int outline_cubic_to(FVecPtr ctl1, FVecPtr ctl2, FVecPtr to, void *user) {
int outline_line_to (FVecPtr to, void *user) {
glyph *g = static_cast<glyph*> (user);
g->pts.push_back (PT_LINE);
g->pts.push_back (to->x - g->x);
g->pts.push_back (to->y - g->y);
g->x = to->x;
g->y = to->y;
return 0;
}
int outline_conic_to (FVecPtr ctl, FVecPtr to, void *user) {
glyph *g = static_cast<glyph*> (user);
g->pts.push_back (PT_CURVE);
g->pts.push_back (ctl->x - g->x);
g->pts.push_back (ctl->y - g->y);
g->pts.push_back (to->x - ctl->x);
g->pts.push_back (to->y - ctl->y);
g->x = to->x;
g->y = to->y;
return 0;
}
int outline_cubic_to (FVecPtr ctl1, FVecPtr ctl2, FVecPtr to, void *user) {
// Cubic curves are not supported, we need to approximate to a quadratic
// TODO: divide into multiple curves
glyph *g = static_cast<glyph*>(user);
glyph *g = static_cast<glyph*> (user);
FT_Vector ctl;
ctl.x = (-0.25 * g->x) + (0.75 * ctl1->x) + (0.75 * ctl2->x) + (-0.25 * to->x);
ctl.y = (-0.25 * g->y) + (0.75 * ctl1->y) + (0.75 * ctl2->y) + (-0.25 * to->y);
g->pts.push_back(PT_CURVE);
g->pts.push_back(ctl.x - g->x);
g->pts.push_back(ctl.y - g->y);
g->pts.push_back(to->x - ctl.x);
g->pts.push_back(to->y - ctl.y);
g->pts.push_back (PT_CURVE);
g->pts.push_back (ctl.x - g->x);
g->pts.push_back (ctl.y - g->y);
g->pts.push_back (to->x - ctl.x);
g->pts.push_back (to->y - ctl.y);
g->x = to->x;
g->y = to->y;
return 0;
}
}
@@ -573,6 +593,20 @@ namespace lime {
}
int Font::GetAscender () {
return ((FT_Face)face)->ascender;
}
int Font::GetDescender () {
return ((FT_Face)face)->descender;
}
wchar_t *Font::GetFamilyName () {
#ifdef LIME_FREETYPE
@@ -628,6 +662,41 @@ namespace lime {
}
int Font::GetHeight () {
return ((FT_Face)face)->height;
}
int Font::GetNumGlyphs () {
return ((FT_Face)face)->num_glyphs;
}
int Font::GetUnderlinePosition () {
return ((FT_Face)face)->underline_position;
}
int Font::GetUnderlineThickness () {
return ((FT_Face)face)->underline_thickness;
}
int Font::GetUnitsPerEM () {
return ((FT_Face)face)->units_per_EM;
}
bool Font::InsertCodepoint (unsigned long codepoint, bool fromIndex) {
GlyphInfo info;

View File

@@ -6,8 +6,8 @@ import haxe.Unserializer;
import lime.app.Preloader;
import lime.audio.openal.AL;
import lime.audio.AudioBuffer;
import lime.graphics.Font;
import lime.graphics.Image;
import lime.text.Font;
import lime.utils.ByteArray;
import lime.utils.UInt8Array;
import lime.Assets;