Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Harfbuzz
提交
9fd08cc2
T
Third Party Harfbuzz
项目概览
OpenHarmony
/
Third Party Harfbuzz
接近 2 年 前同步成功
通知
1
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看板
提交
9fd08cc2
编写于
8月 29, 2018
作者:
M
Michiharu Ariza
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CFF2 subroutine flattner
Factored out CFF1 & CFF2 common subsetting code in hb-subset-cff-common.hh
上级
b95bf075
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
285 addition
and
267 deletion
+285
-267
src/hb-cff2-interp-cs.hh
src/hb-cff2-interp-cs.hh
+25
-9
src/hb-subset-cff-common.hh
src/hb-subset-cff-common.hh
+154
-0
src/hb-subset-cff1.cc
src/hb-subset-cff1.cc
+15
-120
src/hb-subset-cff2.cc
src/hb-subset-cff2.cc
+91
-138
未找到文件。
src/hb-cff2-interp-cs.hh
浏览文件 @
9fd08cc2
...
@@ -54,6 +54,15 @@ struct CFF2CSInterpEnv : CSInterpEnv<CFF2Subrs>
...
@@ -54,6 +54,15 @@ struct CFF2CSInterpEnv : CSInterpEnv<CFF2Subrs>
return
true
;
return
true
;
}
}
inline
bool
process_vsindex
(
void
)
{
unsigned
int
index
;
if
(
unlikely
(
!
argStack
.
check_pop_uint
(
index
)))
return
false
;
set_ivs
(
index
);
return
true
;
}
inline
unsigned
int
get_ivs
(
void
)
const
{
return
ivs
;
}
inline
unsigned
int
get_ivs
(
void
)
const
{
return
ivs
;
}
inline
void
set_ivs
(
unsigned
int
ivs_
)
{
ivs
=
ivs_
;
}
inline
void
set_ivs
(
unsigned
int
ivs_
)
{
ivs
=
ivs_
;
}
...
@@ -69,16 +78,11 @@ struct CFF2CSOpSet : CSOpSet<OPSET, CFF2CSInterpEnv, PARAM>
...
@@ -69,16 +78,11 @@ struct CFF2CSOpSet : CSOpSet<OPSET, CFF2CSInterpEnv, PARAM>
switch
(
op
)
{
switch
(
op
)
{
case
OpCode_blendcs
:
case
OpCode_blendcs
:
//env.flush_stack (); // XXX: TODO
return
OPSET
::
process_blend
(
env
,
param
);
break
;
case
OpCode_vsindexcs
:
case
OpCode_vsindexcs
:
{
return
OPSET
::
process_vsindex
(
env
,
param
);
unsigned
int
ivs
;
if
(
unlikely
(
!
env
.
argStack
.
check_pop_uint
(
ivs
)))
return
false
;
env
.
set_ivs
(
ivs
);
//env.flush_stack ();
}
break
;
default:
default:
typedef
CSOpSet
<
OPSET
,
CFF2CSInterpEnv
,
PARAM
>
SUPER
;
typedef
CSOpSet
<
OPSET
,
CFF2CSInterpEnv
,
PARAM
>
SUPER
;
if
(
unlikely
(
!
SUPER
::
process_op
(
op
,
env
,
param
)))
if
(
unlikely
(
!
SUPER
::
process_op
(
op
,
env
,
param
)))
...
@@ -87,6 +91,18 @@ struct CFF2CSOpSet : CSOpSet<OPSET, CFF2CSInterpEnv, PARAM>
...
@@ -87,6 +91,18 @@ struct CFF2CSOpSet : CSOpSet<OPSET, CFF2CSInterpEnv, PARAM>
}
}
return
true
;
return
true
;
}
}
static
inline
bool
process_blend
(
CFF2CSInterpEnv
&
env
,
PARAM
&
param
)
{
// XXX: TODO leave default values?
OPSET
::
flush_stack
(
env
,
param
);
return
true
;
}
static
inline
bool
process_vsindex
(
CFF2CSInterpEnv
&
env
,
PARAM
&
param
)
{
return
env
.
process_vsindex
();
}
};
};
template
<
typename
OPSET
,
typename
PARAM
>
template
<
typename
OPSET
,
typename
PARAM
>
...
...
src/hb-subset-cff-common.hh
浏览文件 @
9fd08cc2
...
@@ -98,6 +98,160 @@ struct ByteStrBuffArray : hb_vector_t<ByteStrBuff, 1>
...
@@ -98,6 +98,160 @@ struct ByteStrBuffArray : hb_vector_t<ByteStrBuff, 1>
}
}
};
};
struct
CFFSubTableOffsets
{
inline
CFFSubTableOffsets
(
void
)
:
privateDictsOffset
(
0
)
{
topDictInfo
.
init
();
FDSelectInfo
.
init
();
FDArrayInfo
.
init
();
charStringsInfo
.
init
();
globalSubrsInfo
.
init
();
localSubrsInfos
.
init
();
}
inline
~
CFFSubTableOffsets
(
void
)
{
localSubrsInfos
.
fini
();
}
TableInfo
topDictInfo
;
TableInfo
FDSelectInfo
;
TableInfo
FDArrayInfo
;
TableInfo
charStringsInfo
;
unsigned
int
privateDictsOffset
;
TableInfo
globalSubrsInfo
;
hb_vector_t
<
TableInfo
>
localSubrsInfos
;
};
struct
CFFTopDict_OpSerializer
:
OpSerializer
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
CFFSubTableOffsets
&
offsets
)
const
{
TRACE_SERIALIZE
(
this
);
switch
(
opstr
.
op
)
{
case
OpCode_CharStrings
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
charStringsInfo
.
offset
));
case
OpCode_FDArray
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
FDArrayInfo
.
offset
));
case
OpCode_FDSelect
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
FDSelectInfo
.
offset
));
default:
return_trace
(
copy_opstr
(
c
,
opstr
));
}
return_trace
(
true
);
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
{
switch
(
opstr
.
op
)
{
case
OpCode_CharStrings
:
case
OpCode_FDArray
:
case
OpCode_FDSelect
:
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
opstr
.
op
);
default:
return
opstr
.
str
.
len
;
}
}
};
struct
CFFFontDict_OpSerializer
:
OpSerializer
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
TableInfo
&
privateDictInfo
)
const
{
TRACE_SERIALIZE
(
this
);
if
(
opstr
.
op
==
OpCode_Private
)
{
/* serialize the private dict size as a 2-byte integer */
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int2
(
c
,
privateDictInfo
.
size
)))
return_trace
(
false
);
/* serialize the private dict offset as a 4-byte integer */
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int4
(
c
,
privateDictInfo
.
offset
)))
return_trace
(
false
);
/* serialize the opcode */
HBUINT8
*
p
=
c
->
allocate_size
<
HBUINT8
>
(
1
);
if
(
unlikely
(
p
==
nullptr
))
return_trace
(
false
);
p
->
set
(
OpCode_Private
);
return_trace
(
true
);
}
else
{
HBUINT8
*
d
=
c
->
allocate_size
<
HBUINT8
>
(
opstr
.
str
.
len
);
if
(
unlikely
(
d
==
nullptr
))
return_trace
(
false
);
memcpy
(
d
,
&
opstr
.
str
.
str
[
0
],
opstr
.
str
.
len
);
}
return_trace
(
true
);
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
{
if
(
opstr
.
op
==
OpCode_Private
)
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Private
);
else
return
opstr
.
str
.
len
;
}
};
struct
CFFPrivateDict_OpSerializer
:
OpSerializer
{
inline
CFFPrivateDict_OpSerializer
(
bool
drop_hints_
=
false
,
bool
flatten_subrs_
=
false
)
:
drop_hints
(
drop_hints_
),
flatten_subrs
(
flatten_subrs_
)
{}
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
unsigned
int
subrsOffset
)
const
{
TRACE_SERIALIZE
(
this
);
if
(
drop_hints
&&
DictOpSet
::
is_hint_op
(
opstr
.
op
))
return
true
;
if
(
opstr
.
op
==
OpCode_Subrs
)
{
if
(
flatten_subrs
)
return_trace
(
true
);
else
return_trace
(
FontDict
::
serialize_offset2_op
(
c
,
OpCode_Subrs
,
subrsOffset
));
}
else
return_trace
(
copy_opstr
(
c
,
opstr
));
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
{
if
(
drop_hints
&&
DictOpSet
::
is_hint_op
(
opstr
.
op
))
return
0
;
if
(
opstr
.
op
==
OpCode_Subrs
)
{
if
(
flatten_subrs
)
return
0
;
else
return
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Subrs
);
}
else
return
opstr
.
str
.
len
;
}
protected:
const
bool
drop_hints
;
const
bool
flatten_subrs
;
};
template
<
typename
ACCESSOR
,
typename
ENV
,
typename
OPSET
>
template
<
typename
ACCESSOR
,
typename
ENV
,
typename
OPSET
>
struct
SubrFlattener
struct
SubrFlattener
...
...
src/hb-subset-cff1.cc
浏览文件 @
9fd08cc2
...
@@ -34,32 +34,26 @@
...
@@ -34,32 +34,26 @@
using
namespace
CFF
;
using
namespace
CFF
;
struct
CFF1SubTableOffsets
{
struct
CFF1SubTableOffsets
:
CFFSubTableOffsets
{
inline
CFF1SubTableOffsets
(
void
)
inline
CFF1SubTableOffsets
(
void
)
:
CFFSubTableOffsets
(),
nameIndexOffset
(
0
),
stringIndexOffset
(
0
),
encodingOffset
(
0
),
charsetOffset
(
0
)
{
{
memset
(
this
,
0
,
sizeof
(
*
this
));
privateDictInfo
.
init
();
localSubrsInfos
.
init
();
}
inline
~
CFF1SubTableOffsets
(
void
)
{
localSubrsInfos
.
fini
();
}
}
unsigned
int
nameIndexOffset
;
unsigned
int
nameIndexOffset
;
TableInfo
topDictInfo
;
unsigned
int
stringIndexOffset
;
unsigned
int
stringIndexOffset
;
TableInfo
globalSubrsInfo
;
unsigned
int
encodingOffset
;
unsigned
int
encodingOffset
;
unsigned
int
charsetOffset
;
unsigned
int
charsetOffset
;
TableInfo
FDSelectInfo
;
TableInfo
FDArrayInfo
;
TableInfo
charStringsInfo
;
TableInfo
privateDictInfo
;
TableInfo
privateDictInfo
;
hb_vector_t
<
TableInfo
>
localSubrsInfos
;
};
};
struct
CFF1TopDict_OpSerializer
:
OpSerializer
struct
CFF1TopDict_OpSerializer
:
CFFTopDict_
OpSerializer
{
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
OpStr
&
opstr
,
...
@@ -75,15 +69,6 @@ struct CFF1TopDict_OpSerializer : OpSerializer
...
@@ -75,15 +69,6 @@ struct CFF1TopDict_OpSerializer : OpSerializer
case
OpCode_Encoding
:
case
OpCode_Encoding
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
encodingOffset
));
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
encodingOffset
));
case
OpCode_CharStrings
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
charStringsInfo
.
offset
));
case
OpCode_FDArray
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
FDArrayInfo
.
offset
));
case
OpCode_FDSelect
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
FDSelectInfo
.
offset
));
case
OpCode_Private
:
case
OpCode_Private
:
{
{
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int2
(
c
,
offsets
.
privateDictInfo
.
size
)))
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int2
(
c
,
offsets
.
privateDictInfo
.
size
)))
...
@@ -97,7 +82,7 @@ struct CFF1TopDict_OpSerializer : OpSerializer
...
@@ -97,7 +82,7 @@ struct CFF1TopDict_OpSerializer : OpSerializer
break
;
break
;
default:
default:
return_trace
(
copy_opstr
(
c
,
opstr
));
return_trace
(
CFFTopDict_OpSerializer
::
serialize
(
c
,
opstr
,
offsets
));
}
}
return_trace
(
true
);
return_trace
(
true
);
}
}
...
@@ -108,105 +93,15 @@ struct CFF1TopDict_OpSerializer : OpSerializer
...
@@ -108,105 +93,15 @@ struct CFF1TopDict_OpSerializer : OpSerializer
{
{
case
OpCode_charset
:
case
OpCode_charset
:
case
OpCode_Encoding
:
case
OpCode_Encoding
:
case
OpCode_CharStrings
:
case
OpCode_FDArray
:
case
OpCode_FDSelect
:
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
opstr
.
op
);
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
opstr
.
op
);
case
OpCode_Private
:
case
OpCode_Private
:
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Private
);
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Private
);
default:
default:
return
opstr
.
str
.
len
;
return
CFFTopDict_OpSerializer
::
calculate_serialized_size
(
opstr
);
}
}
};
struct
CFF1FontDict_OpSerializer
:
OpSerializer
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
TableInfo
&
privateDictInfo
)
const
{
TRACE_SERIALIZE
(
this
);
if
(
opstr
.
op
==
OpCode_Private
)
{
/* serialize the private dict size as a 2-byte integer */
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int2
(
c
,
privateDictInfo
.
size
)))
return_trace
(
false
);
/* serialize the private dict offset as a 4-byte integer */
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int4
(
c
,
privateDictInfo
.
offset
)))
return_trace
(
false
);
/* serialize the opcode */
HBUINT8
*
p
=
c
->
allocate_size
<
HBUINT8
>
(
1
);
if
(
unlikely
(
p
==
nullptr
))
return_trace
(
false
);
p
->
set
(
OpCode_Private
);
return_trace
(
true
);
}
else
{
HBUINT8
*
d
=
c
->
allocate_size
<
HBUINT8
>
(
opstr
.
str
.
len
);
if
(
unlikely
(
d
==
nullptr
))
return_trace
(
false
);
memcpy
(
d
,
&
opstr
.
str
.
str
[
0
],
opstr
.
str
.
len
);
}
}
return_trace
(
true
);
}
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
{
if
(
opstr
.
op
==
OpCode_Private
)
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Private
);
else
return
opstr
.
str
.
len
;
}
};
struct
CFF1PrivateDict_OpSerializer
:
OpSerializer
{
inline
CFF1PrivateDict_OpSerializer
(
bool
drop_hints_
=
false
,
bool
flatten_subrs_
=
false
)
:
drop_hints
(
drop_hints_
),
flatten_subrs
(
flatten_subrs_
)
{}
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
unsigned
int
subrsOffset
)
const
{
TRACE_SERIALIZE
(
this
);
if
(
drop_hints
&&
DictOpSet
::
is_hint_op
(
opstr
.
op
))
return
true
;
if
(
opstr
.
op
==
OpCode_Subrs
)
{
if
(
flatten_subrs
)
return_trace
(
true
);
else
return_trace
(
FontDict
::
serialize_offset2_op
(
c
,
OpCode_Subrs
,
subrsOffset
));
}
else
return_trace
(
copy_opstr
(
c
,
opstr
));
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
{
if
(
drop_hints
&&
DictOpSet
::
is_hint_op
(
opstr
.
op
))
return
0
;
if
(
opstr
.
op
==
OpCode_Subrs
)
{
if
(
flatten_subrs
)
return
0
;
else
return
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Subrs
);
}
else
return
opstr
.
str
.
len
;
}
protected:
const
bool
drop_hints
;
const
bool
flatten_subrs
;
};
};
struct
CFF1CSOpSet_Flatten
:
CFF1CSOpSet
<
CFF1CSOpSet_Flatten
,
ByteStrBuff
>
struct
CFF1CSOpSet_Flatten
:
CFF1CSOpSet
<
CFF1CSOpSet_Flatten
,
ByteStrBuff
>
...
@@ -387,7 +282,7 @@ struct cff_subset_plan {
...
@@ -387,7 +282,7 @@ struct cff_subset_plan {
/* FDArray (FDIndex) */
/* FDArray (FDIndex) */
if
(
acc
.
fdArray
!=
&
Null
(
CFF1FDArray
))
{
if
(
acc
.
fdArray
!=
&
Null
(
CFF1FDArray
))
{
offsets
.
FDArrayInfo
.
offset
=
final_size
;
offsets
.
FDArrayInfo
.
offset
=
final_size
;
CFF
1
FontDict_OpSerializer
fontSzr
;
CFFFontDict_OpSerializer
fontSzr
;
final_size
+=
CFF1FDArray
::
calculate_serialized_size
(
offsets
.
FDArrayInfo
.
offSize
/*OUT*/
,
acc
.
fontDicts
,
subst_fdcount
,
fdmap
,
fontSzr
);
final_size
+=
CFF1FDArray
::
calculate_serialized_size
(
offsets
.
FDArrayInfo
.
offSize
/*OUT*/
,
acc
.
fontDicts
,
subst_fdcount
,
fdmap
,
fontSzr
);
}
}
...
@@ -422,7 +317,7 @@ struct cff_subset_plan {
...
@@ -422,7 +317,7 @@ struct cff_subset_plan {
if
(
!
fdmap
.
excludes
(
i
))
if
(
!
fdmap
.
excludes
(
i
))
{
{
unsigned
int
priv_size
;
unsigned
int
priv_size
;
CFF
1
PrivateDict_OpSerializer
privSzr
(
plan
->
drop_hints
,
flatten_subrs
);
CFFPrivateDict_OpSerializer
privSzr
(
plan
->
drop_hints
,
flatten_subrs
);
priv_size
=
PrivateDict
::
calculate_serialized_size
(
acc
.
privateDicts
[
i
],
privSzr
);
priv_size
=
PrivateDict
::
calculate_serialized_size
(
acc
.
privateDicts
[
i
],
privSzr
);
TableInfo
privInfo
=
{
final_size
,
priv_size
,
0
};
TableInfo
privInfo
=
{
final_size
,
priv_size
,
0
};
privateDictInfos
.
push
(
privInfo
);
privateDictInfos
.
push
(
privInfo
);
...
@@ -594,7 +489,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
...
@@ -594,7 +489,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
assert
(
plan
.
offsets
.
FDArrayInfo
.
offset
==
c
.
head
-
c
.
start
);
assert
(
plan
.
offsets
.
FDArrayInfo
.
offset
==
c
.
head
-
c
.
start
);
CFF1FDArray
*
fda
=
c
.
start_embed
<
CFF1FDArray
>
();
CFF1FDArray
*
fda
=
c
.
start_embed
<
CFF1FDArray
>
();
if
(
unlikely
(
fda
==
nullptr
))
return
false
;
if
(
unlikely
(
fda
==
nullptr
))
return
false
;
CFF
1
FontDict_OpSerializer
fontSzr
;
CFFFontDict_OpSerializer
fontSzr
;
if
(
unlikely
(
!
fda
->
serialize
(
&
c
,
plan
.
offsets
.
FDArrayInfo
.
offSize
,
if
(
unlikely
(
!
fda
->
serialize
(
&
c
,
plan
.
offsets
.
FDArrayInfo
.
offSize
,
acc
.
fontDicts
,
plan
.
subst_fdcount
,
plan
.
fdmap
,
acc
.
fontDicts
,
plan
.
subst_fdcount
,
plan
.
fdmap
,
fontSzr
,
plan
.
privateDictInfos
)))
fontSzr
,
plan
.
privateDictInfos
)))
...
@@ -626,7 +521,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
...
@@ -626,7 +521,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
if
(
unlikely
(
pd
==
nullptr
))
return
false
;
if
(
unlikely
(
pd
==
nullptr
))
return
false
;
unsigned
int
priv_size
=
plan
.
flatten_subrs
?
0
:
plan
.
privateDictInfos
[
plan
.
fdmap
[
i
]].
size
;
unsigned
int
priv_size
=
plan
.
flatten_subrs
?
0
:
plan
.
privateDictInfos
[
plan
.
fdmap
[
i
]].
size
;
bool
result
;
bool
result
;
CFF
1
PrivateDict_OpSerializer
privSzr
(
plan
.
drop_hints
,
plan
.
flatten_subrs
);
CFFPrivateDict_OpSerializer
privSzr
(
plan
.
drop_hints
,
plan
.
flatten_subrs
);
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
result
=
pd
->
serialize
(
&
c
,
acc
.
privateDicts
[
i
],
privSzr
,
priv_size
);
result
=
pd
->
serialize
(
&
c
,
acc
.
privateDicts
[
i
],
privSzr
,
priv_size
);
if
(
unlikely
(
!
result
))
if
(
unlikely
(
!
result
))
...
...
src/hb-subset-cff2.cc
浏览文件 @
9fd08cc2
...
@@ -34,29 +34,17 @@
...
@@ -34,29 +34,17 @@
using
namespace
CFF
;
using
namespace
CFF
;
struct
CFF2SubTableOffsets
{
struct
CFF2SubTableOffsets
:
CFFSubTableOffsets
{
inline
CFF2SubTableOffsets
(
void
)
inline
CFF2SubTableOffsets
(
void
)
{
:
CFFSubTableOffsets
(),
memset
(
this
,
0
,
sizeof
(
*
this
));
varStoreOffset
(
0
)
localSubrsInfos
.
init
();
{}
}
inline
~
CFF2SubTableOffsets
(
void
)
{
localSubrsInfos
.
fini
();
}
unsigned
int
topDictSize
;
unsigned
int
varStoreOffset
;
unsigned
int
varStoreOffset
;
TableInfo
FDSelectInfo
;
TableInfo
FDArrayInfo
;
TableInfo
charStringsInfo
;
unsigned
int
privateDictsOffset
;
TableInfo
globalSubrsInfo
;
hb_vector_t
<
TableInfo
>
localSubrsInfos
;
};
};
struct
CFF2TopDict_OpSerializer
:
OpSerializer
struct
CFF2TopDict_OpSerializer
:
CFFTopDict_
OpSerializer
{
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
OpStr
&
opstr
,
...
@@ -69,19 +57,9 @@ struct CFF2TopDict_OpSerializer : OpSerializer
...
@@ -69,19 +57,9 @@ struct CFF2TopDict_OpSerializer : OpSerializer
case
OpCode_vstore
:
case
OpCode_vstore
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
varStoreOffset
));
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
varStoreOffset
));
case
OpCode_CharStrings
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
charStringsInfo
.
offset
));
case
OpCode_FDArray
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
FDArrayInfo
.
offset
));
case
OpCode_FDSelect
:
return_trace
(
FontDict
::
serialize_offset4_op
(
c
,
opstr
.
op
,
offsets
.
FDSelectInfo
.
offset
));
default:
default:
return_trace
(
copy_opstr
(
c
,
opstr
));
return_trace
(
CFFTopDict_OpSerializer
::
serialize
(
c
,
opstr
,
offsets
));
}
}
return_trace
(
true
);
}
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
...
@@ -89,102 +67,64 @@ struct CFF2TopDict_OpSerializer : OpSerializer
...
@@ -89,102 +67,64 @@ struct CFF2TopDict_OpSerializer : OpSerializer
switch
(
opstr
.
op
)
switch
(
opstr
.
op
)
{
{
case
OpCode_vstore
:
case
OpCode_vstore
:
case
OpCode_CharStrings
:
case
OpCode_FDArray
:
case
OpCode_FDSelect
:
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
opstr
.
op
);
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
opstr
.
op
);
default:
default:
return
opstr
.
str
.
len
;
return
CFFTopDict_OpSerializer
::
calculate_serialized_size
(
opstr
)
;
}
}
}
}
};
};
struct
CFF2
FontDict_OpSerializer
:
OpSerializer
struct
CFF2
CSOpSet_Flatten
:
CFF2CSOpSet
<
CFF2CSOpSet_Flatten
,
ByteStrBuff
>
{
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
static
inline
bool
process_op
(
OpCode
op
,
CFF2CSInterpEnv
&
env
,
ByteStrBuff
&
flatStr
)
const
OpStr
&
opstr
,
const
TableInfo
&
privDictInfo
)
const
{
{
TRACE_SERIALIZE
(
this
);
if
(
unlikely
(
!
SUPER
::
process_op
(
op
,
env
,
flatStr
)))
return
false
;
if
(
opstr
.
op
==
OpCode_Private
)
switch
(
op
)
{
/* serialize the private dict size as a 2-byte integer */
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int2
(
c
,
privDictInfo
.
size
)))
return_trace
(
false
);
/* serialize the private dict offset as a 4-byte integer */
if
(
unlikely
(
!
UnsizedByteStr
::
serialize_int4
(
c
,
privDictInfo
.
offset
)))
return_trace
(
false
);
/* serialize the opcode */
HBUINT8
*
p
=
c
->
allocate_size
<
HBUINT8
>
(
1
);
if
(
unlikely
(
p
==
nullptr
))
return_trace
(
false
);
p
->
set
(
OpCode_Private
);
return_trace
(
true
);
}
else
{
{
HBUINT8
*
d
=
c
->
allocate_size
<
HBUINT8
>
(
opstr
.
str
.
len
);
case
OpCode_hintmask
:
if
(
unlikely
(
d
==
nullptr
))
return_trace
(
false
);
case
OpCode_cntrmask
:
memcpy
(
d
,
&
opstr
.
str
.
str
[
0
],
opstr
.
str
.
len
);
if
(
unlikely
(
!
flatStr
.
encode_op
(
op
)))
return
false
;
for
(
int
i
=
-
env
.
hintmask_size
;
i
<
0
;
i
++
)
if
(
unlikely
(
!
flatStr
.
encode_byte
(
env
.
substr
[
i
])))
return
false
;
break
;
case
OpCode_return
:
case
OpCode_endchar
:
/* dummy opcodes in CFF2. ignore */
break
;
default:
if
(
!
CSOPSET
::
is_subr_op
(
op
)
&&
!
CSOPSET
::
is_arg_op
(
op
))
return
flatStr
.
encode_op
(
op
);
}
}
return_trace
(
true
);
return
true
;
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
{
if
(
opstr
.
op
==
OpCode_Private
)
return
OpCode_Size
(
OpCode_longintdict
)
+
4
+
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Private
);
else
return
opstr
.
str
.
len
;
}
}
};
struct
CFF2PrivateDict_OpSerializer
:
OpSerializer
static
inline
bool
process_blend
(
CFF2CSInterpEnv
&
env
,
ByteStrBuff
&
flatStr
)
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
unsigned
int
subrsOffset
)
const
{
{
TRACE_SERIALIZE
(
this
);
flush_stack
(
env
,
flatStr
);
return
true
;
if
(
opstr
.
op
==
OpCode_Subrs
)
return_trace
(
FontDict
::
serialize_offset2_op
(
c
,
OpCode_Subrs
,
subrsOffset
));
else
return_trace
(
copy_opstr
(
c
,
opstr
));
}
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
static
inline
bool
process_vsindex
(
CFF2CSInterpEnv
&
env
,
ByteStrBuff
&
flatStr
)
{
{
if
(
opstr
.
op
==
OpCode_Subrs
)
flush_stack
(
env
,
flatStr
);
return
OpCode_Size
(
OpCode_shortint
)
+
2
+
OpCode_Size
(
OpCode_Subrs
);
return
true
;
else
return
opstr
.
str
.
len
;
}
}
};
struct
CFF2PrivateDict_OpSerializer_DropHints
:
CFF2PrivateDict_OpSerializer
static
inline
void
flush_stack
(
CFF2CSInterpEnv
&
env
,
ByteStrBuff
&
flatStr
)
{
inline
bool
serialize
(
hb_serialize_context_t
*
c
,
const
OpStr
&
opstr
,
const
unsigned
int
subrsOffset
)
const
{
{
if
(
DictOpSet
::
is_hint_op
(
opstr
.
op
))
for
(
unsigned
int
i
=
0
;
i
<
env
.
argStack
.
size
;
i
++
)
return
true
;
flatStr
.
encode_num
(
env
.
argStack
.
elements
[
i
]);
else
SUPER
::
flush_stack
(
env
,
flatStr
);
return
CFF2PrivateDict_OpSerializer
::
serialize
(
c
,
opstr
,
subrsOffset
);
}
}
inline
unsigned
int
calculate_serialized_size
(
const
OpStr
&
opstr
)
const
private:
{
typedef
CFF2CSOpSet
<
CFF2CSOpSet_Flatten
,
ByteStrBuff
>
SUPER
;
if
(
DictOpSet
::
is_hint_op
(
opstr
.
op
))
typedef
CSOpSet
<
CFF2CSOpSet_Flatten
,
CFF2CSInterpEnv
,
ByteStrBuff
>
CSOPSET
;
return
0
;
else
return
CFF2PrivateDict_OpSerializer
::
calculate_serialized_size
(
opstr
);
}
};
};
struct
CFF2CSOpSet_SubsetSubrs
:
CFF2CSOpSet
<
CFF2CSOpSet_SubsetSubrs
,
SubrRefMapPair
>
struct
CFF2CSOpSet_SubsetSubrs
:
CFF2CSOpSet
<
CFF2CSOpSet_SubsetSubrs
,
SubrRefMapPair
>
...
@@ -217,11 +157,14 @@ struct cff2_subset_plan {
...
@@ -217,11 +157,14 @@ struct cff2_subset_plan {
:
final_size
(
0
),
:
final_size
(
0
),
orig_fdcount
(
0
),
orig_fdcount
(
0
),
subst_fdcount
(
1
),
subst_fdcount
(
1
),
subst_fdselect_format
(
0
)
subst_fdselect_format
(
0
),
flatten_subrs
(
true
),
drop_hints
(
false
)
{
{
subst_fdselect_first_glyphs
.
init
();
subst_fdselect_first_glyphs
.
init
();
fdmap
.
init
();
fdmap
.
init
();
subset_charstrings
.
init
();
subset_charstrings
.
init
();
flat_charstrings
.
init
();
privateDictInfos
.
init
();
privateDictInfos
.
init
();
subrRefMaps
.
init
();
subrRefMaps
.
init
();
}
}
...
@@ -231,6 +174,7 @@ struct cff2_subset_plan {
...
@@ -231,6 +174,7 @@ struct cff2_subset_plan {
subst_fdselect_first_glyphs
.
fini
();
subst_fdselect_first_glyphs
.
fini
();
fdmap
.
fini
();
fdmap
.
fini
();
subset_charstrings
.
fini
();
subset_charstrings
.
fini
();
flat_charstrings
.
fini
();
privateDictInfos
.
fini
();
privateDictInfos
.
fini
();
subrRefMaps
.
fini
();
subrRefMaps
.
fini
();
}
}
...
@@ -249,12 +193,23 @@ struct cff2_subset_plan {
...
@@ -249,12 +193,23 @@ struct cff2_subset_plan {
/* top dict */
/* top dict */
{
{
CFF2TopDict_OpSerializer
topSzr
;
CFF2TopDict_OpSerializer
topSzr
;
offsets
.
topDict
S
ize
=
TopDict
::
calculate_serialized_size
(
acc
.
topDict
,
topSzr
);
offsets
.
topDict
Info
.
s
ize
=
TopDict
::
calculate_serialized_size
(
acc
.
topDict
,
topSzr
);
final_size
+=
offsets
.
topDict
S
ize
;
final_size
+=
offsets
.
topDict
Info
.
s
ize
;
}
}
/* Subset global & local subrs */
if
(
flatten_subrs
)
{
/* Flatten global & local subrs */
SubrFlattener
<
const
OT
::
cff2
::
accelerator_subset_t
,
CFF2CSInterpEnv
,
CFF2CSOpSet_Flatten
>
flattener
(
acc
,
plan
->
glyphs
);
if
(
!
flattener
.
flatten
(
flat_charstrings
))
return
false
;
/* no global/local subroutines */
offsets
.
globalSubrsInfo
.
size
=
HBUINT32
::
static_size
;
/* count 0 only */
}
else
{
{
/* Subset global & local subrs */
SubrSubsetter
<
const
OT
::
cff2
::
accelerator_subset_t
,
CFF2CSInterpEnv
,
CFF2CSOpSet_SubsetSubrs
>
subsetter
(
acc
,
plan
->
glyphs
);
SubrSubsetter
<
const
OT
::
cff2
::
accelerator_subset_t
,
CFF2CSInterpEnv
,
CFF2CSOpSet_SubsetSubrs
>
subsetter
(
acc
,
plan
->
glyphs
);
if
(
!
subsetter
.
collect_refs
(
subrRefMaps
))
if
(
!
subsetter
.
collect_refs
(
subrRefMaps
))
return
false
;
return
false
;
...
@@ -299,7 +254,7 @@ struct cff2_subset_plan {
...
@@ -299,7 +254,7 @@ struct cff2_subset_plan {
/* FDArray (FDIndex) */
/* FDArray (FDIndex) */
{
{
offsets
.
FDArrayInfo
.
offset
=
final_size
;
offsets
.
FDArrayInfo
.
offset
=
final_size
;
CFF
2
FontDict_OpSerializer
fontSzr
;
CFFFontDict_OpSerializer
fontSzr
;
final_size
+=
CFF2FDArray
::
calculate_serialized_size
(
offsets
.
FDArrayInfo
.
offSize
/*OUT*/
,
acc
.
fontDicts
,
subst_fdcount
,
fdmap
,
fontSzr
);
final_size
+=
CFF2FDArray
::
calculate_serialized_size
(
offsets
.
FDArrayInfo
.
offSize
/*OUT*/
,
acc
.
fontDicts
,
subst_fdcount
,
fdmap
,
fontSzr
);
}
}
...
@@ -309,9 +264,19 @@ struct cff2_subset_plan {
...
@@ -309,9 +264,19 @@ struct cff2_subset_plan {
unsigned
int
dataSize
=
0
;
unsigned
int
dataSize
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
plan
->
glyphs
.
len
;
i
++
)
for
(
unsigned
int
i
=
0
;
i
<
plan
->
glyphs
.
len
;
i
++
)
{
{
const
ByteStr
str
=
(
*
acc
.
charStrings
)[
plan
->
glyphs
[
i
]];
if
(
flatten_subrs
)
subset_charstrings
.
push
(
str
);
{
dataSize
+=
str
.
len
;
ByteStrBuff
&
flatstr
=
flat_charstrings
[
i
];
ByteStr
str
(
&
flatstr
[
0
],
flatstr
.
len
);
subset_charstrings
.
push
(
str
);
dataSize
+=
flatstr
.
len
;
}
else
{
const
ByteStr
str
=
(
*
acc
.
charStrings
)[
plan
->
glyphs
[
i
]];
subset_charstrings
.
push
(
str
);
dataSize
+=
str
.
len
;
}
}
}
offsets
.
charStringsInfo
.
offSize
=
calcOffSize
(
dataSize
+
1
);
offsets
.
charStringsInfo
.
offSize
=
calcOffSize
(
dataSize
+
1
);
final_size
+=
CFF2CharStrings
::
calculate_serialized_size
(
offsets
.
charStringsInfo
.
offSize
,
plan
->
glyphs
.
len
,
dataSize
);
final_size
+=
CFF2CharStrings
::
calculate_serialized_size
(
offsets
.
charStringsInfo
.
offSize
,
plan
->
glyphs
.
len
,
dataSize
);
...
@@ -324,19 +289,13 @@ struct cff2_subset_plan {
...
@@ -324,19 +289,13 @@ struct cff2_subset_plan {
if
(
!
fdmap
.
excludes
(
i
))
if
(
!
fdmap
.
excludes
(
i
))
{
{
unsigned
int
priv_size
;
unsigned
int
priv_size
;
if
(
plan
->
drop_hints
)
CFFPrivateDict_OpSerializer
privSzr
(
drop_hints
,
flatten_subrs
);
{
priv_size
=
PrivateDict
::
calculate_serialized_size
(
acc
.
privateDicts
[
i
],
privSzr
);
CFF2PrivateDict_OpSerializer_DropHints
privSzr_drop
;
priv_size
=
PrivateDict
::
calculate_serialized_size
(
acc
.
privateDicts
[
i
],
privSzr_drop
);
}
else
{
CFF2PrivateDict_OpSerializer
privSzr
;
priv_size
=
PrivateDict
::
calculate_serialized_size
(
acc
.
privateDicts
[
i
],
privSzr
);
}
TableInfo
privInfo
=
{
final_size
,
priv_size
,
0
};
TableInfo
privInfo
=
{
final_size
,
priv_size
,
0
};
privateDictInfos
.
push
(
privInfo
);
privateDictInfos
.
push
(
privInfo
);
final_size
+=
privInfo
.
size
+
offsets
.
localSubrsInfos
[
i
].
size
;
final_size
+=
privInfo
.
size
;
if
(
!
flatten_subrs
)
final_size
+=
offsets
.
localSubrsInfos
[
i
].
size
;
}
}
}
}
...
@@ -356,11 +315,13 @@ struct cff2_subset_plan {
...
@@ -356,11 +315,13 @@ struct cff2_subset_plan {
FDMap
fdmap
;
FDMap
fdmap
;
hb_vector_t
<
ByteStr
>
subset_charstrings
;
hb_vector_t
<
ByteStr
>
subset_charstrings
;
hb_vector_t
<
TableInfo
>
privateDictInfos
;
ByteStrBuffArray
flat_charstrings
;
hb_vector_t
<
TableInfo
>
privateDictInfos
;
SubrRefMaps
subrRefMaps
;
SubrRefMaps
subrRefMaps
;
bool
flatten_subrs
;
bool
drop_hints
;
bool
drop_hints
;
};
};
...
@@ -384,7 +345,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
...
@@ -384,7 +345,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
/* top dict */
/* top dict */
{
{
assert
(
cff2
->
topDict
==
c
.
head
-
c
.
start
);
assert
(
cff2
->
topDict
==
c
.
head
-
c
.
start
);
cff2
->
topDictSize
.
set
(
plan
.
offsets
.
topDict
S
ize
);
cff2
->
topDictSize
.
set
(
plan
.
offsets
.
topDict
Info
.
s
ize
);
TopDict
&
dict
=
cff2
+
cff2
->
topDict
;
TopDict
&
dict
=
cff2
+
cff2
->
topDict
;
CFF2TopDict_OpSerializer
topSzr
;
CFF2TopDict_OpSerializer
topSzr
;
if
(
unlikely
(
!
dict
.
serialize
(
&
c
,
acc
.
topDict
,
topSzr
,
plan
.
offsets
)))
if
(
unlikely
(
!
dict
.
serialize
(
&
c
,
acc
.
topDict
,
topSzr
,
plan
.
offsets
)))
...
@@ -396,7 +357,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
...
@@ -396,7 +357,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
/* global subrs */
/* global subrs */
{
{
assert
(
cff2
->
topDict
+
plan
.
offsets
.
topDict
S
ize
==
c
.
head
-
c
.
start
);
assert
(
cff2
->
topDict
+
plan
.
offsets
.
topDict
Info
.
s
ize
==
c
.
head
-
c
.
start
);
CFF2Subrs
*
dest
=
c
.
start_embed
<
CFF2Subrs
>
();
CFF2Subrs
*
dest
=
c
.
start_embed
<
CFF2Subrs
>
();
if
(
unlikely
(
dest
==
nullptr
))
return
false
;
if
(
unlikely
(
dest
==
nullptr
))
return
false
;
if
(
unlikely
(
!
dest
->
serialize
(
&
c
,
*
acc
.
globalSubrs
,
plan
.
offsets
.
globalSubrsInfo
.
offSize
,
plan
.
subrRefMaps
.
global_map
)))
if
(
unlikely
(
!
dest
->
serialize
(
&
c
,
*
acc
.
globalSubrs
,
plan
.
offsets
.
globalSubrsInfo
.
offSize
,
plan
.
subrRefMaps
.
global_map
)))
...
@@ -450,7 +411,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
...
@@ -450,7 +411,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
assert
(
plan
.
offsets
.
FDArrayInfo
.
offset
==
c
.
head
-
c
.
start
);
assert
(
plan
.
offsets
.
FDArrayInfo
.
offset
==
c
.
head
-
c
.
start
);
CFF2FDArray
*
fda
=
c
.
start_embed
<
CFF2FDArray
>
();
CFF2FDArray
*
fda
=
c
.
start_embed
<
CFF2FDArray
>
();
if
(
unlikely
(
fda
==
nullptr
))
return
false
;
if
(
unlikely
(
fda
==
nullptr
))
return
false
;
CFF
2
FontDict_OpSerializer
fontSzr
;
CFFFontDict_OpSerializer
fontSzr
;
if
(
unlikely
(
!
fda
->
serialize
(
&
c
,
plan
.
offsets
.
FDArrayInfo
.
offSize
,
if
(
unlikely
(
!
fda
->
serialize
(
&
c
,
plan
.
offsets
.
FDArrayInfo
.
offSize
,
acc
.
fontDicts
,
plan
.
subst_fdcount
,
plan
.
fdmap
,
acc
.
fontDicts
,
plan
.
subst_fdcount
,
plan
.
fdmap
,
fontSzr
,
plan
.
privateDictInfos
)))
fontSzr
,
plan
.
privateDictInfos
)))
...
@@ -482,22 +443,14 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
...
@@ -482,22 +443,14 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
if
(
unlikely
(
pd
==
nullptr
))
return
false
;
if
(
unlikely
(
pd
==
nullptr
))
return
false
;
unsigned
int
priv_size
=
plan
.
privateDictInfos
[
plan
.
fdmap
[
i
]].
size
;
unsigned
int
priv_size
=
plan
.
privateDictInfos
[
plan
.
fdmap
[
i
]].
size
;
bool
result
;
bool
result
;
if
(
plan
.
drop_hints
)
CFFPrivateDict_OpSerializer
privSzr
(
plan
.
drop_hints
,
plan
.
flatten_subrs
);
{
result
=
pd
->
serialize
(
&
c
,
acc
.
privateDicts
[
i
],
privSzr
,
priv_size
);
CFF2PrivateDict_OpSerializer_DropHints
privSzr_drop
;
result
=
pd
->
serialize
(
&
c
,
acc
.
privateDicts
[
i
],
privSzr_drop
,
priv_size
);
}
else
{
CFF2PrivateDict_OpSerializer
privSzr
;
result
=
pd
->
serialize
(
&
c
,
acc
.
privateDicts
[
i
],
privSzr
,
priv_size
);
}
if
(
unlikely
(
!
result
))
if
(
unlikely
(
!
result
))
{
{
DEBUG_MSG
(
SUBSET
,
nullptr
,
"failed to serialize CFF2 Private Dict[%d]"
,
i
);
DEBUG_MSG
(
SUBSET
,
nullptr
,
"failed to serialize CFF2 Private Dict[%d]"
,
i
);
return
false
;
return
false
;
}
}
if
(
acc
.
privateDicts
[
i
].
subrsOffset
!=
0
)
if
(
!
plan
.
flatten_subrs
&&
(
acc
.
privateDicts
[
i
].
subrsOffset
!=
0
)
)
{
{
CFF2Subrs
*
subrs
=
c
.
start_embed
<
CFF2Subrs
>
();
CFF2Subrs
*
subrs
=
c
.
start_embed
<
CFF2Subrs
>
();
if
(
unlikely
(
subrs
==
nullptr
)
||
acc
.
privateDicts
[
i
].
localSubrs
==
&
Null
(
CFF2Subrs
))
if
(
unlikely
(
subrs
==
nullptr
)
||
acc
.
privateDicts
[
i
].
localSubrs
==
&
Null
(
CFF2Subrs
))
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录