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
da55f010
Commit
da55f010
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: Use mirrored character only if font supports it.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
bb91e877
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
119 additions
and
120 deletions
+119
-120
analyzer.c
dlls/dwrite/analyzer.c
+15
-91
bidi.c
dlls/dwrite/bidi.c
+0
-7
dwrite_private.h
dlls/dwrite/dwrite_private.h
+6
-1
font.c
dlls/dwrite/font.c
+29
-11
opentype.c
dlls/dwrite/opentype.c
+66
-1
shape.c
dlls/dwrite/shape.c
+3
-9
No files found.
dlls/dwrite/analyzer.c
View file @
da55f010
...
...
@@ -280,16 +280,6 @@ static inline struct dwrite_fontfallback_builder *impl_from_IDWriteFontFallbackB
return
CONTAINING_RECORD
(
iface
,
struct
dwrite_fontfallback_builder
,
IDWriteFontFallbackBuilder_iface
);
}
static
inline
UINT32
decode_surrogate_pair
(
const
WCHAR
*
str
,
UINT32
index
,
UINT32
end
)
{
if
(
index
<
end
-
1
&&
IS_SURROGATE_PAIR
(
str
[
index
],
str
[
index
+
1
]))
{
UINT32
ch
=
0x10000
+
((
str
[
index
]
-
0xd800
)
<<
10
)
+
(
str
[
index
+
1
]
-
0xdc00
);
TRACE
(
"surrogate pair (%x %x) => %x
\n
"
,
str
[
index
],
str
[
index
+
1
],
ch
);
return
ch
;
}
return
0
;
}
static
inline
UINT16
get_char_script
(
WCHAR
c
)
{
UINT16
script
=
get_table_entry
(
wine_scripts_table
,
c
);
...
...
@@ -1059,15 +1049,17 @@ static UINT32 get_opentype_language(const WCHAR *locale)
return
language
;
}
static
DWRITE_NUMBER_SUBSTITUTION_METHOD
get_number_substitutes
(
IDWriteNumberSubstitution
*
substitution
,
WCHAR
*
digits
)
static
void
get_number_substitutes
(
IDWriteNumberSubstitution
*
substitution
,
BOOL
is_rtl
,
WCHAR
*
digits
)
{
struct
dwrite_numbersubstitution
*
numbersubst
=
unsafe_impl_from_IDWriteNumberSubstitution
(
substitution
);
DWRITE_NUMBER_SUBSTITUTION_METHOD
method
;
WCHAR
isolang
[
9
];
DWORD
lctype
;
digits
[
0
]
=
0
;
if
(
!
numbersubst
)
return
DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE
;
return
;
lctype
=
numbersubst
->
ignore_user_override
?
LOCALE_NOUSEROVERRIDE
:
0
;
...
...
@@ -1096,7 +1088,6 @@ static DWRITE_NUMBER_SUBSTITUTION_METHOD get_number_substitutes(IDWriteNumberSub
else
method
=
numbersubst
->
method
;
digits
[
0
]
=
0
;
switch
(
method
)
{
case
DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL
:
...
...
@@ -1125,7 +1116,8 @@ static DWRITE_NUMBER_SUBSTITUTION_METHOD get_number_substitutes(IDWriteNumberSub
method
=
DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE
;
}
return
method
;
if
((
method
==
DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL
&&
!
is_rtl
)
||
method
==
DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE
)
digits
[
0
]
=
0
;
}
static
void
analyzer_dump_user_features
(
DWRITE_TYPOGRAPHIC_FEATURES
const
**
features
,
...
...
@@ -1153,14 +1145,11 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
DWRITE_SHAPING_GLYPH_PROPERTIES
*
glyph_props
,
UINT32
*
actual_glyph_count
)
{
const
struct
dwritescript_properties
*
scriptprops
;
DWRITE_NUMBER_SUBSTITUTION_METHOD
method
;
struct
scriptshaping_context
context
;
struct
scriptshaping_context
context
=
{
0
};
struct
dwrite_fontface
*
font_obj
;
WCHAR
digits
[
NATIVE_DIGITS_LEN
];
unsigned
int
i
,
g
,
script
;
BOOL
update_cluster
;
WCHAR
*
string
;
HRESULT
hr
=
S_OK
;
unsigned
int
script
;
HRESULT
hr
;
TRACE
(
"(%s:%u %p %d %d %s %s %p %p %p %u %u %p %p %p %p %p)
\n
"
,
debugstr_wn
(
text
,
length
),
length
,
fontface
,
is_sideways
,
is_rtl
,
debugstr_sa_script
(
analysis
->
script
),
debugstr_w
(
locale
),
substitution
,
...
...
@@ -1172,78 +1161,11 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
if
(
max_glyph_count
<
length
)
return
E_NOT_SUFFICIENT_BUFFER
;
string
=
heap_calloc
(
length
,
sizeof
(
*
string
));
if
(
!
string
)
return
E_OUTOFMEMORY
;
method
=
get_number_substitutes
(
substitution
,
digits
);
get_number_substitutes
(
substitution
,
is_rtl
,
digits
);
/* FIXME: have the shaping engine set this */
memset
(
text_props
,
0
,
length
*
sizeof
(
*
text_props
));
for
(
i
=
0
;
i
<
length
;
i
++
)
{
/* FIXME: set to better values */
glyph_props
[
i
].
justification
=
text
[
i
]
==
' '
?
SCRIPT_JUSTIFY_BLANK
:
SCRIPT_JUSTIFY_CHARACTER
;
glyph_props
[
i
].
isClusterStart
=
1
;
glyph_props
[
i
].
isDiacritic
=
0
;
glyph_props
[
i
].
isZeroWidthSpace
=
0
;
glyph_props
[
i
].
reserved
=
0
;
clustermap
[
i
]
=
i
;
string
[
i
]
=
text
[
i
];
switch
(
method
)
{
case
DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL
:
if
(
!
is_rtl
)
break
;
/* fallthrough */
default:
if
(
string
[
i
]
>=
'0'
&&
string
[
i
]
<=
'9'
)
string
[
i
]
=
digits
[
string
[
i
]
-
'0'
];
break
;
case
DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE
:
;
}
}
for
(;
i
<
max_glyph_count
;
i
++
)
{
glyph_props
[
i
].
justification
=
SCRIPT_JUSTIFY_NONE
;
glyph_props
[
i
].
isClusterStart
=
0
;
glyph_props
[
i
].
isDiacritic
=
0
;
glyph_props
[
i
].
isZeroWidthSpace
=
0
;
glyph_props
[
i
].
reserved
=
0
;
}
for
(
i
=
0
,
g
=
0
,
update_cluster
=
FALSE
;
i
<
length
;
i
++
)
{
UINT32
codepoint
;
if
(
!
update_cluster
)
{
codepoint
=
decode_surrogate_pair
(
string
,
i
,
length
);
if
(
!
codepoint
)
codepoint
=
is_rtl
?
bidi_get_mirrored_char
(
string
[
i
])
:
string
[
i
];
else
update_cluster
=
TRUE
;
hr
=
IDWriteFontFace_GetGlyphIndices
(
fontface
,
&
codepoint
,
1
,
&
glyphs
[
g
]);
if
(
FAILED
(
hr
))
goto
done
;
g
++
;
}
else
{
INT32
k
;
update_cluster
=
FALSE
;
/* mark surrogate halves with same cluster */
clustermap
[
i
]
=
clustermap
[
i
-
1
];
/* update following clusters */
for
(
k
=
i
+
1
;
k
>=
0
&&
k
<
length
;
k
++
)
clustermap
[
k
]
--
;
}
}
*
actual_glyph_count
=
g
;
font_obj
=
unsafe_impl_from_IDWriteFontFace
(
fontface
);
context
.
cache
=
fontface_get_shaping_cache
(
font_obj
);
...
...
@@ -1253,8 +1175,9 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
context
.
is_sideways
=
is_sideways
;
context
.
u
.
subst
.
glyphs
=
glyphs
;
context
.
u
.
subst
.
glyph_props
=
glyph_props
;
context
.
u
.
subst
.
clustermap
=
clustermap
;
context
.
u
.
subst
.
max_glyph_count
=
max_glyph_count
;
context
.
glyph_count
=
g
;
context
.
u
.
subst
.
digits
=
digits
;
context
.
language_tag
=
get_opentype_language
(
locale
);
context
.
user_features
.
features
=
features
;
context
.
user_features
.
range_lengths
=
feature_range_lengths
;
...
...
@@ -1265,12 +1188,13 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
scriptprops
=
&
dwritescripts_properties
[
script
];
hr
=
shape_get_glyphs
(
&
context
,
scriptprops
->
scripttags
);
if
(
SUCCEEDED
(
hr
))
{
*
actual_glyph_count
=
context
.
glyph_count
;
hr
=
default_shaping_ops
.
set_text_glyphs_props
(
&
context
,
clustermap
,
glyphs
,
*
actual_glyph_count
,
text_props
,
glyph_props
);
}
done:
heap_free
(
context
.
glyph_infos
);
heap_free
(
string
);
return
hr
;
}
...
...
dlls/dwrite/bidi.c
View file @
da55f010
...
...
@@ -158,13 +158,6 @@ static void bidi_classify(const WCHAR *string, UINT8 *chartype, UINT32 count)
chartype
[
i
]
=
get_table_entry
(
bidi_direction_table
,
string
[
i
]
);
}
WCHAR
bidi_get_mirrored_char
(
WCHAR
ch
)
{
extern
const
WCHAR
wine_mirror_map
[]
DECLSPEC_HIDDEN
;
WCHAR
mirror
=
get_table_entry
(
wine_mirror_map
,
ch
);
return
mirror
?
mirror
:
ch
;
}
/* RESOLVE EXPLICIT */
static
inline
UINT8
get_greater_even_level
(
UINT8
level
)
...
...
dlls/dwrite/dwrite_private.h
View file @
da55f010
...
...
@@ -300,6 +300,8 @@ extern void factory_unlock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
extern
HRESULT
create_inmemory_fileloader
(
IDWriteFontFileLoader
**
)
DECLSPEC_HIDDEN
;
extern
HRESULT
create_font_resource
(
IDWriteFactory7
*
factory
,
IDWriteFontFile
*
file
,
UINT32
face_index
,
IDWriteFontResource
**
resource
)
DECLSPEC_HIDDEN
;
extern
HRESULT
fontface_get_glyphs
(
struct
dwrite_fontface
*
fontface
,
UINT32
const
*
codepoints
,
UINT32
count
,
UINT16
*
glyphs
);
struct
dwrite_fontface
;
...
...
@@ -378,7 +380,6 @@ extern unsigned int opentype_get_gasp_flags(const struct dwrite_fonttable *gasp,
/* BiDi helpers */
extern
HRESULT
bidi_computelevels
(
const
WCHAR
*
,
UINT32
,
UINT8
,
UINT8
*
,
UINT8
*
)
DECLSPEC_HIDDEN
;
extern
WCHAR
bidi_get_mirrored_char
(
WCHAR
)
DECLSPEC_HIDDEN
;
/* FreeType integration */
struct
dwrite_glyphbitmap
...
...
@@ -487,7 +488,9 @@ struct scriptshaping_context
{
UINT16
*
glyphs
;
DWRITE_SHAPING_GLYPH_PROPERTIES
*
glyph_props
;
UINT16
*
clustermap
;
unsigned
int
max_glyph_count
;
const
WCHAR
*
digits
;
}
subst
;
}
u
;
...
...
@@ -512,6 +515,8 @@ struct shaping_font_ops
void
(
*
grab_font_table
)(
void
*
context
,
UINT32
table
,
const
BYTE
**
data
,
UINT32
*
size
,
void
**
data_context
);
void
(
*
release_font_table
)(
void
*
context
,
void
*
data_context
);
UINT16
(
*
get_font_upem
)(
void
*
context
);
BOOL
(
*
has_glyph
)(
void
*
context
,
unsigned
int
codepoint
);
UINT16
(
*
get_glyph
)(
void
*
context
,
unsigned
int
codepoint
);
};
extern
struct
scriptshaping_cache
*
create_scriptshaping_cache
(
void
*
context
,
...
...
dlls/dwrite/font.c
View file @
da55f010
...
...
@@ -272,11 +272,29 @@ static UINT16 dwrite_get_font_upem(void *context)
return
fontface
->
metrics
.
designUnitsPerEm
;
}
static
BOOL
dwrite_has_glyph
(
void
*
context
,
unsigned
int
codepoint
)
{
struct
dwrite_fontface
*
fontface
=
context
;
UINT16
index
=
0
;
fontface_get_glyphs
(
fontface
,
&
codepoint
,
1
,
&
index
);
return
!!
index
;
}
static
UINT16
dwrite_get_glyph
(
void
*
context
,
unsigned
int
codepoint
)
{
struct
dwrite_fontface
*
fontface
=
context
;
UINT16
index
=
0
;
fontface_get_glyphs
(
fontface
,
&
codepoint
,
1
,
&
index
);
return
index
;
}
static
const
struct
shaping_font_ops
dwrite_font_ops
=
{
dwrite_grab_font_table
,
dwrite_release_font_table
,
dwrite_get_font_upem
,
dwrite_has_glyph
,
dwrite_get_glyph
,
};
struct
scriptshaping_cache
*
fontface_get_shaping_cache
(
struct
dwrite_fontface
*
fontface
)
...
...
@@ -714,17 +732,9 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa
return
S_OK
;
}
static
HRESULT
fontface_get_glyphs
(
struct
dwrite_fontface
*
fontface
,
UINT32
const
*
codepoints
,
HRESULT
fontface_get_glyphs
(
struct
dwrite_fontface
*
fontface
,
UINT32
const
*
codepoints
,
UINT32
count
,
UINT16
*
glyphs
)
{
if
(
!
glyphs
)
return
E_INVALIDARG
;
if
(
!
codepoints
)
{
memset
(
glyphs
,
0
,
count
*
sizeof
(
*
glyphs
));
return
E_INVALIDARG
;
}
freetype_get_glyphs
(
&
fontface
->
IDWriteFontFace5_iface
,
fontface
->
charmap
,
codepoints
,
count
,
glyphs
);
return
S_OK
;
}
...
...
@@ -736,6 +746,15 @@ static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace5 *iface, UI
TRACE
(
"%p, %p, %u, %p.
\n
"
,
iface
,
codepoints
,
count
,
glyphs
);
if
(
!
glyphs
)
return
E_INVALIDARG
;
if
(
!
codepoints
)
{
memset
(
glyphs
,
0
,
count
*
sizeof
(
*
glyphs
));
return
E_INVALIDARG
;
}
return
fontface_get_glyphs
(
fontface
,
codepoints
,
count
,
glyphs
);
}
...
...
@@ -1390,8 +1409,7 @@ static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace5 *iface, UINT32
TRACE
(
"%p, %#x.
\n
"
,
iface
,
ch
);
index
=
0
;
if
(
FAILED
(
fontface_get_glyphs
(
fontface
,
&
ch
,
1
,
&
index
)))
return
FALSE
;
fontface_get_glyphs
(
fontface
,
&
ch
,
1
,
&
index
);
return
index
!=
0
;
}
...
...
dlls/dwrite/opentype.c
View file @
da55f010
...
...
@@ -4187,6 +4187,9 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
unsigned
int
global_bit_mask
=
1
;
UINT16
feature_index
;
if
(
!
table
->
table
.
data
)
return
;
/* ScriptTable offset. */
table_offset
=
table_read_be_word
(
&
table
->
table
,
table
->
script_list
+
FIELD_OFFSET
(
struct
ot_script_list
,
scripts
)
+
script_index
*
sizeof
(
struct
ot_script_record
)
+
FIELD_OFFSET
(
struct
ot_script_record
,
script
));
...
...
@@ -4329,7 +4332,7 @@ static unsigned int shaping_features_get_mask(const struct shaping_features *fea
if
(
!
feature
||
feature
->
index
==
0xffff
)
return
0
;
*
shift
=
feature
->
shift
;
if
(
shift
)
*
shift
=
feature
->
shift
;
return
feature
->
mask
;
}
...
...
@@ -4671,6 +4674,67 @@ static void opentype_layout_apply_gsub_lookup(struct scriptshaping_context *cont
}
}
static
unsigned
int
unicode_get_mirrored_char
(
unsigned
int
codepoint
)
{
extern
const
WCHAR
wine_mirror_map
[]
DECLSPEC_HIDDEN
;
WCHAR
mirror
;
/* TODO: check if mirroring for higher planes makes sense at all */
if
(
codepoint
>
0xffff
)
return
codepoint
;
mirror
=
get_table_entry
(
wine_mirror_map
,
codepoint
);
return
mirror
?
mirror
:
codepoint
;
}
static
void
opentype_get_nominal_glyphs
(
struct
scriptshaping_context
*
context
,
const
struct
shaping_features
*
features
)
{
unsigned
int
rtlm_mask
=
shaping_features_get_mask
(
features
,
DWRITE_MAKE_OPENTYPE_TAG
(
'r'
,
't'
,
'l'
,
'm'
),
NULL
);
const
struct
shaping_font_ops
*
font
=
context
->
cache
->
font
;
UINT16
*
clustermap
=
context
->
u
.
subst
.
clustermap
;
const
WCHAR
*
text
=
context
->
text
;
unsigned
int
i
,
g
,
c
,
codepoint
;
BOOL
bmp
;
memset
(
context
->
u
.
subst
.
glyph_props
,
0
,
context
->
u
.
subst
.
max_glyph_count
*
sizeof
(
*
context
->
u
.
subst
.
glyph_props
));
for
(
i
=
0
;
i
<
context
->
length
;
++
i
)
{
g
=
context
->
glyph_count
;
if
((
bmp
=
!
(
IS_HIGH_SURROGATE
(
text
[
i
])
&&
(
i
<
context
->
length
-
1
)
&&
IS_LOW_SURROGATE
(
text
[
i
+
1
]))))
{
codepoint
=
text
[
i
];
}
else
{
codepoint
=
0x10000
+
((
text
[
i
]
-
0xd800
)
<<
10
)
+
(
text
[
i
+
1
]
-
0xdc00
);
}
if
(
context
->
is_rtl
)
{
c
=
unicode_get_mirrored_char
(
codepoint
);
if
(
c
!=
codepoint
&&
font
->
has_glyph
(
context
->
cache
->
context
,
c
))
codepoint
=
c
;
else
context
->
glyph_infos
[
i
].
mask
|=
rtlm_mask
;
}
/* TODO: should this check for glyph availability? */
if
(
*
context
->
u
.
subst
.
digits
&&
codepoint
>=
'0'
&&
codepoint
<=
'9'
)
codepoint
=
context
->
u
.
subst
.
digits
[
codepoint
-
'0'
];
context
->
u
.
subst
.
glyphs
[
g
]
=
font
->
get_glyph
(
context
->
cache
->
context
,
codepoint
);
context
->
u
.
subst
.
glyph_props
[
g
].
justification
=
SCRIPT_JUSTIFY_CHARACTER
;
context
->
u
.
subst
.
glyph_props
[
g
].
isClusterStart
=
1
;
context
->
glyph_count
++
;
clustermap
[
i
]
=
i
;
if
(
!
bmp
)
{
clustermap
[
i
+
1
]
=
i
;
++
i
;
}
}
}
HRESULT
opentype_layout_apply_gsub_features
(
struct
scriptshaping_context
*
context
,
unsigned
int
script_index
,
unsigned
int
language_index
,
const
struct
shaping_features
*
features
)
{
...
...
@@ -4679,6 +4743,7 @@ HRESULT opentype_layout_apply_gsub_features(struct scriptshaping_context *contex
opentype_layout_collect_lookups
(
context
,
script_index
,
language_index
,
features
,
&
context
->
cache
->
gsub
,
&
lookups
);
opentype_get_nominal_glyphs
(
context
,
features
);
opentype_layout_set_glyph_masks
(
context
,
features
);
for
(
i
=
0
;
i
<
lookups
.
count
;
++
i
)
...
...
dlls/dwrite/shape.c
View file @
da55f010
...
...
@@ -362,8 +362,7 @@ HRESULT shape_get_glyphs(struct scriptshaping_context *context, const unsigned i
DWRITE_MAKE_OPENTYPE_TAG
(
'l'
,
'i'
,
'g'
,
'a'
),
DWRITE_MAKE_OPENTYPE_TAG
(
'r'
,
'c'
,
'l'
,
't'
),
};
struct
scriptshaping_cache
*
cache
=
context
->
cache
;
unsigned
int
script_index
,
language_index
,
script
;
unsigned
int
script_index
,
language_index
;
struct
shaping_features
features
=
{
0
};
unsigned
int
i
;
...
...
@@ -396,13 +395,8 @@ HRESULT shape_get_glyphs(struct scriptshaping_context *context, const unsigned i
shape_merge_features
(
context
,
&
features
);
/* Resolve script tag to actually supported script. */
if
(
cache
->
gsub
.
table
.
data
)
{
if
((
script
=
shape_get_script_lang_index
(
context
,
scripts
,
MS_GSUB_TAG
,
&
script_index
,
&
language_index
)))
{
opentype_layout_apply_gsub_features
(
context
,
script_index
,
language_index
,
&
features
);
}
}
shape_get_script_lang_index
(
context
,
scripts
,
MS_GSUB_TAG
,
&
script_index
,
&
language_index
);
opentype_layout_apply_gsub_features
(
context
,
script_index
,
language_index
,
&
features
);
heap_free
(
features
.
features
);
...
...
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