سؤال

Ligatures هي أحرف Unicode التي يمثلها أكثر من نقطة رمز واحد. على سبيل المثال ، في Devanagari त्र هو الرباط الذي يتكون من نقاط الرمز त + ् + र.

عند رؤيته في محرري الملفات النصيات البسيطة مثل Notepad ، त्र يظهر كما त् + र ويتم تخزينه على أنه ثلاثة أحرف يونيكود. ومع ذلك ، عندما يتم فتح الملف نفسه في Firefox ، يتم عرضه كربط مناسب.

لذا فإن سؤالي هو ، كيفية اكتشاف مثل هذه الأربطة برمجياً أثناء قراءة الملف من الكود الخاص بي. نظرًا لأن Firefox يفعل ذلك ، يجب أن توجد طريقة للقيام بذلك برمجيًا. هل هناك أي خصائص Unicode التي تحتوي على هذه المعلومات أو هل أحتاج إلى خريطة لجميع هذه الأربطة؟

خاصية SVG CSS text-rendering عند ضبطها على optimizeLegibility هل نفس الشيء (الجمع بين نقاط الرمز في الرباط المناسب).

ملاحظة: أنا أستخدم جافا.

تعديل

الغرض من الكود الخاص بي هو حساب الأحرف في نص Unicode على افتراض أن الرباط ليكون حرفًا واحدًا. لذلك أنا بحاجة إلى طريقة لانهيار نقاط رمز متعددة في أربطة واحدة.

هل كانت مفيدة؟

المحلول 4

في حين إجابة هارون ليس صحيحًا تمامًا ، فقد دفعني في الاتجاه الصحيح. بعد القراءة من خلال مستندات 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))))))))))

نشر أيضا على جوهر.

نصائح أخرى

ال تنضيد الكمبيوتر صفحة ويكيبيديا تقول -

يشمل المحرف الروماني الحديث الذي تم توفيره مع Tex Ligatures الخمسة المشتركة FF و FI و FL و FFI و FFL. عندما يجد Tex هذه المجموعات في نص ، فإنه يحل محل الرباط المناسب ، ما لم يتم تجاوزه بواسطة typeetter.

هذا يشير إلى أن المحرر هو الذي يقوم باستبدال. علاوة على ذلك،

يؤكد Unicode أن ligaturing هو مشكلة عرض تقديمي بدلاً من مشكلة تعريف الشخصية ، وأنه ، على سبيل المثال ، "إذا طُلب من الخط الحديث عرض" H "متبوعًا بـ" R "، والخط لديه رابط" HR "فيه ، يمكن أن يعرض الرباط. "

بقدر ما أرى (لقد حصلت على بعض الاهتمام بهذا الموضوع وقراءة الآن عدد قليل من المقالات) ، يتم تضمين تعليمات بديل الرباط داخل الخط. الآن ، حفرت أكثر ووجدت هذه لك ؛ GSUB - جدول استبدال الرسول الرسومية و استبدال الرباط من مواصفات تنسيق ملف Opentype.

بعد ذلك ، تحتاج إلى العثور على بعض المكتبة التي يمكن أن تسمح لك بالذروة داخل ملفات خطوط Opentype ، أي محلل الملفات للوصول السريع. قراءة الاثنين التاليين مناقشات قد يعطيك بعض الاتجاهات في كيفية القيام بهذه البدائل:

  1. علة الكروم http://code.google.com/p/chromium/issues/detail؟id=22240
  2. حشرة فايرفوكس https://bugs.launchpad.net/firefox/+bug/37828

ما تتحدث عنه ليس أرباحًا (على الأقل ليس في لغة يونيكود) ولكن مجموعات Grapheme. هناك ملحق قياسي يهتم باكتشاف حدود النص ، بما في ذلك حدود مجموعة Grapheme:

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

انظر أيضًا وصف مجموعات Grapheme المصممة في التعبيرات العادية:

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

وتعريف الرسوم البيانية:

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

أعتقد أن هذه نقاط البداية. من المحتمل أن يكون الجزء الأصعب هو إيجاد تطبيق Java لخوارزمية ترتيب Unicode التي تعمل مع أماكن Devanagari. إذا وجدت واحدة ، يمكنك تحليل السلاسل دون اللجوء إلى ميزات Opentype. سيكون هذا أكثر نظافة لأن Opentype يهتم بالتفاصيل التقديرية البحتة وليس مع دلالات مجموعة الأحرف أو Grapheme ، ولكن خوارزمية التجميع وحدود مجموعة Grapheme المخصصة تبدو خوارزمية كما لو كان يمكن تنفيذها بشكل مستقل عن الخطوط.

قد تكون قادرًا على الحصول على هذه المعلومات من فئة GlyphVector.

بالنسبة لسلسلة معينة ، يمكن لمثيل الخط أن ينشئ glyphvector يمكنه تقديم معلومات حول تقديم النص.

ال layoutglyphvector () طريقة على الخط يمكن أن توفر هذا.

ال flag_complex_glyphs يمكن أن تخبرك سمة Glyphvector ما إذا كان النص لا يحتوي على رسم خرائط من 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 للحصول على FontrenderContext.

أعتقد أن ما تبحث عنه حقًا هو Unicode Normalization.

لجافا يجب عليك التحقق http://download.oracle.com/javase/6/docs/api/java/text/normalizer.html

من خلال اختيار نموذج التطبيع المناسب ، يمكنك الحصول على ما تبحث عنه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top