Anında Karakter Aralığı


10

Kullanıcı metin yazdığında, karakterlerin karakter dizisine göre otomatik karakter aralığını hesaplayacak bir algoritma biliyor mu?

İlerleme genişliklerinin veya benzerlerinin önemsiz bir şekilde hesaplanması demek istemiyorum, yani karakterler arasındaki görsel olarak en uygun mesafeyi tahmin etmek için gliflerin şeklini analiz etmek. Örneğin, bir satıra sırayla üç karakter yerleştirirsek, karakterin şekillerine rağmen orta karakterin satırın ortasında olması gerekir. Bir örnek, anında karakter aralığı işlevini aydınlatır:

Anında karakter aralığı örneği:

Ekran görüntüsü

Yukarıdaki görüntüde açok doğru görünüyor. Bu bir kaydırılması gereken miktar doğru To ortasında gibi görünüyor böylece Tve g. Algoritma Tve a(ve muhtemelen diğer harflerin) şekillerini incelemeli ve ne kadarının asola kaydırılması gerektiğine karar vermelidir . Bu belirli miktar , algoritmanın hesaplaması gereken şeydir - YAZI TİPİNİN OLASI KERNING ÇİFTLERİNİ İNCELEMEKTEDİR.

Elle çizilmiş yazı tiplerini kullanan ve birçoğu karakter çiftleri eksik olan bir javascript (+ svg + html) programı kodlamayı düşünüyorum. Metin alanları düzenlenebilir ve birden çok yazı tipinden oluşan metin içerebilir. Bence anında karakter aralığı, bu durumda ortalama metin akışını sağlamanın bir yolu olabilir.

EDIT: Bunun bir başlangıç ​​noktası svg yazı tipi kullanmak olabilir, bu nedenle yol değerleri almak kolaydır. Svg fontunda yol şu şekilde tanımlanır:

<glyph glyph-name="T" unicode="T" horiz-adv-x="1251" d="M531 0v1293h
-483v173h1162v-173h-485v-1293h-194z"/>

<glyph glyph-name="a" unicode="a" horiz-adv-x="1139" d="M828 131q-100 -85
-192.5 -120t-198.5 -35q-175 0 -269 85.5t-94 218.5q0 78 35.5 142.5t93
103.5t129.5 59q53 14 160 27q218 26 321 62q1 37 1 47q0 110 -51 155q-69 61
-205 61q-127 0 -187.5 -44.5t-89.5 -157.5l-176 24q24 113 79 182.5t159
107t241 37.5 q136 0 221 -32t125 -80.5t56 -122.5q9 -46 9 -166v-240q0
-251 11.5 -317.5t45.5 -127.5h-188q-28 56 -36 131zM813 533q-98 -40 -294
-68q-111 -16 -157 -36t-71 -58.5t-25 -85.5q0 -72 54.5 -120t159.5 -48q104
0 185 45.5t119 124.5q29 61 29 180v66z"/>

Algoritma (veya javascript kodu) bu yolları bir şekilde incelemeli ve aralarındaki en uygun mesafeyi belirlemelidir.


1
Bir kodlama çözümü arıyorsanız, bu SO üzerinde daha iyi sorulur. Aradığın şey bu mu? Eğer öyleyse, soruyu oraya taşıyacağım.
Alan Gilbertson

2
Bunun SO sorusu olduğuna katılıyorum. SO'da aynı soruyu sordum, ama orada konu dışı olarak kapatıldı. Sonra math.stackexchange'e sordu, ama aynı kapanış gerçekleşti. Burası üçüncü, belki bu doğru yer, kim bilir.
Timo Kähkönen

2
Algoritmanın nasıl çalıştığını bilmiyorum, ancak InDesign bunu yapabilir: "Optik karakter aralığı, bitişik karakterler arasındaki boşluğu şekillerine göre ayarlar. Bazı yazı tipleri sağlam çekirdek çifti özelliklerini içerir. Ancak, bir yazı tipi yalnızca en az yerleşik karakter aralığı veya hiç yok veya bir satırdaki bir veya daha fazla sözcükte iki farklı yazı tipi veya boyutu kullanıyorsanız, optik karakter aralığı seçeneğini kullanmak isteyebilirsiniz. " help.adobe.com/tr_TR/indesign/cs/using/…
e100

