Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小雨青年
freetype
提交
75fff80b
F
freetype
项目概览
小雨青年
/
freetype
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
F
freetype
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
75fff80b
编写于
9月 24, 2013
作者:
N
Nigel Tao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
freetype/truetype: implement IP, MIAP, MIRP opcodes.
R=bsiegert CC=golang-dev
https://codereview.appspot.com/13855043
上级
a3c53fdc
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
294 addition
and
96 deletion
+294
-96
freetype/truetype/glyph.go
freetype/truetype/glyph.go
+5
-14
freetype/truetype/hint.go
freetype/truetype/hint.go
+248
-41
freetype/truetype/opcodes.go
freetype/truetype/opcodes.go
+40
-40
freetype/truetype/truetype_test.go
freetype/truetype/truetype_test.go
+1
-1
未找到文件。
freetype/truetype/glyph.go
浏览文件 @
75fff80b
...
...
@@ -17,16 +17,15 @@ type Point struct {
// A GlyphBuf holds a glyph's contours. A GlyphBuf can be re-used to load a
// series of glyphs from a Font.
type
GlyphBuf
struct
{
//
T
he glyph's bounding box.
//
B is t
he glyph's bounding box.
B
Bounds
// Point contains all Points from all contours of the glyph. If a
// Hinter was used to load a glyph then Unhinted contains those
// Points before they were hinted, and InFontUnits contains those
// Points before they were hinted and scaled. Twilight is those
// Points created in the 'twilight zone' by the truetype hinting
// process.
Point
,
Unhinted
,
InFontUnits
,
Twilight
[]
Point
// The length of End is the number of contours in the glyph. The i'th
// Points before they were hinted and scaled.
Point
,
Unhinted
,
InFontUnits
[]
Point
// End is the point indexes of the end point of each countour. The
// length of End is the number of contours in the glyph. The i'th
// contour consists of points Point[End[i-1]:End[i]], where End[-1]
// is interpreted to mean zero.
End
[]
int
...
...
@@ -123,7 +122,6 @@ func (g *GlyphBuf) Load(f *Font, scale int32, i Index, h *Hinter) error {
g
.
Point
=
g
.
Point
[
:
0
]
g
.
Unhinted
=
g
.
Unhinted
[
:
0
]
g
.
InFontUnits
=
g
.
InFontUnits
[
:
0
]
g
.
Twilight
=
g
.
Twilight
[
:
0
]
g
.
End
=
g
.
End
[
:
0
]
if
h
!=
nil
{
if
err
:=
h
.
init
(
g
,
f
,
scale
);
err
!=
nil
{
...
...
@@ -285,13 +283,6 @@ func (g *GlyphBuf) load(f *Font, scale int32, i Index, h *Hinter,
return
nil
}
func
(
g
*
GlyphBuf
)
points
(
zonePointer
int32
)
[]
Point
{
if
zonePointer
==
0
{
return
g
.
Twilight
}
return
g
.
Point
}
// NewGlyphBuf returns a newly allocated GlyphBuf.
func
NewGlyphBuf
()
*
GlyphBuf
{
g
:=
new
(
GlyphBuf
)
...
...
freetype/truetype/hint.go
浏览文件 @
75fff80b
...
...
@@ -40,6 +40,9 @@ type Hinter struct {
// default graphics state is the global default graphics state after
// the font's fpgm and prep programs have been run.
gs
,
defaultGS
graphicsState
// twilightXxx are points created in the twilight zone.
twilightPoint
,
twilightUnhinted
,
twilightInFontUnits
[]
Point
}
// graphicsState is described at https://developer.apple.com/fonts/TTRefMan/RM04/Chap4.html
...
...
@@ -77,8 +80,25 @@ var globalDefaultGS = graphicsState{
autoFlip
:
true
,
}
func
resetTwilightPoints
(
f
*
Font
,
p
[]
Point
)
[]
Point
{
// TODO: the C Freetype code uses n+4 for the 4 phantom points, but a
// comment there says "(do we need this?)". Do we need to use n+4 here?
if
n
:=
int
(
f
.
maxTwilightPoints
);
n
<=
cap
(
p
)
{
p
=
p
[
:
n
]
for
i
:=
range
p
{
p
[
i
]
=
Point
{}
}
}
else
{
p
=
make
([]
Point
,
n
)
}
return
p
}
func
(
h
*
Hinter
)
init
(
g
*
GlyphBuf
,
f
*
Font
,
scale
int32
)
error
{
h
.
g
=
g
h
.
twilightPoint
=
resetTwilightPoints
(
f
,
h
.
twilightPoint
)
h
.
twilightUnhinted
=
resetTwilightPoints
(
f
,
h
.
twilightUnhinted
)
h
.
twilightInFontUnits
=
resetTwilightPoints
(
f
,
h
.
twilightInFontUnits
)
rescale
:=
h
.
scale
!=
scale
if
h
.
font
!=
f
{
...
...
@@ -365,13 +385,12 @@ func (h *Hinter) run(program []byte) error {
program
,
pc
=
callStack
[
callStackTop
]
.
program
,
callStack
[
callStackTop
]
.
pc
case
opMDAP0
,
opMDAP1
:
points
:=
h
.
g
.
points
(
h
.
gs
.
zp
[
0
])
top
--
i
:=
int
(
h
.
stack
[
top
])
if
i
<
0
||
len
(
points
)
<=
i
{
i
:=
h
.
stack
[
top
]
p
:=
h
.
point
(
0
,
current
,
i
)
if
p
==
nil
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
p
:=
&
points
[
i
]
distance
:=
f26dot6
(
0
)
if
opcode
==
opMDAP1
{
distance
=
dotProduct
(
f26dot6
(
p
.
X
),
f26dot6
(
p
.
Y
),
h
.
gs
.
pv
)
...
...
@@ -379,23 +398,73 @@ func (h *Hinter) run(program []byte) error {
distance
=
h
.
round
(
distance
)
-
distance
}
h
.
move
(
p
,
distance
)
h
.
gs
.
rp
[
0
]
=
int32
(
i
)
h
.
gs
.
rp
[
1
]
=
int32
(
i
)
h
.
gs
.
rp
[
0
]
=
i
h
.
gs
.
rp
[
1
]
=
i
case
opIUP0
,
opIUP1
:
// TODO: implement IUP.
// Glyph 4 in luxisr.ttf (the '!' glyph) has IUP instructions but
// they have no effect since none of the points are untouched.
// The IUP ops will be implemented when the N in truetype_test.go
// is raised above 5.
const
mask
=
flagTouchedX
|
flagTouchedY
for
_
,
p
:=
range
h
.
g
.
Point
{
if
p
.
Flags
&
mask
!=
mask
{
return
errors
.
New
(
"truetype: hinting: unimplemented IUP instruction"
)
}
}
case
opIP
:
if
top
<
int
(
h
.
gs
.
loop
)
{
return
errors
.
New
(
"truetype: hinting: stack underflow"
)
}
pointType
:=
inFontUnits
twilight
:=
h
.
gs
.
zp
[
0
]
==
0
||
h
.
gs
.
zp
[
1
]
==
0
||
h
.
gs
.
zp
[
2
]
==
0
if
twilight
{
pointType
=
unhinted
}
p
:=
h
.
point
(
1
,
pointType
,
h
.
gs
.
rp
[
2
])
oldP
:=
h
.
point
(
0
,
pointType
,
h
.
gs
.
rp
[
1
])
oldRange
:=
dotProduct
(
f26dot6
(
p
.
X
-
oldP
.
X
),
f26dot6
(
p
.
Y
-
oldP
.
Y
),
h
.
gs
.
dv
)
p
=
h
.
point
(
1
,
current
,
h
.
gs
.
rp
[
2
])
curP
:=
h
.
point
(
0
,
current
,
h
.
gs
.
rp
[
1
])
curRange
:=
dotProduct
(
f26dot6
(
p
.
X
-
curP
.
X
),
f26dot6
(
p
.
Y
-
curP
.
Y
),
h
.
gs
.
pv
)
for
;
h
.
gs
.
loop
!=
0
;
h
.
gs
.
loop
--
{
top
--
i
:=
h
.
stack
[
top
]
p
=
h
.
point
(
2
,
pointType
,
i
)
oldDist
:=
dotProduct
(
f26dot6
(
p
.
X
-
oldP
.
X
),
f26dot6
(
p
.
Y
-
oldP
.
Y
),
h
.
gs
.
dv
)
p
=
h
.
point
(
2
,
current
,
i
)
curDist
:=
dotProduct
(
f26dot6
(
p
.
X
-
curP
.
X
),
f26dot6
(
p
.
Y
-
curP
.
Y
),
h
.
gs
.
pv
)
newDist
:=
f26dot6
(
0
)
if
oldDist
!=
0
{
if
oldRange
!=
0
{
newDist
=
f26dot6
(
(
int64
(
oldDist
)
*
int64
(
curRange
)
+
int64
(
oldRange
/
2
))
/
int64
(
oldRange
))
}
else
{
newDist
=
-
oldDist
}
}
h
.
move
(
p
,
newDist
-
curDist
)
}
h
.
gs
.
loop
=
1
case
opALIGNRP
:
if
top
<
int
(
h
.
gs
.
loop
)
{
return
errors
.
New
(
"truetype: hinting: stack underflow"
)
}
i
,
points
:=
int
(
h
.
gs
.
rp
[
0
]),
h
.
g
.
points
(
h
.
gs
.
zp
[
0
])
if
i
<
0
||
len
(
points
)
<=
i
{
i
:=
h
.
gs
.
rp
[
0
]
ref
:=
h
.
point
(
0
,
current
,
i
)
if
ref
==
nil
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
ref
:=
&
points
[
i
]
points
=
h
.
g
.
points
(
h
.
gs
.
zp
[
1
])
points
:=
h
.
points
(
1
,
current
)
for
;
h
.
gs
.
loop
!=
0
;
h
.
gs
.
loop
--
{
top
--
i
=
int
(
h
.
stack
[
top
])
if
i
<
0
||
len
(
points
)
<=
i
{
i
=
h
.
stack
[
top
]
if
i
<
0
||
len
(
points
)
<=
i
nt
(
i
)
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
p
:=
&
points
[
i
]
...
...
@@ -408,6 +477,30 @@ func (h *Hinter) run(program []byte) error {
h
.
gs
.
roundPhase
=
0
h
.
gs
.
roundThreshold
=
1
<<
4
case
opMIAP0
,
opMIAP1
:
top
-=
2
i
:=
h
.
stack
[
top
]
distance
:=
h
.
cvt
(
h
.
stack
[
top
+
1
])
if
h
.
gs
.
zp
[
0
]
==
0
{
p
:=
h
.
point
(
0
,
unhinted
,
i
)
q
:=
h
.
point
(
0
,
current
,
i
)
p
.
X
=
int32
((
int64
(
distance
)
*
int64
(
h
.
gs
.
fv
[
0
]))
>>
14
)
p
.
Y
=
int32
((
int64
(
distance
)
*
int64
(
h
.
gs
.
fv
[
1
]))
>>
14
)
*
q
=
*
p
}
p
:=
h
.
point
(
0
,
current
,
i
)
oldDist
:=
dotProduct
(
f26dot6
(
p
.
X
),
f26dot6
(
p
.
Y
),
h
.
gs
.
pv
)
if
opcode
==
opMIAP1
{
if
(
distance
-
oldDist
)
.
abs
()
>
h
.
gs
.
controlValueCutIn
{
distance
=
oldDist
}
// TODO: metrics compensation.
distance
=
h
.
round
(
distance
)
}
h
.
move
(
p
,
distance
-
oldDist
)
h
.
gs
.
rp
[
0
]
=
i
h
.
gs
.
rp
[
1
]
=
i
case
opNPUSHB
:
opcode
=
0
goto
push
...
...
@@ -669,50 +762,45 @@ func (h *Hinter) run(program []byte) error {
opMDRP11000
,
opMDRP11001
,
opMDRP11010
,
opMDRP11011
,
opMDRP11100
,
opMDRP11101
,
opMDRP11110
,
opMDRP11111
:
i
,
points
:=
int
(
h
.
gs
.
rp
[
0
]),
h
.
g
.
points
(
h
.
gs
.
zp
[
0
])
if
i
<
0
||
len
(
points
)
<=
i
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
ref
:=
&
points
[
i
]
top
--
i
=
int
(
h
.
stack
[
top
])
points
=
h
.
g
.
points
(
h
.
gs
.
zp
[
1
])
if
i
<
0
||
len
(
points
)
<=
i
{
i
:=
h
.
stack
[
top
]
ref
:=
h
.
point
(
0
,
current
,
h
.
gs
.
rp
[
0
])
p
:=
h
.
point
(
1
,
current
,
i
)
if
ref
==
nil
||
p
==
nil
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
p
:=
&
points
[
i
]
o
rig
Dist
:=
f26dot6
(
0
)
if
h
.
gs
.
zp
[
0
]
==
0
&&
h
.
gs
.
zp
[
1
]
==
0
{
p0
:=
&
h
.
g
.
Unhinted
[
i
]
p1
:=
&
h
.
g
.
Unhinted
[
h
.
gs
.
rp
[
0
]]
o
rig
Dist
=
dotProduct
(
f26dot6
(
p0
.
X
-
p1
.
X
),
f26dot6
(
p0
.
Y
-
p1
.
Y
),
h
.
gs
.
dv
)
o
ld
Dist
:=
f26dot6
(
0
)
if
h
.
gs
.
zp
[
0
]
==
0
||
h
.
gs
.
zp
[
1
]
==
0
{
p0
:=
h
.
point
(
1
,
unhinted
,
i
)
p1
:=
h
.
point
(
0
,
unhinted
,
h
.
gs
.
rp
[
0
])
o
ld
Dist
=
dotProduct
(
f26dot6
(
p0
.
X
-
p1
.
X
),
f26dot6
(
p0
.
Y
-
p1
.
Y
),
h
.
gs
.
dv
)
}
else
{
p0
:=
&
h
.
g
.
InFontUnits
[
i
]
p1
:=
&
h
.
g
.
InFontUnits
[
h
.
gs
.
rp
[
0
]]
o
rig
Dist
=
dotProduct
(
f26dot6
(
p0
.
X
-
p1
.
X
),
f26dot6
(
p0
.
Y
-
p1
.
Y
),
h
.
gs
.
dv
)
o
rigDist
=
f26dot6
(
h
.
font
.
scale
(
h
.
scale
*
int32
(
orig
Dist
)))
p0
:=
h
.
point
(
1
,
inFontUnits
,
i
)
p1
:=
h
.
point
(
0
,
inFontUnits
,
h
.
gs
.
rp
[
0
])
o
ld
Dist
=
dotProduct
(
f26dot6
(
p0
.
X
-
p1
.
X
),
f26dot6
(
p0
.
Y
-
p1
.
Y
),
h
.
gs
.
dv
)
o
ldDist
=
f26dot6
(
h
.
font
.
scale
(
h
.
scale
*
int32
(
old
Dist
)))
}
// Single-width cut-in test.
if
x
:=
(
o
rig
Dist
-
h
.
gs
.
singleWidth
)
.
abs
();
x
<
h
.
gs
.
singleWidthCutIn
{
if
o
rig
Dist
>=
0
{
o
rig
Dist
=
h
.
gs
.
singleWidthCutIn
if
x
:=
(
o
ld
Dist
-
h
.
gs
.
singleWidth
)
.
abs
();
x
<
h
.
gs
.
singleWidthCutIn
{
if
o
ld
Dist
>=
0
{
o
ld
Dist
=
h
.
gs
.
singleWidthCutIn
}
else
{
o
rig
Dist
=
-
h
.
gs
.
singleWidthCutIn
o
ld
Dist
=
-
h
.
gs
.
singleWidthCutIn
}
}
// Rounding bit.
// TODO: metrics compensation.
distance
:=
o
rig
Dist
distance
:=
o
ld
Dist
if
opcode
&
0x04
!=
0
{
distance
=
h
.
round
(
o
rig
Dist
)
distance
=
h
.
round
(
o
ld
Dist
)
}
// Minimum distance bit.
if
opcode
&
0x08
!=
0
{
if
o
rig
Dist
>=
0
{
if
o
ld
Dist
>=
0
{
if
distance
<
h
.
gs
.
minDist
{
distance
=
h
.
gs
.
minDist
}
...
...
@@ -725,14 +813,88 @@ func (h *Hinter) run(program []byte) error {
// Set-RP0 bit.
if
opcode
&
0x10
!=
0
{
h
.
gs
.
rp
[
0
]
=
i
nt32
(
i
)
h
.
gs
.
rp
[
0
]
=
i
}
h
.
gs
.
rp
[
1
]
=
h
.
gs
.
rp
[
0
]
h
.
gs
.
rp
[
2
]
=
i
nt32
(
i
)
h
.
gs
.
rp
[
2
]
=
i
// Move the point.
origDist
=
dotProduct
(
f26dot6
(
p
.
X
-
ref
.
X
),
f26dot6
(
p
.
Y
-
ref
.
Y
),
h
.
gs
.
pv
)
h
.
move
(
p
,
distance
-
origDist
)
oldDist
=
dotProduct
(
f26dot6
(
p
.
X
-
ref
.
X
),
f26dot6
(
p
.
Y
-
ref
.
Y
),
h
.
gs
.
pv
)
h
.
move
(
p
,
distance
-
oldDist
)
case
opMIRP00000
,
opMIRP00001
,
opMIRP00010
,
opMIRP00011
,
opMIRP00100
,
opMIRP00101
,
opMIRP00110
,
opMIRP00111
,
opMIRP01000
,
opMIRP01001
,
opMIRP01010
,
opMIRP01011
,
opMIRP01100
,
opMIRP01101
,
opMIRP01110
,
opMIRP01111
,
opMIRP10000
,
opMIRP10001
,
opMIRP10010
,
opMIRP10011
,
opMIRP10100
,
opMIRP10101
,
opMIRP10110
,
opMIRP10111
,
opMIRP11000
,
opMIRP11001
,
opMIRP11010
,
opMIRP11011
,
opMIRP11100
,
opMIRP11101
,
opMIRP11110
,
opMIRP11111
:
top
-=
2
i
:=
h
.
stack
[
top
]
cvtDist
:=
h
.
cvt
(
h
.
stack
[
top
+
1
])
if
(
cvtDist
-
h
.
gs
.
singleWidth
)
.
abs
()
<
h
.
gs
.
singleWidthCutIn
{
if
cvtDist
>=
0
{
cvtDist
=
+
h
.
gs
.
singleWidth
}
else
{
cvtDist
=
-
h
.
gs
.
singleWidth
}
}
if
h
.
gs
.
zp
[
1
]
==
0
{
// TODO: implement once we have a .ttf file that triggers
// this, so that we can step through C's freetype.
return
errors
.
New
(
"truetype: hinting: unimplemented twilight point adjustment"
)
}
ref
:=
h
.
point
(
0
,
unhinted
,
h
.
gs
.
rp
[
0
])
p
:=
h
.
point
(
1
,
unhinted
,
i
)
if
ref
==
nil
||
p
==
nil
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
oldDist
:=
dotProduct
(
f26dot6
(
p
.
X
-
ref
.
X
),
f26dot6
(
p
.
Y
-
ref
.
Y
),
h
.
gs
.
dv
)
ref
=
h
.
point
(
0
,
current
,
h
.
gs
.
rp
[
0
])
p
=
h
.
point
(
1
,
current
,
i
)
if
ref
==
nil
||
p
==
nil
{
return
errors
.
New
(
"truetype: hinting: point out of range"
)
}
curDist
:=
dotProduct
(
f26dot6
(
p
.
X
-
ref
.
X
),
f26dot6
(
p
.
Y
-
ref
.
Y
),
h
.
gs
.
dv
)
if
h
.
gs
.
autoFlip
&&
oldDist
^
cvtDist
<
0
{
cvtDist
=
-
cvtDist
}
// Rounding bit.
// TODO: metrics compensation.
distance
:=
oldDist
if
opcode
&
0x04
!=
0
{
distance
=
h
.
round
(
oldDist
)
}
// Minimum distance bit.
if
opcode
&
0x08
!=
0
{
if
oldDist
>=
0
{
if
distance
<
h
.
gs
.
minDist
{
distance
=
h
.
gs
.
minDist
}
}
else
{
if
distance
>
-
h
.
gs
.
minDist
{
distance
=
-
h
.
gs
.
minDist
}
}
}
// Set-RP0 bit.
if
opcode
&
0x10
!=
0
{
h
.
gs
.
rp
[
0
]
=
i
}
h
.
gs
.
rp
[
1
]
=
h
.
gs
.
rp
[
0
]
h
.
gs
.
rp
[
2
]
=
i
// Move the point.
h
.
move
(
p
,
distance
-
curDist
)
default
:
return
errors
.
New
(
"truetype: hinting: unrecognized instruction"
)
...
...
@@ -815,6 +977,51 @@ func (h *Hinter) run(program []byte) error {
return
nil
}
// cvt returns the scaled value from the font's Control Value Table.
func
(
h
*
Hinter
)
cvt
(
i
int32
)
f26dot6
{
i
*=
2
if
i
<
0
||
len
(
h
.
font
.
cvt
)
<
int
(
i
)
{
return
0
}
cv
:=
uint16
(
h
.
font
.
cvt
[
i
])
<<
8
|
uint16
(
h
.
font
.
cvt
[
i
+
1
])
return
f26dot6
(
h
.
font
.
scale
(
h
.
scale
*
int32
(
int16
(
cv
))))
}
type
pointType
uint32
const
(
current
pointType
=
0
unhinted
pointType
=
1
inFontUnits
pointType
=
2
)
func
(
h
*
Hinter
)
point
(
zone
uint32
,
pt
pointType
,
i
int32
)
*
Point
{
points
:=
h
.
points
(
zone
,
pt
)
if
i
<
0
||
len
(
points
)
<=
int
(
i
)
{
return
nil
}
return
&
points
[
i
]
}
func
(
h
*
Hinter
)
points
(
zone
uint32
,
pt
pointType
)
[]
Point
{
if
h
.
gs
.
zp
[
zone
]
==
0
{
switch
pt
{
case
unhinted
:
return
h
.
twilightUnhinted
case
inFontUnits
:
return
h
.
twilightInFontUnits
}
return
h
.
twilightPoint
}
switch
pt
{
case
unhinted
:
return
h
.
g
.
Unhinted
case
inFontUnits
:
return
h
.
g
.
InFontUnits
}
return
h
.
g
.
Point
}
func
(
h
*
Hinter
)
move
(
p
*
Point
,
distance
f26dot6
)
{
if
h
.
gs
.
fv
[
0
]
==
0
{
p
.
Y
+=
int32
(
distance
)
...
...
freetype/truetype/opcodes.go
浏览文件 @
75fff80b
...
...
@@ -58,8 +58,8 @@ const (
opENDF
=
0x2d
// END Function definition
opMDAP0
=
0x2e
// Move Direct Absolute Point
opMDAP1
=
0x2f
// .
opIUP0
=
0x30
opIUP1
=
0x31
opIUP0
=
0x30
// Interpolate Untouched Points through the outline
opIUP1
=
0x31
// .
opSHP0
=
0x32
opSHP1
=
0x33
opSHC0
=
0x34
...
...
@@ -67,13 +67,13 @@ const (
opSHZ0
=
0x36
opSHZ1
=
0x37
opSHPIX
=
0x38
opIP
=
0x39
opIP
=
0x39
// Interpolate Point
opMSIRP0
=
0x3a
opMSIRP1
=
0x3b
opALIGNRP
=
0x3c
// ALIGN to Reference Point
opRTDG
=
0x3d
// Round To Double Grid
opMIAP0
=
0x3e
opMIAP1
=
0x3f
opMIAP0
=
0x3e
// Move Indirect Absolute Point
opMIAP1
=
0x3f
// .
opNPUSHB
=
0x40
// PUSH N Bytes
opNPUSHW
=
0x41
// PUSH N Words
opWS
=
0x42
// Write Store
...
...
@@ -234,38 +234,38 @@ const (
opMDRP11101
=
0xdd
// .
opMDRP11110
=
0xde
// .
opMDRP11111
=
0xdf
// .
opMIRP00000
=
0xe0
opMIRP00001
=
0xe1
opMIRP00010
=
0xe2
opMIRP00011
=
0xe3
opMIRP00100
=
0xe4
opMIRP00101
=
0xe5
opMIRP00110
=
0xe6
opMIRP00111
=
0xe7
opMIRP01000
=
0xe8
opMIRP01001
=
0xe9
opMIRP01010
=
0xea
opMIRP01011
=
0xeb
opMIRP01100
=
0xec
opMIRP01101
=
0xed
opMIRP01110
=
0xee
opMIRP01111
=
0xef
opMIRP10000
=
0xf0
opMIRP10001
=
0xf1
opMIRP10010
=
0xf2
opMIRP10011
=
0xf3
opMIRP10100
=
0xf4
opMIRP10101
=
0xf5
opMIRP10110
=
0xf6
opMIRP10111
=
0xf7
opMIRP11000
=
0xf8
opMIRP11001
=
0xf9
opMIRP11010
=
0xfa
opMIRP11011
=
0xfb
opMIRP11100
=
0xfc
opMIRP11101
=
0xfd
opMIRP11110
=
0xfe
opMIRP11111
=
0xff
opMIRP00000
=
0xe0
// Move Indirect Relative Point
opMIRP00001
=
0xe1
// .
opMIRP00010
=
0xe2
// .
opMIRP00011
=
0xe3
// .
opMIRP00100
=
0xe4
// .
opMIRP00101
=
0xe5
// .
opMIRP00110
=
0xe6
// .
opMIRP00111
=
0xe7
// .
opMIRP01000
=
0xe8
// .
opMIRP01001
=
0xe9
// .
opMIRP01010
=
0xea
// .
opMIRP01011
=
0xeb
// .
opMIRP01100
=
0xec
// .
opMIRP01101
=
0xed
// .
opMIRP01110
=
0xee
// .
opMIRP01111
=
0xef
// .
opMIRP10000
=
0xf0
// .
opMIRP10001
=
0xf1
// .
opMIRP10010
=
0xf2
// .
opMIRP10011
=
0xf3
// .
opMIRP10100
=
0xf4
// .
opMIRP10101
=
0xf5
// .
opMIRP10110
=
0xf6
// .
opMIRP10111
=
0xf7
// .
opMIRP11000
=
0xf8
// .
opMIRP11001
=
0xf9
// .
opMIRP11010
=
0xfa
// .
opMIRP11011
=
0xfb
// .
opMIRP11100
=
0xfc
// .
opMIRP11101
=
0xfd
// .
opMIRP11110
=
0xfe
// .
opMIRP11111
=
0xff
// .
)
// popCount is the number of stack elements that each opcode pops.
...
...
@@ -274,7 +274,7 @@ var popCount = [256]uint8{
0
,
0
,
0
,
0
,
0
,
0
,
q
,
q
,
q
,
q
,
2
,
2
,
0
,
0
,
0
,
q
,
// 0x00 - 0x0f
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
0
,
0
,
1
,
0
,
1
,
1
,
1
,
1
,
// 0x10 - 0x1f
1
,
1
,
0
,
2
,
0
,
1
,
1
,
q
,
q
,
q
,
2
,
1
,
1
,
0
,
1
,
1
,
// 0x20 - 0x2f
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
0
,
0
,
q
,
q
,
// 0x30 - 0x3f
0
,
0
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
0
,
q
,
q
,
0
,
0
,
2
,
2
,
// 0x30 - 0x3f
0
,
0
,
2
,
1
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
0
,
0
,
0
,
0
,
0
,
// 0x40 - 0x4f
2
,
2
,
2
,
2
,
2
,
2
,
1
,
1
,
1
,
0
,
2
,
2
,
1
,
q
,
1
,
1
,
// 0x50 - 0x5f
2
,
2
,
2
,
2
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
// 0x60 - 0x6f
...
...
@@ -285,8 +285,8 @@ var popCount = [256]uint8{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
// 0xb0 - 0xbf
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
// 0xc0 - 0xcf
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
// 0xd0 - 0xdf
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
// 0xe0 - 0xef
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
// 0xf0 - 0xff
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
// 0xe0 - 0xef
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
// 0xf0 - 0xff
}
// popCount[opcode] == q means that that opcode is not yet implemented.
...
...
freetype/truetype/truetype_test.go
浏览文件 @
75fff80b
...
...
@@ -116,7 +116,7 @@ func testScaling(t *testing.T, filename string, hinter *Hinter) {
for
i
,
want
:=
range
wants
{
// TODO: completely implement hinting. For now, only the first N glyphs
// of luxisr.ttf are correctly hinted.
const
N
=
1
const
N
=
5
if
hinter
!=
nil
&&
i
==
N
{
break
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录