Shared Fonts Today
[Please note that this post was originally posted on March 2005, there're much better ways of doing this nowadays. I keep it here so the internet doesn't get broken.]
[Este artículo fue publicado en Marzo de 2005, a día de hoy hay formas mucho mejores de hacer esto. Dejo el post más que nada para no romper internet.]
—
Introducción
El uso de tipografías compartidas en Flash nunca ha sido una tarea fácil. Desde hace 3-4 años se ha intentado resolver por varios caminos, algunos con mejor o peor resultado. Este método tampoco es perfecto. Estaría bien que Macromedia aprovechara la nueva versión de Flash para crear un método “científico” que solucionara de una vez por todas este problema.
Aproximaciones anteriores
Anteriormente se han intentado básicamente 2 caminos:
1) Utilización “normal” de librerías compartidas.
La utilización de las librerías compartidas implicaba que la carga de las películas externas no se hacía a través de loadMovie, por lo que el peso de la fuente se cargaba siempre en el primer frame de la película, con los consiguientes problemas de precarga. Además, este sistema no te permite llevar un control (a través de una clase para la gestión de las fuentes, componente o algo similar) de las fuentes que ya han sido cargadas.
Otro de los inconvenientes de utilizar librerías compartidas es que todas las películas que requieran la fuente harán la petición del archivo swf que la contiene, a pesar de que el archivo esté en la caché del navegador (siempre que no estemos en un entorno https o que por cualquier tipo de razón se hayan utilizado cabeceras de no-cache).
2) Carga dinámica de películas con las fuentes.
La resolución del problema que más se acercaba a lo que yo quería era la de Ivan Dembicki con su Shared Font Manager (SFM). Pero tenía una serie de problemas: 1) es de pago, 2) utiliza variables globales para la definición de los objetos TextFormat, 3) utiliza 2 archivos para cada fuente.
Objetivo
Crear un archivo swf por cada una de las tipografías que se vayan a compartir y poder cargarlos dinámicamente a través de loadMovie como si fuera un archivo externo más. La aplicación del formato de texto a los campos nuevos debe ser luego la más transparente posible, evitando además objetos TextFormat globales.
Solución
Puedes bajarte un zip con los fla (MX 2004) de ejemplo.
a) Creación de las películas con las fuentes.
Crear una única película por fuente era una de mis obsesiones, ya que no entendí nunca por qué debería haber 2. Además cuando hay 2 películas, la precarga se complica bastante ya que la película que se carga NO es la que realmente contiene la fuente. Eso quiere decir que se precargaba una película de, por ejemplo, 1kb, cuando la carga real podía ser de 15kb. Cuando sólo hay una película la precarga, evidentemente, es real.
La solución a este problema la encontré por puro azar y no creo que haya que enseñarsela a los niños en la escuela… simplemente funciona. Para saber por qué funciona, lo mejor es preguntar en www.macromedia.com ñ_ñ
- Crear una película nueva. Normalmente yo utilizo como nombre para el archivo el de la fuente que va a contener. Si el nombre tiene un espacio en blanco, los sustituyo por “_”. También es posible crear una película con varias fuentes, lo que puede ser muy útil para agrupar fuentes por proyectos y cargarla todas de una sola vez.
- Agregar un símbolo de tipografía a la biblioteca. Para agregarlo hay que hacer click en el botón de la parte superior derecha de la biblioteca y seleccionar “New Font”. Seleccionamos de la lista la fuente que deseamos y le damos el nombre que queramos, es indiferente. El de la propia fuente es una buena opción, simplemente por temas de organización.
- Hacer click con el botón derecho sobre el símbolo creado, seleccionar la opción “Export for runtime sharing” y como url poner la del archivo swf que resulta de compilar la película. Es decir, si tenemos el archivo fla “nombre_fuente.fla”, pues habría que poner “nombre_fuente.swf”.
- Crear un MovieClip vacío y darle como nombre “ForceShared” (esto es una copia de lo que hacía Branden J. Hall). Arrastralo al escenario. Abrir la biblioteca, hacer click con el botón derecho sobre el y seleccionar “Import for runtime sharing”. En la URL escribir la url que hemos definido en el paso anterior. IMPORTANTE: SI EL ARCHIVO DE LA FUENTE Y LA PELÍCULA QUE LO VA A CARGAR NO ESTÁN EN LA MISMA CARPETA, HAY DEFINIR ESTA RUTA RELATIVA A LA PELÍCULA QUE LA VA A CARGAR. Ver ejemplo en el fla de los archivos que está en “DistintaCarpeta”.
- Compilar. Si la ruta de exportación e importación no es la misma, se producirá un error de carga ya que no podrá cargar la ruta de importación. No pasa nada.
b) Utilización de las fuentes.
Cargar dinámicamente con loadMovie la película de la fuente.
Crear un objeto TextFormat y un campo de texto dinámicos como si la fuente estuviera en la biblioteca.Es decir, si la fuente que queremos cargar es “Quadaptor”, tendremos que definir la propiedad font del TextFormat así: myFomat.font=”Quadaptor”. El campo de texto tiene que incluir las fuentes con myField.embedFonts=true.
Enjoy :)
Problemas
De la misma forma que cualquiera de los otros métodos, éste que acabo de presentar también tiene incovenientes. Supongo que la elección de un método u otro dependerá de las necesidades de cada proyecto. Estos son los que yo he encontrado, si véis cualquier otro, por favor mandadme un mail para que lo pueda actualizar.
- No puede haber en la película campos de texto creados desde el IDE (ni siquiera estáticos) con la misma fuente que la que se va a cargar. Esto es tan sencillo como que si hay un campo de texto con la misma fuente que la que se ha cargado dinámicamente, los campos de texto a los que le apliquemos el TextFormat de la fuente dinámica dejarán de verse correctamente. La forma más sencilla de solucionar esto es crear con createTextField TODOS los campos de texto que utilicen la fuente dinámica. Esto NO AFECTA A LAS PELÍCULAS QUE LA PELÍCULA PRINCIPAL HAYA CARGADO DINÁMICAMENTE. Ver archivo fla de Errores/TextoEstatico para demostración.
- No es posible utilizar fuentes en cursiva o en negrita. No he conseguido utilizar una fuente en cursiva o negrita y no he encontrado otra forma de solucionarlo. Ver archivo fla de Errores/Cursiva para demostración.
- Los campos de texto tienen que tener la fuente incluida (campo.embedFonts = true), por lo que la fuente SIEMPRE estará suavizada.
- Problemas al hacer la precarga con la clase MovieClipLoader. Utilizando la clase MovieClipLoader para la carga del archivo de la fuente, me he dado cuenta de que el evento onLoadInit se dispara ANTES de que la fuente esté lista para usarse. Técnicamente yo creo que esto no debería ser así ya que la referencia pone claramente que este evento es llamado después de que las acciones del primer frame de la película se hayan ejecutado. En nuestro caso, no funciona así ya que se ejecuta primero el onLoadInit y luego los frames de la película cargada. En algunos casos el orden ha sido MovieClip, onLoadInit, Linea principal, lo que es aún más raro.¿Por qué sucede esto? Pues realmente no lo sé, pero supongo que será un “efecto colateral” de utilizar el mismo swf para la exportación y la importación. Si alguien puede aclararnos esto un poco, será de gran ayuda. La única forma que he encontrado para solucionarlo es: 1) esperar un frame o 2) crear un intervalo. Ver archivos fla de Errores/CargaMovieClipLoader y Errores/Trace para demostración. [Como se puede apreciar en la película de Errores/Trace, hay otro método de conseguir las fuentes dinámicas y consiste en sustituir el símbolo de fuente de la biblioteca por un MovieClip con un campo de texto con los caracteres incluidos. Esto puede ser especialmente útil cuando no se quiere incluir toda la fuente sino sólo unos caracteres, por ejemplos, sólo los números de un preload]
- Incompatibilidades de Player. Yo he probado con éxito el método en players 7 de Windows, Mac y Linux y player 6,0,79 de Windows. Habría que hacer una prueba intensiva porque es probable que de problemas en players anteriores.
Agradecimientos
Lo primero agradecer a todas las personas que han intentado esto antes, ya que sus trabajos han sido las bases de éste. También a Oscar Pérez y Gustavo Ramos por su labor de investigación y consejos cuando ya estaba completamente desesperado :D
Agradecería un voluntario/a que traduzca el artículo a inglés, ya que si lo hago yo seguro que el que lo lea no saca mucho beneficio :)
Enlaces