From fe17a43f726b29439c635e8d10f45f792d2b1dac Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Sat, 1 Nov 2014 09:44:59 -0700 Subject: [PATCH] Use true font names and automatically register font names on native platforms --- lime/graphics/Font.hx | 202 +++++++++++++++----------- project/include/graphics/Font.h | 1 + project/src/ExternalInterface.cpp | 13 ++ project/src/graphics/Font.cpp | 7 + templates/haxe/DefaultAssetLibrary.hx | 11 ++ tools/helpers/FlashHelper.hx | 2 +- tools/project/HXProject.hx | 16 ++ 7 files changed, 169 insertions(+), 83 deletions(-) diff --git a/lime/graphics/Font.hx b/lime/graphics/Font.hx index 3f2052d54..4dc7b0ae6 100644 --- a/lime/graphics/Font.hx +++ b/lime/graphics/Font.hx @@ -1,72 +1,41 @@ package lime.graphics; -import haxe.ds.IntMap; + import lime.graphics.Image; +import lime.utils.ByteArray; import lime.utils.UInt8Array; import lime.system.System; + #if js import js.html.CanvasElement; import js.html.CanvasRenderingContext2D; #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; - - } - -} - @:autoBuild(lime.Assets.embedFont()) + + class Font { + public var fontName (default, null):String; public var image:Image; - public var glyphs:IntMap>; + public var glyphs:Map>; - #if js + @:noCompletion private var __fontPath:String; + @:noCompletion private var __handle:Dynamic; - private static var __canvas:CanvasElement; - private static var __context:CanvasRenderingContext2D; - #elseif (cpp || neko) - - public var handle:Dynamic; - - #end - - public var fontFace(default, null):String; - - public function new (fontFace:String) { + public function new (fontName:String = null) { - this.fontFace = fontFace; - this.glyphs = new IntMap>(); - - #if (cpp || neko) - - handle = lime_font_load (fontFace); - - #end + this.fontName = fontName; + this.glyphs = new Map>(); } + public function createImage ():ImageBuffer { - glyphs = new IntMap>(); + glyphs = new Map>(); #if js @@ -202,7 +171,7 @@ class Font { #elseif (cpp || neko) - var data = lime_font_create_image (handle); + var data = lime_font_create_image (__handle); if (data == null) { @@ -210,7 +179,7 @@ class Font { } else { - var glyphRects:IntMap; + var glyphRects:Map; for (glyph in cast (data.glyphs, Array)) { @@ -220,7 +189,7 @@ class Font { } else { - glyphRects = new IntMap(); + glyphRects = new Map(); glyphs.set (glyph.size, glyphRects); } @@ -244,7 +213,7 @@ class Font { #if (cpp || neko) - return lime_font_outline_decompose (handle, 1024 * 20); + return lime_font_outline_decompose (__handle, 1024 * 20); #else @@ -255,6 +224,24 @@ class Font { } + 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) @@ -263,7 +250,7 @@ class Font { #elseif (cpp || neko) - lime_font_load_range (handle, size, start, end); + lime_font_load_range (__handle, size, start, end); #end @@ -284,7 +271,26 @@ class Font { #elseif (cpp || neko) - lime_font_load_glyphs (handle, size, glyphs); + lime_font_load_glyphs (__handle, size, glyphs); + + #end + + } + + + @:noCompletion private function __fromFile (path:String):Void { + + __fontPath = path; + + #if (cpp || neko) + + __handle = lime_font_load (__fontPath); + + if (__handle != null) { + + fontName = lime_font_get_family_name (__handle); + + } #end @@ -292,6 +298,7 @@ class Font { #if (cpp || neko) + 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); @@ -303,39 +310,70 @@ class Font { } -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; +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 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 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 NativeKerningData = -{ - var left_glyph:Int; - var right_glyph:Int; - var x:Int; - var y:Int; + +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; + } \ No newline at end of file diff --git a/project/include/graphics/Font.h b/project/include/graphics/Font.h index bf3557d91..28c710001 100644 --- a/project/include/graphics/Font.h +++ b/project/include/graphics/Font.h @@ -52,6 +52,7 @@ namespace lime { Font (const char *fontFace); value Decompose (int em); + value GetFamilyName (); void LoadGlyphs (const char *glyphs); void LoadRange (unsigned long start, unsigned long end); value RenderToImage (ImageBuffer *image); diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 1767328e0..af38196af 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -118,6 +118,18 @@ namespace lime { } + value lime_font_get_family_name (value fontHandle) { + + #ifdef LIME_FREETYPE + Font *font = (Font*)(intptr_t)val_float (fontHandle); + return font->GetFamilyName (); + #else + return alloc_null (); + #endif + + } + + value lime_font_load (value fontFace) { #ifdef LIME_FREETYPE @@ -389,6 +401,7 @@ namespace lime { DEFINE_PRIM (lime_application_get_ticks, 0); DEFINE_PRIM (lime_audio_load, 1); DEFINE_PRIM (lime_font_create_image, 1); + DEFINE_PRIM (lime_font_get_family_name, 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/graphics/Font.cpp b/project/src/graphics/Font.cpp index b7182a341..800e6b469 100644 --- a/project/src/graphics/Font.cpp +++ b/project/src/graphics/Font.cpp @@ -522,6 +522,13 @@ namespace lime { } + value Font::GetFamilyName () { + + return alloc_wstring (get_familyname_from_sfnt_name (face)); + + } + + bool Font::InsertCodepoint (unsigned long codepoint) { GlyphInfo info; diff --git a/templates/haxe/DefaultAssetLibrary.hx b/templates/haxe/DefaultAssetLibrary.hx index 289f55cca..388886564 100644 --- a/templates/haxe/DefaultAssetLibrary.hx +++ b/templates/haxe/DefaultAssetLibrary.hx @@ -6,6 +6,7 @@ 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.utils.ByteArray; import lime.utils.UInt8Array; @@ -58,6 +59,12 @@ class DefaultAssetLibrary extends AssetLibrary { #else + #if openfl + ::if (assets != null):: + ::foreach assets::::if (type == "font")::openfl.text.Font.registerFont (__ASSET__::flatName::);::end:: + ::end::::end:: + #end + #if (windows || mac || linux) /*var useManifest = false; @@ -650,6 +657,10 @@ class DefaultAssetLibrary extends AssetLibrary { #elseif (windows || mac || linux) ::if (assets != null):: +#if openfl +::foreach assets::::if (type == "font")::class __ASSET__::flatName:: extends openfl.text.Font { public function new () { super (); __fontPath = "::targetPath::"; fontName = "::fontName::"; }} +::end::::end:: +#end //::foreach assets::::if (embed)::::if (type == "image")::@:bitmap("::sourcePath::") class __ASSET__::flatName:: extends openfl.display.BitmapData {} //::elseif (type == "sound")::@:sound("::sourcePath::") class __ASSET__::flatName:: extends openfl.media.Sound {} //::elseif (type == "music")::@:sound("::sourcePath::") class __ASSET__::flatName:: extends openfl.media.Sound {} diff --git a/tools/helpers/FlashHelper.hx b/tools/helpers/FlashHelper.hx index 614c49d22..aba98c17e 100644 --- a/tools/helpers/FlashHelper.hx +++ b/tools/helpers/FlashHelper.hx @@ -297,7 +297,7 @@ class FlashHelper { var src = name; //var font_name = Path.withoutExtension (name); - var face = new Font (src); + var face = Font.fromFile (src); var font = face.decompose (); var font_name = font.family_name; diff --git a/tools/project/HXProject.hx b/tools/project/HXProject.hx index 68dfddce9..9affa15a3 100644 --- a/tools/project/HXProject.hx +++ b/tools/project/HXProject.hx @@ -20,7 +20,9 @@ import sys.io.File; #if lime import helpers.FileHelper; import helpers.ProcessHelper; +import lime.graphics.Font; import sys.io.Process; +@:access(lime.graphics.Font) #end @@ -904,6 +906,20 @@ class HXProject { } embeddedAsset.type = Std.string (asset.type).toLowerCase (); + + #if lime + if (asset.type == FONT) { + + try { + + var font = Font.fromFile (asset.sourcePath); + embeddedAsset.fontName = font.fontName; + + } catch (e:Dynamic) {} + + } + #end + context.assets.push (embeddedAsset); }