Foros del Web » Programando para Internet » PHP »

Lectura de fuentes

Estas en el tema de Lectura de fuentes en el foro de PHP en Foros del Web. Hola!. El asunto es que en http://www.sobreinternet.com/fuentes.php , tengo 758 fuentes gráficas. El tema es que me preguntaba si habría alguna manera de leer los ...
  #1 (permalink)  
Antiguo 03/08/2003, 13:12
Avatar de Kaiser  
Fecha de Ingreso: febrero-2001
Ubicación: Heredia, Costa Rica
Mensajes: 239
Antigüedad: 23 años, 2 meses
Puntos: 1
Información Lectura de fuentes

Hola!.

El asunto es que en http://www.sobreinternet.com/fuentes.php , tengo 758 fuentes gráficas. El tema es que me preguntaba si habría alguna manera de leer los ficheros .TTF, en búsqueda de la información de derechos de la fuente, fecha de creación... autor... etc.

Cuando abro el file viene todo encriptado, por lo que creo que no se puede... pero talvez alguien aca sepa.

Saludos.
  #2 (permalink)  
Antiguo 04/08/2003, 01:36
 
Fecha de Ingreso: julio-2003
Mensajes: 165
Antigüedad: 20 años, 9 meses
Puntos: 1
Hola,

Debo confesar que me ha causado mucha curiosidad el problema que describes. En realidad, el simple hecho de involucrar el estudio de un formato de archivos que desconocía por completo (el formato de fuentes TrueType) me ha parecido suficientemente interesante como para querer encontrar una solución al problema. Siempre es bonito aprender cosas nuevas y poner en práctica los conocimientos en problemas reales como el que has propuesto.

Es por esto que le he dedicado un poco de mi tiempo al estudio del problema y a la creación de una implementación en PHP de un programa que pueda recuperar la información que mencionas de un archivo TTF.

Antes que nada, debo decir que ciertamente he encontrado muy completa y clara la documentación que se ofrece en el sitio web de microsoft al respecto:

http://www.microsoft.com/typography/specs/default.htm

De allí, el documento que encontré más importante para el desarrollo de la solución que a continuación presento ha sido el Capítulo 2 de las especificaciones de TrueType (aquel con el nombre ``The TrueType font file'').

Así que, con la ayuda de un amigo quien amablemente me facilitó el documento (originalmente en formato de microsoft word) en un formato no-propietario, me di a la tarea de estudiar la `anatomía' de los archivos TTF. Estos archivos no se encuentran encriptados, y de hecho están organizados en `tablas' en donde se ubican muy cómodamente todos los registros de datos de la fuente.

La información que mencionas; cosas como nombre del autor, copyright y demás, suele ubicarse en una tabla conocida como `name'. Su formato está claramente descrito en el documento que he indicado anteriormente.

En fin, sin más charla, a continuación te presento una implementación sencilla de un programa en PHP que recupera y presenta la meta-información relevante de los archivos TTF. Por favor, siéntete libre de estudiarlo y usarlo en cualquier modo que desees:

Código:
<?php

// Este trozo de codigo se encarga de leer un segmento de
// meta-informacion de un archivo TTF; especificamente, los datos de
// la tabla `name' (cosas como informacion de copyright, nombre de la
// fuente, version, etc.)

// Areas en donde puede mejorarse este pequenyo programa:
//   - Leer secuencialmente el contenido de las tablas de directorio
//   - Chequear las sumas de verificacion
//   - Realizar algunos chequeos triviales sobre el proceso de lectura
//     desde el archivo
//   - Procesar algunos campos de cada registro `name' que por ahora
//     se estan ignorando: ID especifico de plataforma, ID de lenguaje.


// Variables importantes para este programa

$archivo_ttf = './ejemplo.ttf';  // Ruta al archivo TTF a analizar

