2009-03-19 9 views
1

Je suis en train de concevoir un moteur de polices pour un affichage intégré. Le problème de base est le suivant:Comment ajouter un support UTF-8 et une table de fontes associée à un projet intégré?

Je dois prendre une chaîne de texte générée dynamiquement, rechercher les valeurs de cette chaîne dans une table UTF-8, puis utiliser la table pour pointer vers le tableau bitmap compressé de tous les pris en charge personnages. Après cela est terminée, j'appelle une routine bitcopy qui déplace les données du tableau bitmap à l'affichage. Je ne prendrai pas en charge le jeu de caractères UTF-8 complet, car j'ai des ressources système très limitées pour travailler avec (ROM 32K, 8K RAM), mais je veux pouvoir ajouter les glyphes nécessaires plus tard pour la localisation fins. Tout le développement se fait en C et en assemblage.

La taille du glyphe est de 16 bits maximum sur 16 bits. Nous aurons probablement besoin de soutien pour l'ensemble du plan multilingue de base (3 octets), car certains de nos plus gros clients se trouvent en Asie. Cependant, nous n'inclurions pas toute la table dans une localisation spécifique.

Ma question est la suivante:
Quelle est la meilleure façon d'ajouter ce support UTF-8 et la table associée?

Répondre

1

La solution ci-dessous suppose que les 16 bits inférieurs de l'espace Unicode seront suffisants pour vous. Si votre table bitmap a, disons U + 0020 à U + 007E aux positions 0x00 à 0x5E et U + 00A0 à U + 00FF aux positions 0x5F à 0xBE et U + 1200 à U + 1241 à 0xBF à 0xFF, vous pourriez faire quelque chose comme le code ci-dessous (qui n'est pas testé, pas même compilé-testé). Bitmapmap contient une série de paires de valeurs. La première valeur de la première paire est le point de code Unicode représenté par le bitmap de l'index 0. L'hypothèse est que la table bitmap contient une série de points de code Unicode directement adjacents. Donc, la deuxième valeur indique combien de temps cette série est.

La première partie de la boucle while parcourt l'entrée UTF-8 et crée un point de code Unicode dans ucs2char. Une fois qu'un caractère complet est trouvé, la deuxième partie recherche ce caractère dans l'une des plages mentionnées dans bitmapmap. S'il trouve un index bitmap approprié, il l'ajoute aux index. Les caractères pour lesquels aucun bitmap n'est présent sont supprimés en mode silencieux.

La fonction renvoie le nombre d'index bitmap trouvés.

Cette façon de faire devrait être efficace en mémoire en termes de table unicode-> bitmap, raisonnablement rapide et raisonnablement flexible.

// Code below assumes C99, but is about three cut-and-pastes from C89 
// Assuming an unsigned short is 16-bit 

unsigned short bitmapmap[]={0x0020, 0x005E, 
          0x00A0, 0x0060, 
          0x1200, 0x0041, 
          0x0000}; 

int utf8_to_bitmap_indexes(unsigned char *utf8, unsigned short *indexes) 
{ 
    int bitmapsfound=0; 
    int utf8numchars; 
    unsigned char c; 
    unsigned short ucs2char; 
    while (*utf8) 
    { 
     c=*utf8; 
     if (c>=0xc0) 
     { 
      utf8numchars=0; 
      while (c&0x80) 
      { 
       utf8numchars++; 
       c<<=1; 
      } 
      c>>=utf8numchars; 
      ucs2char=0; 
     } 
     else if (utf8numchars && c<0x80) 
     { 
      // This is invalid UTF-8. Do our best. 
      utf8numchars=0; 
     } 

     if (utf8numchars) 
     { 
      c&=0x3f; 
      ucs2char<<=6; 
      ucs2char+=c; 
      utf8numchars--; 
      if (utf8numchars) 
       continue; // Our work here is done - no char yet 
     } 
     else 
      ucs2char=c; 

     // At this point, we have a complete UCS-2 char in ucs2char 

     unsigned short bmpsearch=0; 
     unsigned short bmpix=0; 
     while (bitmapmap[bmpsearch]) 
     { 
      if (ucs2char>=bitmapmap[bmpsearch] && ucs2char<=bitmapmap[bmpsearch]+bitmapmap[bmpsearch+1]) 
      { 
       *indexes++ = bmpix+(ucs2char-bitmapmap[bmpsearch]); 
       bitmapsfound++; 
       break; 
      } 

      bmpix+=bitmapmap[bmpsearch+1]; 
      bmpsearch+=2; 
     } 
    } 
    return bitmapsfound; 
} 

EDIT: Vous avez mentionné que vous avez besoin de plus que les 16 bits inférieurs. s/unsigned court/non signé int /; s/ucs2char/codepoint /; dans le code ci-dessus et il peut ensuite faire l'ensemble de l'espace Unicode.

+0

Bonne réponse, merci pour votre aide. –

0

Vous n'avez pas spécifié la taille de vos caractères ni la taille de votre jeu de caractères, il est donc difficile d'estimer les dimensions requises.

Je stockerais les bitmaps dans un format linéaire, en fonction de la taille des caractères, il pourrait stocker assez efficacement sans avoir besoin d'emballer/décompresser les éléments. Par exemple, si nous prenons un alphabet de 36 caractères avec un caractère de 8x6, vous avez besoin de 216 octets de stockage pour le tableau. (6 octets/caractère * 36 - Chaque octet serait une tranche verticale du caractère).

Pour l'analyse, il suffit de faire un décalage dans la table.
Les vieux trucs (char - 'A') et (char - '0') se débrouillent plutôt bien.

L'autre question est où stocker le tableau bitmap. En ROM est la réponse évidente, mais si vous avez besoin de prendre en charge d'autres glyphes, il peut être nécessaire de reprogrammer, que vous ne spécifiez pas si c'est un problème.

Si les glyphes doivent être programmés dynamiquement, vous n'avez pas d'autre choix que de les mettre en RAM.

+0

Merci pour les commentaires, j'ai mis à jour la description du problème pour inclure la taille des caractères et (vaguement) répondre à votre question sur la taille du jeu de caractères. –

Questions connexes