Question

<.. Petit retour en arrière / h2>

Je suis en train de faire un jeu OpenGL en utilisant Java et LWJGL . J'ai écrit une TextRenderer-classe qui rend le texte en utilisant les pages mises en cache des glyphes. Les Glyphes se sont rendus dans Java2D à BufferedImages et emballés dans des pages de texture ainsi que les mesures de glyphe. TextRenderer dessine les personnages comme quadriceps texture, en utilisant les informations mises en cache.

Tout cela fonctionne bien, sauf pour une chose: crénage manquante. Certes, ce n'est pas nécessaire d'avoir que le texte semble bien comme il est, mais il améliorerait la qualité si j'avais accès à la police des informations crénage.

Et la question est ..

Est-il possible d'obtenir les informations crénage en utilisant Java simple, d'une manière qui serait portable sur Windows, Linux et Mac OS X? Quand j'écrit le TextRenderer je l'ai brièvement regardé autour mais n'a pas pu trouver une telle façon ..

Une solution possible

S'il n'y a pas moyen de le faire en Java pur, je pensais écrire un outil distinct en utilisant Freetype . Comme indiqué dans leurs caractéristiques page:

  

FreeType 2 fournit des informations qui   est souvent pas disponible d'autres   Les moteurs de polices similaires, comme crénage   distances , les noms de glyphe, verticales   mesures, etc.

L'outil stockerait les paires de crénage pour les caractères communs dans un fichier que mon texte chargeait dans renderer et utiliser. Donc, ce qui est probablement ce que je vais faire si vous les gars ne viennent pas avec une meilleure alternative. :)

Était-ce utile?

La solution

Les bibliothèques que je connais qui a lu correctement l'information crénage « somwhat » sont iText FOP d'Apache.

http://www.1t3xt.info/api /com/lowagie/text/pdf/BaseFont.html http: / /svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-0_95/src/java/org/apache/fop/fonts/ (un lien vers le svn comme il semble y avoir aucune api en ligne)

Autres conseils

A partir de Java SE 6, Java peut fournir des informations crénage lorsque la police fournit. Il est désactivé par défaut et peut être activé comme ceci:

Map<TextAttribute, Object> textAttributes = new HashMap<TextAttribute, Object>();  

textAttributes.put(TextAttribute.FAMILY, "Arial");  
textAttributes.put(TextAttribute.SIZE, 25f);  
textAttributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);  

Font font = Font.getFont(textAttributes);  

Ce fil de discussion contient une discussion plus détaillée sur le sujet:

http://forums.sun.com/thread.jspa?threadID=5359127

sur mon chemin à trouver les informations crénage et en fournissant hors ligne dans mon javaScript, je lis cette question ici, aussi, et comme il n'y avait pas de réponse, je cherchai plus loin et à la fin je suis arrivé ceci:

Deux objets javascript qui peuvent être indexés par le unicode du glyphe:

GLYPHS = {};
KERNS  = {};

Et ils sont définis comme ceci:

// GLYPHS[ unicode ] = [ "name", width ];
// KERNS [ unicode ] = { "nextGlyphName"        : horizontalAdjustment };
//                   = { GLYPHS[ unicode ][ 0 ] : horizontalAdjustment };

Donc, si j'ai mon « texte » string, je passe par ce caractère par caractère et utiliser son unicode pour accéder au nom de glyphes et de la largeur comme ceci:

glUnicode = "Text".charCodeAt( strIndex );            // "T" == 84
glName    = GLYPHS[ glUnicode ][ 0 ];
glWidth   = GLYPHS[ glUnicode ][ 1 ];

Pour accéder à la valeur de crénage, nous devons examiner la prochaine valeur de caractères unicode qui est la suivante:

nextGlyphUnicode = "Text".charCodeAt( strIndex + 1 ); // "e" == 101

Et si l'objet existe suivant, alors cette déclaration vous donnera la largeur de crénage (vous devez vérifier l'existence d'abord comme ceci:

