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
44c135dd
Commit
44c135dd
authored
Jul 06, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jul 06, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Implement leading and trailing text alignment modes.
parent
de46f610
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
173 additions
and
8 deletions
+173
-8
layout.c
dlls/dwrite/layout.c
+121
-6
layout.c
dlls/dwrite/tests/layout.c
+52
-2
No files found.
dlls/dwrite/layout.c
View file @
44c135dd
...
@@ -180,6 +180,8 @@ struct layout_effective_run {
...
@@ -180,6 +180,8 @@ struct layout_effective_run {
UINT32
glyphcount
;
/* total glyph count in this run */
UINT32
glyphcount
;
/* total glyph count in this run */
FLOAT
origin_x
;
/* baseline X position */
FLOAT
origin_x
;
/* baseline X position */
FLOAT
origin_y
;
/* baseline Y position */
FLOAT
origin_y
;
/* baseline Y position */
FLOAT
align_dx
;
/* adjustment from text alignment */
FLOAT
width
;
/* run width */
UINT16
*
clustermap
;
/* effective clustermap, allocated separately, is not reused from nominal map */
UINT16
*
clustermap
;
/* effective clustermap, allocated separately, is not reused from nominal map */
UINT32
line
;
UINT32
line
;
};
};
...
@@ -190,6 +192,8 @@ struct layout_effective_inline {
...
@@ -190,6 +192,8 @@ struct layout_effective_inline {
IUnknown
*
effect
;
IUnknown
*
effect
;
FLOAT
origin_x
;
FLOAT
origin_x
;
FLOAT
origin_y
;
FLOAT
origin_y
;
FLOAT
align_dx
;
FLOAT
width
;
BOOL
is_sideways
;
BOOL
is_sideways
;
BOOL
is_rtl
;
BOOL
is_rtl
;
UINT32
line
;
UINT32
line
;
...
@@ -328,10 +332,12 @@ static inline const char *debugstr_run(const struct regular_layout_run *run)
...
@@ -328,10 +332,12 @@ static inline const char *debugstr_run(const struct regular_layout_run *run)
run
->
descr
.
stringLength
);
run
->
descr
.
stringLength
);
}
}
static
inline
HRESULT
format_set_textalignment
(
struct
dwrite_textformat_data
*
format
,
DWRITE_TEXT_ALIGNMENT
alignment
)
static
inline
HRESULT
format_set_textalignment
(
struct
dwrite_textformat_data
*
format
,
DWRITE_TEXT_ALIGNMENT
alignment
,
BOOL
*
changed
)
{
{
if
((
UINT32
)
alignment
>
DWRITE_TEXT_ALIGNMENT_JUSTIFIED
)
if
((
UINT32
)
alignment
>
DWRITE_TEXT_ALIGNMENT_JUSTIFIED
)
return
E_INVALIDARG
;
return
E_INVALIDARG
;
if
(
changed
)
*
changed
=
format
->
textalignment
!=
alignment
;
format
->
textalignment
=
alignment
;
format
->
textalignment
=
alignment
;
return
S_OK
;
return
S_OK
;
}
}
...
@@ -934,6 +940,8 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
...
@@ -934,6 +940,8 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
inlineobject
->
object
=
r
->
u
.
object
.
object
;
inlineobject
->
object
=
r
->
u
.
object
.
object
;
inlineobject
->
origin_x
=
origin_x
;
inlineobject
->
origin_x
=
origin_x
;
inlineobject
->
origin_y
=
0
.
0
;
/* FIXME */
inlineobject
->
origin_y
=
0
.
0
;
/* FIXME */
inlineobject
->
align_dx
=
0
.
0
;
inlineobject
->
width
=
get_cluster_range_width
(
layout
,
first_cluster
,
first_cluster
+
cluster_count
);
/* It's not clear how these two are set, possibly directionality
/* It's not clear how these two are set, possibly directionality
is derived from surrounding text (replaced text could have
is derived from surrounding text (replaced text could have
different ranges which differ in reading direction). */
different ranges which differ in reading direction). */
...
@@ -969,6 +977,8 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
...
@@ -969,6 +977,8 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
run
->
length
=
length
;
run
->
length
=
length
;
run
->
origin_x
=
origin_x
;
run
->
origin_x
=
origin_x
;
run
->
origin_y
=
0
.
0
;
/* set after line is built */
run
->
origin_y
=
0
.
0
;
/* set after line is built */
run
->
align_dx
=
0
.
0
;
run
->
width
=
get_cluster_range_width
(
layout
,
first_cluster
,
first_cluster
+
cluster_count
);
run
->
line
=
line
;
run
->
line
=
line
;
if
(
r
->
u
.
regular
.
run
.
glyphCount
)
{
if
(
r
->
u
.
regular
.
run
.
glyphCount
)
{
...
@@ -1083,6 +1093,95 @@ static inline struct layout_effective_inline *layout_get_next_inline_run(struct
...
@@ -1083,6 +1093,95 @@ static inline struct layout_effective_inline *layout_get_next_inline_run(struct
return
LIST_ENTRY
(
e
,
struct
layout_effective_inline
,
entry
);
return
LIST_ENTRY
(
e
,
struct
layout_effective_inline
,
entry
);
}
}
static
FLOAT
layout_get_line_width
(
struct
dwrite_textlayout
*
layout
,
struct
layout_effective_run
*
erun
,
struct
layout_effective_inline
*
inrun
,
UINT32
line
)
{
FLOAT
width
=
0
.
0
;
while
(
erun
&&
erun
->
line
==
line
)
{
width
+=
erun
->
width
;
erun
=
layout_get_next_erun
(
layout
,
erun
);
if
(
!
erun
)
break
;
}
while
(
inrun
&&
inrun
->
line
==
line
)
{
width
+=
inrun
->
width
;
inrun
=
layout_get_next_inline_run
(
layout
,
inrun
);
if
(
!
inrun
)
break
;
}
return
width
;
}
static
void
layout_apply_leading_alignment
(
struct
dwrite_textlayout
*
layout
)
{
struct
layout_effective_inline
*
inrun
;
struct
layout_effective_run
*
erun
;
erun
=
layout_get_next_erun
(
layout
,
NULL
);
inrun
=
layout_get_next_inline_run
(
layout
,
NULL
);
while
(
erun
)
{
erun
->
align_dx
=
0
.
0
;
erun
=
layout_get_next_erun
(
layout
,
erun
);
}
while
(
inrun
)
{
inrun
->
align_dx
=
0
.
0
;
inrun
=
layout_get_next_inline_run
(
layout
,
inrun
);
}
layout
->
metrics
.
left
=
0
;
}
static
void
layout_apply_trailing_alignment
(
struct
dwrite_textlayout
*
layout
)
{
struct
layout_effective_inline
*
inrun
;
struct
layout_effective_run
*
erun
;
UINT32
line
;
erun
=
layout_get_next_erun
(
layout
,
NULL
);
inrun
=
layout_get_next_inline_run
(
layout
,
NULL
);
for
(
line
=
0
;
line
<
layout
->
metrics
.
lineCount
;
line
++
)
{
FLOAT
width
=
layout_get_line_width
(
layout
,
erun
,
inrun
,
line
);
FLOAT
shift
=
layout
->
metrics
.
layoutWidth
-
width
;
while
(
erun
&&
erun
->
line
==
line
)
{
erun
->
align_dx
=
shift
;
erun
=
layout_get_next_erun
(
layout
,
erun
);
}
while
(
inrun
&&
inrun
->
line
==
line
)
{
erun
->
align_dx
=
shift
;
inrun
=
layout_get_next_inline_run
(
layout
,
inrun
);
}
}
layout
->
metrics
.
left
=
layout
->
metrics
.
layoutWidth
-
layout
->
metrics
.
width
;
}
static
void
layout_apply_text_alignment
(
struct
dwrite_textlayout
*
layout
)
{
switch
(
layout
->
format
.
textalignment
)
{
case
DWRITE_TEXT_ALIGNMENT_LEADING
:
layout_apply_leading_alignment
(
layout
);
break
;
case
DWRITE_TEXT_ALIGNMENT_TRAILING
:
layout_apply_trailing_alignment
(
layout
);
break
;
case
DWRITE_TEXT_ALIGNMENT_JUSTIFIED
:
case
DWRITE_TEXT_ALIGNMENT_CENTER
:
FIXME
(
"alignment %d not implemented
\n
"
,
layout
->
format
.
textalignment
);
break
;
default:
;
}
}
static
HRESULT
layout_compute_effective_runs
(
struct
dwrite_textlayout
*
layout
)
static
HRESULT
layout_compute_effective_runs
(
struct
dwrite_textlayout
*
layout
)
{
{
struct
layout_effective_inline
*
inrun
;
struct
layout_effective_inline
*
inrun
;
...
@@ -1251,6 +1350,10 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
...
@@ -1251,6 +1350,10 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
layout
->
metrics
.
height
+=
layout
->
lines
[
line
].
height
;
layout
->
metrics
.
height
+=
layout
->
lines
[
line
].
height
;
}
}
/* initial alignment is always leading */
if
(
layout
->
format
.
textalignment
!=
DWRITE_TEXT_ALIGNMENT_LEADING
)
layout_apply_text_alignment
(
layout
);
layout
->
metrics
.
heightIncludingTrailingWhitespace
=
layout
->
metrics
.
height
;
/* FIXME: not true for vertical text */
layout
->
metrics
.
heightIncludingTrailingWhitespace
=
layout
->
metrics
.
height
;
/* FIXME: not true for vertical text */
layout
->
recompute
&=
~
RECOMPUTE_EFFECTIVE_RUNS
;
layout
->
recompute
&=
~
RECOMPUTE_EFFECTIVE_RUNS
;
...
@@ -2555,7 +2658,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
...
@@ -2555,7 +2658,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
/* return value is ignored */
/* return value is ignored */
IDWriteTextRenderer_DrawGlyphRun
(
renderer
,
IDWriteTextRenderer_DrawGlyphRun
(
renderer
,
context
,
context
,
run
->
origin_x
+
origin_x
,
run
->
origin_x
+
run
->
align_dx
+
origin_x
,
run
->
origin_y
+
origin_y
,
run
->
origin_y
+
origin_y
,
DWRITE_MEASURING_MODE_NATURAL
,
DWRITE_MEASURING_MODE_NATURAL
,
&
glyph_run
,
&
glyph_run
,
...
@@ -2567,8 +2670,8 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
...
@@ -2567,8 +2670,8 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
LIST_FOR_EACH_ENTRY
(
inlineobject
,
&
This
->
inlineobjects
,
struct
layout_effective_inline
,
entry
)
{
LIST_FOR_EACH_ENTRY
(
inlineobject
,
&
This
->
inlineobjects
,
struct
layout_effective_inline
,
entry
)
{
IDWriteTextRenderer_DrawInlineObject
(
renderer
,
IDWriteTextRenderer_DrawInlineObject
(
renderer
,
context
,
context
,
inlineobject
->
origin_x
,
inlineobject
->
origin_x
+
inlineobject
->
align_dx
+
origin_x
,
inlineobject
->
origin_y
,
inlineobject
->
origin_y
+
origin_y
,
inlineobject
->
object
,
inlineobject
->
object
,
inlineobject
->
is_sideways
,
inlineobject
->
is_sideways
,
inlineobject
->
is_rtl
,
inlineobject
->
is_rtl
,
...
@@ -2978,8 +3081,20 @@ static ULONG WINAPI dwritetextformat1_layout_Release(IDWriteTextFormat1 *iface)
...
@@ -2978,8 +3081,20 @@ static ULONG WINAPI dwritetextformat1_layout_Release(IDWriteTextFormat1 *iface)
static
HRESULT
WINAPI
dwritetextformat1_layout_SetTextAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_TEXT_ALIGNMENT
alignment
)
static
HRESULT
WINAPI
dwritetextformat1_layout_SetTextAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_TEXT_ALIGNMENT
alignment
)
{
{
struct
dwrite_textlayout
*
This
=
impl_layout_form_IDWriteTextFormat1
(
iface
);
struct
dwrite_textlayout
*
This
=
impl_layout_form_IDWriteTextFormat1
(
iface
);
BOOL
changed
;
HRESULT
hr
;
TRACE
(
"(%p)->(%d)
\n
"
,
This
,
alignment
);
TRACE
(
"(%p)->(%d)
\n
"
,
This
,
alignment
);
return
format_set_textalignment
(
&
This
->
format
,
alignment
);
hr
=
format_set_textalignment
(
&
This
->
format
,
alignment
,
&
changed
);
if
(
FAILED
(
hr
))
return
hr
;
/* if layout is not ready there's nothing to align */
if
(
changed
&&
!
(
This
->
recompute
&
RECOMPUTE_EFFECTIVE_RUNS
))
layout_apply_text_alignment
(
This
);
return
S_OK
;
}
}
static
HRESULT
WINAPI
dwritetextformat1_layout_SetParagraphAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_PARAGRAPH_ALIGNMENT
alignment
)
static
HRESULT
WINAPI
dwritetextformat1_layout_SetParagraphAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_PARAGRAPH_ALIGNMENT
alignment
)
...
@@ -3853,7 +3968,7 @@ static HRESULT WINAPI dwritetextformat_SetTextAlignment(IDWriteTextFormat1 *ifac
...
@@ -3853,7 +3968,7 @@ static HRESULT WINAPI dwritetextformat_SetTextAlignment(IDWriteTextFormat1 *ifac
{
{
struct
dwrite_textformat
*
This
=
impl_from_IDWriteTextFormat1
(
iface
);
struct
dwrite_textformat
*
This
=
impl_from_IDWriteTextFormat1
(
iface
);
TRACE
(
"(%p)->(%d)
\n
"
,
This
,
alignment
);
TRACE
(
"(%p)->(%d)
\n
"
,
This
,
alignment
);
return
format_set_textalignment
(
&
This
->
format
,
alignment
);
return
format_set_textalignment
(
&
This
->
format
,
alignment
,
NULL
);
}
}
static
HRESULT
WINAPI
dwritetextformat_SetParagraphAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_PARAGRAPH_ALIGNMENT
alignment
)
static
HRESULT
WINAPI
dwritetextformat_SetParagraphAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_PARAGRAPH_ALIGNMENT
alignment
)
...
...
dlls/dwrite/tests/layout.c
View file @
44c135dd
...
@@ -2865,12 +2865,15 @@ todo_wine {
...
@@ -2865,12 +2865,15 @@ todo_wine {
static
void
test_SetTextAlignment
(
void
)
static
void
test_SetTextAlignment
(
void
)
{
{
static
const
WCHAR
strW
[]
=
{
'a'
,
'b'
,
'c'
,
'd'
,
0
};
static
const
WCHAR
strW
[]
=
{
'a'
,
0
};
DWRITE_CLUSTER_METRICS
clusters
[
1
];
DWRITE_TEXT_METRICS
metrics
;
IDWriteTextFormat1
*
format1
;
IDWriteTextFormat1
*
format1
;
IDWriteTextFormat
*
format
;
IDWriteTextFormat
*
format
;
IDWriteTextLayout
*
layout
;
IDWriteTextLayout
*
layout
;
IDWriteFactory
*
factory
;
IDWriteFactory
*
factory
;
DWRITE_TEXT_ALIGNMENT
v
;
DWRITE_TEXT_ALIGNMENT
v
;
UINT32
count
;
HRESULT
hr
;
HRESULT
hr
;
factory
=
create_factory
();
factory
=
create_factory
();
...
@@ -2882,7 +2885,7 @@ static void test_SetTextAlignment(void)
...
@@ -2882,7 +2885,7 @@ static void test_SetTextAlignment(void)
v
=
IDWriteTextFormat_GetTextAlignment
(
format
);
v
=
IDWriteTextFormat_GetTextAlignment
(
format
);
ok
(
v
==
DWRITE_TEXT_ALIGNMENT_LEADING
,
"got %d
\n
"
,
v
);
ok
(
v
==
DWRITE_TEXT_ALIGNMENT_LEADING
,
"got %d
\n
"
,
v
);
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
strW
,
4
,
format
,
3
00
.
0
,
100
.
0
,
&
layout
);
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
strW
,
1
,
format
,
5
00
.
0
,
100
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
v
=
IDWriteTextLayout_GetTextAlignment
(
layout
);
v
=
IDWriteTextLayout_GetTextAlignment
(
layout
);
...
@@ -2891,6 +2894,9 @@ static void test_SetTextAlignment(void)
...
@@ -2891,6 +2894,9 @@ static void test_SetTextAlignment(void)
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_TRAILING
);
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_TRAILING
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_TRAILING
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
v
=
IDWriteTextFormat_GetTextAlignment
(
format
);
v
=
IDWriteTextFormat_GetTextAlignment
(
format
);
ok
(
v
==
DWRITE_TEXT_ALIGNMENT_LEADING
,
"got %d
\n
"
,
v
);
ok
(
v
==
DWRITE_TEXT_ALIGNMENT_LEADING
,
"got %d
\n
"
,
v
);
...
@@ -2916,8 +2922,52 @@ static void test_SetTextAlignment(void)
...
@@ -2916,8 +2922,52 @@ static void test_SetTextAlignment(void)
else
else
win_skip
(
"IDWriteTextFormat1 is not supported
\n
"
);
win_skip
(
"IDWriteTextFormat1 is not supported
\n
"
);
count
=
0
;
hr
=
IDWriteTextLayout_GetClusterMetrics
(
layout
,
clusters
,
1
,
&
count
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
count
==
1
,
"got %u
\n
"
,
count
);
/* maxwidth is 500, leading alignment */
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_LEADING
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_GetMetrics
(
layout
,
&
metrics
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
metrics
.
left
==
0
.
0
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
clusters
[
0
].
width
,
"got %.2f
\n
"
,
metrics
.
width
);
ok
(
metrics
.
layoutWidth
==
500
.
0
,
"got %.2f
\n
"
,
metrics
.
layoutWidth
);
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
/* maxwidth is 500, trailing alignment */
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_TRAILING
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_GetMetrics
(
layout
,
&
metrics
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
metrics
.
left
==
metrics
.
layoutWidth
-
metrics
.
width
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
clusters
[
0
].
width
,
"got %.2f
\n
"
,
metrics
.
width
);
ok
(
metrics
.
layoutWidth
==
500
.
0
,
"got %.2f
\n
"
,
metrics
.
layoutWidth
);
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
IDWriteTextLayout_Release
(
layout
);
/* initially created with trailing alignment */
hr
=
IDWriteTextFormat_SetTextAlignment
(
format
,
DWRITE_TEXT_ALIGNMENT_TRAILING
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
strW
,
1
,
format
,
500
.
0
,
100
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_GetMetrics
(
layout
,
&
metrics
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
metrics
.
left
==
metrics
.
layoutWidth
-
metrics
.
width
,
"got %.2f
\n
"
,
metrics
.
left
);
ok
(
metrics
.
width
==
clusters
[
0
].
width
,
"got %.2f
\n
"
,
metrics
.
width
);
ok
(
metrics
.
layoutWidth
==
500
.
0
,
"got %.2f
\n
"
,
metrics
.
layoutWidth
);
ok
(
metrics
.
lineCount
==
1
,
"got %d
\n
"
,
metrics
.
lineCount
);
IDWriteTextLayout_Release
(
layout
);
IDWriteTextLayout_Release
(
layout
);
IDWriteTextFormat_Release
(
format
);
IDWriteTextFormat_Release
(
format
);
IDWriteFactory_Release
(
factory
);
IDWriteFactory_Release
(
factory
);
}
}
...
...
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