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
fbcf1531
Commit
fbcf1531
authored
Jan 28, 2016
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jan 28, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Return valid metrics for layout created on empty text.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
df687431
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
86 additions
and
69 deletions
+86
-69
layout.c
dlls/dwrite/layout.c
+85
-45
layout.c
dlls/dwrite/tests/layout.c
+1
-24
No files found.
dlls/dwrite/layout.c
View file @
fbcf1531
...
...
@@ -350,10 +350,9 @@ static inline struct dwrite_typography *impl_from_IDWriteTypography(IDWriteTypog
return
CONTAINING_RECORD
(
iface
,
struct
dwrite_typography
,
IDWriteTypography_iface
);
}
static
inline
const
char
*
debugstr_run
(
const
struct
regular_layout_run
*
run
)
static
inline
const
char
*
debugstr_run
descr
(
const
DWRITE_GLYPH_RUN_DESCRIPTION
*
descr
)
{
return
wine_dbg_sprintf
(
"[%u,%u)"
,
run
->
descr
.
textPosition
,
run
->
descr
.
textPosition
+
run
->
descr
.
stringLength
);
return
wine_dbg_sprintf
(
"[%u,%u)"
,
descr
->
textPosition
,
descr
->
textPosition
+
descr
->
stringLength
);
}
static
inline
BOOL
is_layout_gdi_compatible
(
struct
dwrite_textlayout
*
layout
)
...
...
@@ -670,6 +669,57 @@ static void layout_set_cluster_metrics(struct dwrite_textlayout *layout, const s
#define SCALE_FONT_METRIC(metric, emSize, metrics) ((FLOAT)(metric) * (emSize) / (FLOAT)(metrics)->designUnitsPerEm)
static
HRESULT
create_fontface_by_pos
(
struct
dwrite_textlayout
*
layout
,
struct
layout_range
*
range
,
IDWriteFontFace
**
fontface
)
{
static
DWRITE_GLYPH_RUN_DESCRIPTION
descr
=
{
0
};
IDWriteFontFamily
*
family
;
BOOL
exists
=
FALSE
;
IDWriteFont
*
font
;
UINT32
index
;
HRESULT
hr
;
*
fontface
=
NULL
;
hr
=
IDWriteFontCollection_FindFamilyName
(
range
->
collection
,
range
->
fontfamily
,
&
index
,
&
exists
);
if
(
FAILED
(
hr
)
||
!
exists
)
{
WARN
(
"%s: family %s not found in collection %p
\n
"
,
debugstr_rundescr
(
&
descr
),
debugstr_w
(
range
->
fontfamily
),
range
->
collection
);
return
hr
;
}
hr
=
IDWriteFontCollection_GetFontFamily
(
range
->
collection
,
index
,
&
family
);
if
(
FAILED
(
hr
))
return
hr
;
hr
=
IDWriteFontFamily_GetFirstMatchingFont
(
family
,
range
->
weight
,
range
->
stretch
,
range
->
style
,
&
font
);
IDWriteFontFamily_Release
(
family
);
if
(
FAILED
(
hr
))
{
WARN
(
"%s: failed to get a matching font
\n
"
,
debugstr_rundescr
(
&
descr
));
return
hr
;
}
hr
=
IDWriteFont_CreateFontFace
(
font
,
fontface
);
IDWriteFont_Release
(
font
);
return
hr
;
}
static
void
layout_get_font_metrics
(
struct
dwrite_textlayout
*
layout
,
IDWriteFontFace
*
fontface
,
FLOAT
emsize
,
DWRITE_FONT_METRICS
*
fontmetrics
)
{
if
(
is_layout_gdi_compatible
(
layout
))
{
HRESULT
hr
=
IDWriteFontFace_GetGdiCompatibleMetrics
(
fontface
,
emsize
,
layout
->
ppdip
,
&
layout
->
transform
,
fontmetrics
);
if
(
FAILED
(
hr
))
WARN
(
"failed to get compat metrics, 0x%08x
\n
"
,
hr
);
}
else
IDWriteFontFace_GetMetrics
(
fontface
,
fontmetrics
);
}
static
void
layout_get_font_height
(
FLOAT
emsize
,
DWRITE_FONT_METRICS
*
fontmetrics
,
FLOAT
*
baseline
,
FLOAT
*
height
)
{
*
baseline
=
SCALE_FONT_METRIC
(
fontmetrics
->
ascent
+
fontmetrics
->
lineGap
,
emsize
,
fontmetrics
);
*
height
=
SCALE_FONT_METRIC
(
fontmetrics
->
ascent
+
fontmetrics
->
descent
+
fontmetrics
->
lineGap
,
emsize
,
fontmetrics
);
}
static
HRESULT
layout_compute_runs
(
struct
dwrite_textlayout
*
layout
)
{
IDWriteTextAnalyzer
*
analyzer
;
...
...
@@ -737,10 +787,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
DWRITE_SHAPING_TEXT_PROPERTIES
*
text_props
=
NULL
;
struct
regular_layout_run
*
run
=
&
r
->
u
.
regular
;
DWRITE_FONT_METRICS
fontmetrics
=
{
0
};
IDWriteFontFamily
*
family
;
UINT32
index
,
max_count
;
IDWriteFont
*
font
;
BOOL
exists
=
TRUE
;
UINT32
max_count
;
/* we need to do very little in case of inline objects */
if
(
r
->
kind
==
LAYOUT_RUN_INLINE
)
{
...
...
@@ -776,26 +823,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
}
range
=
get_layout_range_by_pos
(
layout
,
run
->
descr
.
textPosition
);
hr
=
IDWriteFontCollection_FindFamilyName
(
range
->
collection
,
range
->
fontfamily
,
&
index
,
&
exists
);
if
(
FAILED
(
hr
)
||
!
exists
)
{
WARN
(
"%s: family %s not found in collection %p
\n
"
,
debugstr_run
(
run
),
debugstr_w
(
range
->
fontfamily
),
range
->
collection
);
continue
;
}
hr
=
IDWriteFontCollection_GetFontFamily
(
range
->
collection
,
index
,
&
family
);
if
(
FAILED
(
hr
))
continue
;
hr
=
IDWriteFontFamily_GetFirstMatchingFont
(
family
,
range
->
weight
,
range
->
stretch
,
range
->
style
,
&
font
);
IDWriteFontFamily_Release
(
family
);
if
(
FAILED
(
hr
))
{
WARN
(
"%s: failed to get a matching font
\n
"
,
debugstr_run
(
run
));
continue
;
}
hr
=
IDWriteFont_CreateFontFace
(
font
,
&
run
->
run
.
fontFace
);
IDWriteFont_Release
(
font
);
hr
=
create_fontface_by_pos
(
layout
,
range
,
&
run
->
run
.
fontFace
);
if
(
FAILED
(
hr
))
continue
;
...
...
@@ -838,7 +866,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
if
(
FAILED
(
hr
))
{
heap_free
(
text_props
);
heap_free
(
glyph_props
);
WARN
(
"%s: shaping failed 0x%08x
\n
"
,
debugstr_run
(
run
),
hr
);
WARN
(
"%s: shaping failed 0x%08x
\n
"
,
debugstr_run
descr
(
&
run
->
descr
),
hr
);
continue
;
}
...
...
@@ -866,7 +894,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
heap_free
(
text_props
);
heap_free
(
glyph_props
);
if
(
FAILED
(
hr
))
WARN
(
"%s: failed to get glyph placement info, 0x%08x
\n
"
,
debugstr_run
(
run
),
hr
);
WARN
(
"%s: failed to get glyph placement info, 0x%08x
\n
"
,
debugstr_run
descr
(
&
run
->
descr
),
hr
);
run
->
run
.
glyphAdvances
=
run
->
advances
;
run
->
run
.
glyphOffsets
=
run
->
offsets
;
...
...
@@ -880,23 +908,10 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
run
->
run
.
glyphCount
=
run
->
glyphcount
;
/* baseline derived from font metrics */
if
(
is_layout_gdi_compatible
(
layout
))
{
hr
=
IDWriteFontFace_GetGdiCompatibleMetrics
(
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
ppdip
,
&
layout
->
transform
,
&
fontmetrics
);
if
(
FAILED
(
hr
))
WARN
(
"failed to get compat metrics, 0x%08x
\n
"
,
hr
);
}
else
IDWriteFontFace_GetMetrics
(
run
->
run
.
fontFace
,
&
fontmetrics
);
r
->
baseline
=
SCALE_FONT_METRIC
(
fontmetrics
.
ascent
+
fontmetrics
.
lineGap
,
run
->
run
.
fontEmSize
,
&
fontmetrics
);
r
->
height
=
SCALE_FONT_METRIC
(
fontmetrics
.
ascent
+
fontmetrics
.
descent
+
fontmetrics
.
lineGap
,
run
->
run
.
fontEmSize
,
&
fontmetrics
);
layout_get_font_metrics
(
layout
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
&
fontmetrics
);
layout_get_font_height
(
run
->
run
.
fontEmSize
,
&
fontmetrics
,
&
r
->
baseline
,
&
r
->
height
);
layout_set_cluster_metrics
(
layout
,
r
,
&
cluster
);
continue
;
memerr:
...
...
@@ -1702,7 +1717,32 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
textpos
+=
layout
->
clustermetrics
[
i
].
length
;
}
layout
->
metrics
.
left
=
is_rtl
?
layout
->
metrics
.
layoutWidth
-
layout
->
metrics
.
width
:
0
;
/* Add dummy line when there's no text. Metrics come from first range. */
if
(
layout
->
len
==
0
)
{
DWRITE_FONT_METRICS
fontmetrics
;
struct
layout_range
*
range
;
IDWriteFontFace
*
fontface
;
range
=
get_layout_range_by_pos
(
layout
,
0
);
hr
=
create_fontface_by_pos
(
layout
,
range
,
&
fontface
);
if
(
FAILED
(
hr
))
return
hr
;
layout_get_font_metrics
(
layout
,
fontface
,
range
->
fontsize
,
&
fontmetrics
);
layout_get_font_height
(
range
->
fontsize
,
&
fontmetrics
,
&
metrics
.
baseline
,
&
metrics
.
height
);
IDWriteFontFace_Release
(
fontface
);
line
=
0
;
metrics
.
length
=
0
;
metrics
.
trailingWhitespaceLength
=
0
;
metrics
.
newlineLength
=
0
;
metrics
.
isTrimmed
=
FALSE
;
hr
=
layout_set_line_metrics
(
layout
,
&
metrics
,
&
line
);
if
(
FAILED
(
hr
))
return
hr
;
}
layout
->
metrics
.
left
=
is_rtl
?
layout
->
metrics
.
layoutWidth
-
layout
->
metrics
.
width
:
0
.
0
f
;
layout
->
metrics
.
top
=
0
.
0
f
;
layout
->
metrics
.
maxBidiReorderingDepth
=
1
;
/* FIXME */
layout
->
metrics
.
height
=
0
.
0
f
;
...
...
dlls/dwrite/tests/layout.c
View file @
fbcf1531
...
...
@@ -3391,15 +3391,12 @@ todo_wine {
memset
(
metrics
,
0
,
sizeof
(
metrics
));
hr
=
IDWriteTextLayout_GetLineMetrics
(
layout
,
metrics
,
1
,
&
count
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
todo_wine
ok
(
count
==
1
,
"got %u
\n
"
,
count
);
ok
(
metrics
[
0
].
length
==
0
,
"got %u
\n
"
,
metrics
[
0
].
length
);
ok
(
metrics
[
0
].
trailingWhitespaceLength
==
0
,
"got %u
\n
"
,
metrics
[
0
].
trailingWhitespaceLength
);
ok
(
metrics
[
0
].
newlineLength
==
0
,
"got %u
\n
"
,
metrics
[
0
].
newlineLength
);
todo_wine
{
ok
(
metrics
[
0
].
height
>
0
.
0
f
,
"got %f
\n
"
,
metrics
[
0
].
height
);
ok
(
metrics
[
0
].
baseline
>
0
.
0
f
,
"got %f
\n
"
,
metrics
[
0
].
baseline
);
}
ok
(
!
metrics
[
0
].
isTrimmed
,
"got %d
\n
"
,
metrics
[
0
].
isTrimmed
);
/* change font size at first position, see if metrics changed */
...
...
@@ -3411,12 +3408,10 @@ todo_wine {
count
=
0
;
hr
=
IDWriteTextLayout_GetLineMetrics
(
layout
,
metrics
+
1
,
1
,
&
count
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
todo_wine
ok
(
count
==
1
,
"got %u
\n
"
,
count
);
todo_wine
{
ok
(
metrics
[
1
].
height
>
metrics
[
0
].
height
,
"got %f
\n
"
,
metrics
[
1
].
height
);
ok
(
metrics
[
1
].
baseline
>
metrics
[
0
].
baseline
,
"got %f
\n
"
,
metrics
[
1
].
baseline
);
}
/* revert font size back to format value, set different size for position 1 */
hr
=
IDWriteTextLayout_SetFontSize
(
layout
,
12
.
0
f
,
range
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
...
...
@@ -3430,7 +3425,6 @@ todo_wine {
count
=
0
;
hr
=
IDWriteTextLayout_GetLineMetrics
(
layout
,
metrics
+
1
,
1
,
&
count
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
todo_wine
ok
(
count
==
1
,
"got %u
\n
"
,
count
);
ok
(
metrics
[
1
].
height
==
metrics
[
0
].
height
,
"got %f
\n
"
,
metrics
[
1
].
height
);
ok
(
metrics
[
1
].
baseline
==
metrics
[
0
].
baseline
,
"got %f
\n
"
,
metrics
[
1
].
baseline
);
...
...
@@ -3508,7 +3502,6 @@ static void test_SetTextAlignment(void)
win_skip
(
"IDWriteTextFormat1 is not supported
\n
"
);
for
(
i
=
0
;
i
<
sizeof
(
stringsW
)
/
sizeof
(
stringsW
[
0
]);
i
++
)
{
BOOL
todo
=
lstrlenW
(
stringsW
[
i
])
==
0
;
FLOAT
text_width
;
hr
=
IDWriteTextFormat_SetTextAlignment
(
format
,
DWRITE_TEXT_ALIGNMENT_LEADING
);
...
...
@@ -3542,10 +3535,6 @@ static void test_SetTextAlignment(void)
ok
(
metrics
.
left
==
0
.
0
f
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
text_width
,
"got %.2f
\n
"
,
metrics
.
width
);
ok
(
metrics
.
layoutWidth
==
500
.
0
f
,
"got %.2f
\n
"
,
metrics
.
layoutWidth
);
if
(
todo
)
todo_wine
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
else
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
/* maxwidth is 500, trailing alignment */
...
...
@@ -3558,10 +3547,6 @@ static void test_SetTextAlignment(void)
ok
(
metrics
.
left
==
metrics
.
layoutWidth
-
metrics
.
width
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
text_width
,
"got %.2f
\n
"
,
metrics
.
width
);
ok
(
metrics
.
layoutWidth
==
500
.
0
f
,
"got %.2f
\n
"
,
metrics
.
layoutWidth
);
if
(
todo
)
todo_wine
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
else
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
IDWriteTextLayout_Release
(
layout
);
...
...
@@ -3578,10 +3563,6 @@ static void test_SetTextAlignment(void)
ok
(
metrics
.
left
==
metrics
.
layoutWidth
-
metrics
.
width
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
text_width
,
"got %.2f
\n
"
,
metrics
.
width
);
ok
(
metrics
.
layoutWidth
==
500
.
0
f
,
"got %.2f
\n
"
,
metrics
.
layoutWidth
);
if
(
todo
)
todo_wine
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
else
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
IDWriteTextLayout_Release
(
layout
);
...
...
@@ -3611,10 +3592,6 @@ static void test_SetTextAlignment(void)
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
metrics
.
left
==
(
metrics
.
layoutWidth
-
metrics
.
width
)
/
2
.
0
f
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
text_width
,
"got %.2f
\n
"
,
metrics
.
width
);
if
(
todo
)
todo_wine
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
else
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
IDWriteTextLayout_Release
(
layout
);
...
...
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