airsdk / Adobe-Runtime-Support

Report, track and discuss issues in Adobe AIR. Monitored by Adobe - and HARMAN - and maintained by the AIR community.
197 stars 11 forks source link

Text with AntiAliasType.ADVANCED with some external loaded fonts via SWF cause crash #150

Open itlancer opened 4 years ago

itlancer commented 4 years ago

Problem Description

Using text with antiAliasType=AntiAliasType.ADVANCED with some external loaded fonts via SWF cause silent crash (without any error/crash logs). To prepare font (ttf, otf, ...) to use by AIR dynamically at run-time (without embedding it to project or application bundle/manifest) we use fontswf-cli or fontswf utility from AIRSDK/lib directory or Flex SDK to convert it to SWF bytes and then use https://github.com/claus/as3swf to create SWF with these bytes defined as Font class inside it. It necessary because end users can choose and use any custom (not installed in system) font they need for graphics/text editor solution.

Using some of SWF fonts converted by such way cause application crash. It has been tested with many different AIR versions even with latests AIR 32.0.0.144 beta and AIR 33.0.2.315. Tested with multiple devices across many OSes: Windows, Android, macOS. *iOS not support SWF bytes loading in such way. Same problem in all cases with some SWF fonts (bytes).

Related feature request: https://github.com/Gamua/Adobe-Runtime-Support/issues/149

Steps to Reproduce

Launch code below. SWF font bytes already embedded (for simplicity). Application use Loader::loadBytes() to load SWF font bytes and then use ApplicationDomain::getDefinition() to get target font class from loaded SWF. Then register new Font and try to use it with TextField that has antiAliasType = AntiAliasType.ADVANCED (necessary for high quality text render). Application example with sources, problem SWF font and other "valid" SWF font attached. font_swf_bytes_anti_aliasing_crash.zip

package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.Font;
    import flash.display.Loader;
    import flash.system.LoaderContext;
    import flash.system.ApplicationDomain;
    import flash.display.LoaderInfo;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.AntiAliasType;

    public class FontSWFBytesAntiAliasingCrash extends Sprite {

        //[Embed(source = "RobotoBold.swf", mimeType="application/octet-stream")]//This SWF font works fine
        [Embed(source = "framd.swf", mimeType="application/octet-stream")]//This SWF font cause crash
        private const FONT_SWF_CLASS:Class;

        private var fontLoader:Loader;

        public function FontSWFBytesAntiAliasingCrash() {
            fontLoader = new Loader();
            var lc:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
            lc.allowCodeImport = true;
            fontLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            fontLoader.loadBytes(new FONT_SWF_CLASS(), lc);
        }

        private function completeHandler(event:Event):void {
            const loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo;
            const applicationDomain:ApplicationDomain = loaderInfo.applicationDomain;

            var fontClass:Class = applicationDomain.getDefinition("FONT001") as Class;//There is such font class defined in loaded SWF
            Font.registerFont(fontClass);

            var font:Font = new fontClass();
            trace(fontClass, font.fontName, font.fontType, font.fontStyle);

            var textField:TextField = new TextField();
            var tf:TextFormat = new TextFormat(font.fontName);
            tf.font = font.fontName;
            textField.embedFonts = true;//Necessary for external loaded fonts
            textField.width = 100;
            textField.height = 100;
            textField.antiAliasType = AntiAliasType.ADVANCED;//This line cause crash a little bit later
            textField.defaultTextFormat = tf;
            textField.setTextFormat(tf);
            textField.text = "TEXT";//There is no crash if you comment this line. If you "do not use text field with this font".
            addChild(textField);
        }
    }
}

Actual Result: Application silent crash (without any error/crash logs).

Expected Result: Application should correctly display text with external font loaded via SWF or throw error (if something invalid in loaded SWF bytes) at Font.registerFont or some other place without crash.

Known Workarounds

none There is no other way right now to use external (dynamic loaded at runtime) fonts with AIR. Feature request for that: https://github.com/Gamua/Adobe-Runtime-Support/issues/149

itlancer commented 1 year ago

Crash still exists with latest AIR 50.2.2.4.