/
ot_kern.go
95 lines (81 loc) · 1.92 KB
/
ot_kern.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package harfbuzz
import fontP "github.com/benoitkugler/go-opentype/api/font"
func simpleKern(kernTable fontP.Kernx) fontP.SimpleKerns {
for _, subtable := range kernTable {
if simple, ok := subtable.Data.(fontP.SimpleKerns); ok {
return simple
}
}
return nil
}
func kern(driver fontP.SimpleKerns, crossStream bool, font *Font, buffer *Buffer, kernMask GlyphMask, scale bool) {
c := newOtApplyContext(1, font, buffer)
c.setLookupMask(kernMask)
c.setLookupProps(uint32(otIgnoreMarks))
skippyIter := &c.iterInput
horizontal := buffer.Props.Direction.isHorizontal()
info := buffer.Info
pos := buffer.Pos
for idx := 0; idx < len(pos); {
if info[idx].Mask&kernMask == 0 {
idx++
continue
}
skippyIter.reset(idx, 1)
if !skippyIter.next() {
idx++
continue
}
i := idx
j := skippyIter.idx
rawKern := driver.KernPair(info[i].Glyph, info[j].Glyph)
kern := Position(rawKern)
if rawKern == 0 {
goto skip
}
if horizontal {
if scale {
kern = font.emScaleX(rawKern)
}
if crossStream {
pos[j].YOffset = kern
buffer.scratchFlags |= bsfHasGPOSAttachment
} else {
kern1 := kern >> 1
kern2 := kern - kern1
pos[i].XAdvance += kern1
pos[j].XAdvance += kern2
pos[j].XOffset += kern2
}
} else {
if scale {
kern = font.emScaleY(rawKern)
}
if crossStream {
pos[j].XOffset = kern
buffer.scratchFlags |= bsfHasGPOSAttachment
} else {
kern1 := kern >> 1
kern2 := kern - kern1
pos[i].YAdvance += kern1
pos[j].YAdvance += kern2
pos[j].YOffset += kern2
}
}
buffer.unsafeToBreak(i, j+1)
skip:
idx = skippyIter.idx
}
}
func (sp *otShapePlan) otApplyFallbackKern(font *Font, buffer *Buffer) {
reverse := buffer.Props.Direction.isBackward()
if reverse {
buffer.Reverse()
}
if driver := simpleKern(font.face.Kern); driver != nil {
kern(driver, false, font, buffer, sp.kernMask, false)
}
if reverse {
buffer.Reverse()
}
}