diff --git a/lime/Assets.hx b/lime/Assets.hx index f5e3a0ad0..6c85745cf 100644 --- a/lime/Assets.hx +++ b/lime/Assets.hx @@ -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 { diff --git a/lime/graphics/Font.hx b/lime/graphics/Font.hx deleted file mode 100644 index ca957f548..000000000 --- a/lime/graphics/Font.hx +++ /dev/null @@ -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>; - - @:noCompletion private var __fontPath:String; - @:noCompletion private var __handle:Dynamic; - - - public function new (fontName:String = null) { - - this.fontName = fontName; - this.glyphs = new Map>(); - - } - - - public function createImage ():ImageBuffer { - - glyphs = new Map>(); - - #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(); - 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(); - 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; - - for (glyph in cast (data.glyphs, Array)) { - - if (glyphs.exists (glyph.size)) { - - glyphRects = glyphs.get (glyph.size); - - } else { - - glyphRects = new Map(); - 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; - var kerning:Array; - -} - - -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; - -} - - -typedef NativeKerningData = { - - var left_glyph:Int; - var right_glyph:Int; - var x:Int; - var y:Int; - -} diff --git a/lime/graphics/TextFormat.hx b/lime/graphics/TextFormat.hx deleted file mode 100644 index 6fca18166..000000000 --- a/lime/graphics/TextFormat.hx +++ /dev/null @@ -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 { - - #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 - -} diff --git a/lime/project/HXProject.hx b/lime/project/HXProject.hx index 61a2a764a..5fe1af5bc 100644 --- a/lime/project/HXProject.hx +++ b/lime/project/HXProject.hx @@ -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) {} diff --git a/lime/text/Font.hx b/lime/text/Font.hx index 65f614781..0a071a80d 100644 --- a/lime/text/Font.hx +++ b/lime/text/Font.hx @@ -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>; @@ -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> (); } @@ -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); diff --git a/lime/tools/helpers/FlashHelper.hx b/lime/tools/helpers/FlashHelper.hx index 6019444a0..9cd827391 100644 --- a/lime/tools/helpers/FlashHelper.hx +++ b/lime/tools/helpers/FlashHelper.hx @@ -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; diff --git a/project/include/text/Font.h b/project/include/text/Font.h index a18edb081..fcaee015d 100644 --- a/project/include/text/Font.h +++ b/project/include/text/Font.h @@ -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); diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 7c1aab6b5..beb0cd054 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -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); diff --git a/project/src/text/Font.cpp b/project/src/text/Font.cpp index 880df0a41..0c70734a5 100644 --- a/project/src/text/Font.cpp +++ b/project/src/text/Font.cpp @@ -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 pts; + FT_ULong char_code; + FT_Vector advance; + FT_Glyph_Metrics metrics; + int index, x, y; + std::vector 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(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(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 (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(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 (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 (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(user); + glyph *g = static_cast (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; diff --git a/templates/haxe/DefaultAssetLibrary.hx b/templates/haxe/DefaultAssetLibrary.hx index 01c5d7f52..6869cd3e4 100644 --- a/templates/haxe/DefaultAssetLibrary.hx +++ b/templates/haxe/DefaultAssetLibrary.hx @@ -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;