
793 زوجًا متشابهًا مفقودًا من Unicode TR39، مجموعة بيانات عبر النصوص لأول مرة في العالم، تقييم SSIM مدرك للخطوط عبر 230 خط وأكثر من 22,000 حرف
تسجيل تشابه الحروف الرسومية التجريبي باستخدام تتبع الشعاع من الخطوط المتجهة. يعرض أزواج الأحرف المربكة في Unicode عبر 245 خط نظام، ويقيس التشابه الهيكلي مباشرة من ملامح الخط (بدون معالجة نقطية)، وينتج مخرجات JSON مسجلة بدرجات مسافة مستمرة لكل خط.
نتائج رئيسية من 52.6 مليون مقارنة لحرف واحد و190 مليون مقارنة متعددة الأحرف عبر 22,581 حرفًا و12 نظام كتابة:
المخرجات تُغذي مباشرة namespace-guard للكشف عن التشابه المربك في وقت التشغيل في أسماء الحزم وأسماء النطاقات والمعرفات.
يقوم RaySpace بإطلاق أشعة متوازية عبر ملامح الخطوط بزوايا 36 ويلتقط خمس طبقات من المعلومات لكل حرف رسومي: أعداد التقاطعات، مواقع التقاطعات، زوايا التقاطعات، مسافات النبض (عرض الضربة عند كل تقاطع)، وأقصى نبض (عرض العداد بين التقاطعات). ينتج عن ذلك توقيع مضغوط لكل حرف في كل خط. تتم مقارنة توقيعين باستخدام مسافة L1 موزونة عبر جميع الطبقات الخمس.
مصفاة متتالية من ثلاث مراحل تجعل المقارنة الشاملة ممكنة:
بنك التوقيعات (أكثر من 294,646 إدخال عبر 245 خطًا؛ المزيد مع --include-uppercase) يُحسب مسبقًا مرة واحدة. ثم يعمل الاكتشاف كعملية حسابية أحادية الخيط على البنك، مكملاً 52.6 مليون مقارنة زوجية في 31 دقيقة دون خيوط عمل أو GPU.
npm install
# 1. Build the ray signature bank (prerequisite, ~24 min)
npx tsx scripts/build-signature-bank.ts
# 1b. Include uppercase Latin A-Z (optional)
# By default the bank only includes IDNA PVALID codepoints (lowercase,
# digits, symbols). Use --include-uppercase to add uppercase A-Z, useful
# for font identification and trademark visual comparison where uppercase
# glyph shapes matter. The builder is resumable, so this only computes
# the additional codepoints.
npx tsx scripts/build-signature-bank.ts --include-uppercase
# 1c. Include arbitrary codepoint ranges (optional)
npx tsx scripts/build-signature-bank.ts --extra-range=0041-005A
# 2. Single-char discovery (22,581 chars, 12 scripts, ~36 min)
npx tsx scripts/discover-singlechar-sdf.ts --scorer=ray
# 3. Multi-char (bigram) discovery (676 bigrams, ~63 min)
npx tsx scripts/discover-multichar-sdf.ts --scorer=ray
# 4. Score known TR39 multi-char confusables (~5 min)
npx tsx scripts/score-multichar-sdf.ts --scorer=ray
الأنابيب الأصلية المستندة إلى SSIM سجلت 26.5 مليون مقارنة عبر 230 خطًا. لا تزال عاملة ولكن تم تجاوزها بواسطة RaySpace لجميع مهام الاكتشاف والتسجيل.
# TR39 confusable pair scoring
npx tsx scripts/build-index.ts # Render index (~160s, 11,370 PNGs)
npx tsx scripts/score-all-pairs.ts # Score all pairs (~65s, 235K comparisons)
# Novel confusable discovery
npx tsx scripts/build-candidates.ts # Candidate set (~23K chars)
npx tsx scripts/build-index.ts --candidates # Render candidates (~40min, 89K PNGs)
npx tsx scripts/score-candidates.ts # Score against Latin targets (~15min, 2.9M comparisons)
# Extract high-scoring discoveries from both pipelines
npx tsx scripts/extract-discoveries.ts
الأصفار = الخطوط حيث تنتج الملامح توقيعات شعاعية متطابقة بتًا (مسافة 0.000). w اللاتينية/ԝ السيريلية متطابقتان في جميع الخطوط الـ19 التي تحتوي على كلا الحرفين.
يشكل الحرف الجورجي Coda (U+10FF) حلقة مربكة رباعية الاتجاهات مع o اللاتينية وo السيريلية وomicron اليونانية، جميعها تحت مسافة 0.08.
اكتشاف oy/الـ uk السيريلية هو النتيجة الجديدة البارزة: الزوج الثنائي اللاتيني "oy" متطابق بصريًا مع الحرف المزدوج السيريلي uk (ѹ) على مسافة 0.000 في Helvetica و0.0005 في Arial Unicode MS.
| عتبة المتوسط |
|---|
ثلاث مستويات تشغيل موصى بها:
الاستعلام عن الأزواج المربكة الموجودة لخط معين. مفيد لمصممي الخطوط الذين يشحنون محرفًا جديدًا، لبائعي المتصفحات الذين يقيمون تغيير خط النظام، أو لأي شخص يختار خط عرض للسياقات الحساسة أمنيًا مثل نطاقات IDN.
npx tsx scripts/query-font.ts --list-fonts # 218 fonts in discovery data
npx tsx scripts/query-font.ts "Arial" # All pairs for Arial (SSIM >= 0.7)
npx tsx scripts/query-font.ts "Arial" --threshold 0.8 # High-confidence only
npx tsx scripts/query-font.ts "Arial" --compare "Georgia" # Diff two fonts by SSIM delta
npx tsx scripts/query-font.ts "Arial" --json # JSON for downstream processing
مطابقة اسم الخط هي سلسلة فرعية غير حساسة لحالة الأحرف، لذا فإن "arial" يطابق Arial وArial Black وArial Unicode MS. وضع المقارنة يرتب حسب أكبر اختلافات SSIM أولاً، مما يكشف بالضبط الأزواج التي تتحسن أو تسوء عند تبديل الخطوط.
يتطلب ملفات الاكتشاف من أنابيب التسجيل (مهملة في git، يُعاد توليدها محليًا).
| الملف | الوصف |
|---|---|
data/output/render-index/ | صور PNG للعرض + الفهرس (أنابيب SSIM) |
confusable-weights-v2.json مع سجلات توزيعية لكل زوج: المتوسط، p50، p90، عدد الخطوط، عدد المسافة الصفرية، جزء المسافة الصفرية، والمستوى الموصى به (صارم/قياسي/استكشافي). مسافات RaySpace تحل محل SSIM. 4,174 زوجًا عند العتبة القياسية.confusable-weights.json لتقييم المخاطر البصرية المقاسة عبر confusableDistance({ weights })كتابات على paultendo.github.io تغطي النتائج والمنهجية وراء هذا المشروع:
منهجية RaySpace ونتائجها:
نتائج أنابيب SSIM:
كتابات تغطي مساحة المشكلة الأوسع التي حفزت هذا المشروع:
| المصدر | الهدف | النصوص | المتوسط | الخطوط | الأصفار |
|---|
| w U+0077 | ԝ U+051D | Latin-Cyrillic | 0.000 | 19 | 19 |
| j U+006A | ϳ U+03F3 | Latin-Greek | 0.013 | 21 | 18 |
| i U+0069 | і U+0456 | Latin-Cyrillic | 0.018 | 62 | 50 |
| s U+0073 | ѕ U+0455 | Latin-Cyrillic | 0.018 | 62 | 46 |
| c U+0063 | с U+0441 | Latin-Cyrillic | 0.019 | 61 | 45 |
| o U+006F | о U+043E | Latin-Cyrillic | 0.020 | 61 | 44 |
| j U+006A | ј U+0458 | Latin-Cyrillic | 0.021 | 60 | 48 |
| x U+0078 | х U+0445 | Latin-Cyrillic | 0.023 | 59 | 50 |
| p U+0070 | р U+0440 | Latin-Cyrillic | 0.024 | 61 | 46 |
| e U+0065 | е U+0435 | Latin-Cyrillic | 0.032 | 61 | 44 |
| a U+0061 | а U+0430 | Latin-Cyrillic | 0.042 | 61 | 45 |
| المصدر | الهدف | النصوص | المتوسط | الخطوط |
|---|
| ο U+03BF | ჿ U+10FF | Greek-Georgian | 0.057 | 2 |
| ヘ U+30D8 | へ U+3078 | Katakana-Hiragana | 0.122 | 11 |
| 丶 U+4E36 | ヽ U+30FD | Han-Katakana | 0.125 | 9 |
| 二 U+4E8C | ニ U+30CB | Han-Katakana | 0.249 | 11 |
| 口 U+53E3 | ロ U+30ED | Han-Katakana | 0.268 | 11 |
| الزوج الثنائي | الهدف | المتوسط | الخطوط | ملاحظات |
|---|
| ll | ॥ U+0965 (Devanagari double danda) | 0.176 | 8 | عبر النصوص |
| oy | ѹ U+0479 (Cyrillic uk) | 0.322 | 16 | زوج ثنائي مربك جديد عبر النصوص |
| rn | m U+006D | 0.531 | 95 | 33 خطًا تحت 0.40 |
| bl | ы U+044B (Cyrillic yeru) | 0.797 | 49 | عبر النصوص |
| أزواج فريدة لحرف واحد |
|---|
| أزواج فريدة متعددة الأحرف |
|---|
| < 0.50 | 138 | 13 |
| < 1.00 | 4,174 | 1,631 |
| < 1.50 | 59,700 | (ضوضاء) |
| < 2.00 | 249,976 | 2,524,275 |
| الملف | الوصف |
|---|
data/output/confusable-discoveries.json | 110 زوجًا من TR39 مع SSIM عالي (>= 0.7) أو متطابقة بكسلًا |
data/output/candidate-discoveries.json | 793 زوجًا جديدًا غير موجود في TR39، متوسط SSIM >= 0.7 |
data/output/confusable-weights.json | 1,397 حافة موزونة لتكامل namespace-guard |
data/output/cross-script-discoveries.json | 563 زوجًا مربكًا عبر النصوص |
data/output/cross-script-summary.json | ملخص عبر النصوص حسب زوج النص |
data/output/multichar-discoveries.json | اكتشافات مربكة متعددة الأحرف |
data/output/singlechar-sdf-scores.jsonl |
| درجات RaySpace لحرف واحد |
data/output/multichar-rayspace-scores.jsonl | درجات RaySpace متعددة الأحرف |
data/output/signature-bank/ | بنك توقيعات RaySpace (294,646 إدخال، 7.9GB مضغوط) |