-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathot_kern.go
97 lines (83 loc) · 1.93 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
96
97
package harfbuzz
import (
tt "github.com/benoitkugler/textlayout/fonts/truetype"
)
func simpleKern(kernTable tt.TableKernx) tt.SimpleKerns {
for _, subtable := range kernTable {
if simple, ok := subtable.Data.(tt.SimpleKerns); ok {
return simple
}
}
return nil
}
func kern(driver tt.SimpleKerns, crossStream bool, font *Font, buffer *Buffer, kernMask GlyphMask, scale bool) {
c := newOtApplyContext(1, font, buffer)
c.setLookupMask(kernMask)
c.setLookupProps(uint32(tt.IgnoreMarks))
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.otTables.Kern); driver != nil {
kern(driver, false, font, buffer, sp.kernMask, false)
}
if reverse {
buffer.Reverse()
}
}