Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Harfbuzz
提交
cfb9771a
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看板
提交
cfb9771a
编写于
11月 16, 2018
作者:
B
Behdad Esfahbod
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[coretext] Try to fix
上级
e3e95473
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
43 addition
and
64 deletion
+43
-64
src/hb-coretext.cc
src/hb-coretext.cc
+38
-10
src/hb-machinery.hh
src/hb-machinery.hh
+5
-10
src/hb-shaper.hh
src/hb-shaper.hh
+0
-44
未找到文件。
src/hb-coretext.cc
浏览文件 @
cfb9771a
...
...
@@ -99,11 +99,6 @@ _hb_cg_font_release (void *data)
}
/* XXX TODO */
//HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
// fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
//);
static
CTFontDescriptorRef
get_last_resort_font_desc
(
void
)
{
...
...
@@ -318,7 +313,8 @@ hb_coretext_font_data_t *
_hb_coretext_shaper_font_data_create
(
hb_font_t
*
font
)
{
hb_face_t
*
face
=
font
->
face
;
if
(
unlikely
(
!
hb_coretext_shaper_face_data_ensure
(
face
)))
return
nullptr
;
const
hb_coretext_face_data
*
face_data
=
face
->
data
.
coretext
;
if
(
unlikely
(
!
face_data
))
return
nullptr
;
CGFontRef
cg_font
=
(
CGFontRef
)
(
const
void
*
)
face
->
data
.
coretext
;
CTFontRef
ct_font
=
create_ct_font
(
cg_font
,
coretext_font_size_from_ptem
(
font
->
ptem
));
...
...
@@ -338,6 +334,38 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
CFRelease
((
CTFontRef
)
data
);
}
static
const
hb_coretext_font_data_t
*
hb_coretext_font_data_sync
(
hb_font_t
*
font
)
{
retry:
const
hb_coretext_shaper_font_data_t
*
data
=
font
->
data
.
font
;
if
(
unlikely
(
!
data
))
return
nullptr
;
if
(
fabs
(
CTFontGetSize
((
CTFontRef
)
data
)
-
coretext_font_size_from_ptem
(
font
->
ptem
))
>
.5
)
{
/* XXX-MT-bug
* Note that evaluating condition above can be dangerous if another thread
* got here first and destructed data. That's, as always, bad use pattern.
* If you modify the font (change font size), other threads must not be
* using it at the same time. However, since this check is delayed to
* when one actually tries to shape something, this is a XXX race condition
* (and the only one we have that I know of) right now. Ie. you modify the
* font size in one thread, then (supposedly safely) try to use it from two
* or more threads and BOOM! I'm not sure how to fix this. We want RCU.
*/
/* Drop and recreate. */
/* If someone dropped it in the mean time, throw it away and don't touch it.
* Otherwise, destruct it. */
if
(
likely
(
cmpexch
(
data
,
nullptr
)))
_hb_coretext_shaper_font_data_destroy
(
data
);
else
goto
retry
;
}
return
font
->
data
.
coretext
;
}
/*
* Since: 1.7.2
*/
...
...
@@ -364,8 +392,8 @@ hb_coretext_font_create (CTFontRef ct_font)
CTFontRef
hb_coretext_font_get_ct_font
(
hb_font_t
*
font
)
{
if
(
unlikely
(
!
hb_coretext_shaper_font_data_ensure
(
font
)))
return
nullptr
;
return
(
CTFontRef
)
(
const
void
*
)
font
->
data
.
coretext
;
const
hb_coretext_font_data
*
data
=
hb_coretext_font_data_sync
(
font
)
;
return
data
?
(
CTFontRef
)
data
:
nullptr
;
}
...
...
@@ -425,7 +453,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
{
hb_face_t
*
face
=
font
->
face
;
CGFontRef
cg_font
=
(
CGFontRef
)
(
const
void
*
)
face
->
data
.
coretext
;
CTFontRef
ct_font
=
(
CTFontRef
)
(
const
void
*
)
font
->
data
.
coretext
;
CTFontRef
ct_font
=
(
CTFontRef
)
hb_coretext_font_data
*
data
=
hb_coretext_font_data_sync
(
font
)
;
CGFloat
ct_font_size
=
CTFontGetSize
(
ct_font
);
CGFloat
x_mult
=
(
CGFloat
)
font
->
x_scale
/
ct_font_size
;
...
...
@@ -1169,7 +1197,7 @@ struct hb_coretext_aat_font_data_t {};
hb_coretext_aat_font_data_t
*
_hb_coretext_aat_shaper_font_data_create
(
hb_font_t
*
font
)
{
return
hb_coretext_shaper_font_data_ensure
(
font
)
?
(
hb_coretext_aat_font_data_t
*
)
HB_SHAPER_DATA_SUCCEEDED
:
nullptr
;
return
font
->
data
.
coretext
?
(
hb_coretext_aat_font_data_t
*
)
HB_SHAPER_DATA_SUCCEEDED
:
nullptr
;
}
void
...
...
src/hb-machinery.hh
浏览文件 @
cfb9771a
...
...
@@ -790,7 +790,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
{
retry:
Stored
*
p
=
instance
.
get
();
if
(
unlikely
(
p
&&
!
this
->
instance
.
cmpexch
(
p
,
nullptr
)))
if
(
unlikely
(
p
&&
!
cmpexch
(
p
,
nullptr
)))
goto
retry
;
do_destroy
(
p
);
}
...
...
@@ -820,7 +820,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
if
(
unlikely
(
!
p
))
p
=
const_cast
<
Stored
*>
(
Funcs
::
get_null
());
if
(
unlikely
(
!
this
->
instance
.
cmpexch
(
nullptr
,
p
)))
if
(
unlikely
(
!
cmpexch
(
nullptr
,
p
)))
{
do_destroy
(
p
);
goto
retry
;
...
...
@@ -833,15 +833,10 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
return
this
->
instance
.
get_relaxed
();
}
inline
void
set_stored
(
Stored
*
instance_
)
inline
bool
cmpexch
(
Stored
*
current
,
Stored
*
value
)
const
{
/* This *must* be called when there are no other threads accessing.
* However, to make TSan, etc, happy, we using cmpexch. */
retry:
Stored
*
p
=
this
->
instance
.
get
();
if
(
unlikely
(
!
this
->
instance
.
cmpexch
(
p
,
instance_
)))
goto
retry
;
do_destroy
(
p
);
/* This *must* be called when there are no other threads accessing. */
return
this
->
instance
.
cmpexch
(
current
,
value
);
}
inline
const
Returned
*
get
(
void
)
const
{
return
Funcs
::
convert
(
get_stored
());
}
...
...
src/hb-shaper.hh
浏览文件 @
cfb9771a
...
...
@@ -50,50 +50,6 @@ HB_INTERNAL const hb_shaper_entry_t *
_hb_shapers_get
(
void
);
#if 0
#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
bool \
HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
{\
retry: \
HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get (); \
if (likely (data) && !(condition)) { \
/* XXX-MT-bug \
* Note that evaluating condition above can be dangerous if another thread \
* got here first and destructed data. That's, as always, bad use pattern. \
* If you modify the font (change font size), other threads must not be \
* using it at the same time. However, since this check is delayed to \
* when one actually tries to shape something, this is a XXX race condition \
* (and the only know we have that I know of) right now. Ie. you modify the \
* font size in one thread, then (supposedly safely) try to use it from two \
* or more threads and BOOM! I'm not sure how to fix this. We want RCU. \
* Maybe when it doesn't matter when we finally implement AAT shaping, as
* this (condition) is currently only used by hb-coretext. */ \
/* Drop and recreate. */ \
/* If someone dropped it in the mean time, throw it away and don't touch it. \
* Otherwise, destruct it. */ \
if (likely (HB_SHAPER_DATA (shaper, object).cmpexch (data, nullptr))) \
{ \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
} \
goto retry; \
} \
if (unlikely (!data)) { \
data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
if (unlikely (!data)) \
data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
if (unlikely (!HB_SHAPER_DATA (shaper, object).cmpexch (nullptr, data))) { \
if (data) \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
goto retry; \
} \
} \
return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \
} \
static_assert (true, "") /* Require semicolon. */
#endif
template
<
typename
Data
,
unsigned
int
WheresData
,
typename
T
>
struct
hb_shaper_lazy_loader_t
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录