Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小雨青年
freetype
提交
995030b9
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看板
提交
995030b9
编写于
9月 21, 2015
作者:
S
Stephen Edwards
提交者:
Nigel Tao
9月 21, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add Font.Name method.
上级
fb514f71
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
144 addition
and
38 deletion
+144
-38
truetype/truetype.go
truetype/truetype.go
+121
-38
truetype/truetype_test.go
truetype/truetype_test.go
+23
-0
未找到文件。
truetype/truetype.go
浏览文件 @
995030b9
...
...
@@ -26,6 +26,41 @@ import (
// An Index is a Font's index of a rune.
type
Index
uint16
// A NameID represents the Name Identifiers in the name table.
type
NameID
uint16
const
(
NameIDCopyright
NameID
=
0
NameIDFontFamily
=
1
NameIDFontSubfamily
=
2
NameIDUniqueSubfamilyID
=
3
NameIDFontFullName
=
4
NameIDNameTableVersion
=
5
NameIDPostscriptName
=
6
NameIDTrademarkNotice
=
7
NameIDManufacturerName
=
8
NameIDDesignerName
=
9
NameIDFontDescription
=
10
NameIDFontVendorURL
=
11
NameIDFontDesignerURL
=
12
NameIDFontLicense
=
13
NameIDFontLicenseURL
=
14
NameIDPreferredFamily
=
16
NameIDPreferredSubfamily
=
17
NameIDCompatibleName
=
18
NameIDSampleText
=
19
)
const
(
// A 32-bit encoding consists of a most-significant 16-bit Platform ID and a
// least-significant 16-bit Platform Specific ID. The magic numbers are
// specified at https://www.microsoft.com/typography/otspec/name.htm
unicodeEncoding
=
0x00000003
// PID = 0 (Unicode), PSID = 3 (Unicode 2.0)
microsoftSymbolEncoding
=
0x00030000
// PID = 3 (Microsoft), PSID = 0 (Symbol)
microsoftUCS2Encoding
=
0x00030001
// PID = 3 (Microsoft), PSID = 1 (UCS-2)
microsoftUCS4Encoding
=
0x0003000a
// PID = 3 (Microsoft), PSID = 10 (UCS-4)
)
// An HMetric holds the horizontal metrics of a single glyph.
type
HMetric
struct
{
AdvanceWidth
,
LeftSideBearing
fixed
.
Int26_6
...
...
@@ -78,6 +113,43 @@ func readTable(ttf []byte, offsetLength []byte) ([]byte, error) {
return
ttf
[
offset
:
end
],
nil
}
// parseSubtables wraps the commonality in Name and parseCmap.
func
parseSubtables
(
b
[]
byte
,
name
string
,
offset
,
size
int
,
tableCheckPred
func
(
b
[]
byte
)
bool
)
(
int
,
int
,
error
)
{
if
len
(
b
)
<
4
{
return
0
,
0
,
FormatError
(
name
+
" too short"
)
}
nsubtab
:=
int
(
u16
(
b
,
2
))
if
len
(
b
)
<
size
*
nsubtab
+
offset
{
return
0
,
0
,
FormatError
(
name
+
" too short"
)
}
pid
,
x
:=
0
,
offset
offset
=
0
for
i
:=
0
;
i
<
nsubtab
;
i
,
x
=
i
+
1
,
x
+
size
{
if
tableCheckPred
!=
nil
&&
!
tableCheckPred
(
b
[
x
:
])
{
// When tableCheck is nil, examine the table.
continue
}
// We read the 16-bit Platform ID and 16-bit Platform Specific ID as a single uint32.
// All values are big-endian.
pidPsid
:=
u32
(
b
,
x
)
// We prefer the Unicode cmap encoding. Failing to find that, we fall
// back onto the Microsoft cmap encoding.
if
pidPsid
==
unicodeEncoding
{
offset
,
pid
=
x
,
int
(
pidPsid
>>
16
)
break
}
else
if
pidPsid
==
microsoftSymbolEncoding
||
pidPsid
==
microsoftUCS2Encoding
||
pidPsid
==
microsoftUCS4Encoding
{
offset
,
pid
=
x
,
int
(
pidPsid
>>
16
)
// We don't break out of the for loop, so that Unicode can override Microsoft.
}
}
return
offset
,
pid
,
nil
}
const
(
locaOffsetFormatUnknown
int
=
iota
locaOffsetFormatShort
...
...
@@ -93,7 +165,7 @@ type cm struct {
type
Font
struct
{
// Tables sliced from the TTF data. The different tables are documented
// at http://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html
cmap
,
cvt
,
fpgm
,
glyf
,
hdmx
,
head
,
hhea
,
hmtx
,
kern
,
loca
,
maxp
,
os2
,
prep
,
vmtx
[]
byte
cmap
,
cvt
,
fpgm
,
glyf
,
hdmx
,
head
,
hhea
,
hmtx
,
kern
,
loca
,
maxp
,
name
,
os2
,
prep
,
vmtx
[]
byte
cmapIndexes
[]
byte
...
...
@@ -112,45 +184,12 @@ func (f *Font) parseCmap() error {
cmapFormat4
=
4
cmapFormat12
=
12
languageIndependent
=
0
// A 32-bit encoding consists of a most-significant 16-bit Platform ID and a
// least-significant 16-bit Platform Specific ID. The magic numbers are
// specified at https://www.microsoft.com/typography/otspec/name.htm
unicodeEncoding
=
0x00000003
// PID = 0 (Unicode), PSID = 3 (Unicode 2.0)
microsoftSymbolEncoding
=
0x00030000
// PID = 3 (Microsoft), PSID = 0 (Symbol)
microsoftUCS2Encoding
=
0x00030001
// PID = 3 (Microsoft), PSID = 1 (UCS-2)
microsoftUCS4Encoding
=
0x0003000a
// PID = 3 (Microsoft), PSID = 10 (UCS-4)
)
if
len
(
f
.
cmap
)
<
4
{
return
FormatError
(
"cmap too short"
)
}
nsubtab
:=
int
(
u16
(
f
.
cmap
,
2
))
if
len
(
f
.
cmap
)
<
8
*
nsubtab
+
4
{
return
FormatError
(
"cmap too short"
)
}
offset
,
found
,
x
:=
0
,
false
,
4
for
i
:=
0
;
i
<
nsubtab
;
i
++
{
// We read the 16-bit Platform ID and 16-bit Platform Specific ID as a single uint32.
// All values are big-endian.
pidPsid
,
o
:=
u32
(
f
.
cmap
,
x
),
u32
(
f
.
cmap
,
x
+
4
)
x
+=
8
// We prefer the Unicode cmap encoding. Failing to find that, we fall
// back onto the Microsoft cmap encoding.
if
pidPsid
==
unicodeEncoding
{
offset
,
found
=
int
(
o
),
true
break
}
else
if
pidPsid
==
microsoftSymbolEncoding
||
pidPsid
==
microsoftUCS2Encoding
||
pidPsid
==
microsoftUCS4Encoding
{
offset
,
found
=
int
(
o
),
true
// We don't break out of the for loop, so that Unicode can override Microsoft.
}
}
if
!
found
{
return
UnsupportedError
(
"cmap encoding"
)
x
,
_
,
err
:=
parseSubtables
(
f
.
cmap
,
"cmap"
,
4
,
8
,
nil
)
offset
:=
int
(
u32
(
f
.
cmap
,
x
+
4
))
if
err
!=
nil
{
return
err
}
if
offset
<=
0
||
offset
>
len
(
f
.
cmap
)
{
return
FormatError
(
"bad cmap offset"
)
...
...
@@ -345,6 +384,48 @@ func (f *Font) Index(x rune) Index {
return
0
}
// Name returns the NameID value of a Font.
// Returns "" on error or not found.
func
(
f
*
Font
)
Name
(
id
NameID
)
string
{
x
,
platformID
,
err
:=
parseSubtables
(
f
.
name
,
"name"
,
6
,
12
,
func
(
b
[]
byte
)
bool
{
return
NameID
(
u16
(
b
,
6
))
==
id
})
if
err
!=
nil
{
return
""
}
offset
,
length
:=
u16
(
f
.
name
,
x
+
10
),
u16
(
f
.
name
,
x
+
8
)
offset
+=
u16
(
f
.
name
,
4
)
// Return the ASCII value of the encoded string.
// The string is encoded as UTF-16 on non-Apple platformIDs; Apple is platformID 1.
src
:=
f
.
name
[
offset
:
offset
+
length
]
var
dst
[]
byte
if
platformID
!=
1
{
// UTF-16.
if
len
(
src
)
&
1
!=
0
{
return
""
}
dst
=
make
([]
byte
,
len
(
src
)
/
2
)
for
i
:=
range
dst
{
dst
[
i
]
=
printable
(
u16
(
src
,
2
*
i
))
}
}
else
{
// ASCII.
dst
=
make
([]
byte
,
len
(
src
))
for
i
,
c
:=
range
src
{
dst
[
i
]
=
printable
(
uint16
(
c
))
}
}
return
string
(
dst
)
}
func
printable
(
r
uint16
)
byte
{
if
0x20
<=
r
&&
r
<=
0x7f
{
return
byte
(
r
)
}
return
'?'
}
// unscaledHMetric returns the unscaled horizontal metrics for the glyph with
// the given index.
func
(
f
*
Font
)
unscaledHMetric
(
i
Index
)
(
h
HMetric
)
{
...
...
@@ -518,6 +599,8 @@ func parse(ttf []byte, offset int) (font *Font, err error) {
f
.
loca
,
err
=
readTable
(
ttf
,
ttf
[
x
+
8
:
x
+
16
])
case
"maxp"
:
f
.
maxp
,
err
=
readTable
(
ttf
,
ttf
[
x
+
8
:
x
+
16
])
case
"name"
:
f
.
name
,
err
=
readTable
(
ttf
,
ttf
[
x
+
8
:
x
+
16
])
case
"OS/2"
:
f
.
os2
,
err
=
readTable
(
ttf
,
ttf
[
x
+
8
:
x
+
16
])
case
"prep"
:
...
...
truetype/truetype_test.go
浏览文件 @
995030b9
...
...
@@ -211,6 +211,29 @@ func TestIndex(t *testing.T) {
}
}
func
TestName
(
t
*
testing
.
T
)
{
testCases
:=
map
[
string
]
string
{
"luximr"
:
"Luxi Mono"
,
"luxirr"
:
"Luxi Serif"
,
"luxisr"
:
"Luxi Sans"
,
}
for
name
,
want
:=
range
testCases
{
f
,
testdataIsOptional
,
err
:=
parseTestdataFont
(
name
)
if
err
!=
nil
{
if
testdataIsOptional
{
t
.
Log
(
err
)
}
else
{
t
.
Fatal
(
err
)
}
continue
}
if
got
:=
f
.
Name
(
NameIDFontFamily
);
got
!=
want
{
t
.
Errorf
(
"%s: got %q, want %q"
,
name
,
got
,
want
)
}
}
}
type
scalingTestData
struct
{
advanceWidth
fixed
.
Int26_6
bounds
fixed
.
Rectangle26_6
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录