Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
7780d785
Commit
7780d785
authored
May 22, 2020
by
Nikolay Sivov
Committed by
Alexandre Julliard
May 22, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Propagate feature mask to lookups collected from it.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2f5ea323
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
111 additions
and
36 deletions
+111
-36
dwrite_private.h
dlls/dwrite/dwrite_private.h
+3
-0
opentype.c
dlls/dwrite/opentype.c
+108
-36
No files found.
dlls/dwrite/dwrite_private.h
View file @
7780d785
...
...
@@ -492,6 +492,7 @@ struct scriptshaping_context
const
unsigned
int
*
range_lengths
;
unsigned
int
range_count
;
}
user_features
;
unsigned
int
global_mask
;
unsigned
int
glyph_count
;
float
emsize
;
...
...
@@ -525,6 +526,8 @@ struct shaping_feature
unsigned
int
flags
;
unsigned
int
max_value
;
unsigned
int
default_value
;
unsigned
int
mask
;
unsigned
int
shift
;
};
struct
shaping_features
...
...
dlls/dwrite/opentype.c
View file @
7780d785
...
...
@@ -3210,6 +3210,36 @@ static inline unsigned int dwrite_popcount(unsigned int x)
#endif
}
static
inline
unsigned
int
dwrite_log2i
(
unsigned
int
x
)
{
#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
return
__builtin_clz
(
x
)
^
0x1f
;
#else
static
const
unsigned
int
l
[]
=
{
~
0u
,
0
,
1
,
1
,
2
,
2
,
2
,
2
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
4
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
5
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
6
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
7
,
};
unsigned
int
i
;
return
(
i
=
x
>>
16
)
?
(
x
=
i
>>
8
)
?
l
[
x
]
+
24
:
l
[
i
]
+
16
:
(
i
=
x
>>
8
)
?
l
[
i
]
+
8
:
l
[
x
];
#endif
}
static
float
opentype_scale_gpos_be_value
(
WORD
value
,
float
emsize
,
UINT16
upem
)
{
return
(
short
)
GET_BE_WORD
(
value
)
*
emsize
/
upem
;
...
...
@@ -3333,7 +3363,7 @@ static unsigned int opentype_layout_get_gsub_subtable(const struct scriptshaping
return
lookup_offset
+
subtable_offset
;
}
struct
lookup
struct
ot_
lookup
{
unsigned
int
offset
;
unsigned
int
subtable_count
;
...
...
@@ -3406,7 +3436,7 @@ static BOOL glyph_iterator_prev(struct glyph_iterator *iter)
}
static
BOOL
opentype_layout_apply_gpos_single_adjustment
(
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
WORD
format
,
value_format
,
value_len
,
coverage
;
...
...
@@ -3469,7 +3499,7 @@ static int gpos_pair_adjustment_compare_format1(const void *g, const void *r)
}
static
BOOL
opentype_layout_apply_gpos_pair_adjustment
(
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
unsigned
int
i
,
first_glyph
,
second_glyph
;
...
...
@@ -3676,7 +3706,7 @@ static void opentype_layout_gpos_get_anchor(const struct scriptshaping_context *
}
static
BOOL
opentype_layout_apply_gpos_cursive_attachment
(
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
unsigned
int
i
;
...
...
@@ -3760,7 +3790,7 @@ static BOOL opentype_layout_apply_gpos_cursive_attachment(struct scriptshaping_c
}
static
BOOL
opentype_layout_apply_gpos_mark_to_base_attachment
(
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
unsigned
int
i
;
...
...
@@ -3843,7 +3873,7 @@ static BOOL opentype_layout_apply_gpos_mark_to_base_attachment(struct scriptshap
}
static
BOOL
opentype_layout_apply_gpos_mark_to_lig_attachment
(
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
unsigned
int
i
;
...
...
@@ -3889,7 +3919,7 @@ static BOOL opentype_layout_apply_gpos_mark_to_lig_attachment(struct scriptshapi
}
static
BOOL
opentype_layout_apply_gpos_mark_to_mark_attachment
(
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
unsigned
int
i
;
...
...
@@ -3974,13 +4004,13 @@ static BOOL opentype_layout_apply_gpos_mark_to_mark_attachment(struct scriptshap
}
static
BOOL
opentype_layout_apply_gpos_contextual_positioning
(
const
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
return
FALSE
;
}
static
BOOL
opentype_layout_apply_gpos_chaining_contextual_positioning
(
const
struct
scriptshaping_context
*
context
,
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
return
FALSE
;
}
...
...
@@ -3990,7 +4020,7 @@ static void opentype_layout_apply_gpos_lookup(struct scriptshaping_context *cont
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
const
struct
ot_lookup_table
*
lookup_table
;
struct
glyph_iterator
iter
;
struct
lookup
lookup
;
struct
ot_
lookup
lookup
;
WORD
lookup_type
;
lookup
.
offset
=
table_read_be_word
(
&
cache
->
gpos
.
table
,
cache
->
gpos
.
lookup_list
+
...
...
@@ -4081,16 +4111,24 @@ static void opentype_layout_apply_gpos_lookup(struct scriptshaping_context *cont
}
}
struct
lookup
{
unsigned
short
index
;
unsigned
int
mask
;
};
struct
lookups
{
int
*
indexe
s
;
struct
lookup
*
lookup
s
;
size_t
capacity
;
size_t
count
;
};
static
int
lookups_sorting_compare
(
const
void
*
left
,
const
void
*
right
)
static
int
lookups_sorting_compare
(
const
void
*
a
,
const
void
*
b
)
{
return
*
(
int
*
)
left
-
*
(
int
*
)
right
;
const
struct
lookup
*
left
=
(
const
struct
lookup
*
)
a
;
const
struct
lookup
*
right
=
(
const
struct
lookup
*
)
b
;
return
left
->
index
<
right
->
index
?
-
1
:
left
->
index
>
right
->
index
?
1
:
0
;
};
static
void
opentype_layout_collect_lookups
(
struct
scriptshaping_context
*
context
,
unsigned
int
script_index
,
...
...
@@ -4099,8 +4137,11 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
{
UINT16
table_offset
,
langsys_offset
,
script_feature_count
,
total_feature_count
,
total_lookup_count
;
const
struct
ot_feature_list
*
feature_list
;
struct
shaping_feature
*
feature
;
unsigned
int
i
,
j
,
l
,
next_bit
;
unsigned
int
global_bit_shift
=
1
;
unsigned
int
global_bit_mask
=
1
;
UINT16
feature_index
;
unsigned
int
i
,
j
,
l
;
/* ScriptTable offset. */
table_offset
=
table_read_be_word
(
&
table
->
table
,
table
->
script_list
+
FIELD_OFFSET
(
struct
ot_script_list
,
scripts
)
+
...
...
@@ -4133,19 +4174,34 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
if
(
!
feature_list
)
return
;
context
->
global_mask
=
global_bit_mask
;
next_bit
=
global_bit_shift
+
1
;
for
(
i
=
0
;
i
<
features
->
count
;
++
i
)
{
unsigned
int
bits_needed
;
BOOL
found
=
FALSE
;
feature
=
&
features
->
features
[
i
];
feature
->
index
=
0xffff
;
if
((
feature
->
flags
&
FEATURE_GLOBAL
)
&&
feature
->
max_value
==
1
)
bits_needed
=
0
;
else
bits_needed
=
min
(
8
,
dwrite_log2i
(
feature
->
max_value
));
if
(
!
feature
->
max_value
||
next_bit
+
bits_needed
>
8
*
sizeof
(
feature
->
mask
))
continue
;
for
(
j
=
0
;
j
<
script_feature_count
;
++
j
)
{
feature_index
=
table_read_be_word
(
&
table
->
table
,
table
->
script_list
+
table_offset
+
langsys_offset
+
FIELD_OFFSET
(
struct
ot_langsys
,
feature_index
[
j
]));
if
(
feature_index
>=
total_feature_count
)
continue
;
if
((
found
=
feature_list
->
features
[
feature_index
].
tag
==
feature
s
->
features
[
i
].
tag
))
if
((
found
=
feature_list
->
features
[
feature_index
].
tag
==
feature
->
tag
))
{
feature
s
->
features
[
i
].
index
=
feature_index
;
feature
->
index
=
feature_index
;
break
;
}
}
...
...
@@ -4154,16 +4210,29 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
{
for
(
j
=
0
;
j
<
total_feature_count
;
++
j
)
{
if
((
found
=
(
feature_list
->
features
[
j
].
tag
==
feature
s
->
features
[
i
].
tag
)))
if
((
found
=
(
feature_list
->
features
[
j
].
tag
==
feature
->
tag
)))
{
feature
s
->
features
[
i
].
index
=
j
;
feature
->
index
=
j
;
break
;
}
}
}
if
(
!
found
)
features
->
features
[
i
].
index
=
0xffff
;
continue
;
if
(
feature
->
flags
&
FEATURE_GLOBAL
&&
feature
->
max_value
==
1
)
{
feature
->
shift
=
global_bit_shift
;
feature
->
mask
=
global_bit_mask
;
}
else
{
feature
->
shift
=
next_bit
;
feature
->
mask
=
(
1
<<
(
next_bit
+
bits_needed
))
-
(
1
<<
next_bit
);
next_bit
+=
bits_needed
;
context
->
global_mask
|=
(
feature
->
default_value
<<
feature
->
shift
)
&
feature
->
mask
;
}
}
/* Collect lookups for all given features. */
...
...
@@ -4171,25 +4240,25 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
{
UINT16
feature_offset
,
lookup_count
;
feature
_index
=
features
->
features
[
i
].
index
;
feature
=
&
features
->
features
[
i
]
;
/* Feature wasn't found */
if
(
feature
_
index
==
0xffff
)
if
(
feature
->
index
==
0xffff
)
continue
;
/* FIXME: skip non-global ones for now. */
if
(
!
(
feature
s
->
features
[
i
].
flags
&
FEATURE_GLOBAL
))
if
(
!
(
feature
->
flags
&
FEATURE_GLOBAL
))
continue
;
feature_offset
=
GET_BE_WORD
(
feature_list
->
features
[
feature
_
index
].
offset
);
feature_offset
=
GET_BE_WORD
(
feature_list
->
features
[
feature
->
index
].
offset
);
lookup_count
=
table_read_be_word
(
&
table
->
table
,
table
->
feature_list
+
feature_offset
+
FIELD_OFFSET
(
struct
ot_feature
,
lookup_count
));
if
(
!
lookup_count
)
continue
;
if
(
!
dwrite_array_reserve
((
void
**
)
&
lookups
->
indexe
s
,
&
lookups
->
capacity
,
lookups
->
count
+
lookup_count
,
sizeof
(
*
lookups
->
indexe
s
)))
if
(
!
dwrite_array_reserve
((
void
**
)
&
lookups
->
lookup
s
,
&
lookups
->
capacity
,
lookups
->
count
+
lookup_count
,
sizeof
(
*
lookups
->
lookup
s
)))
{
return
;
}
...
...
@@ -4202,12 +4271,15 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
if
(
lookup_index
>=
total_lookup_count
)
continue
;
lookups
->
indexes
[
lookups
->
count
++
]
=
lookup_index
;
j
=
lookups
->
count
;
lookups
->
lookups
[
j
].
index
=
lookup_index
;
lookups
->
lookups
[
j
].
mask
=
feature
->
mask
;
lookups
->
count
++
;
}
}
/* Sort lookups. */
qsort
(
lookups
->
indexes
,
lookups
->
count
,
sizeof
(
*
lookups
->
indexe
s
),
lookups_sorting_compare
);
qsort
(
lookups
->
lookups
,
lookups
->
count
,
sizeof
(
*
lookups
->
lookup
s
),
lookups_sorting_compare
);
}
void
opentype_layout_apply_gpos_features
(
struct
scriptshaping_context
*
context
,
unsigned
int
script_index
,
...
...
@@ -4221,16 +4293,16 @@ void opentype_layout_apply_gpos_features(struct scriptshaping_context *context,
for
(
i
=
0
;
i
<
lookups
.
count
;
++
i
)
{
/* Skip duplicates. */
if
(
i
&&
lookups
.
indexes
[
i
]
==
lookups
.
indexes
[
i
-
1
]
)
if
(
i
&&
lookups
.
lookups
[
i
].
index
==
lookups
.
lookups
[
i
-
1
].
index
)
continue
;
opentype_layout_apply_gpos_lookup
(
context
,
lookups
.
indexes
[
i
]
);
opentype_layout_apply_gpos_lookup
(
context
,
lookups
.
lookups
[
i
].
index
);
}
heap_free
(
lookups
.
indexe
s
);
heap_free
(
lookups
.
lookup
s
);
}
static
BOOL
opentype_layout_apply_gsub_single_substitution
(
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
static
BOOL
opentype_layout_apply_gsub_single_substitution
(
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
iter
->
context
->
cache
;
UINT16
format
,
coverage
;
...
...
@@ -4376,7 +4448,7 @@ static BOOL opentype_layout_apply_gsub_chain_context_lookup(struct glyph_iterato
opentype_layout_context_gsub_apply_lookup
(
iter
,
input_count
,
lookup_count
,
lookup_records
);
}
static
BOOL
opentype_layout_apply_gsub_chain_context_substitution
(
struct
glyph_iterator
*
iter
,
const
struct
lookup
*
lookup
)
static
BOOL
opentype_layout_apply_gsub_chain_context_substitution
(
struct
glyph_iterator
*
iter
,
const
struct
ot_
lookup
*
lookup
)
{
struct
scriptshaping_cache
*
cache
=
iter
->
context
->
cache
;
UINT16
format
,
coverage
;
...
...
@@ -4468,7 +4540,7 @@ static void opentype_layout_apply_gsub_lookup(struct scriptshaping_context *cont
struct
ot_gsubgpos_table
*
table
=
&
context
->
cache
->
gsub
;
const
struct
ot_lookup_table
*
lookup_table
;
struct
glyph_iterator
iter
;
struct
lookup
lookup
;
struct
ot_
lookup
lookup
;
WORD
lookup_type
;
lookup
.
offset
=
table_read_be_word
(
&
table
->
table
,
table
->
lookup_list
+
FIELD_OFFSET
(
struct
ot_lookup_list
,
lookup
[
lookup_index
]));
...
...
@@ -4537,13 +4609,13 @@ HRESULT opentype_layout_apply_gsub_features(struct scriptshaping_context *contex
for
(
i
=
0
;
i
<
lookups
.
count
;
++
i
)
{
/* Skip duplicates. */
if
(
i
&&
lookups
.
indexes
[
i
]
==
lookups
.
indexes
[
i
-
1
]
)
if
(
i
&&
lookups
.
lookups
[
i
].
index
==
lookups
.
lookups
[
i
-
1
].
index
)
continue
;
opentype_layout_apply_gsub_lookup
(
context
,
0
,
context
->
glyph_count
,
lookups
.
indexes
[
i
]
);
opentype_layout_apply_gsub_lookup
(
context
,
0
,
context
->
glyph_count
,
lookups
.
lookups
[
i
].
index
);
}
heap_free
(
lookups
.
indexe
s
);
heap_free
(
lookups
.
lookup
s
);
return
S_OK
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment