domingo, 29 de novembro de 2009

Loading True Type fonts in Flash/Flex at runtime

UPDATE 06/01/2010
  • It doesn't use Tamarin ESC Compiler anymore.
  • You can download the source code here.
-------------------------------------------------

Currently there are two usual ways to use embedded fonts in Flash/Flex:
  • Embed the font in the application SWF.
  • Or generate SWF files with the fonts, and then load them at runtime.
But with some tricks, it's also possible to load True Type fonts in a Flash/Flex application at runtime.

Click here to open an experiment I've made that does that.

What are the advantages?
  • It's easy to use and share fonts between Flash/Flex applications.
  • RIAs like text processors, image editors and others, can use this technique to allow users to use their own fonts.
How it was done?
  1. The font file (.ttf) is loaded and parsed.
  2. The glyphs are converted and a SWF file is generated in memory.
  3. Using the class flash.display.Loader, the in-memory SWF is loaded, and the font is registered.
What I've used?
Em português:

Atualmente, há duas maneiras usuais de utilizar fontes embutidas em uma aplicação Flash/Flex:
  • Gerar o SWF da aplicação com a fonte embutida.
  • Gerar arquivos SWF para as fontes, e carregá-los dinamicamente na aplicação.
Mas com alguns truques, também é possível carregar fontes True Type no Flash/Flex em tempo de execução.

Clique aqui para abrir um experimento que desenvolvi que faz isso.

Quais as vantagens?
  • Maior facilidade na utilização de fontes compartilhadas em aplicações Flash/Flex.
  • RIAs como processadores de texto, editores de imagens e outros, poderão utilizar o carregamento de fontes True Type para permitir aos usuários a utilização de suas próprias fontes.
Como isso é feito?
  1. O arquivo da fonte (.ttf) é carregado e interpretado.
  2. Os caracteres da fonte são convertidos e um arquivo SWF é gerado na memória.
  3. Utilizando a classe flash.display.Loader é feito o carregamento desse SWF, e a fonte é registrada.
O que utilizei?

9 comentários:

  1. Parebéns Lucas.

    A livraria swfassist é muito nova e poderosa, e dificilmente se acha artigos falando sobre ele, mesmo assim você realizou um ótimo projeto.

    Parebéns pelo trabalho.
    Abraços.

    ResponderExcluir
  2. Hi,

    Did you try this in Flex/AIR with CFF fonts? Any idea if it can be done?

    Cheers,
    Kai

    ResponderExcluir
  3. Kia, no, it doesn't load CFF fonts.

    Ryan

    ResponderExcluir
  4. Totally Exellent ! It's running fine on most .ttf, although sometimes I get horizontal line running accross the window.
    It's some kind of graphic bug, because moving the textfield makes it come and go.
    Any hint about it?

    Besides that it's a very helpfull example ! Thank you !

    ResponderExcluir
  5. It doesn't embed CFF fonts.

    Yeah, I saw that line bug, try Liu's project, it may not have that bug.
    http://portfolio.raisedtech.com/archives/as3-load-and-register-ttf-font-in-runtime/
    http://code.google.com/p/load-and-register-ttf-font-in-runtime/

    Later, AS3SWF became more mature and I swiched to it (replacing SWFAssist). But I will not share TTF loading classes again because Liu already did a good work on it :-)

    Lucas

    ResponderExcluir
  6. To follow up regarding CFF, it's actually really easy. You just need to add the DefineFont4 to the SWFAssist side of things, and then simply copy the entire CFF font bytes into the FONTDATA part of the DefineFont4 tag. Though you have to switch to using the new flash.text.engine package (use TextLine instead of TextField). I've got all this running in memory, at runtime, and works great. (and no horizontal line bug either)

    Ryan

    ResponderExcluir
  7. That's great Ryan.

    I tried to do that some time ago, but it didn't work.
    Good to know that you got it working, I will write the code again.

    Thanks for the tip.

    Lucas

    ResponderExcluir
  8. I actually tested it first by changing the bytes of an UNcompressed SWF file with an embedded CFF font.

    Then I copied all the bytes from another CFF font into the SWF file (you need to match the beginning/end byte patterns of the external CFF font to the beginning/end byte patterns of the embedded CFF of course).

    Then you need to update the DefineFont4 and SWF Headers to reflect the new lengths.

    Glad this information is helpful. Thanks for the great work.

    Ryan

    ResponderExcluir
  9. hi there

    Is there any reason why this code only work with setStyle and not with setFormatOfRange

    ResponderExcluir