2 Replies Latest reply on Nov 11, 2010 4:09 AM by deshggg

    How do I embed fonts at runtime (AS2 in CS3)?

    deshggg Level 1

      Hey everyone,

       

      I have a shared fonts.swf file containing a variety of fonts that my  main swf uses. I have a movieclip within the fonts.swf file which is  exported for runtime sharing. In my main swf i have the fonts.swf  imported for runtime via a movieclip. This all works fine and allows me  to use the fonts within the fonts.swf file in my main swf.

       

      I am trying to work out how to import fonts.swf for runtime via as2 (instead of manually within the library), as in different circumstances different fonts are required and it is massively increasing the filesize having to import all fonts every time when only a few are needed. I have read up on the internet about this and cannot for the life of me work out how to do it, i would be immensely grateful if someone could point me in the right direction?

       

      Thanks so much for any advice you can give, this has been confusing me for ages and i really would love to know how to do it!

       

      Dave

        • 1. Re: How do I embed fonts at runtime (AS2 in CS3)?
          kglad Adobe Community Professional & MVP

          it's doable but it's not easy.  here's the core coding but i don't think it's easy to understand and i haven't written a tutorial to teach how to use it:

           

          // kglad's code.  no need to edit **************************************************************
          function fontEmbedF(tf:TextField, font:String, callbackF:Function, callbackParams:Array) {
              // fontObj declared in fla
              fontObj["refA"] = [];
             
              if(!fontObj["setup"]){
                  // done once for all fonts
                  fontloadSetupF();
                  fontObj["setup"] = true;
              }
              // record orig tf properties
              var o:Object = recordTFPropsF(tf);
              loadFontF(o,tf,font,callbackF,callbackParams);
          }
          function loadFontF(o:Object,tf:TextField, font:String, callbackF:Function, callbackParams:Array) {
                  fontObj["mclLO"]["o"] = o;
                  fontObj["mclLO"]["currentFont"] = font;
                  fontObj["mclLO"]["callbackF"] = callbackF;
                  fontObj["mclLO"]["callbackParams"] = callbackParams;
                  // leave _root alone.  it should reference the _level containing this code
                  findReferencesF(tf,_root);
                 
                  var targetMC:MovieClip = createFontHolderMC(tf)
                  fontObj["mcl"].loadClip("fonts/"+fontObj[font],targetMC);
          }
          function fontloadSetupF(){
              fontObj["mcl"] = new MovieClipLoader();
              fontObj["mclLO"] = new Object();
              fontObj["mclLO"].onLoadInit = function(target){
                  // pseudo-duplicate textfield of tf.  tf is removed in createTF when its depth is taken
                  var newTF:TextField = createTF(this["o"],target);
             
                  restoreReferencesF(fontObj["refA"],newTF)
                 
                  assignTFPropsF(this["o"],newTF);
                  embedFontF(newTF,target);
                  this["callbackF"].apply(null,this["callbackParams"]);
              }
             
              fontObj["mclLO"].onLoadError = function(target,errorCode,httpStatus){
                  trace("onLoadError");
                  trace(target);
                  trace(errorCode);
                  trace(httpStatus);
              }
             
              fontObj["mcl"].addListener(fontObj["mclLO"]);
          }
          function embedFontF(tf:TextField,target:MovieClip){
              tf.embedFonts = true;
              var tfor:TextFormat = new TextFormat();
              tfor.font = target.fontID;
              tf.setTextFormat(tfor);
              tf.setNewTextFormat(tfor);
          }
          function assignTFPropsF(o:Object,tf:TextField){
              var tfPropA:Array = ["_alpha","_highquality","menu","_quality","_rotation","_soundbuftime","tabEnabled","_vis ible","_xscale","_yscale"]
             
              tf.setTextFormat(o.textFormat);
              tf.setNewTextFormat(o.newTextFormat);
             
              for(var s:String in tf){
                  tf[s] = o[s];
              }
              for(var i:Number=0;i<tfPropA.length;i++){
                  tf[tfPropA[i]] = o[tfPropA[i]];
              }
              if(tf.html && tf.htmlText){
                  tf.htmlText = o["htmlText"];
              } else if(tf.text){
                  tf.text = o["text"];
              } else {
                  tf.text = "";
              }
          }
          function recordTFPropsF(tf:TextField):Object{
              var tfPropA:Array = ["_alpha","_highquality","menu","_quality","_rotation","_soundbuftime","tabEnabled","_vis ible","_xscale","_yscale"]
              var o:Object = new Object();
              for(var s:String in tf){
                  o[s] = tf[s];
              }
              for(var i:Number=0;i<tfPropA.length;i++){
                  o[tfPropA[i]] = tf[tfPropA[i]];
              }
              o["newTextFormat"] = tf.getNewTextFormat();
              o["textFormat"] = tf.getTextFormat();
              o["tfX"] = tf._x;
              o["tfY"] = tf._y;
              o["tfW"] = tf._width;
              o["tfH"] = tf._height;
              o["tfName"] = tf._name;
              o["tfDepth"] = tf.getDepth();
             
              return o;
          }
          function createFontHolderMC(tf:TextField):MovieClip{
              var d:Number = Math.abs(tf.getDepth());
              var tfParent:MovieClip = tf._parent;
              if(!tfParent["mc"+d]){
                  // remove tf
                 mc=tfParent.createEmptyMovieClip("mc"+d,tf.getDepth());
              
              }
              return tfParent["mc"+d];
          }
          function createTF(o:Object,target:MovieClip):TextField{
              target.createTextField(o["tfName"],o["tfDepth"],o["tfX"],o["tfY"],o["tfW"],o["tfH"]);
              // reset references.  ie, was path.timeline.tf, now path.timeline.mc.tf
              // so:  path.timeline.mc._parent[tfName] = path.timeline.mc[tfName] or path.timeline[tfName] now points to path.timeline.mc[tfName]
              target._parent[o["tfName"]] = target[o["tfName"]];
             
              return target[o["tfName"]];
          }
          function restoreReferencesF(refA,newTF){
              for(var i=0;i<refA.length;i++){
                  refA[i][0][refA[i][1]] = newTF;
              }
          }
          function findReferencesF(tf,obj){
                  for(s in obj){
                  if(obj[s] == tf){
                      fontObj["refA"].push([obj,s]);
                  }
                  if(typeof(obj[s])=="movieclip" && obj[s]._parent == obj){
                      findReferencesF(tf,obj[s]);
                  }
                  // comment if-block below to speed processing IF associative array references to textfields are not used.
                 
                  if(typeof(obj[s])=="object"){
                      findReferencesF(tf,obj[s]);
                  }
                 
              }
          }

          • 2. Re: How do I embed fonts at runtime (AS2 in CS3)?
            deshggg Level 1

            Wow, thank you so much for the code, my apologies for the delay in replying i have been going through it and trying to work out what's going on, you are correct it is not that easy to understand (not for me anyway)! In its simplest form (so i can understand it better!) I have tried the following code which i thought should allow the use of a particular font on the specified textfield (assuming you don't need any callback function):

             

            fontObj = new Array();
            /*Your Functions */

            this.createTextField("titletext", getNextHighestDepth(), 0, 0, 200, 150);
            titletext.text='This is some test text';
            fontEmbedF(titletext, "Geneva.ttf");

             

            This obviously isn't right as the textfield goes blank after fontEmbed is run (and no replacement is made) and fontObj[font] (within loadFontF) is undefined (and I can't actuallly work out where this is set). Similarly i cannot work out where target.fontID (within embedFontsF) is set (and this also comes up as undefined). I have been messing with the code (purely so I can understand how it works rather than so as to change anything) and if i change:

             

            fontObj["mcl"].loadClip("fonts/"+fontObj[font],targetMC);

            to

            fontObj["mcl"].loadClip("fonts/"+font,targetMC);

             

            then it is able to load the font correctly (assuming a matching file is found within the fonts folder) however target.fontID is still undefined (i'm sure i'm not supposed to do this, but i was just trying it to see what happened!)

             

            I totally appreciate this is complicated and you probably don't have time to explain it to me in detail but would it be at all possible to provide me with some sample code similar to mine above that should enable it to function correctly on basic level, then i can much more easily look through it and see what is happening along the way?

             

            Thank you so, so much for your help, I am immensely grateful as this has been perplexing me for quite some time and there is no way i would have been able to come up with that myself!

             

            Dave