Update: Now the project is on google code
A promise is a promise đ Now you can download sources of my library handling progressive download of fonts for Flash.
I clean up all to separate different works.
Main demo proof of concept. Demonstrate the system with non embed fonts where chars are loaded when them entered. Also give an example to the usage with Flex on custom components (through Text.fontContext
)
An AS3 Command line executable (made with redtamarin) allow quickly generate fonts cache. A binary file format used to serve fast small amount of font data (optionaly a format used to storage data).
Use it to add more supported fonts for build in test (Waterfall demo). For generate font cache files simply use console: fcgen embed_fonts.swf
(or use --help
for display help), put generated files (by default *.foncache
) in fontcache folder and update fontlist.xml
This contains also 2 others version, an old version in AS3/SWF by passing the SWF file by clicking on stage first and save the result by click second, and an not working flex alternative (read only some information about the SWF file passing through the button “open”).
Not realy important but used for generated the template used in library for generate dynamically SWF file contain fonts data.
Here miss an other part used to modify the SWF template for keep only needed informations (remove debug, metadata …)
And finally an example to embed font with Flex SDK.
I’m currently work on a big multilingual project which use it. But the server get in trouble (we suppose) with PHP when handling huge file like for Arial Unicode MS for CJK texts. We use a (temporary ?) solution by caching requested files and serve again for same requests. This not include in sources.
Beyond, is hard to get styles applied on HTML text. This for what, I had create a class handling HTML text and parsing it to know used text/fonts, improve HTML support by TextField (by some hack and HTML transformations). Is not yet include in souces.
No licence explicitly declared but sure i think as GPL, no AS3 package, more examples, SVN, dedicated page, real name, logo … this will come.
Je viens de mettre au point un systĂšme qui permet d’utiliser des polices embarquĂ©es, mais seulement de charger les caractĂšres nĂ©cessaires.
Le systĂšme est simple :
La police Arial Unicode MS, contient la majoritĂ© des plages unicodes : Latin, CJK (Chinois, Japonais, CorĂ©en), Cyrillique, HĂ©breu, …
A titre d’information :
Total 31,48Mo (56,81Mo)
Ces graphiques sont gĂ©nĂ©rĂ© Ă partir de 1 000 000 valeurs (Ă chaque affichage). Le rouge est la valeur moyenne et le rose est la rĂ©partition moyenne de probabilitĂ© (tout les valeurs on le mĂȘme probabilitĂ© de sortir)
Ce qui serai excellent c’est de faire la mĂȘme chose mais avec des points de contrĂŽles comme pour les courbes de bĂ©zier.
Des liens :
L’AS3 Ă permis d’ouvrir la porte Ă pas mal de choses dont 2 intĂ©ressantes : la gestion native de ByteArray et le chargement dynamique de SWF Ă partir de donnĂ©es contenu dans un ByteArray.
Dit comme ça, ça n’a pas forcĂ©ment d’intĂ©rĂȘt immĂ©diat. Seulement, le fait de pouvoir modifier/gĂ©nĂ©rer les donnĂ©es binaires d’un SWF et de les charger pour les rĂ©cuperer sous forme native, ça change pas mal de choses !
Image, vidĂ©o ou vectoriel bon ça on peut dĂ©jĂ le faire nativement avec BitmapData et Video ou Shape. Mais on peux aussi le faire pour du son, du code ActionScript, ou pour une police embarquĂ©e. C’est ce dernier point, qui m’intĂ©resse et qui n’a pas encore vraiment Ă©tĂ© explorĂ©.
Pour ce faire, j’ai appris Ă lire les donnĂ©es brut du format SWF : demo, sources
Attention les logs gĂ©nĂ©rĂ©s sont assez lourds ~1Mo pour un SWF d’environ 30Ko contenant seulement une police embarquĂ©.
Ca lit les donnĂ©es global d’un SWF (dimensions, couleur de fond, bibliothĂšque) ainsi que tout la partie qui gĂšre les polices (le nom de la police, les donnĂ©es de dessins des glyphs …). Il faudra ensuite que je fasse l’opĂ©ration inverse : gĂ©nerer les donnĂ©es nĂ©cĂ©ssaire Ă l’intĂ©gration d’une police dans un SWF.
Liens :
Un problĂšme auquel j’ai Ă©tĂ© confrontĂ© rĂ©cemment, c’est le poids que font des PNG 32bits de taille moyen ~ 400px * 500px pour ~ 200Ko. En passant par PNGOUT on gagne une ou deux dizaine de kilooctet au maximum.
Seulement, ces images au nombre d’une vingtaine Ă©tait utilisĂ© simultanĂ©ment (ou presque). Rien qu’une image au poids de 200Ko dĂ©passe largement le poids normal conseillĂ© d’une page HTML (JS + CSS + images compris).
Pourtant je devais absolument disposer d’images transparente. HĂ©las seul le format acceptable dans ce cas est le PNG. Le BMP, TIFF ou encore TGA Ă©tant encore plus lourd, de plus non gĂ©rĂ© nativement dans Flash. Comment rĂ©duire le poid (compression lossy ?) et tout en conservant la transparence (une palette gris ?) tout ça en utilisant un containers supportĂ©s par Flash ou en passant par une librairies (si faut pas la faire une sois mĂȘme) ?
Je suis pas allĂ© trĂšs loin pour trouver la solution : utiliser 2 images au lieu d’une. Un JPEG pour les canneaux rouge, vert, bleu, plus un PNG 8bits (voir moins) en palette de gris pour la transparence. Restait plus qu’a les gĂ©rer dans flash.
var rgb:BitmapData = myRGBBitmapData; var alpha:BitmapData = myAlphaBitmapData; //Loaded JPEG BitmapData are not transparent argb = new BitmapData(rgb.width, rgb.height, true, 0x00000000); //Copy RGB argb.copyPixels ( rgb, new Rectangle(0, 0, rgb.width, rgb.height), new Point(0, 0) ) //Apply alpha channel argb.copyChannel ( alpha, new Rectangle(0, 0, alpha.width, alpha.height), new Point(0, 0), BitmapDataChannel.RED,//r = g = b = gray BitmapDataChannel.ALPHA ); //ARGB is ready to use argb;
Le réslutat :
RGB (JPEG) (32 024 octets) + Alpha (PNG8) (12 037 octets) = 44 061 octets vs. Result (PNG32) (58 618 octets). Soit un gain de 25% par rapport Ă l’original. On peut mĂȘme atteindre un gain de 90%.
On pourrai aller encore plus loin en les compressant dans un fichier 7zip. Dans notre cas celui ci permet de gagner encore 10 422 octets, soit au final 57% de la taille originale.
Dans tout ça, le problĂšme aprĂšs, c’est le temps de calcul nĂ©cessaire Ă la lecture et la dĂ©compression du(des) fichier(s) chargĂ©(s) plus le temps de calcul pour que Flash fasse la fusion des 2 images.
Les sources :
Mais sinon pourquoi pas ?
Taper (1 || "").toString();
dans le code d’une classe ou dans la timeline et compiler …
Ca donne un erreur 1068 : Impossible de réconcilier int et String.
D’aprĂšs la doc ça doit donner “int et String ne peuvent pas ĂȘtre rapprochĂ©s.”
A mon avis c’est un “bug” du compileur qui ne fait pas de check de ce qu’il y a dans les parenthĂšses. Le VM elle quand elle vois ça elle sais pas si toString c’est de int, de String ou de leur parent Object.
Pour résoudre le problÚme suffit de forcer la conversion dans un type définit :
Object(1 || "").toString();
Outre les ajouts connu tels que le support des codecs H.264/HE-AAC, de la gestion du multicore dans les tĂąches de rendu (vectoriel, travail par pixel …) de flash player et la rĂ©gression sur certaines choses comme l’evenement Event.SOUND_COMPLETE ou des bug toujours pas corrigĂ©s.
Certains ajout sont apparus sans qu’on en parle trop, dont une que je viens de dĂ©couvrir : LoaderInfo::getLoaderInfoByDefinition()
.
Cette méthode statique permet récuperer le LoaderInfo
de n’importe quel Object
associĂ© Ă un SWF. En fait c’est n’importe quel objet(Object
), classe (Class
), mĂ©thode de la racine (top level) … tout sauf de type Number
, int
et uint
, null
, undefined
, String
et Boolean
(j’en oublie peut ĂȘtre d’autres).
L’un des avantages que j’ai tout de suite vu, que je cherchais Ă faire depuis un bout de temps : rĂ©cuperer l’url du flash chargĂ© (LoaderInfo.loaderURL
ou LoaderInfo.url
) dans lequel mon code s’execute, sans avoir un accĂšs direct au Stage, par exemple pour une classe qui n’est pas un DisplayObject
.
var target:Object = new Object();// new Sprite()|Number|int|Class|this|new Array()|[]|... var loaderInfo:LoaderInfo = LoaderInfo.getLoaderInfoByDefinition(target); // loaderInfo === <root>.loaderInfo trace(loaderInfo.loaderURL);
Attention l’accĂšs ne peut ce faire qu’aprĂšs l’evenement Event.COMPLETE
du root du SWF sinon le code d’erreur d’execution 2099 est retournĂ© pour la majoritĂ© des propriĂ©tĂ© du LoaderInfo
package { import flash.display.Sprite; import flash.display.LoaderInfo; import flash.events.Event; public class GetLoaderInfoByDefinitionDemo extends Sprite { public function GetLoaderInfoByDefinitionDemo():void { this.loaderInfo.addEventListener(Event.COMPLETE, this.traceLoaderInfoProperties, false, 0, false); } private function traceLoaderInfoProperties(event:Event):void { var loaderInfo = LoaderInfo.getLoaderInfoByDefinition([]); trace("actionScriptVersion: " + loaderInfo.actionScriptVersion); trace("applicationDomain: " + loaderInfo.applicationDomain); trace("bytes: " + loaderInfo.bytes); trace("bytesLoaded: " + loaderInfo.bytesLoaded); trace("bytesTotal: " + loaderInfo.bytesTotal); trace("childAllowsParent: " + loaderInfo.childAllowsParent); trace("content: " + loaderInfo.content); trace("contentType: " + loaderInfo.contentType); trace("frameRate: " + loaderInfo.frameRate); trace("height: " + loaderInfo.height); trace("loader: " + loaderInfo.loader); trace("loaderURL: " + loaderInfo.loaderURL); trace("parameters: " + loaderInfo.parameters); trace("parentAllowsChild: " + loaderInfo.parentAllowsChild); trace("sameDomain: " + loaderInfo.sameDomain); trace("sharedEvents: " + loaderInfo.sharedEvents); trace("swfVersion: " + loaderInfo.swfVersion); trace("url: " + loaderInfo.url); trace("width: " + loaderInfo.width); } } }
L’ouverture du code (Tamarin) de la Machine Virtuel ActionScript 2 (AVM2) ne pouvais ĂȘtre que bĂ©nĂ©fique. En voici une preuve !
Une librairie qui permet d’Ă©valuer du code ActionScript 3 EcmaScript 4 au run-time tout Ă©crit en AS3.
On a la possibilitĂ© en plus de gĂ©nĂ©rer le bytecode, dĂ©compiler du bytecode, de rĂ©cuperer les erreurs d’execution (tout ça Ă la volĂ©) :
La démo !
Une autre librairie permettais dĂ©jĂ de le faire depuis quelques temps, mais l’inconvĂ©nient c’est qu’elle est payante et ne bĂ©nĂ©ficie pas du projet Tamarin.
Moi qui veux dans un futur plus ou moins loin voir parallĂšle đ rĂ©aliser un moteur AS3/ES4 en JavaScript qui puisse utiliser le mĂȘme code JavaEcmaActionScript sur presque n’import quel navigateur (IE!, FF, Opera, Safari …) ça ne peut qu’aider !
J’ai aussi dans l’idĂ©e de faire un moteur Web (like Geko, Tridion, WebKit …) permettant en plus d’avoir une page HTML(+CSS +IMG +SWF) dans Flash de pouvoir supporter le JavaScript (voir mĂȘme de l’ES4), avec ça ça sera beaucoup plus facile !
Package AS3 supportant beaucoup d’algorithmes de cryptage/hashage/sĂ©curitĂ©
Beaucoup mieux que Adobe Core Lib !