package harfbuzz
import (
ot "github.com/go-text/typesetting/font/opentype"
"github.com/go-text/typesetting/font/opentype/tables"
ucd "github.com/go-text/typesetting/internal/unicodedata"
"github.com/go-text/typesetting/language"
)
type zeroWidthMarks uint8
const (
zeroWidthMarksNone zeroWidthMarks = iota
zeroWidthMarksByGdefEarly
zeroWidthMarksByGdefLate
)
type otComplexShaper interface {
marksBehavior() (zwm zeroWidthMarks , fallbackPosition bool )
normalizationPreference() normalizationMode
gposTag() tables .Tag
collectFeatures(plan *otShapePlanner )
overrideFeatures(plan *otShapePlanner )
dataCreate(plan *otShapePlan )
preprocessText(plan *otShapePlan , buffer *Buffer , font *Font )
decompose(c *otNormalizeContext , ab rune ) (a, b rune , ok bool )
compose(c *otNormalizeContext , a, b rune ) (ab rune , ok bool )
setupMasks(plan *otShapePlan , buffer *Buffer , font *Font )
reorderMarks(plan *otShapePlan , buffer *Buffer , start, end int )
postprocessGlyphs(plan *otShapePlan , buffer *Buffer , font *Font )
}
var scriptMyanmarZawgyi = language .Script (ot .NewTag ('Q' , 'a' , 'a' , 'g' ))
func categorizeComplex(script language .Script , direction Direction , gsubScript ot .Tag ) otComplexShaper {
switch script {
case language .Arabic , language .Syriac :
if (gsubScript != tagDefaultScript || script == language .Arabic ) &&
direction .isHorizontal () {
return &complexShaperArabic {}
}
return complexShaperDefault {}
case language .Thai , language .Lao :
return complexShaperThai {}
case language .Hangul :
return &complexShaperHangul {}
case language .Hebrew :
return complexShaperHebrew {}
case language .Bengali , language .Devanagari , language .Gujarati , language .Gurmukhi , language .Kannada ,
language .Malayalam , language .Oriya , language .Tamil , language .Telugu :
if gsubScript == ot .NewTag ('D' , 'F' , 'L' , 'T' ) ||
gsubScript == ot .NewTag ('l' , 'a' , 't' , 'n' ) {
return complexShaperDefault {}
} else if (gsubScript & 0x000000FF ) == '3' {
return &complexShaperUSE {}
}
return &complexShaperIndic {}
case language .Khmer :
return &complexShaperKhmer {}
case language .Myanmar :
if gsubScript == ot .NewTag ('D' , 'F' , 'L' , 'T' ) ||
gsubScript == ot .NewTag ('l' , 'a' , 't' , 'n' ) ||
gsubScript == ot .NewTag ('m' , 'y' , 'm' , 'r' ) {
return complexShaperDefault {}
}
return complexShaperMyanmar {}
case scriptMyanmarZawgyi :
return complexShaperDefault {dumb : true , disableNorm : true }
case language .Tibetan ,
language .Mongolian , language .Sinhala ,
language .Buhid , language .Hanunoo , language .Tagalog , language .Tagbanwa ,
language .Limbu , language .Tai_Le ,
language .Buginese , language .Kharoshthi , language .Syloti_Nagri , language .Tifinagh ,
language .Balinese , language .Nko , language .Phags_Pa ,
language .Cham , language .Kayah_Li , language .Lepcha , language .Rejang , language .Saurashtra , language .Sundanese ,
language .Egyptian_Hieroglyphs , language .Javanese , language .Kaithi , language .Meetei_Mayek , language .Tai_Tham , language .Tai_Viet ,
language .Batak , language .Brahmi , language .Mandaic ,
language .Chakma , language .Miao , language .Sharada , language .Takri ,
language .Duployan , language .Grantha , language .Khojki , language .Khudawadi ,
language .Mahajani , language .Manichaean , language .Modi , language .Pahawh_Hmong ,
language .Psalter_Pahlavi , language .Siddham , language .Tirhuta ,
language .Ahom , language .Multani ,
language .Adlam , language .Bhaiksuki , language .Marchen , language .Newa ,
language .Masaram_Gondi , language .Soyombo , language .Zanabazar_Square ,
language .Dogra , language .Gunjala_Gondi , language .Hanifi_Rohingya , language .Makasar , language .Medefaidrin , language .Old_Sogdian ,
language .Sogdian , language .Elymaic , language .Nandinagari , language .Nyiakeng_Puachue_Hmong , language .Wancho ,
language .Chorasmian , language .Dives_Akuru , language .Khitan_Small_Script , language .Yezidi ,
language .Cypro_Minoan , language .Old_Uyghur , language .Tangsa , language .Toto , language .Vithkuqi ,
language .Kawi , language .Nag_Mundari ,
language .Garay , language .Gurung_Khema , language .Kirat_Rai , language .Ol_Onal , language .Sunuwar , language .Todhri , language .Tulu_Tigalari ,
language .Beria_Erfe , language .Sidetic , language .Tai_Yo , language .Tolong_Siki :
if gsubScript == ot .NewTag ('D' , 'F' , 'L' , 'T' ) ||
gsubScript == ot .NewTag ('l' , 'a' , 't' , 'n' ) {
return complexShaperDefault {}
}
return &complexShaperUSE {}
default :
return complexShaperDefault {}
}
}
type complexShaperNil struct {}
func (complexShaperNil ) gposTag () tables .Tag { return 0 }
func (complexShaperNil ) collectFeatures (plan *otShapePlanner ) {}
func (complexShaperNil ) overrideFeatures (plan *otShapePlanner ) {}
func (complexShaperNil ) dataCreate (plan *otShapePlan ) {}
func (complexShaperNil ) decompose (_ *otNormalizeContext , ab rune ) (a , b rune , ok bool ) {
return ucd .Decompose (ab )
}
func (complexShaperNil ) compose (_ *otNormalizeContext , a , b rune ) (ab rune , ok bool ) {
return ucd .Compose (a , b )
}
func (complexShaperNil ) preprocessText (*otShapePlan , *Buffer , *Font ) {}
func (complexShaperNil ) postprocessGlyphs (*otShapePlan , *Buffer , *Font ) {
}
func (complexShaperNil ) setupMasks (*otShapePlan , *Buffer , *Font ) {}
func (complexShaperNil ) reorderMarks (*otShapePlan , *Buffer , int , int ) {}
type complexShaperDefault struct {
complexShaperNil
dumb bool
disableNorm bool
}
func (cs complexShaperDefault ) marksBehavior () (zeroWidthMarks , bool ) {
if cs .dumb {
return zeroWidthMarksNone , false
}
return zeroWidthMarksByGdefLate , true
}
func (cs complexShaperDefault ) normalizationPreference () normalizationMode {
if cs .disableNorm {
return nmNone
}
return nmDefault
}
func syllabicInsertDottedCircles(font *Font , buffer *Buffer , brokenSyllableType ,
dottedcircleCategory uint8 , rephaCategory , dottedCirclePosition int ,
) bool {
if (buffer .Flags & DoNotinsertDottedCircle ) != 0 {
return false
}
if (buffer .scratchFlags & bsfHasBrokenSyllable ) == 0 {
return false
}
dottedcircleGlyph , ok := font .face .NominalGlyph (0x25CC )
if !ok {
return false
}
dottedcircle := GlyphInfo {
Glyph : dottedcircleGlyph ,
complexCategory : dottedcircleCategory ,
}
if dottedCirclePosition != -1 {
dottedcircle .complexAux = uint8 (dottedCirclePosition )
}
buffer .clearOutput ()
buffer .idx = 0
var lastSyllable uint8
for buffer .idx < len (buffer .Info ) {
syllable := buffer .cur (0 ).syllable
if lastSyllable != syllable && (syllable &0x0F ) == brokenSyllableType {
lastSyllable = syllable
ginfo := dottedcircle
ginfo .Cluster = buffer .cur (0 ).Cluster
ginfo .Mask = buffer .cur (0 ).Mask
ginfo .syllable = buffer .cur (0 ).syllable
if rephaCategory != -1 {
for buffer .idx < len (buffer .Info ) &&
lastSyllable == buffer .cur (0 ).syllable &&
buffer .cur (0 ).complexCategory == uint8 (rephaCategory ) {
buffer .nextGlyph ()
}
}
buffer .outInfo = append (buffer .outInfo , ginfo )
} else {
buffer .nextGlyph ()
}
}
buffer .swapBuffers ()
return true
}
The pages are generated with Golds v0.8.7 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .