how to load fonts in flex 4.6 windowed application - apache-flex

I have a window application that i have developed in flex sdk 4.6 . I have the same version in web based application. In this application i am loading external swf font file. In web application everything is working fine but font is not loaded in window application.
Below is the code for loading the fonts..
package com
{
import adobe.utils.CustomActions;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
import flash.text.Font;
import injectors.CentralInjector;
import mx.core.FontAsset;
public class LF extends EventDispatcher
{
public function LF()
{
}
public function avaliable(style:String):Boolean{
var embeddedFonts:Array = Font.enumerateFonts(false);
for(var i:Number = 0; i < embeddedFonts.length; i++){
var item:Font = embeddedFonts[i];
if(item.fontStyle==style){
return true;
}
}
return false;
}
public function load(url:String):void{
//=====url is http://www.mydomain.com/font1.swf=================
CustomWaitAlert.show(CustomWaitAlert.WAIT,null,"Loading fonts...");
var loader:Loader = new Loader();
var loaderInfo:LoaderInfo = loader.contentLoaderInfo;
loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioerror);
loaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest(url));
}
private function ioerror(evt:IOErrorEvent):void{
this.dispatchEvent(new Event("IOERROR"));
}
private function onLoadComplete(evt:Event):void{
var embeddedFonts:Array = Font.enumerateFonts(false);
this.dispatchEvent(new Event("COMPLETE"));
CustomWaitAlert.hide();
}
}
}

The solution i got is to first load the font swf via url loader then we get the bytearray.after that just load tge bytearray with the loader class with loading context which is having allowcodeimport sets to true...

Related

Flex 4.5 - Custom NativeWindow and problems