2
Bence bu genel bir algoritma kadar bir kapsam içinde - bir problemi çözmek için atılacak adımlar dizisi. Ancak JS veya başka bir dilde uygulama özelliklerinin ait olduğunu düşünmüyorum ve yalnızca JS'yi arka plan kullanım durumu olarak belirtmek için düzenleme yapıyorum.
e100

1
Bence işin ilk sırası, bir makine algoritması için faydalı bir şekilde "optimal" i tanımlamaktır.
horatio

Yanıtlar:


4

Bunun eski olduğunu biliyorum. Şu anda titrek metin (ne olursa olsun) bir WebGL uygulamasında bu üzerinde çalışıyorum. Üzerinde çalıştığım çözüm şöyle:

  1. Glif çiftinin bitmapped sürümünü edinin (veya isterseniz vektörlerle yapın)
  2. Her piksel sırası (veya vektörlerle giderseniz rastgele dikey birim) için, her iki glifte de en az bir piksel bulunduğundan emin olun
  3. 2. adımı geçen her satır için, ilk glifin en sağ pikseli ile ikinci glifin en sol pikseli arasındaki mesafeyi hesaplayın
  4. İkinci glifi, şu ölçütleri karşılamaya devam ederken olabildiğince sola hareket ettirin:
    • bu piksel satırındaki boşluk belirttiğiniz bazı minimum boşluktan büyük
    • toplam alan (gliflerden birinde piksel içermeyen satırları yoksaymak) belirttiğiniz minimum alandan daha büyük

Bu şekilde, harfler arasındaki boş 'alan' oldukça yaygın bir ortama sıkıştırılmalıdır. Deneme ve hata ve kendi zevkinizi kullanarak minimum boşluğu ve minimum alanı belirtin ve belki de bu parametrelerin manuel bir karakter aralığı değeri gibi başka bir ajan tarafından ayarlanmasına izin verin.

Yaşasın :)

Düzenleme: Bu başarıyla şimdi alıştırdım ve gerçekten iyi çalışıyor :)


Güzel cevap! GD.SE'ye Hoşgeldiniz :)
Yisela

Karşılama için teşekkürler: D !! Alanın gerçekten test edilen satır sayısına bölünmesi gerektiğini eklemeliyim (aslında sadece bir alan değil, ortalama bir boşluk oluşturur). Ayrıca, bir satır boşluğunun istatistiksel bir aykırı olup olmadığını test etmek ve varsa satırın yoksayılması iyi olur. 'G' gibi büyük bir açıklık olduğunda harfleri çok yakın sıkmaktan kaçınmanıza yardımcı olacaktır
jaya

Burada ve orada birkaç sorunlu çocuk var gibi görünüyor, örneğin bazı yazı tiplerinin bazı yazı tipi stillerinde T veya o 'gibi. T- tirenin T'ye çok yaklaşmasına izin verin ve o 'aynı satırda hiç piksel paylaşmadı, bu yüzden her gerçekleştiğinde bir pikselle en yakın satırları kullanmak için bir geri dönüş yaptım. Yukarıdaki algoritmayı daha sağlam hale getirmek için, bu tür sorunları bir şekilde kontrol etmeniz gerekir. Benim amacım için gerekli değildi.
jaya

3

Bu bir kez denediğim oldukça basit bir algoritma ve yeterince iyi olabilir.

Karakterleri düşük çözünürlükte işleyin - diyelim ki altı veya yedi piksel yüksekliğinde (tipik büyüklüğün yüksekliği) yatay olarak aynı. Basit bir düşük çözünürlüklü ızgara üzerinde, boş alanın nerede olduğu, mektubun bölümleri gibi basit bir ikili harita istiyorsunuz.

Bu harf haritalarını “şişmanla”. Yani, dolu bir hücreye bitişik olan her boş hücreyi doldurun. Bu, harf kenarlarına en yakın boş bölgeyi talep etmek içindir, bu nedenle komşu harf çok yakın olmaz.

Ortaya çıkan harf haritaları ile "yatay Tetris" oynayın. Yerçekimi sola doğru hareket etsin. "A" nın sol tarafındaki "göbeği", "T" nin üst çubuğunun altındaki boşluğa düşecektir. "A" kaç hücre hareket etti? Harflerin gerçek boyutuyla orantılı olarak ölçeklendirin ve gerçek yüksek çözünürlüklü "a" sola doğru ne kadar çok karakter aralığı oluşturacağınız.


