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"
)
var _ otComplexShaper = (*complexShaperHangul )(nil )
type complexShaperHangul struct {
complexShaperNil
plan hangulShapePlan
}
const (
_ = iota
ljmo
vjmo
tjmo
firstHangulFeature = ljmo
hangulFeatureCount = tjmo + 1
)
var hangulFeatures = [hangulFeatureCount ]tables .Tag {
0 ,
ot .NewTag ('l' , 'j' , 'm' , 'o' ),
ot .NewTag ('v' , 'j' , 'm' , 'o' ),
ot .NewTag ('t' , 'j' , 'm' , 'o' ),
}
func (complexShaperHangul ) collectFeatures (plan *otShapePlanner ) {
map_ := &plan .otMap
for i := firstHangulFeature ; i < hangulFeatureCount ; i ++ {
map_ .addFeature (hangulFeatures [i ])
}
}
func (complexShaperHangul ) overrideFeatures (plan *otShapePlanner ) {
plan .otMap .disableFeature (ot .NewTag ('c' , 'a' , 'l' , 't' ))
}
type hangulShapePlan struct {
maskArray [hangulFeatureCount ]GlyphMask
}
func (cs *complexShaperHangul ) dataCreate (plan *otShapePlan ) {
var hangulPlan hangulShapePlan
for i := range hangulPlan .maskArray {
hangulPlan .maskArray [i ] = plan .otMap .getMask1 (hangulFeatures [i ])
}
cs .plan = hangulPlan
}
func isCombiningT(u rune ) bool {
return ucd .HangulTBase +1 <= u && u <= ucd .HangulTBase +ucd .HangulTCount -1
}
func isL(u rune ) bool {
return 0x1100 <= u && u <= 0x115F || 0xA960 <= u && u <= 0xA97C
}
func isV(u rune ) bool {
return 0x1160 <= u && u <= 0x11A7 || 0xD7B0 <= u && u <= 0xD7C6
}
func isT(u rune ) bool {
return 0x11A8 <= u && u <= 0x11FF || 0xD7CB <= u && u <= 0xD7FB
}
func isZeroWidthChar(font *Font , unicode rune ) bool {
glyph , ok := font .face .NominalGlyph (unicode )
return ok && font .GlyphHAdvance (glyph ) == 0
}
func (cs *complexShaperHangul ) preprocessText (_ *otShapePlan , buffer *Buffer , font *Font ) {
buffer .clearOutput ()
var start , end int
count := len (buffer .Info )
for buffer .idx = 0 ; buffer .idx < count ; {
u := buffer .cur (0 ).codepoint
if 0x302E <= u && u <= 0x302F {
if start < end && end == len (buffer .outInfo ) {
buffer .unsafeToBreakFromOutbuffer (start , buffer .idx )
buffer .nextGlyph ()
if !isZeroWidthChar (font , u ) {
buffer .mergeOutClusters (start , end +1 )
info := buffer .outInfo
tone := info [end ]
copy (info [start +1 :], info [start :end ])
info [start ] = tone
}
} else {
if buffer .Flags &DoNotinsertDottedCircle == 0 && font .hasGlyph (0x25CC ) {
var chars [2 ]rune
if !isZeroWidthChar (font , u ) {
chars [0 ] = u
chars [1 ] = 0x25CC
} else {
chars [0 ] = 0x25CC
chars [1 ] = u
}
buffer .replaceGlyphs (1 , chars [:], nil )
} else {
buffer .nextGlyph ()
}
}
start = len (buffer .outInfo )
end = len (buffer .outInfo )
continue
}
start = len (buffer .outInfo )
if isL (u ) && buffer .idx +1 < count {
l := u
v := buffer .cur (+1 ).codepoint
if isV (v ) {
var t , tindex rune
if buffer .idx +2 < count {
t = buffer .cur (+2 ).codepoint
if isT (t ) {
tindex = t - ucd .HangulTBase
} else {
t = 0
}
}
offset := 2
if t != 0 {
offset = 3
}
buffer .unsafeToBreak (buffer .idx , buffer .idx +offset )
if (ucd .HangulLBase <= l && l <= ucd .HangulLBase +ucd .HangulLCount -1 ) && (ucd .HangulVBase <= v && v <= ucd .HangulVBase +ucd .HangulVCount -1 ) && (t == 0 || isCombiningT (t )) {
s := ucd .HangulSBase + (l -ucd .HangulLBase )*ucd .HangulNCount + (v -ucd .HangulVBase )*ucd .HangulTCount + tindex
if font .hasGlyph (s ) {
buffer .replaceGlyphs (offset , []rune {s }, nil )
end = start + 1
continue
}
}
buffer .cur (0 ).complexAux = ljmo
buffer .nextGlyph ()
buffer .cur (0 ).complexAux = vjmo
buffer .nextGlyph ()
if t != 0 {
buffer .cur (0 ).complexAux = tjmo
buffer .nextGlyph ()
end = start + 3
} else {
end = start + 2
}
buffer .mergeOutClusters (start , end )
continue
}
} else if ucd .HangulSBase <= u && u <= ucd .HangulSBase +ucd .HangulSCount -1 {
s := u
HasGlyph := font .hasGlyph (s )
lindex := (s - ucd .HangulSBase ) / ucd .HangulNCount
nindex := (s - ucd .HangulSBase ) % ucd .HangulNCount
vindex := nindex / ucd .HangulTCount
tindex := nindex % ucd .HangulTCount
if tindex == 0 && buffer .idx +1 < count && isCombiningT (buffer .cur (+1 ).codepoint ) {
newTindex := buffer .cur (+1 ).codepoint - ucd .HangulTBase
newS := s + newTindex
if font .hasGlyph (newS ) {
buffer .replaceGlyphs (2 , []rune {newS }, nil )
end = start + 1
continue
} else {
buffer .unsafeToBreak (buffer .idx , buffer .idx +2 )
}
}
if !HasGlyph || (tindex == 0 && buffer .idx +1 < count && isT (buffer .cur (+1 ).codepoint )) {
decomposed := [3 ]rune {
ucd .HangulLBase + lindex ,
ucd .HangulVBase + vindex ,
ucd .HangulTBase + tindex ,
}
if font .hasGlyph (decomposed [0 ]) && font .hasGlyph (decomposed [1 ]) &&
(tindex == 0 || font .hasGlyph (decomposed [2 ])) {
sLen := 2
if tindex != 0 {
sLen = 3
}
buffer .replaceGlyphs (1 , decomposed [:sLen ], nil )
if HasGlyph && tindex == 0 {
buffer .nextGlyph ()
sLen ++
}
info := buffer .outInfo
end = start + sLen
i := start
info [i ].complexAux = ljmo
i ++
info [i ].complexAux = vjmo
i ++
if i < end {
info [i ].complexAux = tjmo
i ++
}
buffer .mergeOutClusters (start , end )
continue
} else if tindex == 0 && buffer .idx +1 < count && isT (buffer .cur (+1 ).codepoint ) {
buffer .unsafeToBreak (buffer .idx , buffer .idx +2 )
}
}
if HasGlyph {
end = start + 1
buffer .nextGlyph ()
continue
}
}
buffer .nextGlyph ()
}
buffer .swapBuffers ()
}
func (cs *complexShaperHangul ) setupMasks (_ *otShapePlan , buffer *Buffer , _ *Font ) {
hangulPlan := cs .plan
info := buffer .Info
for i := range info {
info [i ].Mask |= hangulPlan .maskArray [info [i ].complexAux ]
}
}
func (complexShaperHangul ) marksBehavior () (zeroWidthMarks , bool ) {
return zeroWidthMarksNone , true
}
func (complexShaperHangul ) normalizationPreference () normalizationMode {
return nmNone
}
func (complexShaperHangul ) gposTag () tables .Tag { return 0 }
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 .