PDA

Click to See Complete Forum and Search --> : dynamic text - kern font



heppy
06-04-2001, 10:18 AM
I see its not possible to kern fonts when using 'dynamic text' this is a serious problem for me. Anyone have any idea how to get around this?

thanks

tone001
06-04-2001, 11:28 AM
Well i'm pretty sure there's no easy way in Flash itself .. i suspect the solution would be to alter the font itself in Fontographer so it had wider/smaller kerning, then you can create a new version of the TTF font file (with a new name)to use in your Flash file.

I used this technique to simulate normal bold and italic in non-HTML Flash 4 dynamic text boxes.

heppy
06-06-2001, 03:21 AM
Thats the solution i ended up with. However had to alter the spacing and not the kerning of the font, as the kerning information was not being read..

ThePromenader
10-14-2006, 08:57 AM
I have managed to find a solution to this problem for flash version <=6, albeit not a simple one.

First off, you'll have to have access to a font's kerning information. Myself I use Fontlab, and from the "Metrics" window can export this information in text format.

PHP file

Next you'll have to "clean up" the exported kerning data into arrays - Aa, Az, etc. If you want to use these with versions of Flash earlier than 7, you'll have to use php, as versions prior are case-insensitive. What I did was make a series of associative arrays based on the first letter in the kerning pair:


$s = array(a=>-25, o=>16);
$S = array(T=>-7);
$t = array(a=>-90,'-'=>-100);
$T = array(A=>-86, h=>-7, i=>-8);

and this array must be turned into yet another associative array with the first letter as keys:


$kern_array = array(a=>$a, A=>$A, c=>$c, d=>$d, e=>$e, F=>$F, etc

Everything above this line will change depending on the font/kerning information you are using.

Next you must take your input text, break it into individual letters and loop through the above two arrays.


$input_text = $_GET['phrase'];

$input_array=split("-1-", chunk_split($input_text,1,"-1-"));
array_pop($input_array);


Then you must loop through this array, checking to see if a) the letter being 'tested' is affected by kerning (is the letter in the second array?) and if it is, b) checking to see whether the letter after the 'tested' letter is in the list of letters to be kerned for the 'tested' letter.

In this you will build an array of kerning information with the same length as that of the text to be kerned. All letters not to be kerned will be set to a zero value, and all letters whose spacing will be modified will have its value retrieved from the kerning info array (note-the first letter, not kerned, is set to zero):


$spacing_array=array();
$spacing_array[0]=0;

for ($ii = 0;$ii<(count($input_array)-1);$ii++) {
if ($kern_array[$input_array[$ii]] != '') {
if ($kern_array[$input_array[$ii]] != '') {
if ($kern_array[$input_array[$ii]][$input_array[($ii+1)]] != '') {
$spacing_array[]=$kern_array[$input_array[$ii]][$input_array[($ii+1)]];
} else {
$spacing_array[]='0';
}
}
} else {
$spacing_array[]='0';
}
}

Now you must output the above arrays into a format flash understands (the following could be cleaner, but hey):


echo 'space_sequence=0';
for ($iv=1;$iv<count($spacing_array);$iv++) {
echo ', '.$spacing_array[$iv];
}
echo '&input_sequence=';
for ($vi=0;$vi<count($input_array);$vi++) {
echo utf8_encode($input_array[$vi]);
if ($input_array[($vi+1)] != '') {
echo ', ';
};
}

...all of the above should go into a .php file that you will call from flash. If you would like to test it, open it in a php-enabled site with "?phrase=HelloThere" after, and you should get the following:

space_sequence=0, 0, 0, 0, 0, 0, 0, -7, 0, 4, 0&input_sequence=H, e, l, l, o, , T, h, e, r, e

Flash file:

Now you must retrieve the data and reassemble the array (the lines with the "split()" functions). Also, in the flash file, it would be useful to prepare a movie containing a named dynamic text box, named in this case "letter". The first frame of the movie should contain a line:


this.letter.autoSize = "left";

...that will ensure that the text field will shrink to the letter width.

Now you must either create an empty clip on the stage through code, or have one already there, and populated it with one of the above movies for every letter. This code goes into the first frame of the root, but adapt it to whereever you want:


MyVars = new LoadVars ();
MyVars.load ("/path/to/above_php_file.php?phrase=TextToKern");
MyVars.onLoad = function () {
space_array = this.space_sequence.split( ', ' );
input_array = this.input_sequence.split( ', ' );
_global.arrayCount = input_array.length;
for (i=0;i<space_array.length;i++) {
_root.mainline.attachMovie("letterHolder", "letter_"+i, i+20);
_root.mainline["letter_"+i].letter.text=input_array[i];
}
};


The above will crunch all of the letters onto a single spot. Now we must space them correctly using the kerning info "space_array":


_root.mainline.onEnterFrame = function() {
mulnumber=.11;
basenumber=0;
widnumber=0;
for (i=0;i<_global.arrayCount;i++) {
basenumber=basenumber+_root.mainline["letter_"+(i-1)]._width + (_root.space_array[i]*mulnumber)-3;
_root.mainline["letter_"+i]._x=basenumber;
widnumber = _root.mainline["letter_"+i]._width
}


...now you may have noticed that the above is an "onEnterFrame" function, so once the letters are positioned correctly we will have no further need for this loop. What the below does is check to see that the width of the last "letter_#" movie loaded is equal to the width of the letter it contains - this done, the onEnterFrame quits:



if (widnumber == _root.mainline["letter_"+(_global.arrayCount-1)]._width) {
delete this.onEnterFrame;
/*perhaps position movie here*/
}
}

...and that should do it, your dynamic text should be correctly kerned. I hope I was clear in my explanation, and if not please don't hesitate to reply here. The complete code is in the attached .txt files.

Cheers,

ThePromenader