I have a class FlexNativeWindow who extends to NativeWindow.
I use this method to create new window on my AIR app.
All works well but some keyboard interraction is not availaible.
For exemple focus arround textinput is not visible.
Key down and up don't work on DropDownList.
TabOrder doesn't work well!
Can you explain Why? Because I'm very desapointed!
Code to create the new window
var wdetcorr:wDetailCorrespondant = new wDetailCorrespondant();
wdetcorr.monIdCorresp = correspDG.selectedItem.crIndex;
var wOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
wOptions.systemChrome = NativeWindowSystemChrome.NONE;
wOptions.transparent = false;
var fnwDetailPatient:FlexNativeWindow = new FlexNativeWindow(wdetcorr, wOptions);
fnwDetailPatient.active();
Code about my custom NativeWindow
package fr.int.ui.windowSkin
{
import flash.display.NativeWindow;
import flash.display.NativeWindowInitOptions;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import mx.core.IUIComponent;
import mx.core.IVisualElement;
import mx.core.IVisualElementContainer;
import mx.core.UIComponent;
import mx.events.*;
import mx.managers.WindowedSystemManager;
[Event(name="creationComplete", type="mx.events.FlexEvent")]
public class FlexNativeWindow extends NativeWindow implements IFlexNativeWindow
{
private var _systemManager:WindowedSystemManager;
private var _content:UIComponent;
private var _window:IVisualElementContainer;
public function FlexNativeWindow(window:IVisualElementContainer, initOptions:NativeWindowInitOptions = null)
{
super(initOptions);
_window = window;
addEventListener(Event.ACTIVATE, windowActivateHandler);
}
public function addElement(control:IVisualElement):void
{
_window.addElement(control);
}
public function removeElement(control:IVisualElement):void
{
_window.removeElement(control);
}
private function windowActivateHandler(event:Event):void
{
event.preventDefault();
event.stopImmediatePropagation();
removeEventListener(Event.ACTIVATE, windowActivateHandler);
if (stage)
{
if (!_systemManager)
_systemManager = new WindowedSystemManager(IUIComponent(_window));
stage.addChild(_systemManager);
dispatchEvent(new FlexEvent(FlexEvent.CREATION_COMPLETE));
stage.addEventListener(Event.RESIZE, windowResizeHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
}
}
private function keyDownListener (e:KeyboardEvent):void {
if (e.keyCode == Keyboard.ESCAPE) {
stage.nativeWindow.dispatchEvent(new Event("myEventClose", true));
stage.nativeWindow.close();
}
}
private function windowResizeHandler(event:Event):void
{
// prise en compte de la valeur mini
UIComponent(_window).height = stage.stageHeight;
UIComponent(_window).width = stage.stageWidth;
}
}
}
You should implement IFocusManagerContainer in FlexNativeWindow to fix the focus issues.
Here is how to do it in Flash Builder:
Press Ctrl + Shift + T and type in IFocusManagerContainer
Open corresponding file
Implement all declared methods in your class FlexNativeWindow
P.S: However this approach can fail because flex components should be placed inside flex container while NativeWindow is a native class, not a Flex SDK class. I suggest you to use Window class that is a Flex container and already implements IFocusManagerContainer.

Loading external SWF into AIR Application

I'm trying to load external SWF (JW Player) into my AIR Application using loadBytes. I'm using the following code:
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
public function Invoker()
{
trace("INIT");
var uldr : URLLoader = new URLLoader();
uldr.dataFormat = URLLoaderDataFormat.BINARY;
uldr.addEventListener(Event.COMPLETE, onBytesComplete);
uldr.load(new URLRequest("Resources/5.1.swf"));
}
private function onBytesComplete(e : Event) : void
{
trace("LOADED");
var bytes : ByteArray = (e.target as URLLoader).data;
var ldr : Loader = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onChildComplete);
var ldrC : LoaderContext = new LoaderContext();
ldrC.allowLoadBytesCodeExecution = true;
ldr.loadBytes(bytes, ldrC);
}
private function onChildComplete(e : Event):void
{
trace("COMPLETE");
var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain;
var inad : ApplicationDomain = ApplicationDomain.currentDomain;
trace(c1ad);
trace(inad);
}
But, when I put
uic.addChild(ldr);
or
canv.addChild(ldr); (uic is mx:UIComponent and canv is mx:Canvas)
into the onBytesComplete function, I get the following error:
SecurityError: Error #3207: Application-sandbox content cannot access this feature.
at flash.system::Security$/allowDomain()
at com.longtailvideo.jwplayer.media::YouTubeMediaProvider/initializeMediaProvider()
at com.longtailvideo.jwplayer.model::Model/setMediaProvider()
at com.longtailvideo.jwplayer.model::Model/setupMediaProviders()
at com.longtailvideo.jwplayer.controller::PlayerSetup/setupMediaProviders()
at com.longtailvideo.jwplayer.controller::TaskQueue/nextTask()
at com.longtailvideo.jwplayer.controller::TaskQueue/success()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at com.longtailvideo.jwplayer.view.skins::DefaultSkin/loadComplete()
Idea? Please Help!
Thanks in advice!
Got it!
I changed a few functions in the JW Player source classes.
In the com/longtailvideo/jwplayer/media/YouTubeMediaProvider.as in the function initializeMediaProvider() added Security.allowDomain("*");
In the com/longtailvideo/jwplayer/model/Model.as in the function setupMediaProviders() commented the rows: setMediaProvider('default', new MediaProvider('default')); and setMediaProvider('youtube', new YouTubeMediaProvider());
I'm not using youtube, so it works fine!
Hope this helps!

AS3: AddChild issue -- "TypeError: Error #2007: Parameter child must be non-null."

My following code gave me
TypeError: Error #2007: Parameter child must be non-null runtime error.
not sure why...I would appreciate any help...
mySb = new ScrollBar();
mySb.x = cont.x; //+ cont.width;
mySb.y = cont.y;
mySb.height = contMask.height;
mySb.enabled = true;
addChild(mySb);
Updated
package com.search.view
{
import com.search.events.YouTubeSearchEvent;
import fl.controls.ScrollBar;
import fl.controls.Slider;
import fl.controls.UIScrollBar;
import fl.events.ScrollEvent;
import fl.events.SliderEvent;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.net.URLLoader;
public class SearchResultContainer extends Sprite
{
private var cont:videoCont;
private var contMask:Sprite;
private var mySb:ScrollBar;
public function SearchResultContainer()
{
super();
}
public function get selectedVideoID():String{
return newVideoID;
}
public function createContainer(_x:Number,_y:Number, videoResult:Array):void{
cont=new videoCont();
cont.x=_x;
cont.y=_y;
addChild(cont);
contMask = new Sprite();
contMask.x = cont.x;
contMask.y = cont.y;
createMask(contMask,0x000000,452,88);
addChild(contMask);
cont.mask = contMask;
mySb = new ScrollBar();
mySb.x = cont.x; //+ cont.width;
mySb.y = cont.y;
mySb.height = contMask.height;
mySb.enabled = true;
addChild(mySb); //problem code here...
}
private function createMask(inSrc:*,inColor:Number=0x999999,inW:Number=80,inH:Number=50):void{
var rect:Shape=new Shape();
rect.graphics.clear();
rect.graphics.beginFill(inColor);
rect.graphics.drawRect(0,0,inW,inH);
rect.graphics.endFill();
inSrc.addChild(rect);
}
}
}
I am in Flex environment....
Try to add a breakpoint before the problem occurs and check the mySb value , it looks like it's probably null , if it's not you'll have to look for null values either in the DisplayObjects you're using or the properties you're assigning them... if it is null , maybe you need to set more properties to your ScrollBar instance before adding it to the display list...
In my case I solved it adding the component to the movie library, but working in Flash CS5.5 environment.