if ( !( KERNS[ glUnicode ] == undefined ) ) {
  if ( !( KERNS[ glUnicode ][ GLYPHS[ nextGlyphUnicode ][ 0 ] ] == undefined ) ) {
  ...

):

kernWidth = KERNS[ glUnicode ][ GLYPHS[ nextGlyphUnicode ][ 0 ] ];

Dans cet exemple, kernWidth pour le "e" après la "T" serait

kernWidth == -143

Je pense que, c'est ce que vous cherchez, non? Toutes les informations accessibles via la valeur unicode du caractère et de la valeur unicode du caractère suivant. Très simple et très agréable.

Alors j'ai créé un fichier pour chaque police et la première page ressemble à ceci:

// Family Name
// 'Times New Roman'
// EM size
// '2048'
// is_quadratic
// '1'
//
// GLYPHS[ unicode ] = [ "name", width ];
// KERNS [ unicode ] = { "nextGlyphName"        : horizontalAdjustment };
//                   = { GLYPHS[ unicode ][ 0 ] : horizontalAdjustment };
GLYPHS = {};
KERNS  = {};

GLYPHS[    32 ] = [ "space",  512 ];
KERNS [    32 ] = {
  "Upsilondieresis" :   -76,
  "Upsilon"         :   -76,
  "Tau"             :   -37,
  "Lambda"          :  -113,
  "Delta"           :  -113,
  "Alpha"           :  -113,
  "Alphatonos"      :  -113,
  "Y"               :   -76,
  "W"               :   -37,
  "V"               :   -37,
  "T"               :   -37,
  "A"               :  -113
};
GLYPHS[    33 ] = [ "exclam",  682 ];
GLYPHS[    34 ] = [ "quotedbl",  836 ];
GLYPHS[    35 ] = [ "numbersign", 1024 ];
GLYPHS[    36 ] = [ "dollar", 1024 ];
GLYPHS[    37 ] = [ "percent", 1706 ];
GLYPHS[    38 ] = [ "ampersand", 1593 ];
GLYPHS[    39 ] = [ "quotesingle",  369 ];
GLYPHS[    40 ] = [ "parenleft",  682 ];
GLYPHS[    41 ] = [ "parenright",  682 ];
GLYPHS[    42 ] = [ "asterisk", 1024 ];
GLYPHS[    43 ] = [ "plus", 1155 ];
GLYPHS[    44 ] = [ "comma",  512 ];
GLYPHS[    45 ] = [ "hyphen",  682 ];
GLYPHS[    46 ] = [ "period",  512 ];
GLYPHS[    47 ] = [ "slash",  569 ];
GLYPHS[    48 ] = [ "zero", 1024 ];
GLYPHS[    49 ] = [ "one", 1024 ];
KERNS [    49 ] = {
  "one"             :   -76
};
GLYPHS[    50 ] = [ "two", 1024 ];
GLYPHS[    51 ] = [ "three", 1024 ];
GLYPHS[    52 ] = [ "four", 1024 ];
GLYPHS[    53 ] = [ "five", 1024 ];
GLYPHS[    54 ] = [ "six", 1024 ];
GLYPHS[    55 ] = [ "seven", 1024 ];
GLYPHS[    56 ] = [ "eight", 1024 ];
GLYPHS[    57 ] = [ "nine", 1024 ];
GLYPHS[    58 ] = [ "colon",  569 ];
GLYPHS[    59 ] = [ "semicolon",  569 ];
GLYPHS[    60 ] = [ "less", 1155 ];
GLYPHS[    61 ] = [ "equal", 1155 ];
GLYPHS[    62 ] = [ "greater", 1155 ];
GLYPHS[    63 ] = [ "question",  909 ];
GLYPHS[    64 ] = [ "at", 1886 ];
GLYPHS[    65 ] = [ "A", 1479 ];
KERNS [    65 ] = {
  "quoteright"      :  -227,
  "y"               :  -188,
  "w"               :  -188,
  "v"               :  -152,
  "Y"               :  -188,
  "W"               :  -164,
  "V"               :  -264,
  "T"               :  -227,
  "space"           :  -113
};
GLYPHS[    66 ] = [ "B", 1366 ];
GLYPHS[    67 ] = [ "C", 1366 ];

Vous pouvez copier le contenu de chaque fichier que vous avez besoin dans votre code source ou le lire dans lors de l'exécution pour que les objets availlable.

Les fichiers peuvent être créés avec le script suivant qui fonctionne très bien au sein de l'interpréteur python « intégré » 2.7 du fontforge. Ce script est conçu pour une machine Windows, donc vous devez adapter vos chemins d'abord!

#
# run these two commands in the fontforge "embedded" python interpreter (ffpython.exe)
# >>> script = open( "Scripts\\Kernings.py", "r" )
# >>> exec script

import fontforge

fontFilenames = [
  "arial.ttf",
  "arialbd.ttf",
  "ariali.ttf",
  "arialbi.ttf",
  "ARIALN.TTF",
  "ARIALNB.TTF",
  "ARIALNI.TTF",
  "ARIALNBI.TTF",
  "calibri.ttf",
  "calibrib.ttf",
  "calibrii.ttf",
  "calibriz.ttf",
  "cambria.ttc",
  "cambriab.ttf",
  "cambriai.ttf",
  "cambriaz.ttf",
  "times.ttf",
  "timesbd.ttf",
  "timesi.ttf",
  "timesbi.ttf",
  "verdana.ttf",
  "verdanab.ttf",
  "verdanai.ttf",
  "verdanaz.ttf"
  ]

for actFontFile in fontFilenames :
  print( "c:\\windows\\fonts\\" + actFontFile )
  out  = open( "Scripts\\Kern_" + actFontFile[ : len( actFontFile ) - 4 ] + "_json.txt", "w" )
  font = fontforge.open( "c:\\windows\\fonts\\" + actFontFile )
  out.write(
      "// Family Name\n// '"  + font.familyname          + "'\n"
    + "// EM size\n// '"      + str( font.em )           + "'\n"
    + "// is_quadratic\n// '" + str( font.is_quadratic ) + "'\n"
    + "//\n"
    + '// GLYPHS[ unicode ] = [ "name", width ];\n'
    + '// KERNS [ unicode ] = { "nextGlyphName"        : horizontalAdjustment };\n'
    + "//                   = { GLYPHS[ unicode ][ 0 ] : horizontalAdjustment };\n"
    + "GLYPHS = {};\n"
    + "KERNS  = {};\n\n"
    )
  glyphIdIterator = font.__iter__()
  for glyphName in glyphIdIterator :
    if font[ glyphName ].unicode >=0 :
      kerningStrings = []
      outstring = ( "GLYPHS[ "
        + str( font[ glyphName ].unicode ).rjust( 5 ) + " ] = [ \""
        + glyphName + "\"," 
        + str( font[ glyphName ].width ).rjust( 5 ) + " ];\n"
        )
      subs = font[ glyphName ].getPosSub("*")
      if len( subs ):
        for sub in subs:
          if len( sub ):
            for subsub in sub:
              if str( subsub ).lower().find( "'kern'" ) >=0:
                kerningStrings.append(
                  ("  \"" + str( sub[ 2 ] ) + "\"").ljust( 20 )
                + ":"     + str( sub[ 5 ] ).rjust( 6 )
                )
                break
      krnStrLen = len( kerningStrings )
      if ( krnStrLen ) :
        outstring = outstring + ( "KERNS [ "
          + str( font[ glyphName ].unicode ).rjust( 5 ) + " ] = {" )
        for kerningString in kerningStrings :
          outstring = outstring + "\n" + kerningString + ","
        outstring = outstring.rstrip( "," )
        outstring = outstring + "\n};\n"
      out.write( outstring )
  out.close()
  font.close()

Je l'espère, cela peut aider. Merci beaucoup pour votre attention,

Richard

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top