// Valor booleano que indica si la informacion cargada desde el
// archivo TTF debe ser procesada para obtener unicamente caracteres
// `regulares' (alfanumericos y espacios) de cada registro. Esto puede
// resultar util ya que, en muchos casos, los caracteres que describen
// la meta-informacion de los archivos TTF se encuentran codificados
// como `palabras' (registros de 2 bytes), de modo que algunos bytes
// extranyos podrian ser simplemente retirados. Si desea manipular el
// contenido `crudo' de los registros, puede asignarle a esta variable
// el valor `false'.

$solo_caracteres_regulares = true;


// Funcion de apoyo que recibe una cadena de bytes y lo transforma en
// un valor entero sin signo, asumiendo que el valor esta representado
// como big-endian (byte mas significativo primero)

function valor_big_endian ($cadena)
{
    $l = strlen ($cadena);

    $valor = 0;
    for ($i = $l - 1; $i >= 0; $i--)
        $valor += ord ($cadena{$i}) << ($l - $i - 1) * 8;

    return $valor;
}


// Otra funcion que se encarga de retirar todos los caracteres
// extranyos de una cadena determinada, y devuelve la cadena
// `limpia'. Esta funcion trabaja basada en el resultado de
// ctype_print().

function limpiar_cadena ($cadena)
{
    $nueva = '';

    $l = strlen ($cadena);
    for ($i = 0; $i < $l; $i++)
        if (ctype_print ($cadena{$i}))
            $nueva .= $cadena{$i};

    return $nueva;
}


// Aqui inicia el programa principal

// Abrir el archivo TTF. Probablemente sea una buena idea pasar la
// bandera `b', en caso de que el sistema operativo sea de aquellos
// que diferencia entre ``modo texto'' y ``modo binario''.

$ap = fopen ($archivo_ttf, 'rb');

if (! $ap) {
    print "Ha ocurrido un error y no ha sido posible abrir el archivo " .
        "$archivo_ttf\n";
    exit (1);
}


// Primero, busquemos la tabla de directorio que contiene la
// referencia a la tabla `name'. Podria implementarse un mecanismo de
// busqueda mas estricto y coherente con la especificacion del formato
// TrueType (es decir, leer todas las tablas de directorio
// secuencialmente), pero, por simplicidad, nos limitaremos a buscar
// el campo `tag' correspondiente de forma directa.

for ($bufer = fread ($ap, 4); $bufer != 'name' && ! feof ($ap);
     $bufer = substr ($bufer, 1) . fread ($ap, 1));

if (feof ($ap)) {
    fclose ($ap);
    print "No se ha encontrado informacion relevante sobre el archivo TTF.";
    exit (1);
}


// Contenido de la tabla de directorio `name'; suma de verificacion,
// desplazamiento y longitud. Por ahora simplemente ignoraremos la
// suma de verificacion... Por supuesto, seria interesante calcular la
// suma de verificacion real de la tabla y comparar su valor con este
// registro. Quizas si se encuentra aburrido un dia de estos, quiera
// dedicarle su tiempo a este bonito problema.

fread ($ap, 4);  // Suma de verificacion ignorada

$offset = valor_big_endian (fread ($ap, 4));  // Desplazamiento
$length = valor_big_endian (fread ($ap, 4));  // Longitud


// Leer el contenido de la tabla `name'. Quizas sea buena idea agregar
// algunos chequeos que se aseguren de la integridad del
// proceso. Pero, perezosamente, asumiremos que el contenido de la
// tabla de directorio es correcta.

fseek ($ap, $offset, SEEK_SET);
$tabla = fread ($ap, $length);

fclose ($ap);  // Ya hemos cargado todo lo que nos interesa desde el
               // archivo. Ya puede retirarse, senyor `handler'.


// Separar el contenido de la tabla en los campos que nos interesan

// Numero de registros `name'
$n = valor_big_endian (substr ($tabla, 2, 2));

// Desplazamiento del area de datos
$data_offset = valor_big_endian (substr ($tabla, 4, 2));


