Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小雨青年
freetype
提交
494079eb
F
freetype
项目概览
小雨青年
/
freetype
通知
14
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看板
提交
494079eb
编写于
8月 31, 2015
作者:
N
Nigel Tao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Cache the glyph index lookup.
benchmark old ns/op new ns/op delta BenchmarkDrawString-8 8618239 8149527 -5.44%
上级
03bdcc0f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
54 addition
and
31 deletion
+54
-31
truetype/face.go
truetype/face.go
+54
-31
未找到文件。
truetype/face.go
浏览文件 @
494079eb
...
...
@@ -151,39 +151,47 @@ func subPixels(q int) (value uint32, bias, mask fixed.Int26_6) {
return
uint32
(
q
),
32
/
fixed
.
Int26_6
(
q
),
-
64
/
fixed
.
Int26_6
(
q
)
}
//
c
acheEntry caches the arguments and return values of rasterize.
type
c
acheEntry
struct
{
key
c
acheKey
val
c
acheVal
//
glyphC
acheEntry caches the arguments and return values of rasterize.
type
glyphC
acheEntry
struct
{
key
glyphC
acheKey
val
glyphC
acheVal
}
type
c
acheKey
struct
{
type
glyphC
acheKey
struct
{
index
Index
fx
,
fy
uint8
}
type
c
acheVal
struct
{
type
glyphC
acheVal
struct
{
advanceWidth
fixed
.
Int26_6
offset
image
.
Point
gw
int
gh
int
}
type
indexCacheEntry
struct
{
rune
rune
index
Index
}
// NewFace returns a new font.Face for the given Font.
func
NewFace
(
f
*
Font
,
opts
*
Options
)
font
.
Face
{
a
:=
&
face
{
f
:
f
,
hinting
:
opts
.
hinting
(),
scale
:
fixed
.
Int26_6
(
0.5
+
(
opts
.
size
()
*
opts
.
dpi
()
*
64
/
72
)),
cache
:
make
([]
c
acheEntry
,
opts
.
glyphCacheEntries
()),
f
:
f
,
hinting
:
opts
.
hinting
(),
scale
:
fixed
.
Int26_6
(
0.5
+
(
opts
.
size
()
*
opts
.
dpi
()
*
64
/
72
)),
glyphCache
:
make
([]
glyphC
acheEntry
,
opts
.
glyphCacheEntries
()),
}
a
.
subPixelX
,
a
.
subPixelBiasX
,
a
.
subPixelMaskX
=
opts
.
subPixelsX
()
a
.
subPixelY
,
a
.
subPixelBiasY
,
a
.
subPixelMaskY
=
opts
.
subPixelsY
()
// Fill the cache with invalid entries. Valid cache entries have fx and fy
// in the range [0, 64).
for
i
:=
range
a
.
cache
{
a
.
cache
[
i
]
.
key
.
fy
=
0xff
// Fill the cache with invalid entries. Valid glyph cache entries have fx
// and fy in the range [0, 64). Valid index cache entries have rune >= 0.
for
i
:=
range
a
.
glyphCache
{
a
.
glyphCache
[
i
]
.
key
.
fy
=
0xff
}
for
i
:=
range
a
.
indexCache
{
a
.
indexCache
[
i
]
.
rune
=
-
1
}
// Set the rasterizer's bounds to be big enough to handle the largest glyph.
...
...
@@ -194,7 +202,7 @@ func NewFace(f *Font, opts *Options) font.Face {
ymax
:=
-
int
(
b
.
Min
.
Y
-
63
)
>>
6
a
.
maxw
=
xmax
-
xmin
a
.
maxh
=
ymax
-
ymin
a
.
masks
=
image
.
NewAlpha
(
image
.
Rect
(
0
,
0
,
a
.
maxw
,
a
.
maxh
*
len
(
a
.
c
ache
)))
a
.
masks
=
image
.
NewAlpha
(
image
.
Rect
(
0
,
0
,
a
.
maxw
,
a
.
maxh
*
len
(
a
.
glyphC
ache
)))
a
.
r
.
SetBounds
(
a
.
maxw
,
a
.
maxh
)
a
.
p
=
facePainter
{
a
}
...
...
@@ -212,24 +220,39 @@ type face struct {
subPixelBiasY
fixed
.
Int26_6
subPixelMaskY
fixed
.
Int26_6
masks
*
image
.
Alpha
cache
[]
c
acheEntry
glyphCache
[]
glyphC
acheEntry
r
raster
.
Rasterizer
p
raster
.
Painter
paintOffset
int
maxw
int
maxh
int
glyphBuf
GlyphBuf
indexCache
[
indexCacheLen
]
indexCacheEntry
// TODO: clip rectangle?
}
const
indexCacheLen
=
256
func
(
a
*
face
)
index
(
r
rune
)
Index
{
const
mask
=
indexCacheLen
-
1
c
:=
&
a
.
indexCache
[
r
&
mask
]
if
c
.
rune
==
r
{
return
c
.
index
}
i
:=
a
.
f
.
Index
(
r
)
c
.
rune
=
r
c
.
index
=
i
return
i
}
// Close satisfies the font.Face interface.
func
(
a
*
face
)
Close
()
error
{
return
nil
}
// Kern satisfies the font.Face interface.
func
(
a
*
face
)
Kern
(
r0
,
r1
rune
)
fixed
.
Int26_6
{
i0
:=
a
.
f
.
I
ndex
(
r0
)
i1
:=
a
.
f
.
I
ndex
(
r1
)
i0
:=
a
.
i
ndex
(
r0
)
i1
:=
a
.
i
ndex
(
r1
)
kern
:=
a
.
f
.
Kern
(
a
.
scale
,
i0
,
i1
)
if
a
.
hinting
!=
font
.
HintingNone
{
kern
=
(
kern
+
32
)
&^
63
...
...
@@ -249,27 +272,27 @@ func (a *face) Glyph(dot fixed.Point26_6, r rune) (
ix
,
fx
:=
int
(
dotX
>>
6
),
dotX
&
0x3f
iy
,
fy
:=
int
(
dotY
>>
6
),
dotY
&
0x3f
index
:=
a
.
f
.
I
ndex
(
r
)
index
:=
a
.
i
ndex
(
r
)
cIndex
:=
uint32
(
index
)
cIndex
=
cIndex
*
a
.
subPixelX
-
uint32
(
fx
/
a
.
subPixelMaskX
)
cIndex
=
cIndex
*
a
.
subPixelY
-
uint32
(
fy
/
a
.
subPixelMaskY
)
cIndex
&=
uint32
(
len
(
a
.
c
ache
)
-
1
)
cIndex
&=
uint32
(
len
(
a
.
glyphC
ache
)
-
1
)
a
.
paintOffset
=
a
.
maxh
*
int
(
cIndex
)
k
:=
c
acheKey
{
k
:=
glyphC
acheKey
{
index
:
index
,
fx
:
uint8
(
fx
),
fy
:
uint8
(
fy
),
}
var
v
c
acheVal
if
a
.
c
ache
[
cIndex
]
.
key
!=
k
{
var
v
glyphC
acheVal
if
a
.
glyphC
ache
[
cIndex
]
.
key
!=
k
{
var
ok
bool
v
,
ok
=
a
.
rasterize
(
index
,
fx
,
fy
)
if
!
ok
{
return
image
.
Rectangle
{},
nil
,
image
.
Point
{},
0
,
false
}
a
.
cache
[
cIndex
]
=
c
acheEntry
{
k
,
v
}
a
.
glyphCache
[
cIndex
]
=
glyphC
acheEntry
{
k
,
v
}
}
else
{
v
=
a
.
c
ache
[
cIndex
]
.
val
v
=
a
.
glyphC
ache
[
cIndex
]
.
val
}
dr
.
Min
=
image
.
Point
{
...
...
@@ -284,7 +307,7 @@ func (a *face) Glyph(dot fixed.Point26_6, r rune) (
}
func
(
a
*
face
)
GlyphBounds
(
r
rune
)
(
bounds
fixed
.
Rectangle26_6
,
advance
fixed
.
Int26_6
,
ok
bool
)
{
if
err
:=
a
.
glyphBuf
.
Load
(
a
.
f
,
a
.
scale
,
a
.
f
.
I
ndex
(
r
),
a
.
hinting
);
err
!=
nil
{
if
err
:=
a
.
glyphBuf
.
Load
(
a
.
f
,
a
.
scale
,
a
.
i
ndex
(
r
),
a
.
hinting
);
err
!=
nil
{
return
fixed
.
Rectangle26_6
{},
0
,
false
}
xmin
:=
+
a
.
glyphBuf
.
Bounds
.
Min
.
X
...
...
@@ -307,7 +330,7 @@ func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.In
}
func
(
a
*
face
)
GlyphAdvance
(
r
rune
)
(
advance
fixed
.
Int26_6
,
ok
bool
)
{
if
err
:=
a
.
glyphBuf
.
Load
(
a
.
f
,
a
.
scale
,
a
.
f
.
I
ndex
(
r
),
a
.
hinting
);
err
!=
nil
{
if
err
:=
a
.
glyphBuf
.
Load
(
a
.
f
,
a
.
scale
,
a
.
i
ndex
(
r
),
a
.
hinting
);
err
!=
nil
{
return
0
,
false
}
return
a
.
glyphBuf
.
AdvanceWidth
,
true
...
...
@@ -317,9 +340,9 @@ func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
// the width and height of the given glyph at the given sub-pixel offsets.
//
// The 26.6 fixed point arguments fx and fy must be in the range [0, 1).
func
(
a
*
face
)
rasterize
(
index
Index
,
fx
,
fy
fixed
.
Int26_6
)
(
v
c
acheVal
,
ok
bool
)
{
func
(
a
*
face
)
rasterize
(
index
Index
,
fx
,
fy
fixed
.
Int26_6
)
(
v
glyphC
acheVal
,
ok
bool
)
{
if
err
:=
a
.
glyphBuf
.
Load
(
a
.
f
,
a
.
scale
,
index
,
a
.
hinting
);
err
!=
nil
{
return
c
acheVal
{},
false
return
glyphC
acheVal
{},
false
}
// Calculate the integer-pixel bounds for the glyph.
xmin
:=
int
(
fx
+
a
.
glyphBuf
.
Bounds
.
Min
.
X
)
>>
6
...
...
@@ -327,7 +350,7 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (v cacheVal, ok bool
xmax
:=
int
(
fx
+
a
.
glyphBuf
.
Bounds
.
Max
.
X
+
0x3f
)
>>
6
ymax
:=
int
(
fy
-
a
.
glyphBuf
.
Bounds
.
Min
.
Y
+
0x3f
)
>>
6
if
xmin
>
xmax
||
ymin
>
ymax
{
return
c
acheVal
{},
false
return
glyphC
acheVal
{},
false
}
// A TrueType's glyph's nodes can have negative co-ordinates, but the
// rasterizer clips anything left of x=0 or above y=0. xmin and ymin are
...
...
@@ -346,7 +369,7 @@ func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (v cacheVal, ok bool
e0
=
e1
}
a
.
r
.
Rasterize
(
a
.
p
)
return
c
acheVal
{
return
glyphC
acheVal
{
a
.
glyphBuf
.
AdvanceWidth
,
image
.
Point
{
xmin
,
ymin
},
xmax
-
xmin
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录