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
aa1bd1e0
Commit
aa1bd1e0
authored
Feb 17, 2021
by
Nikolay Sivov
Committed by
Alexandre Julliard
Feb 17, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite/layout: Pass user features to shaping calls.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
d4784a92
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
147 additions
and
31 deletions
+147
-31
layout.c
dlls/dwrite/layout.c
+147
-31
No files found.
dlls/dwrite/layout.c
View file @
aa1bd1e0
...
...
@@ -648,7 +648,33 @@ static HRESULT layout_update_breakpoints_range(struct dwrite_textlayout *layout,
return
S_OK
;
}
static
struct
layout_range
*
get_layout_range_by_pos
(
struct
dwrite_textlayout
*
layout
,
UINT32
pos
);
static
struct
layout_range
*
get_layout_range_by_pos
(
struct
dwrite_textlayout
*
layout
,
UINT32
pos
)
{
struct
layout_range
*
cur
;
LIST_FOR_EACH_ENTRY
(
cur
,
&
layout
->
ranges
,
struct
layout_range
,
h
.
entry
)
{
DWRITE_TEXT_RANGE
*
r
=
&
cur
->
h
.
range
;
if
(
r
->
startPosition
<=
pos
&&
pos
<
r
->
startPosition
+
r
->
length
)
return
cur
;
}
return
NULL
;
}
static
struct
layout_range_header
*
get_layout_range_header_by_pos
(
struct
list
*
ranges
,
UINT32
pos
)
{
struct
layout_range_header
*
cur
;
LIST_FOR_EACH_ENTRY
(
cur
,
ranges
,
struct
layout_range_header
,
entry
)
{
DWRITE_TEXT_RANGE
*
r
=
&
cur
->
range
;
if
(
r
->
startPosition
<=
pos
&&
pos
<
r
->
startPosition
+
r
->
length
)
return
cur
;
}
return
NULL
;
}
static
inline
DWRITE_LINE_BREAKPOINT
get_effective_breakpoint
(
const
struct
dwrite_textlayout
*
layout
,
UINT32
pos
)
{
...
...
@@ -940,14 +966,123 @@ struct shaping_context
struct
regular_layout_run
*
run
;
DWRITE_SHAPING_GLYPH_PROPERTIES
*
glyph_props
;
DWRITE_SHAPING_TEXT_PROPERTIES
*
text_props
;
struct
{
DWRITE_TYPOGRAPHIC_FEATURES
**
features
;
unsigned
int
*
range_lengths
;
unsigned
int
range_count
;
}
user_features
;
};
static
void
layout_shape_clear_user_features_context
(
struct
shaping_context
*
context
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
context
->
user_features
.
range_count
;
++
i
)
{
heap_free
(
context
->
user_features
.
features
[
i
]
->
features
);
heap_free
(
context
->
user_features
.
features
[
i
]);
}
heap_free
(
context
->
user_features
.
features
);
memset
(
&
context
->
user_features
,
0
,
sizeof
(
context
->
user_features
));
}
static
void
layout_shape_clear_context
(
struct
shaping_context
*
context
)
{
layout_shape_clear_user_features_context
(
context
);
heap_free
(
context
->
glyph_props
);
heap_free
(
context
->
text_props
);
}
static
HRESULT
layout_shape_add_empty_user_features_range
(
struct
shaping_context
*
context
,
unsigned
int
length
)
{
DWRITE_TYPOGRAPHIC_FEATURES
*
features
;
unsigned
int
r
=
context
->
user_features
.
range_count
;
if
(
!
(
context
->
user_features
.
features
[
r
]
=
heap_alloc_zero
(
sizeof
(
*
features
))))
return
E_OUTOFMEMORY
;
context
->
user_features
.
range_lengths
[
r
]
=
length
;
context
->
user_features
.
range_count
++
;
return
S_OK
;
}
static
HRESULT
layout_shape_get_user_features
(
struct
dwrite_textlayout
*
layout
,
struct
shaping_context
*
context
)
{
unsigned
int
i
,
f
,
start
=
0
,
r
,
covered_length
=
0
,
length
,
feature_count
;
struct
regular_layout_run
*
run
=
context
->
run
;
DWRITE_TYPOGRAPHIC_FEATURES
*
features
;
struct
layout_range_iface
*
range
;
IDWriteTypography
*
typography
;
HRESULT
hr
=
E_OUTOFMEMORY
;
range
=
(
struct
layout_range_iface
*
)
get_layout_range_header_by_pos
(
&
layout
->
typographies
,
0
);
if
(
range
->
h
.
range
.
length
>=
run
->
descr
.
stringLength
&&
!
range
->
iface
)
return
S_OK
;
if
(
!
(
context
->
user_features
.
features
=
heap_calloc
(
run
->
descr
.
stringLength
,
sizeof
(
*
context
->
user_features
.
features
))))
goto
failed
;
if
(
!
(
context
->
user_features
.
range_lengths
=
heap_calloc
(
run
->
descr
.
stringLength
,
sizeof
(
*
context
->
user_features
.
range_lengths
))))
goto
failed
;
for
(
i
=
run
->
descr
.
textPosition
;
i
<
run
->
descr
.
textPosition
+
run
->
descr
.
stringLength
;
++
i
)
{
range
=
(
struct
layout_range_iface
*
)
get_layout_range_header_by_pos
(
&
layout
->
typographies
,
i
);
if
(
!
range
||
!
range
->
iface
)
continue
;
typography
=
(
IDWriteTypography
*
)
range
->
iface
;
feature_count
=
IDWriteTypography_GetFontFeatureCount
(
typography
);
if
(
!
feature_count
)
{
i
=
range
->
h
.
range
.
length
-
i
+
1
;
continue
;
}
if
(
start
!=
i
)
{
if
(
FAILED
(
hr
=
layout_shape_add_empty_user_features_range
(
context
,
i
-
start
)))
goto
failed
;
covered_length
+=
i
-
start
;
start
+=
range
->
h
.
range
.
length
;
}
r
=
context
->
user_features
.
range_count
;
if
(
!
(
features
=
context
->
user_features
.
features
[
r
]
=
heap_alloc
(
sizeof
(
*
features
))))
goto
failed
;
context
->
user_features
.
range_lengths
[
r
]
=
length
=
min
(
run
->
descr
.
textPosition
+
run
->
descr
.
stringLength
,
range
->
h
.
range
.
startPosition
+
range
->
h
.
range
.
length
)
-
i
;
features
->
featureCount
=
feature_count
;
if
(
!
(
features
->
features
=
heap_calloc
(
feature_count
,
sizeof
(
*
features
->
features
))))
goto
failed
;
for
(
f
=
0
;
f
<
feature_count
;
++
f
)
{
IDWriteTypography_GetFontFeature
(
typography
,
f
,
&
features
->
features
[
f
]);
}
i
+=
length
;
covered_length
+=
length
;
context
->
user_features
.
range_count
++
;
}
if
(
context
->
user_features
.
range_count
&&
covered_length
<
run
->
descr
.
stringLength
)
{
if
(
FAILED
(
hr
=
layout_shape_add_empty_user_features_range
(
context
,
run
->
descr
.
stringLength
-
covered_length
)))
goto
failed
;
}
hr
=
S_OK
;
failed:
if
(
!
context
->
user_features
.
range_count
||
FAILED
(
hr
))
layout_shape_clear_user_features_context
(
context
);
return
hr
;
}
static
HRESULT
layout_shape_get_glyphs
(
struct
dwrite_textlayout
*
layout
,
struct
shaping_context
*
context
)
{
struct
regular_layout_run
*
run
=
context
->
run
;
...
...
@@ -969,11 +1104,16 @@ static HRESULT layout_shape_get_glyphs(struct dwrite_textlayout *layout, struct
if
(
!
context
->
text_props
||
!
context
->
glyph_props
)
return
E_OUTOFMEMORY
;
if
(
FAILED
(
hr
=
layout_shape_get_user_features
(
layout
,
context
)))
return
hr
;
for
(;;)
{
hr
=
IDWriteTextAnalyzer_GetGlyphs
(
context
->
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
stringLength
,
run
->
run
.
fontFace
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
/* FIXME */
,
NULL
,
NULL
,
0
,
max_count
,
run
->
clustermap
,
context
->
text_props
,
run
->
glyphs
,
context
->
glyph_props
,
&
run
->
glyphcount
);
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
/* FIXME */
,
(
const
DWRITE_TYPOGRAPHIC_FEATURES
**
)
context
->
user_features
.
features
,
context
->
user_features
.
range_lengths
,
context
->
user_features
.
range_count
,
max_count
,
run
->
clustermap
,
context
->
text_props
,
run
->
glyphs
,
context
->
glyph_props
,
&
run
->
glyphcount
);
if
(
hr
==
E_NOT_SUFFICIENT_BUFFER
)
{
heap_free
(
run
->
glyphs
);
...
...
@@ -1020,12 +1160,14 @@ static HRESULT layout_shape_get_positions(struct dwrite_textlayout *layout, stru
context
->
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
context
->
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
ppdip
,
&
layout
->
transform
,
layout
->
measuringmode
==
DWRITE_MEASURING_MODE_GDI_NATURAL
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
&
run
->
sa
,
run
->
descr
.
localeName
,
(
const
DWRITE_TYPOGRAPHIC_FEATURES
**
)
context
->
user_features
.
features
,
context
->
user_features
.
range_lengths
,
context
->
user_features
.
range_count
,
run
->
advances
,
run
->
offsets
);
else
hr
=
IDWriteTextAnalyzer_GetGlyphPlacements
(
context
->
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
clusterMap
,
context
->
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
context
->
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
run
->
descr
.
localeName
,
(
const
DWRITE_TYPOGRAPHIC_FEATURES
**
)
context
->
user_features
.
features
,
context
->
user_features
.
range_lengths
,
context
->
user_features
.
range_count
,
run
->
advances
,
run
->
offsets
);
if
(
FAILED
(
hr
))
{
...
...
@@ -1204,19 +1346,6 @@ static inline FLOAT get_cluster_range_width(struct dwrite_textlayout *layout, UI
return
width
;
}
static
struct
layout_range_header
*
get_layout_range_header_by_pos
(
struct
list
*
ranges
,
UINT32
pos
)
{
struct
layout_range_header
*
cur
;
LIST_FOR_EACH_ENTRY
(
cur
,
ranges
,
struct
layout_range_header
,
entry
)
{
DWRITE_TEXT_RANGE
*
r
=
&
cur
->
range
;
if
(
r
->
startPosition
<=
pos
&&
pos
<
r
->
startPosition
+
r
->
length
)
return
cur
;
}
return
NULL
;
}
static
inline
IUnknown
*
layout_get_effect_from_pos
(
struct
dwrite_textlayout
*
layout
,
UINT32
pos
)
{
struct
layout_range_header
*
h
=
get_layout_range_header_by_pos
(
&
layout
->
effects
,
pos
);
...
...
@@ -2483,19 +2612,6 @@ static struct layout_range_header *find_outer_range(struct list *ranges, const D
return
NULL
;
}
static
struct
layout_range
*
get_layout_range_by_pos
(
struct
dwrite_textlayout
*
layout
,
UINT32
pos
)
{
struct
layout_range
*
cur
;
LIST_FOR_EACH_ENTRY
(
cur
,
&
layout
->
ranges
,
struct
layout_range
,
h
.
entry
)
{
DWRITE_TEXT_RANGE
*
r
=
&
cur
->
h
.
range
;
if
(
r
->
startPosition
<=
pos
&&
pos
<
r
->
startPosition
+
r
->
length
)
return
cur
;
}
return
NULL
;
}
static
inline
BOOL
set_layout_range_iface_attr
(
IUnknown
**
dest
,
IUnknown
*
value
)
{
if
(
*
dest
==
value
)
return
FALSE
;
...
...
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