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 {
UINT32
glyphcount
;
/* total glyph count in this run */
FLOAT
origin_x
;
/* baseline X 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 */
UINT32
line
;
};
...
...
@@ -190,6 +192,8 @@ struct layout_effective_inline {
IUnknown
*
effect
;
FLOAT
origin_x
;
FLOAT
origin_y
;
FLOAT
align_dx
;
FLOAT
width
;
BOOL
is_sideways
;
BOOL
is_rtl
;
UINT32
line
;
...
...
@@ -328,10 +332,12 @@ static inline const char *debugstr_run(const struct regular_layout_run *run)
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
)
return
E_INVALIDARG
;
if
(
changed
)
*
changed
=
format
->
textalignment
!=
alignment
;
format
->
textalignment
=
alignment
;
return
S_OK
;
}
...
...
@@ -934,6 +940,8 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
inlineobject
->
object
=
r
->
u
.
object
.
object
;
inlineobject
->
origin_x
=
origin_x
;
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
is derived from surrounding text (replaced text could have
different ranges which differ in reading direction). */
...
...
@@ -969,6 +977,8 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
run
->
length
=
length
;
run
->
origin_x
=
origin_x
;
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
;
if
(
r
->
u
.
regular
.
run
.
glyphCount
)
{
...
...
@@ -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
);
}
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
)
{
struct
layout_effective_inline
*
inrun
;
...
...
@@ -1251,6 +1350,10 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
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
->
recompute
&=
~
RECOMPUTE_EFFECTIVE_RUNS
;
...
...
@@ -2555,7 +2658,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
/* return value is ignored */
IDWriteTextRenderer_DrawGlyphRun
(
renderer
,
context
,
run
->
origin_x
+
origin_x
,
run
->
origin_x
+
run
->
align_dx
+
origin_x
,
run
->
origin_y
+
origin_y
,
DWRITE_MEASURING_MODE_NATURAL
,
&
glyph_run
,
...
...
@@ -2567,8 +2670,8 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
LIST_FOR_EACH_ENTRY
(
inlineobject
,
&
This
->
inlineobjects
,
struct
layout_effective_inline
,
entry
)
{
IDWriteTextRenderer_DrawInlineObject
(
renderer
,
context
,
inlineobject
->
origin_x
,
inlineobject
->
origin_y
,
inlineobject
->
origin_x
+
inlineobject
->
align_dx
+
origin_x
,
inlineobject
->
origin_y
+
origin_y
,
inlineobject
->
object
,
inlineobject
->
is_sideways
,
inlineobject
->
is_rtl
,
...
...
@@ -2978,8 +3081,20 @@ static ULONG WINAPI dwritetextformat1_layout_Release(IDWriteTextFormat1 *iface)
static
HRESULT
WINAPI
dwritetextformat1_layout_SetTextAlignment
(
IDWriteTextFormat1
*
iface
,
DWRITE_TEXT_ALIGNMENT
alignment
)
{
struct
dwrite_textlayout
*
This
=
impl_layout_form_IDWriteTextFormat1
(
iface
);
BOOL
changed
;
HRESULT
hr
;
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
)
...
...
@@ -3853,7 +3968,7 @@ static HRESULT WINAPI dwritetextformat_SetTextAlignment(IDWriteTextFormat1 *ifac
{
struct
dwrite_textformat
*
This
=
impl_from_IDWriteTextFormat1
(
iface
);
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
)
...
...
dlls/dwrite/tests/layout.c
View file @
44c135dd
...
...
@@ -2865,12 +2865,15 @@ todo_wine {
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
;
IDWriteTextFormat
*
format
;
IDWriteTextLayout
*
layout
;
IDWriteFactory
*
factory
;
DWRITE_TEXT_ALIGNMENT
v
;
UINT32
count
;
HRESULT
hr
;
factory
=
create_factory
();
...
...
@@ -2882,7 +2885,7 @@ static void test_SetTextAlignment(void)
v
=
IDWriteTextFormat_GetTextAlignment
(
format
);
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
);
v
=
IDWriteTextLayout_GetTextAlignment
(
layout
);
...
...
@@ -2891,6 +2894,9 @@ static void test_SetTextAlignment(void)
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_TRAILING
);
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
);
ok
(
v
==
DWRITE_TEXT_ALIGNMENT_LEADING
,
"got %d
\n
"
,
v
);
...
...
@@ -2916,8 +2922,52 @@ static void test_SetTextAlignment(void)
else
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
);
IDWriteTextFormat_Release
(
format
);
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