Question

Les ligatures sont des caractères Unicode qui sont représentés par plus d'un point de code. Par exemple, dans Devanagari त्र est un ligatures qui se compose de points de code त + ् + र.

vu dans de simples éditeurs de fichiers texte comme le Bloc-notes, त्र est affiché comme त् + र et est stocké sous forme de trois caractères Unicode. Toutefois, lorsque le même fichier est ouvert dans Firefox, il apparaît comme un bon ligatures.

Alors, ma question est, comment détecter de telles ligatures programme pendant la lecture du fichier de mon code. Depuis Firefox le fait, il doit exister une façon de le faire par programme. Y a-t-il des propriétés Unicode qui contiennent ces informations ou ai-je besoin d'avoir une carte à tous ces ligatures?

SVG propriété CSS text-rendering lorsqu'il est réglé sur optimizeLegibility fait la même chose (combiner points de code dans ligatures approprié).

PS:. J'utilise Java

EDIT

Le but de mon code est de compter les caractères dans le texte Unicode en supposant un ligatures être un seul caractère. Donc je besoin d'un moyen de s'effondrer plusieurs points de code en un seul ligatures.

Était-ce utile?

La solution 4

Alors que réponse d'Aaron est pas tout à fait correct, il m'a poussé dans la bonne direction. Après avoir lu l'API Java docs de java.awt.font.GlyphVector et de jouer beaucoup sur la Clojure REPL, j'ai pu écrire une fonction qui fait ce que je veux.

L'idée est de trouver la largeur de glyphes dans la glyphVector et combiner les glyphes avec zéro largeur avec la dernière largeur de glyphe Trouvées non nulle. La solution est en Clojure, mais il devrait être traduisible à Java si nécessaire.

(ns net.abhinavsarkar.unicode
  (:import [java.awt.font TextAttribute GlyphVector]
           [java.awt Font]
           [javax.swing JTextArea]))

(let [^java.util.Map text-attrs {
        TextAttribute/FAMILY "Arial Unicode MS"
        TextAttribute/SIZE 25
        TextAttribute/LIGATURES TextAttribute/LIGATURES_ON}
      font (Font/getFont text-attrs)
      ta (doto (JTextArea.) (.setFont font))
      frc (.getFontRenderContext (.getFontMetrics ta font))]
  (defn unicode-partition
    "takes an unicode string and returns a vector of strings by partitioning
    the input string in such a way that multiple code points of a single
    ligature are in same partition in the output vector"
    [^String text]
    (let [glyph-vector 
            (.layoutGlyphVector
              font, frc, (.toCharArray text),
              0, (.length text), Font/LAYOUT_LEFT_TO_RIGHT)
          glyph-num (.getNumGlyphs glyph-vector)
          glyph-positions
            (map first (partition 2
                          (.getGlyphPositions glyph-vector 0 glyph-num nil)))
          glyph-widths
            (map -
              (concat (next glyph-positions)
                      [(.. glyph-vector getLogicalBounds width)])
              glyph-positions)
          glyph-indices 
            (seq (.getGlyphCharIndices glyph-vector 0 glyph-num nil))
          glyph-index-width-map (zipmap glyph-indices glyph-widths)
          corrected-glyph-widths
            (vec (reduce
                    (fn [acc [k v]] (do (aset acc k v) acc))
                    (make-array Float (count glyph-index-width-map))
                    glyph-index-width-map))]
      (loop [idx 0 pidx 0 char-seq text acc []]
        (if (nil? char-seq)
          acc
          (if-not (zero? (nth corrected-glyph-widths idx))
            (recur (inc idx) (inc pidx) (next char-seq)
              (conj acc (str (first char-seq))))
            (recur (inc idx) pidx (next char-seq)
              (assoc acc (dec pidx)
                (str (nth acc (dec pidx)) (first char-seq))))))))))

Également publié sur Gist .

Autres conseils

La page wikipedia du Computer Typesetting dit -

  

L'ordinateur moderne de caractères romains   muni d'TeX comprend les cinq   ligatures communes ff, fi, fl, ffi, et   FLP. Lorsque TeX trouve ces combinaisons   dans un texte, il remplace le   ligatures appropriée, à moins que   supplantée par le typographe.