// Leer cada registro y procesarlo

$registros = array ();
for ($i = 0; $i < $n; $i++) {

    // Informacion de cada registro tipo `name': ID de plataforma, ID
    // especifico de plataforma, ID de lenguaje, ID de nombre,
    // longitud de cadena, desplazamiento de datos. Por ahora,
    // ignoraremos dos de los tres primeros valores...

    $plat_id    = valor_big_endian (substr ($tabla, 6 + 12 * $i, 2));
    $name_id    = valor_big_endian (substr ($tabla, 12 + 12 * $i, 2));
    $str_len    = valor_big_endian (substr ($tabla, 14 + 12 * $i, 2));
    $str_offset = valor_big_endian (substr ($tabla, 16 + 12 * $i, 2));

    $datos = substr ($tabla, $data_offset + $str_offset, $str_len);

    $registros[$plat_id][$name_id] = $solo_caracteres_regulares ?
        limpiar_cadena ($datos) : $datos;
}


// Ahora toda la informacion que queriamos se encuentra en el arreglo
// $registros. Podemos mostrarla ahora (lo haremos usando tablas).

print <<<EOC
<p>
La fuente contenida en el archivo <strong>$archivo_ttf</strong> posee
la siguiente meta-informacion:
</p>
EOC;

reset ($registros);

while (list ($plat_id, $data) = each ($registros)) {
    print "<br />\n<br />\n";
    print "<table border=\"1\">\n<tr>\n<td>Plataforma:</td>\n<td>";

    switch ($plat_id) {
    case 0:
        print "Apple Unicode";
        break;

    case 1:
        print "Macintosh";
        break;

    case 2:
        print "ISO";
        break;

    case 3:
        print "Microsoft";
        break;

    default:
        print "Desconocida";
        break;
    }

    print "</td>\n</tr>\n";

    reset ($data);
    while (list ($name_id, $string) = each ($data)) {
        print "<tr>\n<td>";

        switch ($name_id) {
        case 0:
            print "Copyright: ";
            break;

        case 1:
            print "Familia de fuente: ";
            break;

        case 2:
            print "Subfamilia de fuente: ";
            break;

        case 3:
            print "ID unico de fuente: ";
            break;

        case 4:
            print "Nombre completo de fuente: ";
            break;

        case 5:
            print "Version: ";
            break;

        case 6:
            print "Nombre postscript de la fuente: ";
            break;

        case 7:
            print "Marca registrada: ";
            break;
        }
        print "</td>\n<td><code>$string</code></td>\n</tr>\n";
    }

    print "</table>\n";
}

?>
Un cordial saludo.
  #3 (permalink)  
Antiguo 04/08/2003, 01:44
Avatar de Kaiser  
Fecha de Ingreso: febrero-2001
Ubicación: Heredia, Costa Rica
Mensajes: 239
Antigüedad: 23 años, 2 meses
Puntos: 1
Estoy simplemente sin palabras. El trabajo que desarrollaste es magnifico.

Te agradezco el aporte, y se que para muchos será de una utilidad incalculable.

Te pido por favor que me brindes tu nombre, para incluirlo en los créditos de la actualización que realizare a la sección de fuentes.

__________________
http://www.abdicar.com - Undisputed Hosting Leader!
  #4 (permalink)  
Antiguo 04/08/2003, 03:46
Avatar de epplestun  
Fecha de Ingreso: octubre-2001
Mensajes: 1.621
Antigüedad: 22 años, 5 meses
Puntos: 5
Un pequeño apunte jej necesitas tener compilado PHP con soporte para ctype es decir, en tu ./configure deberas indicarle un --enable-ctype para que ese programa funcione correctamente , por defecto a partir de la version 4.2.0 queda activado por defecto pero bueno por las moscas ... no esta de mas saberlo
__________________
Usuario registrado de Linux #288725
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:21.