Can I dynamically embed fonts in Flex?

I'm wondering if I can dynamically embed fonts in Flex. I want to embed different fonts for different users so I don't want to embed all possible fonts in the same Flex file. If it's possible could you please post sample code.
You can do this in Actionscript. I've used this trick primarily to use opentype fonts that weren't supported with the compiler in the Flash IDE and to create font libraries that could be loaded lazily (only when needed), but you can also use this to selectively load fonts. If you had the mxmlc compiler on your server you could even generate the fontlib.as file and compile it on command.
// fontlib.as
// font library file
package {
import flash.display.Sprite;
public class fontlib extends Sprite {
[Embed(source = 'font/path/FontFile.otf', fontName = 'FontFile', unicodeRange = 'U+0020-U+007E,U+00AB,etc...')]
public static var FontFile:Class;
public static const FontFile_name:String = "FontFile"; // matches 'fontName' in embed
public function fontlib() {
}
}
}
This can be compiled like so:
mxmlc fontlib.as
You can use in your application like this:
// Main.as
// document class
package {
import flash.text.Font;
import flash.display.Loader;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.text.StyleSheet;
public var fontsLoader:Loader;
public var fontFile:String = "";
public var ss:StyleSheet;
public function Main() {
fontsLoader = new Loader();
fontsLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onFontsLoadComplete);
}
private function _onFontsLoadComplete(e:Event):void {
var fontlib:Class = e.target.applicationDomain.getDefinition('fontlib');
Font.registerFont(fontlib.FontFile); // registers font
fontFile = fontlib.FontFile_name; // name the font was loaded as
// actually using the font looks like this:
ss = new StyleSheet();
ss.parseCSS("div { fontFamily: " + fontFile + "; }");
}
}

generate screenshot and send it to server (not using FileReference.upload)

Do you have any ideas?
Maybe this can help too, this example creates a BitmapData instance, and then sends that as a ByteArray to the server, (in my case, I was using PHP) ... you'll need to write the server side code, but there's nothing quite special here
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.utils.ByteArray;
import mx.graphics.codec.PNGEncoder;
import mx.utils.Base64Encoder;
public class DataUpload extends Sprite
{
private var _loader:URLLoader;
public function DataUpload()
{
// create a bitmap data
var bd:BitmapData = createDummyImage();
var png:PNGEncoder = new PNGEncoder();
var ba:ByteArray = png.encode(bd);
var b64:Base64Encoder = new Base64Encoder();
b64.encodeBytes(ba);
// initialize loader
_loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
_loader.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
var request:URLRequest = new URLRequest("http://localhost/YOUR_PHP_SCRIPT_URI");
request.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.fileData = b64;
variables.fileName = "foobar";
request.data = variables;
_loader.load(request);
}
protected function loadCompleteHandler(event:Event):void {
trace("complete");
}
protected function loadProgressHandler(event:ProgressEvent):void {
trace("progress : ", event.bytesLoaded / event.bytesTotal);
}
private function createDummyImage():BitmapData {
var bd:BitmapData = new BitmapData(300, 300, true, 0x00ffffff);
var shape:Shape = new Shape();
shape.graphics.beginFill(0xff0000);
shape.graphics.drawCircle(10, 10, 10);
shape.graphics.endFill();
bd.draw(shape);
return bd;
}
}
}
Step 1: Use ImageSnapshot to capture the screenshot (I assume we're just talking about the Flash screen, not the OS). This can handle the image encoding for you, or you can capture BitmapData and reencode yourself.
Step 2(a): Use a MultipartLoader to post the generated bytes. Flash security in Flash Player 10 will require the HTTP post to occur on user interaction.
or
Step 2(b): Use a regular URLLoader/URLRequest to post the generated bytes (Base64 encoded, say).

Resources