views:

634

answers:

3

I have a project coming up where I'll be rendering text paths on a circle; the text has to be dynamic, so I can't just bring in a precomputed set from illustrator.

Now, laying text on a circle ought not be too hard, I'll do it per character with per character rotation. The trouble is, I can't seem to figure out how to get per-character advance from flash's font engine. It's 99% probable that I'm just overlooking something obvious. But as far as I can tell, the only way to get flash font metrics is via flash.text.engine.FontMetrics which ostensibly is per-font, not per-character.

Any ideas?

A fallback that I'm not looking forward to implementing is pre-computing per-char advance on my own ( since this project will be using embedded fonts known in advance ). I've got ObjC code lying around for generating glyph maps for opengl, so I could generate that data offline and make it available to my flash code ( probably as static constants or some malarkey ).

P.S. This is my first question on StackOverflow, if I've asked the question poorly, please let me know.

A: 

You want TextLine.getAtomBounds(), and/or TextLine.getAtomGraphic().

Jonathan Feinberg
+2  A: 
import flash.text.TextLineMetrics;

Docs

and use

flash.text.TextField.getLineMetrics();

So, you would create a separate dynamic TextField (dynamically) for each letter. Place your first letter (say in TextField letter_1) and call:

var TLM:TextLineMetrics = letter_1.getLineMetrics(0);

This will give you the TextLineMetrics object for the first line (in your case a single letter.) Then use the width property to determine how much offset is needed for the next letter.

sberry2A
I don't have enough reputation to upvote you -- so thanks for this, it looks like my best bet!
TomorrowPlusX
Well, let's work on the rep and get an upvote! :) Good luck. If possible post an example when you get it working.
sberry2A
+1  A: 

I had to do something similar a long time ago. Since it was AS2 I used a snippet by senocular.

If you want letters in a line, that should easy enough using textWidth:

var theText:String = 'text on a path';
var letters:Array = [];
var lettersNum:int = theText.length;

for(var i:int = 0; i < lettersNum; i++){
    var t:TextField = new TextField();
    t.defaultTextFormat = new TextFormat('Verdana',12,0x000000);
    t.embedFonts = true;
    t.text = theText.charAt(i);
    t.selectable = false;
    letters.push(t);

    addChild(t);
    if(i > 0) t.x = letters[i-1].x + letters[i-1].textWidth;
}

I've tried to put things on a path quick and hacky using TweenMax.

import com.greensock.*; 
import com.greensock.easing.*;
import com.greensock.plugins.*;

TweenPlugin.activate([BezierThroughPlugin, BezierPlugin]);

var theText:String = 'text on a path';
var letters:Array = [];
var lettersNum:int = theText.length;

for(var i:int = 0; i < lettersNum; i++){
    var t:TextField = new TextField();
    t.defaultTextFormat = new TextFormat('Verdana',12,0x000000);
    t.embedFonts = true;
    t.text = theText.charAt(i);
    t.selectable = false;
    letters.push(t);

    addChild(t);
    //if(i > 0) t.x = letters[i-1].x + letters[i-1].textWidth;

    var tween:TweenMax = TweenMax.to(t, 3, {bezierThrough:[{x:0, y:0},{x:50, y:50},{x:100, y:0}], orientToBezier:true, ease:Linear.easeNone});
    tween.complete(true,true);
    tween.currentProgress = i/lettersNum;
}

Not a very good one. Nesting the TextFields in some sprites, to adjust the position of the letter on the path(vertical offset) would be handy, also, spacing is an issue as the BezierThrough is using Quadratic Beziers I think. Hermite Curves should be more precise.

Jim Armstrong is the man for the Math. His work on Degrafa is amazing, if you're not constrained, Degrafa already had plenty of features for this kind of things.

HTH

George Profenza