Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Harfbuzz
提交
ce6639cd
T
Third Party Harfbuzz
项目概览
OpenHarmony
/
Third Party Harfbuzz
1 年多 前同步成功
通知
0
Star
18
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Harfbuzz
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ce6639cd
编写于
10月 11, 2018
作者:
M
Michiharu Ariza
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into cff-subset
上级
a6b6faf2
0b9d60e1
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
479 addition
and
128 deletion
+479
-128
src/hb-aat-layout-ankr-table.hh
src/hb-aat-layout-ankr-table.hh
+20
-5
src/hb-aat-layout-common.hh
src/hb-aat-layout-common.hh
+10
-3
src/hb-aat-layout-kerx-table.hh
src/hb-aat-layout-kerx-table.hh
+265
-24
src/hb-aat-layout-morx-table.hh
src/hb-aat-layout-morx-table.hh
+2
-2
src/hb-aat-layout-trak-table.hh
src/hb-aat-layout-trak-table.hh
+81
-54
src/hb-aat-layout.cc
src/hb-aat-layout.cc
+43
-2
src/hb-aat-layout.hh
src/hb-aat-layout.hh
+8
-0
src/hb-ot-layout-gpos-table.hh
src/hb-ot-layout-gpos-table.hh
+0
-4
src/hb-ot-shape.cc
src/hb-ot-shape.cc
+38
-32
src/hb-ot-shape.hh
src/hb-ot-shape.hh
+3
-2
test/shaping/data/in-house/Makefile.sources
test/shaping/data/in-house/Makefile.sources
+1
-0
test/shaping/data/in-house/fonts/TestTRAK.ttf
test/shaping/data/in-house/fonts/TestTRAK.ttf
+0
-0
test/shaping/data/in-house/tests/aat-trak.tests
test/shaping/data/in-house/tests/aat-trak.tests
+8
-0
未找到文件。
src/hb-aat-layout-ankr-table.hh
浏览文件 @
ce6639cd
...
...
@@ -45,32 +45,47 @@ struct Anchor
return_trace
(
c
->
check_struct
(
this
));
}
public:
FWORD
xCoordinate
;
FWORD
yCoordinate
;
public:
DEFINE_SIZE_STATIC
(
4
);
};
typedef
LArrayOf
<
Anchor
>
GlyphAnchors
;
struct
ankr
{
static
const
hb_tag_t
tableTag
=
HB_AAT_TAG_ankr
;
inline
const
Anchor
&
get_anchor
(
hb_codepoint_t
glyph_id
,
unsigned
int
i
,
unsigned
int
num_glyphs
,
const
char
*
end
)
const
{
unsigned
int
offset
=
(
this
+
lookupTable
).
get_value_or_null
(
glyph_id
,
num_glyphs
);
const
GlyphAnchors
&
anchors
=
StructAtOffset
<
GlyphAnchors
>
(
&
(
this
+
anchorData
),
offset
);
/* TODO Use sanitizer; to avoid overflows and more. */
if
(
unlikely
((
const
char
*
)
&
anchors
+
anchors
.
get_size
()
>
end
))
return
Null
(
Anchor
);
return
anchors
[
i
];
}
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
)
const
{
TRACE_SANITIZE
(
this
);
return_trace
(
likely
(
c
->
check_struct
(
this
)
&&
version
==
0
&&
lookupTable
.
sanitize
(
c
,
this
)
&&
anchors
.
sanitize
(
c
,
this
)));
lookupTable
.
sanitize
(
c
,
this
)));
}
protected:
HBUINT16
version
;
/* Version number (set to zero) */
HBUINT16
flags
;
/* Flags (currently unused; set to zero) */
LOffsetTo
<
Lookup
<
HBUINT16
>
>
LOffsetTo
<
Lookup
<
Offset
<
HBUINT16
,
false
>
>
>
lookupTable
;
/* Offset to the table's lookup table */
LOffsetTo
<
LArrayOf
<
Anchor
>
>
anchor
s
;
/* Offset to the glyph data table */
LOffsetTo
<
HBUINT8
>
anchor
Data
;
/* Offset to the glyph data table */
public:
DEFINE_SIZE_STATIC
(
12
);
...
...
src/hb-aat-layout-common.hh
浏览文件 @
ce6639cd
...
...
@@ -514,6 +514,7 @@ struct StateTableDriver
};
struct
ankr
;
struct
hb_aat_apply_context_t
:
hb_dispatch_context_t
<
hb_aat_apply_context_t
,
bool
,
HB_DEBUG_APPLY
>
...
...
@@ -529,6 +530,8 @@ struct hb_aat_apply_context_t :
hb_face_t
*
face
;
hb_buffer_t
*
buffer
;
hb_sanitize_context_t
sanitizer
;
const
ankr
&
ankr_table
;
const
char
*
ankr_end
;
/* Unused. For debug tracing only. */
unsigned
int
lookup_index
;
...
...
@@ -537,11 +540,15 @@ struct hb_aat_apply_context_t :
inline
hb_aat_apply_context_t
(
hb_ot_shape_plan_t
*
plan_
,
hb_font_t
*
font_
,
hb_buffer_t
*
buffer_
,
hb_blob_t
*
table
)
:
hb_blob_t
*
blob
=
const_cast
<
hb_blob_t
*>
(
&
Null
(
hb_blob_t
)),
const
ankr
&
ankr_table_
=
Null
(
ankr
),
const
char
*
ankr_end_
=
nullptr
)
:
plan
(
plan_
),
font
(
font_
),
face
(
font
->
face
),
buffer
(
buffer_
),
sanitizer
(),
lookup_index
(
0
),
debug_depth
(
0
)
sanitizer
(),
ankr_table
(
ankr_table_
),
ankr_end
(
ankr_end_
),
lookup_index
(
0
),
debug_depth
(
0
)
{
sanitizer
.
init
(
table
);
sanitizer
.
init
(
blob
);
sanitizer
.
set_num_glyphs
(
face
->
get_num_glyphs
());
sanitizer
.
start_processing
();
sanitizer
.
set_max_ops
(
HB_SANITIZE_MAX_OPS_MAX
);
...
...
src/hb-aat-layout-kerx-table.hh
浏览文件 @
ce6639cd
...
...
@@ -30,6 +30,7 @@
#include "hb-open-type.hh"
#include "hb-aat-layout-common.hh"
#include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-kern-table.hh"
/*
...
...
@@ -99,6 +100,100 @@ struct KerxSubTableFormat0
struct
KerxSubTableFormat1
{
struct
EntryData
{
HBUINT16
kernActionIndex
;
/* Index into the kerning value array. If
* this index is 0xFFFF, then no kerning
* is to be performed. */
public:
DEFINE_SIZE_STATIC
(
2
);
};
struct
driver_context_t
{
static
const
bool
in_place
=
true
;
enum
Flags
{
Push
=
0x8000
,
/* If set, push this glyph on the kerning stack. */
DontAdvance
=
0x4000
,
/* If set, don't advance to the next glyph
* before going to the new state. */
Reset
=
0x2000
,
/* If set, reset the kerning data (clear the stack) */
Reserved
=
0x1FFF
,
/* Not used; set to 0. */
};
inline
driver_context_t
(
const
KerxSubTableFormat1
*
table
,
hb_aat_apply_context_t
*
c_
)
:
c
(
c_
),
/* Apparently the offset kernAction is from the beginning of the state-machine,
* similar to offsets in morx table, NOT from beginning of this table, like
* other subtables in kerx. Discovered via testing. */
kernAction
(
&
table
->
machine
+
table
->
kernAction
),
depth
(
0
)
{}
inline
bool
is_actionable
(
StateTableDriver
<
EntryData
>
*
driver
,
const
Entry
<
EntryData
>
*
entry
)
{
return
entry
->
data
.
kernActionIndex
!=
0xFFFF
;
}
inline
bool
transition
(
StateTableDriver
<
EntryData
>
*
driver
,
const
Entry
<
EntryData
>
*
entry
)
{
hb_buffer_t
*
buffer
=
driver
->
buffer
;
unsigned
int
flags
=
entry
->
flags
;
if
(
flags
&
Reset
)
{
depth
=
0
;
}
if
(
flags
&
Push
)
{
if
(
likely
(
depth
<
ARRAY_LENGTH
(
stack
)))
stack
[
depth
++
]
=
buffer
->
idx
;
else
depth
=
0
;
/* Probably not what CoreText does, but better? */
}
if
(
entry
->
data
.
kernActionIndex
!=
0xFFFF
)
{
const
FWORD
*
actions
=
&
kernAction
[
entry
->
data
.
kernActionIndex
];
if
(
!
c
->
sanitizer
.
check_array
(
actions
,
depth
))
{
depth
=
0
;
return
false
;
}
hb_mask_t
kern_mask
=
c
->
plan
->
kern_mask
;
for
(
unsigned
int
i
=
0
;
i
<
depth
;
i
++
)
{
/* Apparently, when spec says "Each pops one glyph from the kerning stack
* and applies the kerning value to it.", it doesn't mean it in that order.
* The deepest item in the stack corresponds to the first item in the action
* list. Discovered by testing. */
unsigned
int
idx
=
stack
[
i
];
int
v
=
*
actions
++
;
if
(
buffer
->
info
[
idx
].
mask
&
kern_mask
)
{
/* XXX Non-forward direction... */
if
(
HB_DIRECTION_IS_HORIZONTAL
(
buffer
->
props
.
direction
))
buffer
->
pos
[
idx
].
x_advance
+=
c
->
font
->
em_scale_x
(
v
);
else
buffer
->
pos
[
idx
].
y_advance
+=
c
->
font
->
em_scale_y
(
v
);
}
}
depth
=
0
;
}
return
true
;
}
private:
hb_aat_apply_context_t
*
c
;
const
UnsizedArrayOf
<
FWORD
>
&
kernAction
;
unsigned
int
stack
[
8
];
unsigned
int
depth
;
};
inline
bool
apply
(
hb_aat_apply_context_t
*
c
)
const
{
TRACE_APPLY
(
this
);
...
...
@@ -106,7 +201,10 @@ struct KerxSubTableFormat1
if
(
!
c
->
plan
->
requested_kerning
)
return
false
;
/* TODO */
driver_context_t
dc
(
this
,
c
);
StateTableDriver
<
EntryData
>
driver
(
machine
,
c
->
buffer
,
c
->
font
->
face
);
driver
.
drive
(
&
dc
);
return_trace
(
true
);
}
...
...
@@ -114,14 +212,13 @@ struct KerxSubTableFormat1
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
)
const
{
TRACE_SANITIZE
(
this
);
return_trace
(
likely
(
c
->
check_struct
(
this
)
&&
stateHeader
.
sanitize
(
c
)));
return_trace
(
likely
(
machine
.
sanitize
(
c
)));
}
protected:
KerxSubTableHeader
header
;
StateTable
<
HBUINT16
>
stateHeader
;
LOffsetTo
<
ArrayOf
<
HBUINT16
>
>
valueTable
;
KerxSubTableHeader
header
;
StateTable
<
EntryData
>
machine
;
LOffsetTo
<
UnsizedArrayOf
<
FWORD
>
,
false
>
kernAction
;
public:
DEFINE_SIZE_STATIC
(
32
);
};
...
...
@@ -136,7 +233,7 @@ struct KerxSubTableFormat2
unsigned
int
offset
=
l
+
r
;
const
FWORD
*
v
=
&
StructAtOffset
<
FWORD
>
(
&
(
this
+
array
),
offset
);
if
(
unlikely
((
const
char
*
)
v
<
(
const
char
*
)
&
array
||
(
const
char
*
)
v
+
v
->
static_size
-
(
const
char
*
)
this
<=
header
.
length
))
(
const
char
*
)
v
+
v
->
static_size
-
(
const
char
*
)
this
>
header
.
length
))
return
0
;
return
*
v
;
}
...
...
@@ -159,11 +256,9 @@ struct KerxSubTableFormat2
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
)
const
{
TRACE_SANITIZE
(
this
);
return_trace
(
likely
(
c
->
check_struct
(
this
)
&&
rowWidth
.
sanitize
(
c
)
&&
return_trace
(
likely
(
rowWidth
.
sanitize
(
c
)
&&
leftClassTable
.
sanitize
(
c
,
this
)
&&
rightClassTable
.
sanitize
(
c
,
this
)
&&
array
.
sanitize
(
c
,
this
)));
rightClassTable
.
sanitize
(
c
,
this
)));
}
struct
accelerator_t
...
...
@@ -190,7 +285,8 @@ struct KerxSubTableFormat2
LOffsetTo
<
Lookup
<
HBUINT16
>
>
rightClassTable
;
/* Offset from beginning of this subtable to
* right-hand class table. */
LOffsetTo
<
FWORD
>
array
;
/* Offset from beginning of this subtable to
LOffsetTo
<
UnsizedArrayOf
<
FWORD
>
,
false
>
array
;
/* Offset from beginning of this subtable to
* the start of the kerning array. */
public:
DEFINE_SIZE_STATIC
(
28
);
...
...
@@ -198,11 +294,152 @@ struct KerxSubTableFormat2
struct
KerxSubTableFormat4
{
struct
EntryData
{
HBUINT16
ankrActionIndex
;
/* Either 0xFFFF (for no action) or the index of
* the action to perform. */
public:
DEFINE_SIZE_STATIC
(
2
);
};
struct
driver_context_t
{
static
const
bool
in_place
=
true
;
enum
Flags
{
Mark
=
0x8000
,
/* If set, remember this glyph as the marked glyph. */
DontAdvance
=
0x4000
,
/* If set, don't advance to the next glyph before
* going to the new state. */
Reserved
=
0x3FFF
,
/* Not used; set to 0. */
};
enum
SubTableFlags
{
ActionType
=
0xC0000000
,
/* A two-bit field containing the action type. */
Unused
=
0x3F000000
,
/* Unused - must be zero. */
Offset
=
0x00FFFFFF
,
/* Masks the offset in bytes from the beginning
* of the subtable to the beginning of the control
* point table. */
};
inline
driver_context_t
(
const
KerxSubTableFormat4
*
table
,
hb_aat_apply_context_t
*
c_
)
:
c
(
c_
),
action_type
((
table
->
flags
&
ActionType
)
>>
30
),
ankrData
((
HBUINT16
*
)
((
const
char
*
)
&
table
->
machine
+
(
table
->
flags
&
Offset
))),
mark_set
(
false
),
mark
(
0
)
{}
inline
bool
is_actionable
(
StateTableDriver
<
EntryData
>
*
driver
,
const
Entry
<
EntryData
>
*
entry
)
{
return
entry
->
data
.
ankrActionIndex
!=
0xFFFF
;
}
inline
bool
transition
(
StateTableDriver
<
EntryData
>
*
driver
,
const
Entry
<
EntryData
>
*
entry
)
{
hb_buffer_t
*
buffer
=
driver
->
buffer
;
unsigned
int
flags
=
entry
->
flags
;
if
(
mark_set
&&
entry
->
data
.
ankrActionIndex
!=
0xFFFF
)
{
hb_glyph_position_t
&
o
=
buffer
->
cur_pos
();
switch
(
action_type
)
{
case
0
:
/* Control Point Actions.*/
{
/* indexed into glyph outline. */
const
HBUINT16
*
data
=
&
ankrData
[
entry
->
data
.
ankrActionIndex
];
if
(
!
c
->
sanitizer
.
check_array
(
data
,
2
))
return
false
;
HB_UNUSED
unsigned
int
markControlPoint
=
*
data
++
;
HB_UNUSED
unsigned
int
currControlPoint
=
*
data
++
;
hb_position_t
markX
=
0
;
hb_position_t
markY
=
0
;
hb_position_t
currX
=
0
;
hb_position_t
currY
=
0
;
if
(
!
c
->
font
->
get_glyph_contour_point_for_origin
(
c
->
buffer
->
info
[
mark
].
codepoint
,
markControlPoint
,
HB_DIRECTION_LTR
/*XXX*/
,
&
markX
,
&
markY
)
||
!
c
->
font
->
get_glyph_contour_point_for_origin
(
c
->
buffer
->
cur
().
codepoint
,
currControlPoint
,
HB_DIRECTION_LTR
/*XXX*/
,
&
currX
,
&
currY
))
return
true
;
/* True, such that the machine continues. */
o
.
x_offset
=
markX
-
currX
;
o
.
y_offset
=
markY
-
currY
;
}
break
;
case
1
:
/* Anchor Point Actions. */
{
/* Indexed into 'ankr' table. */
const
HBUINT16
*
data
=
&
ankrData
[
entry
->
data
.
ankrActionIndex
];
if
(
!
c
->
sanitizer
.
check_array
(
data
,
2
))
return
false
;
unsigned
int
markAnchorPoint
=
*
data
++
;
unsigned
int
currAnchorPoint
=
*
data
++
;
const
Anchor
markAnchor
=
c
->
ankr_table
.
get_anchor
(
c
->
buffer
->
info
[
mark
].
codepoint
,
markAnchorPoint
,
c
->
face
->
get_num_glyphs
(),
c
->
ankr_end
);
const
Anchor
currAnchor
=
c
->
ankr_table
.
get_anchor
(
c
->
buffer
->
cur
().
codepoint
,
currAnchorPoint
,
c
->
face
->
get_num_glyphs
(),
c
->
ankr_end
);
o
.
x_offset
=
c
->
font
->
em_scale_x
(
markAnchor
.
xCoordinate
)
-
c
->
font
->
em_scale_x
(
currAnchor
.
xCoordinate
);
o
.
y_offset
=
c
->
font
->
em_scale_y
(
markAnchor
.
yCoordinate
)
-
c
->
font
->
em_scale_y
(
currAnchor
.
yCoordinate
);
}
break
;
case
2
:
/* Control Point Coordinate Actions. */
{
const
FWORD
*
data
=
(
const
FWORD
*
)
&
ankrData
[
entry
->
data
.
ankrActionIndex
];
if
(
!
c
->
sanitizer
.
check_array
(
data
,
4
))
return
false
;
int
markX
=
*
data
++
;
int
markY
=
*
data
++
;
int
currX
=
*
data
++
;
int
currY
=
*
data
++
;
o
.
x_offset
=
c
->
font
->
em_scale_x
(
markX
)
-
c
->
font
->
em_scale_x
(
currX
);
o
.
y_offset
=
c
->
font
->
em_scale_y
(
markY
)
-
c
->
font
->
em_scale_y
(
currY
);
}
break
;
}
o
.
attach_type
()
=
ATTACH_TYPE_MARK
;
o
.
attach_chain
()
=
(
int
)
mark
-
(
int
)
buffer
->
idx
;
buffer
->
scratch_flags
|=
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT
;
}
if
(
flags
&
Mark
)
{
mark_set
=
true
;
mark
=
buffer
->
idx
;
}
return
true
;
}
private:
hb_aat_apply_context_t
*
c
;
unsigned
int
action_type
;
const
HBUINT16
*
ankrData
;
bool
mark_set
;
unsigned
int
mark
;
};
inline
bool
apply
(
hb_aat_apply_context_t
*
c
)
const
{
TRACE_APPLY
(
this
);
/* TODO */
driver_context_t
dc
(
this
,
c
);
StateTableDriver
<
EntryData
>
driver
(
machine
,
c
->
buffer
,
c
->
font
->
face
);
driver
.
drive
(
&
dc
);
return_trace
(
true
);
}
...
...
@@ -211,14 +448,18 @@ struct KerxSubTableFormat4
{
TRACE_SANITIZE
(
this
);
/* TODO */
return_trace
(
likely
(
c
->
check_struct
(
this
)));
/* The rest of array sanitizations are done at run-time. */
return_trace
(
c
->
check_struct
(
this
)
&&
machine
.
sanitize
(
c
)
&&
flags
.
sanitize
(
c
));
}
protected:
KerxSubTableHeader
header
;
StateTable
<
EntryData
>
machine
;
HBUINT32
flags
;
public:
DEFINE_SIZE_STATIC
(
1
2
);
DEFINE_SIZE_STATIC
(
3
2
);
};
struct
KerxSubTableFormat6
...
...
@@ -241,7 +482,7 @@ struct KerxSubTableFormat6
unsigned
int
offset
=
l
+
r
;
const
FWORD32
*
v
=
&
StructAtOffset
<
FWORD32
>
(
&
(
this
+
t
.
array
),
offset
*
sizeof
(
FWORD32
));
if
(
unlikely
((
const
char
*
)
v
<
(
const
char
*
)
&
t
.
array
||
(
const
char
*
)
v
+
v
->
static_size
-
(
const
char
*
)
this
<=
header
.
length
))
(
const
char
*
)
v
+
v
->
static_size
-
(
const
char
*
)
this
>
header
.
length
))
return
0
;
return
*
v
;
}
...
...
@@ -253,7 +494,7 @@ struct KerxSubTableFormat6
unsigned
int
offset
=
l
+
r
;
const
FWORD
*
v
=
&
StructAtOffset
<
FWORD
>
(
&
(
this
+
t
.
array
),
offset
*
sizeof
(
FWORD
));
if
(
unlikely
((
const
char
*
)
v
<
(
const
char
*
)
&
t
.
array
||
(
const
char
*
)
v
+
v
->
static_size
-
(
const
char
*
)
this
<=
header
.
length
))
(
const
char
*
)
v
+
v
->
static_size
-
(
const
char
*
)
this
>
header
.
length
))
return
0
;
return
*
v
;
}
...
...
@@ -281,12 +522,10 @@ struct KerxSubTableFormat6
is_long
()
?
(
u
.
l
.
rowIndexTable
.
sanitize
(
c
,
this
)
&&
u
.
l
.
columnIndexTable
.
sanitize
(
c
,
this
)
&&
u
.
l
.
array
.
sanitize
(
c
,
this
)
u
.
l
.
columnIndexTable
.
sanitize
(
c
,
this
)
)
:
(
u
.
s
.
rowIndexTable
.
sanitize
(
c
,
this
)
&&
u
.
s
.
columnIndexTable
.
sanitize
(
c
,
this
)
&&
u
.
s
.
array
.
sanitize
(
c
,
this
)
u
.
s
.
columnIndexTable
.
sanitize
(
c
,
this
)
)));
}
...
...
@@ -316,13 +555,15 @@ struct KerxSubTableFormat6
{
LOffsetTo
<
Lookup
<
HBUINT32
>
>
rowIndexTable
;
LOffsetTo
<
Lookup
<
HBUINT32
>
>
columnIndexTable
;
LOffsetTo
<
FWORD32
>
array
;
LOffsetTo
<
UnsizedArrayOf
<
FWORD32
>
,
false
>
array
;
}
l
;
struct
Short
{
LOffsetTo
<
Lookup
<
HBUINT16
>
>
rowIndexTable
;
LOffsetTo
<
Lookup
<
HBUINT16
>
>
columnIndexTable
;
LOffsetTo
<
FWORD
>
array
;
LOffsetTo
<
UnsizedArrayOf
<
FWORD
>
,
false
>
array
;
}
s
;
}
u
;
public:
...
...
src/hb-aat-layout-morx-table.hh
浏览文件 @
ce6639cd
...
...
@@ -164,7 +164,7 @@ struct RearrangementSubtable
driver_context_t
dc
(
this
);
StateTableDriver
<
void
>
driver
(
machine
,
c
->
buffer
,
c
->
face
);
StateTableDriver
<
EntryData
>
driver
(
machine
,
c
->
buffer
,
c
->
face
);
driver
.
drive
(
&
dc
);
return_trace
(
dc
.
ret
);
...
...
@@ -365,7 +365,7 @@ struct LigatureSubtable
inline
bool
is_actionable
(
StateTableDriver
<
EntryData
>
*
driver
,
const
Entry
<
EntryData
>
*
entry
)
{
return
!!
(
entry
->
flags
&
PerformAction
)
;
return
entry
->
flags
&
PerformAction
;
}
inline
bool
transition
(
StateTableDriver
<
EntryData
>
*
driver
,
const
Entry
<
EntryData
>
*
entry
)
...
...
src/hb-aat-layout-trak-table.hh
浏览文件 @
ce6639cd
...
...
@@ -46,28 +46,32 @@ struct TrackTableEntry
{
friend
struct
TrackData
;
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
,
const
void
*
base
,
unsigned
int
size
)
const
inline
float
get_track_value
()
const
{
TRACE_SANITIZE
(
this
);
return_trace
(
likely
(
c
->
check_struct
(
this
)
&&
(
valuesZ
.
sanitize
(
c
,
base
,
size
))));
return
track
.
to_float
();
}
private:
inline
float
get_track_value
()
const
inline
int
get_value
(
const
void
*
base
,
unsigned
int
index
,
unsigned
int
nSizes
)
const
{
return
track
.
to_float
()
;
return
hb_array_t
<
FWORD
>
((
base
+
valuesZ
).
arrayZ
,
nSizes
)[
index
]
;
}
inline
int
get_value
(
const
void
*
base
,
unsigned
int
index
)
const
public:
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
,
const
void
*
base
,
unsigned
int
nSizes
)
const
{
return
(
base
+
valuesZ
)[
index
];
TRACE_SANITIZE
(
this
);
return_trace
(
likely
(
c
->
check_struct
(
this
)
&&
(
valuesZ
.
sanitize
(
c
,
base
,
nSizes
))));
}
protected:
Fixed
track
;
/* Track value for this record. */
NameID
trackNameID
;
/* The 'name' table index for this track */
NameID
trackNameID
;
/* The 'name' table index for this track.
* (a short word or phrase like "loose"
* or "very tight") */
OffsetTo
<
UnsizedArrayOf
<
FWORD
>
,
HBUINT16
,
false
>
valuesZ
;
/* Offset from start of tracking table to
* per-size tracking values for this track. */
...
...
@@ -78,12 +82,20 @@ struct TrackTableEntry
struct
TrackData
{
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
,
const
void
*
base
)
const
inline
float
interpolate_at
(
unsigned
int
idx
,
float
target_size
,
const
TrackTableEntry
&
trackTableEntry
,
const
void
*
base
)
const
{
TRACE_SANITIZE
(
this
);
return_trace
(
c
->
check_struct
(
this
)
&&
sizeTable
.
sanitize
(
c
,
base
,
nSizes
)
&&
trackTable
.
sanitize
(
c
,
nTracks
,
base
,
nSizes
));
unsigned
int
sizes
=
nSizes
;
hb_array_t
<
Fixed
>
size_table
((
base
+
sizeTable
).
arrayZ
,
sizes
);
float
s0
=
size_table
[
idx
].
to_float
();
float
s1
=
size_table
[
idx
+
1
].
to_float
();
float
t
=
unlikely
(
s0
==
s1
)
?
0.
f
:
(
target_size
-
s0
)
/
(
s1
-
s0
);
return
(
float
)
t
*
trackTableEntry
.
get_value
(
base
,
idx
+
1
,
sizes
)
+
((
float
)
1.0
-
t
)
*
trackTableEntry
.
get_value
(
base
,
idx
,
sizes
);
return
0
;
}
inline
float
get_tracking
(
const
void
*
base
,
float
ptem
)
const
...
...
@@ -94,48 +106,59 @@ struct TrackData
* https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
*/
float
csspx
=
ptem
*
96.
f
/
72.
f
;
Fixed
fixed_size
;
fixed_size
.
set_float
(
csspx
);
/* XXX Clean this up. Make it work with nSizes==1 and 0. */
/*
* Choose track.
*/
const
TrackTableEntry
*
trackTableEntry
=
nullptr
;
unsigned
int
count
=
nTracks
;
for
(
unsigned
int
i
=
0
;
i
<
count
;
i
++
)
{
/* Note: Seems like the track entries are sorted by values. But the
* spec doesn't explicitly say that. It just mentions it in the example. */
unsigned
int
sizes
=
nSizes
;
/* For now we only seek for track entries with zero tracking value */
const
TrackTableEntry
*
trackTableEntry
=
nullptr
;
for
(
unsigned
int
i
=
0
;
i
<
sizes
;
++
i
)
// For now we only seek for track entries with zero tracking value
if
(
trackTable
[
i
].
get_track_value
()
==
0.
f
)
trackTableEntry
=
&
trackTable
[
0
];
// We couldn't match any, exit
{
trackTableEntry
=
&
trackTable
[
0
];
break
;
}
}
if
(
!
trackTableEntry
)
return
0.
;
/*
* Choose size.
*/
unsigned
int
sizes
=
nSizes
;
if
(
!
sizes
)
return
0.
;
if
(
sizes
==
1
)
return
trackTableEntry
->
get_value
(
base
,
0
,
sizes
);
/* TODO bfind() */
hb_array_t
<
Fixed
>
size_table
((
base
+
sizeTable
).
arrayZ
,
sizes
);
unsigned
int
size_index
;
UnsizedArrayOf
<
Fixed
>
size_table
=
base
+
sizeTable
;
for
(
size_index
=
0
;
size_index
<
sizes
;
++
size_index
)
if
(
size_table
[
size_index
]
>=
fixed_size
)
for
(
size_index
=
0
;
size_index
<
sizes
;
size_index
++
)
if
(
size_table
[
size_index
].
to_float
()
>=
csspx
)
break
;
// TODO(ebraminio): We don't attempt to extrapolate to larger or
// smaller values for now but we should do, per spec
if
(
size_index
==
sizes
)
return
trackTableEntry
->
get_value
(
base
,
sizes
-
1
);
if
(
size_index
==
0
||
size_table
[
size_index
]
==
fixed_size
)
return
trackTableEntry
->
get_value
(
base
,
size_index
);
float
s0
=
size_table
[
size_index
-
1
].
to_float
();
float
s1
=
size_table
[
size_index
].
to_float
();
float
t
=
(
csspx
-
s0
)
/
(
s1
-
s0
);
return
(
float
)
t
*
trackTableEntry
->
get_value
(
base
,
size_index
)
+
((
float
)
1.0
-
t
)
*
trackTableEntry
->
get_value
(
base
,
size_index
-
1
);
return
interpolate_at
(
size_index
?
size_index
-
1
:
0
,
csspx
,
*
trackTableEntry
,
base
);
}
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
,
const
void
*
base
)
const
{
TRACE_SANITIZE
(
this
);
return_trace
(
c
->
check_struct
(
this
)
&&
sizeTable
.
sanitize
(
c
,
base
,
nSizes
)
&&
trackTable
.
sanitize
(
c
,
nTracks
,
base
,
nSizes
));
}
protected:
HBUINT16
nTracks
;
/* Number of separate tracks included in this table. */
HBUINT16
nSizes
;
/* Number of point sizes included in this table. */
LOffsetTo
<
UnsizedArrayOf
<
Fixed
>
,
false
>
sizeTable
;
/* Offset to array[nSizes] of size values. */
sizeTable
;
/* Offset from start of the tracking table to
* Array[nSizes] of size values.. */
UnsizedArrayOf
<
TrackTableEntry
>
trackTable
;
/* Array[nTracks] of TrackTableEntry records. */
...
...
@@ -147,6 +170,8 @@ struct trak
{
static
const
hb_tag_t
tableTag
=
HB_AAT_TAG_trak
;
inline
bool
has_data
(
void
)
const
{
return
version
.
to_int
()
!=
0
;
}
inline
bool
sanitize
(
hb_sanitize_context_t
*
c
)
const
{
TRACE_SANITIZE
(
this
);
...
...
@@ -169,24 +194,24 @@ struct trak
{
const
TrackData
&
trackData
=
this
+
horizData
;
float
tracking
=
trackData
.
get_tracking
(
this
,
ptem
);
hb_position_t
advance_to_add
=
c
->
font
->
em_scalef_x
(
tracking
/
2
);
hb_position_t
offset_to_add
=
c
->
font
->
em_scalef_x
(
tracking
/
2
);
hb_position_t
advance_to_add
=
c
->
font
->
em_scalef_x
(
tracking
);
foreach_grapheme
(
buffer
,
start
,
end
)
{
buffer
->
pos
[
start
].
x_offset
+=
advance_to_add
;
buffer
->
pos
[
start
].
x_advance
+=
advance_to_add
;
buffer
->
pos
[
end
].
x_advance
+=
advance
_to_add
;
buffer
->
pos
[
start
].
x_offset
+=
offset
_to_add
;
}
}
else
{
const
TrackData
&
trackData
=
this
+
vertData
;
float
tracking
=
trackData
.
get_tracking
(
this
,
ptem
);
hb_position_t
advance_to_add
=
c
->
font
->
em_scalef_y
(
tracking
/
2
);
hb_position_t
offset_to_add
=
c
->
font
->
em_scalef_y
(
tracking
/
2
);
hb_position_t
advance_to_add
=
c
->
font
->
em_scalef_y
(
tracking
);
foreach_grapheme
(
buffer
,
start
,
end
)
{
buffer
->
pos
[
start
].
y_offset
+=
advance_to_add
;
buffer
->
pos
[
start
].
y_advance
+=
advance_to_add
;
buffer
->
pos
[
end
].
y_advance
+=
advance
_to_add
;
buffer
->
pos
[
start
].
y_offset
+=
offset
_to_add
;
}
}
...
...
@@ -194,15 +219,17 @@ struct trak
}
protected:
FixedVersion
<>
version
;
/* Version of the tracking table--currently
* 0x00010000u for version 1.0. */
HBUINT16
format
;
/* Format of the tracking table */
OffsetTo
<
TrackData
>
horizData
;
/* TrackData for horizontal text */
OffsetTo
<
TrackData
>
vertData
;
/* TrackData for vertical text */
FixedVersion
<>
version
;
/* Version of the tracking table
* (0x00010000u for version 1.0). */
HBUINT16
format
;
/* Format of the tracking table (set to 0). */
OffsetTo
<
TrackData
>
horizData
;
/* Offset from start of tracking table to TrackData
* for horizontal text (or 0 if none). */
OffsetTo
<
TrackData
>
vertData
;
/* Offset from start of tracking table to TrackData
* for vertical text (or 0 if none). */
HBUINT16
reserved
;
/* Reserved. Set to 0. */
public:
DEFINE_SIZE_
MIN
(
12
);
DEFINE_SIZE_
STATIC
(
12
);
};
}
/* namespace AAT */
...
...
src/hb-aat-layout.cc
浏览文件 @
ce6639cd
...
...
@@ -37,7 +37,7 @@
#include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise.
/*
* morx/kerx/trak
/ankr
* morx/kerx/trak
*/
static
inline
const
AAT
::
morx
&
...
...
@@ -68,6 +68,26 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
*
blob
=
hb_ot_face_data
(
face
)
->
kerx
.
get_blob
();
return
kerx
;
}
static
inline
const
AAT
::
ankr
&
_get_ankr
(
hb_face_t
*
face
,
hb_blob_t
**
blob
=
nullptr
)
{
if
(
unlikely
(
!
hb_ot_shaper_face_data_ensure
(
face
)))
{
if
(
blob
)
*
blob
=
hb_blob_get_empty
();
return
Null
(
AAT
::
ankr
);
}
const
AAT
::
ankr
&
ankr
=
*
(
hb_ot_face_data
(
face
)
->
ankr
.
get
());
if
(
blob
)
*
blob
=
hb_ot_face_data
(
face
)
->
ankr
.
get_blob
();
return
ankr
;
}
static
inline
const
AAT
::
trak
&
_get_trak
(
hb_face_t
*
face
)
{
if
(
unlikely
(
!
hb_ot_shaper_face_data_ensure
(
face
)))
return
Null
(
AAT
::
trak
);
return
*
(
hb_ot_face_data
(
face
)
->
trak
.
get
());
}
hb_bool_t
...
...
@@ -103,6 +123,27 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan,
hb_blob_t
*
blob
;
const
AAT
::
kerx
&
kerx
=
_get_kerx
(
font
->
face
,
&
blob
);
AAT
::
hb_aat_apply_context_t
c
(
plan
,
font
,
buffer
,
blob
);
hb_blob_t
*
ankr_blob
;
const
AAT
::
ankr
&
ankr
=
_get_ankr
(
font
->
face
,
&
ankr_blob
);
AAT
::
hb_aat_apply_context_t
c
(
plan
,
font
,
buffer
,
blob
,
ankr
,
ankr_blob
->
data
+
ankr_blob
->
length
);
kerx
.
apply
(
&
c
);
}
hb_bool_t
hb_aat_layout_has_tracking
(
hb_face_t
*
face
)
{
return
_get_trak
(
face
).
has_data
();
}
void
hb_aat_layout_track
(
hb_ot_shape_plan_t
*
plan
,
hb_font_t
*
font
,
hb_buffer_t
*
buffer
)
{
const
AAT
::
trak
&
trak
=
_get_trak
(
font
->
face
);
AAT
::
hb_aat_apply_context_t
c
(
plan
,
font
,
buffer
);
trak
.
apply
(
&
c
);
}
src/hb-aat-layout.hh
浏览文件 @
ce6639cd
...
...
@@ -47,4 +47,12 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan,
hb_font_t
*
font
,
hb_buffer_t
*
buffer
);
HB_INTERNAL
hb_bool_t
hb_aat_layout_has_tracking
(
hb_face_t
*
face
);
HB_INTERNAL
void
hb_aat_layout_track
(
hb_ot_shape_plan_t
*
plan
,
hb_font_t
*
font
,
hb_buffer_t
*
buffer
);
#endif
/* HB_AAT_LAYOUT_HH */
src/hb-ot-layout-gpos-table.hh
浏览文件 @
ce6639cd
...
...
@@ -1755,10 +1755,6 @@ template <typename context_t>
struct
GPOS_accelerator_t
:
GPOS
::
accelerator_t
{};
#undef attach_chain
#undef attach_type
}
/* namespace OT */
...
...
src/hb-ot-shape.cc
浏览文件 @
ce6639cd
...
...
@@ -100,22 +100,23 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
else
if
(
hb_aat_layout_has_positioning
(
face
))
plan
.
apply_kerx
=
true
;
if
(
plan
.
requested_kerning
)
if
(
plan
.
requested_kerning
&&
!
plan
.
apply_kerx
&&
!
has_gpos_kern
)
{
if
(
plan
.
apply_kerx
)
;
/* kerx supercedes kern. */
else
if
(
!
has_gpos_kern
)
{
if
(
hb_ot_layout_has_kerning
(
face
))
plan
.
apply_kern
=
true
;
else
plan
.
fallback_kerning
=
true
;
}
/* Apparently Apple applies kerx if GPOS kern was not applied. */
if
(
hb_aat_layout_has_positioning
(
face
))
plan
.
apply_kerx
=
true
;
if
(
hb_ot_layout_has_kerning
(
face
))
plan
.
apply_kern
=
true
;
else
plan
.
fallback_kerning
=
true
;
}
plan
.
has_gpos_mark
=
!!
plan
.
map
.
get_1_mask
(
HB_TAG
(
'm'
,
'a'
,
'r'
,
'k'
));
if
(
!
plan
.
apply_gpos
)
if
(
!
plan
.
apply_gpos
&&
!
plan
.
apply_kerx
)
plan
.
fallback_mark_positioning
=
true
;
/* Currently we always apply trak. */
plan
.
apply_trak
=
hb_aat_layout_has_tracking
(
face
);
}
...
...
@@ -820,34 +821,39 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
hb_ot_layout_position_start
(
c
->
font
,
c
->
buffer
);
switch
(
c
->
plan
->
shaper
->
zero_width_marks
)
{
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY
:
zero_mark_widths_by_gdef
(
c
->
buffer
,
adjust_offsets_when_zeroing
);
break
;
default:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE
:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
:
break
;
}
if
(
!
c
->
plan
->
apply_kerx
)
switch
(
c
->
plan
->
shaper
->
zero_width_marks
)
{
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY
:
zero_mark_widths_by_gdef
(
c
->
buffer
,
adjust_offsets_when_zeroing
);
break
;
default:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE
:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
:
break
;
}
if
(
c
->
plan
->
apply_gpos
)
c
->
plan
->
position
(
c
->
font
,
c
->
buffer
);
else
if
(
c
->
plan
->
apply_kerx
)
hb_aat_layout_position
(
c
->
plan
,
c
->
font
,
c
->
buffer
);
switch
(
c
->
plan
->
shaper
->
zero_width_marks
)
{
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
:
zero_mark_widths_by_gdef
(
c
->
buffer
,
adjust_offsets_when_zeroing
);
break
;
if
(
c
->
plan
->
apply_trak
)
hb_aat_layout_track
(
c
->
plan
,
c
->
font
,
c
->
buffer
);
default:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE
:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY
:
break
;
}
if
(
!
c
->
plan
->
apply_kerx
)
switch
(
c
->
plan
->
shaper
->
zero_width_marks
)
{
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
:
zero_mark_widths_by_gdef
(
c
->
buffer
,
adjust_offsets_when_zeroing
);
break
;
default:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE
:
case
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY
:
break
;
}
/* Finishing off GPOS has to follow a certain order. */
hb_ot_layout_position_finish_advances
(
c
->
font
,
c
->
buffer
);
...
...
src/hb-ot-shape.hh
浏览文件 @
ce6639cd
...
...
@@ -50,10 +50,11 @@ struct hb_ot_shape_plan_t
bool
fallback_kerning
:
1
;
bool
fallback_mark_positioning
:
1
;
bool
apply_
morx
:
1
;
bool
apply_
gpos
:
1
;
bool
apply_kerx
:
1
;
bool
apply_kern
:
1
;
bool
apply_gpos
:
1
;
bool
apply_morx
:
1
;
bool
apply_trak
:
1
;
inline
void
collect_lookups
(
hb_tag_t
table_tag
,
hb_set_t
*
lookups
)
const
...
...
test/shaping/data/in-house/Makefile.sources
浏览文件 @
ce6639cd
TESTS
=
\
tests/aat-trak.tests
\
tests/arabic-fallback-shaping.tests
\
tests/arabic-feature-order.tests
\
tests/arabic-like-joining.tests
\
...
...
test/shaping/data/in-house/fonts/TestTRAK.ttf
0 → 100644
浏览文件 @
ce6639cd
文件已添加
test/shaping/data/in-house/tests/aat-trak.tests
0 → 100644
浏览文件 @
ce6639cd
../fonts/TestTRAK.ttf::U+0041,U+0042,U+0043:[A.alt=0+1000|B=1+1000|C.alt=2+1000]
../fonts/TestTRAK.ttf:--font-ptem=.5:U+0041,U+0042,U+0043:[A.alt=0@100,0+1200|B=1@100,0+1200|C.alt=2@100,0+1200]
../fonts/TestTRAK.ttf:--font-ptem=1:U+0041,U+0042,U+0043:[A.alt=0@100,0+1200|B=1@100,0+1200|C.alt=2@100,0+1200]
../fonts/TestTRAK.ttf:--font-ptem=2:U+0041,U+0042,U+0043:[A.alt=0@93,0+1187|B=1@93,0+1187|C.alt=2@93,0+1187]
../fonts/TestTRAK.ttf:--font-ptem=9:U+0041,U+0042,U+0043:[A.alt=0+1000|B=1+1000|C.alt=2+1000]
../fonts/TestTRAK.ttf:--font-ptem=24:U+0041,U+0042,U+0043:[A.alt=0@-12,0+976|B=1@-12,0+976|C.alt=2@-12,0+976]
../fonts/TestTRAK.ttf:--font-ptem=72:U+0041,U+0042,U+0043:[A.alt=0@-50,0+900|B=1@-50,0+900|C.alt=2@-50,0+900]
../fonts/TestTRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-100,0+800|B=1@-100,0+800|C.alt=2@-100,0+800]
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录