Abh*_*kar 6 java unicode text clojure ligature
连字是Unicode字符,由多个代码点表示.例如,在Devanagari中???是一个由代码点组成的连字? + ? + ?.
在简单的文本文件编辑器中看到,如记事本,???显示为?? + ?并存储为三个Unicode字符.但是,当在Firefox中打开相同的文件时,它会显示为正确的连字.
所以我的问题是,如何从我的代码中读取文件时以编程方式检测此类连字.自从Firefox成功以来,必须有一种以编程方式完成它的方法.是否有任何包含此信息的Unicode属性,或者我是否需要有所有此类连字的映射?
text-rendering设置为SVG CSS属性时optimizeLegibility做同样的事情(将代码点组合成适当的连字).
PS:我正在使用Java.
编辑
我的代码的目的是计算Unicode文本中的字符,假设连字是一个单一字符.所以我需要一种方法将多个代码点折叠成一个连字.
虽然亚伦的答案并不完全正确,但它把我推向了正确的方向。在阅读了 Java API 文档java.awt.font.GlyphVector并在 Clojure REPL 上玩了很多之后,我能够编写一个可以完成我想要的功能的函数。
这个想法是找到 中字形的宽度,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))))))))))
Run Code Online (Sandbox Code Playgroud)
也发布在 Gist 上。