Ceci indique qu'il est l'éditeur qui fait la substitution. Par ailleurs,

  

Unicode soutient que ligaturer est   une question de présentation plutôt qu'une   caractère question de la définition, et que,   par exemple, « si une police moderne   demandé à afficher « h » suivi de « r »,   et la police a une ligatures « h » en   , il peut afficher le ligatures. "

Pour autant que je vois (je suis certain intérêt à ce sujet et juste en train de lire quelques articles), les instructions de remplacement de ligatures est à l'intérieur de police couplées et plongées. Maintenant, je creusais en plus et trouvé ceux-ci pour vous; gsub - Le Glyphe table de substitution et ligatures Remplacement Soustable de la spécification du format de fichier OpenType.

Ensuite, vous devez trouver une bibliothèque qui peut vous permettre de pointe dans les fichiers de polices OpenType, à savoir l'analyseur de fichiers pour un accès rapide. La lecture de ce qui suit deux discussions peut vous donner quelques directions dans la façon de faire ces substitutions:

  1. http://code.google.com/p / chrome / questions / détail? id = 22240
  2. https://bugs.launchpad.net/firefox/+bug/37828

Ce que vous parlez ne sont pas ligatures (du moins pas dans le langage Unicode) mais les clusters graphèmes. Il y a une annexe standard concerne les limites de texte découverte, y compris les limites de cluster graphème:

http://www.unicode.org/reports/tr29 /tr29-15.html#Grapheme_Cluster_Boundaries

Voir aussi la description des grappes de graphèmes sur mesure dans les expressions régulières:

http://unicode.org/reports/tr18/#Tailored_Graphemes_Clusters

Et la définition de graphèmes de classement:

http://www.unicode.org/reports/tr10/#Collation_Graphemes

Je pense que ce sont des points de départ. La partie la plus difficile sera probablement de trouver une implémentation Java de l'algorithme de classement Unicode qui fonctionne pour les locales devanagari. Si vous trouvez une, vous pouvez analyser les chaînes sans avoir recours à des fonctions OpenType. Ce serait un peu plus propre depuis OpenType concerne les détails purement présentation et non pas avec le caractère ou la sémantique du cluster graphèmes, mais l'algorithme de classement et l'algorithme de calcul limite groupe graphème sur mesure regard comme si elles peuvent être mises en œuvre indépendamment des polices.

Vous pouvez être en mesure d'obtenir ces informations de la classe GlyphVector.

Pour une chaîne d'une instance de police donnée peut créer un GlyphVector qui peut fournir des informations sur le rendu du texte.

layoutGlyphVector () procédé de la police peut fournir.

Le FLAG_COMPLEX_GLYPHS attribut du GlyphVector peut vous dire si le texte ne comporte pas de 1 à 1 correspondance avec les caractères d'entrée.

Le code suivant montre un exemple de ceci:

JTextField textField = new JTextField();
String textToTest = "abcdefg";
FontRenderContext fontRenderContext = textField.getFontMetrics(font).getFontRenderContext();

GlyphVector glyphVector = font.layoutGlyphVector(fontRenderContext, textToTest.toCharArray(), 0, 4, Font.LAYOUT_LEFT_TO_RIGHT);
int layoutFlags = glyphVector.getLayoutFlags();
boolean hasComplexGlyphs = (layoutFlags & GlyphVector.FLAG_COMPLEX_GLYPHS) != 0;
int numberOfGlyphs = glyphVector.getNumGlyphs();

numberOfGlyphs doit représenter le nombre de caractères utilisés pour afficher le texte d'entrée.

Malheureusement, vous devez créer un composant graphique java pour obtenir le FontRenderContext.

Je pense que ce que vous cherchez vraiment est Unicode Normalization.

Pour Java, vous devriez vérifier http: // download.oracle.com/javase/6/docs/api/java/text/Normalizer.html

En choisissant la bonne forme de normalisation, vous pouvez obtenir ce que vous recherchez.

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