1
Teşekkürler! Algoritmanızı görselleştirmek için Arial kullanarak "db", "AA", "Ta" ve "c-" çiftlerini kullanarak bazı düşük çözünürlüklü görüntü örnekleri sunabilirsiniz.
Timo Kähkönen

İyi bir başlangıç, ancak çıkıntılı karakter çiftlerinin birlikte "Tetris" olmadığı durumlarda bunun sınırlı olabileceğini düşünüyorum, örneğin "bd", "TT", "pq", "gj"
e100

@ e100: İlk bakışta bu eşleştirmenin çakışan sınırlayıcı kutuları olmazdı ...
horatio

Ancak genel olarak konuşursak, "MM", "NN" vb. Karakterlerden daha sıkı bir şekilde karakterize edilmelidirler
e100

2

Otomatik karakter aralığı için algoritmalar zaten var. Hiçbiri kusursuz değildir ve özellikle izlemeniz nispeten sıkıysa, belirli yönlerin biraz elle tutulması ve manuel olarak düzeltilmesi gerekir.

Ama bu algoritmalar karakter aralığı uygulamak içindir yazı tipi dosyası değil onlar yazı dosyası oluşturulur olarak harflere.

Yazı tipi dosyasına otomatik karakter aralığı uygulamayı düşündünüz mü?

Fontforge (açık kaynak) ve Fontlab (ticari) otomatik karakter aralığı algoritmaları içerir. Nispeten dik bir öğrenme eğrisine sahip olacaklardı - yazı tiplerinin nasıl çalıştığının teknik yönlerine aşina olmalısınız.

Ayrıca, ticari yazı tipi karakter aralığı hizmeti sunan bir adam olan iKern de var, böylece yazı tipinizi sizin için yakar ve oldukça mükemmel bir iş çıkarır . Ne kadara mal olacağını bilmiyorum.


Ama soru gerçekten "böyle bir algoritma nasıl çalışır?" - FontForge'un nasıl çalıştığına dair herhangi bir ayrıntı ekleyebilir misiniz?
e100


0

Bunu tam olarak düşünmek ya da illüstrasyonlar çizmek için zamanım yok, ama önce her glifi dikey olarak ikiye bölmek gibi bir yarı fikrim vardı.

Sonra her yarım için iki dikey eksen belirleyin: - açıortay - sol ve sağ uçlar arasında tam yarısı - "ağırlık" ekseni - her iki taraftaki mürekkebin tam yarısı

Ardından, bitişik komşu glifi iki eksenin göreli konumlarına dayanarak test yarım glifine doğru veya ondan uzağa hareket ettirin.

Yani, örneğin, "AV" çiftinde, A'nın sağ yarısı sol ağırdır ve V'yi "çeker"; V'nin sol yarısı sağ-ağırdır, A'yı çeker, bu nedenle birlikte önemli ölçüde çekirdeklenirler.

Ancak, eminim ki "AA" da "AV" kadar bir araya gelecektir.


0

Büyük harf ve küçük harf göz önüne alındığında, 56X55=2652endişelenmeniz gereken font çifti durumları vardır, yazı tipi stilini değiştirirseniz tüm çözümler kolayca kırılabilir, tüm kurallar gitti.

En iyi yol, makine öğrenme tekniğini kullanmak, sinir ağı çalışma modeli oluşturmaya çalışmak ve birden çok çekirdekli metin görüntüsü veya vektörü veya bunun gibi şeyleri içe aktarmak, bu modeli eğitmek ve herhangi bir yazı tipini akıllıca ayarlamak için bu eğitimli modeli kullanmaktır.

çünkü yazı tipini kökte mükemmel şekilde ayarlamak için statik bir algoritma olmadığından, makine öğrenimi bu tür bir soruna iyi bir çözüm olacaktır!


Sadece çoğunlukla öznel kriterler varsa değil. "Bu bir köpek mi yoksa bir kedi mi?", Köpek ne kadar tuhaf görünse de, hala kesin bir cevabı var. (Doğrulamak için bir veteriner
alsa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.