UPDATE: please use newer and improved version at http://wu-media.com/2009/05/extracting-vector-from-swfs-writing-and-now-drawing-with-them/
Drawing text in flash using font glyph information is definitely not new. five3D does it, PV3D uses the five3D files to do it. and Michael Baczynski also did it.
So what’s so different with my approach?
I extract the font glyphs from your SWFs, so you don’t need to go through the extra step of creating a Class that has a bunch of arrays describing your font. You can now embed fonts just as you normally would, and the best part is… you can use the same fonts with regular TextFields which lowers your overall file size.
SWF files store fonts as a bunch of ShapeRecords the same way it does with graphics youd draw on the Stage in the Flash IDE. These ShapeRecords are composed of a bunched of lineTo, moveTo, curveTo and styles instructions. For fonts we only need the first three. since we’ll be doing they styling in code when we’re about to draw text our text.
Now that we’ve extracted these ShapeRecords. I’ve created a DynamicText class that draws on a Graphics target. This target can be
- the graphics property of a DisplayObject
- the graphics3D property of a Shape3D in five3D
- the graphics property of a VectorShape3D in PV3D
Sample code:
1 2 3 4 5 6 7 | // extract font information from swf bytes DynamicText.extractFontInformation(root.loaderInfo.bytes, true); // set the style graphics.beginGradientFill(GradientType.LINEAR, [0xff4400, 0x0], [1, 1], [0x00, 0xff], m); // draw the ext DynamicText.write(graphics, "Futura Md BT", 20, 20, 0, "Hello World"); graphics.endFill(); |
Flash DisplayObject.graphics draw sample:
Noticed the gradient fill? because we’re using the flash drawing API, we can use beginFill, beginBitmapFill and beginGradientFill when drawing to a DisplayObject.
The DynamicText class has the following features,
- Kerning and Leading that use the same values as photoshop which makes it easier to match text styles to comps
- TextBlock alignment of TL, T, TR, L, C, R, BL, B, and BR. TLC, LC and BLC provides centering of the text within the text block
- Ability to align the text either using it’s baseline or it’s top or bottom edges. baseline alignment provides more accurate alignment, as the text starts from it’s baseline which also happens to be its zero point.
The same code can be use to draw on five3D and PV3D!
five3D Shape3D.graphics3D draw sample:
PV3D VectorShape3D.graphics draw sample:
Currently, It only works with fonts that were transcoded with the flash IDE. you can still embed the fonts with the [Embed] tag, as long as it’s from a SWF that was published with the flash IDE. embedding TTF directly with the [Embed] tags breaks my parser for some reason.
Source code: Download
Tags: ActionScript, ByteArray, PV3D

Great work! Anything that makes vector based fonts easier to use in 3D is incredibly helpful. Now how about extruding vector text. Thanks for the great work.
I have already made the same a while, but only extract some fonts informations in logs :
http://memmie.lenglet.name/documents/lab/cadratin/index.html
But yours is relay more complete :p
This is brilliant. Nice work
Mem’s
You were 80% there
I am using your api in my project in a mode in which there will typically be several Fonts registered concurrently. Thus, based on user interaction, I have a need to get the correct SWFDefineFont upon which to operate. There are probably other use cases where the same logic will be required.
After adding a private var _flags:uint and getting its value set,. these four getter methods seem to be working properly, and do simplify the ‘matching’ against Font.fontStyle:
public function get isRegular():Boolean { return ((_flags & 0×06) == 0); }
public function get isBold():Boolean { return ((_flags & 0×06) == 2); }
public function get isItalic():Boolean { return ((_flags & 0×06) == 4); }
public function get isBoldItalic():Boolean { return ((_flags & 0×06) == 6); }
They are written using the style of the rest of the code, so maybe you will want to add them to your source.
thanks. i’ll add those later today
When you add them, I imagine you will find my error! After further testing, it seems that the SWF document to which you provide the link is either out of date or just plain wrong with regards to which Flag bits are actually assigned to Italic and Bold. I wrote the code relying on the document’s table saying that information should be in bits 5 and 6, but when I tested, I did not get the correct results. Then, in your commented out code, I noticed that you were testing for Wide in bit 5, while the document would lead you to believe that that information should be in bit 7!
Evidently you either have a more up-to-date source of information, or you just kept trying combinations as I did until I found that, indeed, Italic and Bold are encoded using bits 6 and 7 respectively. So, at least for me, the actual modification that works is:
// Based on Wide being at 4 rather than 1 as tested above for kerning.
public function get isRegular():Boolean { return ((_flags & 0×03) == 0); }
public function get isBold():Boolean { return ((_flags & 0×03) == 1); }
public function get isItalic():Boolean { return ((_flags & 0×03) == 2); }
public function get isBoldItalic():Boolean { return ((_flags & 0×03) == 3); }
// public function get flag():uint { return (_flags); }
I had actually forgotten to add the properties
I went added and added these
also, I’m pretty sure we’re looking at the same documentation.
7. UB[1] Has font metrics/layout information.
6. UB[1] ShiftJIS encoding.
5. UB[1] SWF 7 or later: Font is small. Character glyphs are aligned on pixel boundaries for dynamic and input text.
4. UB[1] ANSI encoding.
3. UB[1] If 1, uses 32 bit offsets.
2. UB[1] If 1, font uses 16-bit codes; otherwise font uses 8 bit codes.
1. UB[1] Italic Font.
0. UB[1] Bold Font.
so Bold should be _flags & 0×01 and italic should be _flags & 0×02. I didn’t test these. I’m just assuming is right. let me know if you find it to be flawed.
[...] надежде найти уже готовое решение, обратился к гуглу. Гугл как всегда радует Тут решен вопрос и для graphics, и для graphics3D (Five3d), и для [...]
[...] источник – wu-media lab (Guojian Miguel Wu) использует несколько иной подход. Источником контуров служит загружаемая свфка(swf) в [...]
Very impressive! Thanks for sharing the code!
Very nice blog, your article is interesting, i have bookmarked it for future referrence
I am using VectorText.extractFont( . . . in Away3D in a Flash Builder4 Beta 2 project.
Would it be possible to extract fonts that are already embedded in the same swf file ( the FB4 output file ) instead of loading a swf for font extraction?
It would be more memory and load-time efficient to use the same embedded fonts for both regular and 3D text.
VectorText.extractFont takes any ByteArray including the that of the current swf.
VectorText.extractFont(root.loaderInfo.bytes);
[...] как-то стало неловко и я пошел искать как это делатся) Нашел Тут решен вопрос и для graphics, и для graphics3D (Five3d), Papervision3d [...]
exelent but doesn’t works with cyrilic
got this problem:
TypeError: Error #1010: … terms are not inited or has null value
at wumedia.text::DynamicText$/measureLines()
at wumedia.text::DynamicText$/write()
at TestFive3D/init()
at TestFive3D()
Sweet Post!
That is the fitting blog for anyone who needs to seek out out about this topic. You realize so much its nearly laborious to argue with you (not that I actually would need…HaHa). You positively put a new spin on a subject thats been written about for years. Great stuff, simply great!
Hallo daar, ik hou van uw blog. Is er iets wat ik kan doen om updates, zoals een abonnement of een of ander ding te ontvangen? Het spijt me ik ben niet bekend met RSS?
A better magazine theme would make the blog nicer.:)
I wish to voice my respect for your kind-heartedness in support of men who absolutely need help with this important idea. Your very own commitment to passing the solution up and down has been unbelievably practical and has continuously enabled others like me to achieve their pursuits. Your personal helpful information signifies a whole lot a person like me and even more to my office workers. Thank you; from everyone of us.