dcsimg
A Flash Developer Resource Site

Results 1 to 4 of 4

Thread: dynamic text - kern font

  1. #1
    Junior Member
    Join Date
    Aug 2000
    Posts
    7
    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

  2. #2
    Senior Member
    Join Date
    May 2001
    Posts
    180
    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.

  3. #3
    Junior Member
    Join Date
    Aug 2000
    Posts
    7
    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..

  4. #4
    Junior Member
    Join Date
    Oct 2006
    Posts
    1

    Solution

    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:

    Code:
    $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:

    Code:
    $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.

    Code:
    $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):

    Code:
    $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):

    Code:
    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:

    Code:
    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:

    Code:
    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":

    Code:
    _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:

    Code:
     
    	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
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center