Frage

Ligatures sind die Unicode-Zeichen, die durch mehr als einen Codepunkt dargestellt werden. Zum Beispiel in Devanaga त्र ist eine Ligatur, welche Codepunkte त + ् + र besteht.

Wenn in einfacher Textdatei-Editoren wie Notepad zu sehen, ist त्र als त् + र dargestellt und gespeichert als drei Unicode-Zeichen. Allerdings, wenn die gleiche Datei in Firefox geöffnet wird, wird es als eine richtige Ligatur gezeigt.

Also meine Frage ist, wie solche Ligatur programmatisch zu erfassen, während die Datei von meinem Code zu lesen. Da Firefox es tut, muss es einen Weg gibt es es programmatisch zu tun. Gibt es Unicode-Eigenschaften, die diese Informationen enthalten, oder muss ich eine Karte zu diesen Ligaturen haben?

SVG CSS-Eigenschaft text-rendering , wenn auf optimizeLegibility die gleiche Sache tut (kombinieren Codepunkte in die richtige Ligatur).

. PS: Ich bin mit Java

EDIT

Der Zweck meines Codes ist es, die Zeichen im Unicode-Text zu zählen eine Ligatur unter der Annahme, ein einzelnes Zeichen zu sein. Also habe ich einen Weg benötigen mehrere Codepunkte in einem einzigen Ligatur kollabieren.

War es hilfreich?

Lösung 4

Während Aaron Antwort nicht genau richtig ist es, in der richtigen Richtung schob mich. Nach der Lektüre über die Java-API-Dokumentation von java.awt.font.GlyphVector und eine Menge auf dem Clojure REPL spielen, konnte ich eine Funktion schreiben, die das tut, was ich will.

Die Idee ist, die Breite der Glyphen in den glyphVector und kombinierte die Glyphen mit einer Breite von Null mit der zuletzt gefundenen Nicht-Null-Breite Glyphe zu finden. Die Lösung ist in Clojure, aber es sollte auf Java übersetzbar sein, falls erforderlich.

(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))))))))))

Auch geschrieben auf Gist .

Andere Tipps

Der Computer-Satz- Wikipedia-Seite sagt -

  

Der Computer Modern Roman Schriftart   versehen mit TeX umfasst die fünf   gemeinsame Ligatur ff, fi, fl, ffi und   ffl. Wenn findet TeX diese Kombinationen   in einem Text ersetzt es die   entsprechende Ligatur, es sei denn,   von den Schriftsetzer außer Kraft gesetzt.

Dies zeigt, dass es der Editor ist die Substitution der Fall ist. Außerdem

  

Unicode behauptet, dass Verengen ist   eine Präsentation Problem eher als eine   Zeichendefinition Problem, und dass,   zum Beispiel „wenn eine moderne Schriftart   fragte ‚h‘ durch ‚R‘ angezeigt werden,   und die Schrift eine ‚hr‘ Ligatur   es kann die Ligatur angezeigt werden soll. "

Soweit ich sehen (Ich habe ein gewisses Interesse an diesem Thema und gerade jetzt einige Artikel zu lesen), die Anweisungen für die Ligatur Ersatz innerhalb Schriftart eingebettet. Nun grub ich in mehr und fand diese für Sie; GSUB - Die Glyph-Substitutionstabelle und Ligatureinsetzung Untertabelle aus der Opentype-Dateiformatspezifikation.

Als nächstes müssen Sie einige Bibliothek finden, die Sie Spitze innerhalb Opentype-Schriftart-Dateien erlauben kann, das heißt Dateiparser für den schnellen Zugriff. Lesen Sie die folgenden zwei Diskussionen können Sie einige Richtungen geben, wie diese Ersetzungen zu tun:

  1. Chromium bug http://code.google.com/p / Chrom / Themen / detail? id = 22240
  2. Firefox Bug https://bugs.launchpad.net/firefox/+bug/37828

Was Sie sprechen sind über nicht Ligatur (zumindest nicht in Unicode parlance) aber Graphem-Cluster. Es ist eine Standard-Anlage, die mit der Entdeckung Text Grenzen betreffen, einschließlich grapheme Clustergrenzen:

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

Siehe auch die Beschreibung von maßgeschneiderten Graphem-Cluster in regulären Ausdrücken:

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

Und die Definition der Sortierungs Grapheme:

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

Ich denke, dass diese Punkte beginnen. Schwieriger wird wahrscheinlich eine Java-Implementierung des Unicode-Sortieralgorithmus, der arbeitet für Devanagari Gegenden zu finden sein. Wenn Sie eine finden, können Sie Zeichenfolge analysieren, ohne zu Opentype-Funktionen zurückgreifen. Dies wäre ein bisschen sauberer sein, da Opentype mit rein Präsentations Details betreffen und nicht mit Zeichen oder Graphem-Cluster Semantik, aber der Vergleich Algorithmus und die angepasste grapheme Clustergrenze Findungs-Algorithmus aus, als ob sie unabhängig von Schriften umgesetzt werden kann.

Unter Umständen können Sie diese Informationen aus der GlyphVector Klasse erhalten.

Für einen gegebenen String einer Font-Instanz eine GlyphVector erstellen kann, die Informationen über die Wiedergabe des Textes zur Verfügung stellen kann.

Die layoutGlyphVector () Methode auf dem Font kann dies bieten.

Die FLAG_COMPLEX_GLYPHS Attribut des GlyphVector können Ihnen sagen, wenn der Text nicht 1 zu 1-Mapping mit den eingegebenen Zeichen hat.

Der folgende Code zeigt ein Beispiel dafür:

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 sollte die Anzahl der Zeichen darstellen verwendet, um die Eingabe von Text angezeigt werden soll.

Leider benötigen Sie eine Java-GUI-Komponente zu erstellen, die FontRenderContext zu erhalten.

Ich denke, dass Sie, was wirklich suchen Unicode Normalization ist.

Für Java sollten Sie überprüfen, http: // download.oracle.com/javase/6/docs/api/java/text/Normalizer.html

Durch die richtige Normalisierungsform wählen, können Sie erhalten, was Sie suchen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top