Вопрос

Лигатуры - это символы Unicode, которые представлены более чем одним кодовым точками. Например, в деванагари त्र это лигатура, которая состоит из кодовых точек त + ् + र.

Когда видно в простых текстовых редакторах файлов, таких как блокнот, त्र показано как त् + र и хранится как три символа Unicode. Однако, когда один и тот же файл открыт в Firefox, он показан как правильная лигатура.

Таким образом, мой вопрос, как определить такие лигации программно, читая файл из моего кода. Поскольку Firefox делает это, должен существовать способ сделать это программно. Существуют ли какие-либо свойства Unicode, которые содержат эту информацию или мне нужно иметь карту всем таким лигациям?

SVG CSS Property text-rendering При установке optimizeLegibility делает то же самое (сочетание кода указывает в правильную лигатуру).

PS: Я использую Java.

РЕДАКТИРОВАТЬ

Целью моего кода является подсчет символов в тексте Unicode, предполагая, что лигатура является одним символом. Поэтому мне нужен способ свернуть несколько точек кода в одну лигатуру.

Это было полезно?

Решение 4

Пока Ответ Аарона не совсем правильно, он подталкивал меня в правильном направлении. После прочтения через документы Java API java.awt.font.GlyphVector И много играет на Clojure Rep, я смог написать функцию, которая делает то, что я хочу.

Идея состоит в том, чтобы найти ширину глифов в glyphVector и объединяйте глифы с нулевой шириной с последним найденным ненулевым шириной глифом. Раствор находится в Clojure, но он должен быть переведен в Java, если требуется.

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

Также опубликовал на гид.

Другие советы

То Набор компьютеров Страница Википедии говорит -

Компьютер современный римский шрифт, снабженный TEX, включает в себя пять обычных лигатур FF, FI, FL, FFI и FFL. Когда TEX находит эти комбинации в тексте, он заменяет соответствующую лигатуру, если не переопределен на сеть сетевых данных.

Это указывает на то, что это редактор, который делает замену. Кроме того,

Unicode поддерживает, что лигатарирование представляет собой проблему презентации, а не проблемой определения характера, и что, например, «если современный шрифт просят отображать« h », а затем« R », и шрифт имеет лигатуру« HR »в этом это может отображать лигатуру. "

Насколько я вижу (я получил некоторую интерес к этой теме и только сейчас читаю несколько статей), инструкции по замене лигатуры встраиваются внутри шрифта. Теперь я выкопал в более и нашел их для вас; GSUB - таблица замещения глифа а также Лигатура замена субстативы из спецификации формата файлов OpenType.

Далее необходимо найти некоторую библиотеку, которая может позволить вам пик внутри файлов шрифтов OpenType, т. Е. Файловый парсер для быстрого доступа. Чтение следующих двух дискуссии Может дать вам некоторые направления в том, как сделать эти замены:

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

То, о чем вы говорите, не являются лигатурными (по крайней мере, не в формате Unicode), но графические кластеры. Существует стандартное приложение, которое связано с обнаруживанием границ текстовых границ, включая графические границы кластера:

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

Также см. Описание адаптированных графических кластеров в регулярных выражениях:

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

И определение графиков сопоставления:

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

Я думаю, что это начинающие. Чем сложнее участие, вероятно, будет находить реализацию Java алгоритма сопоставления Unicode, который работает для локалей Деванагари. Если вы найдете один, вы можете проанализировать строки, не прибегая к функциям OpenType. Это будет немного уборщиком, поскольку OpenType связан с чисто презентационными деталями, а не с семантикой символов или графической кластеры, а алгоритм сопоставления и адаптируемой графической кластером граничной кластеры нахождения алгоритма поиска, как будто их можно реализовать независимо от шрифтов.

Вы можете получить эту информацию из класса Glyphvector.

Для данной строки экземпляр шрифта может создать глифвектор, который может предоставить информацию о рендеринге текста.

То Layoutglyphvector () Способ на шрифте может дать это.

То Flag_complex_glyphs. Атрибут глифвектора может сказать вам, если текст не имеет сопоставления от 1 до 1 со входными символами.

Следующий код показывает пример этого:

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 должен представлять количество символов, используемых для отображения входного текста.

К сожалению, вам нужно создать компонент Java GUI для получения FontredeCteCtext.

Я думаю, что то, что вы действительно ищете Unicode Normalization.

Для Java вы должны проверить http://download.orcle.com/javase/6/docs/api/java/text/normalizer.html.

Выбирая правильную форму нормализации, вы можете получить то, что вы ищете.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top