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
b7fb00e9
Commit
b7fb00e9
authored
Jun 15, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jun 15, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Fix the way drawing effects are reported for inline objects.
parent
6655b0c9
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
320 additions
and
53 deletions
+320
-53
layout.c
dlls/dwrite/layout.c
+98
-38
layout.c
dlls/dwrite/tests/layout.c
+222
-15
No files found.
dlls/dwrite/layout.c
View file @
b7fb00e9
...
...
@@ -95,7 +95,8 @@ struct layout_range_attr_value {
enum
layout_range_kind
{
LAYOUT_RANGE_REGULAR
,
LAYOUT_RANGE_STRIKETHROUGH
LAYOUT_RANGE_STRIKETHROUGH
,
LAYOUT_RANGE_EFFECT
};
struct
layout_range_header
{
...
...
@@ -111,7 +112,6 @@ struct layout_range {
FLOAT
fontsize
;
DWRITE_FONT_STRETCH
stretch
;
IDWriteInlineObject
*
object
;
IUnknown
*
effect
;
BOOL
underline
;
BOOL
pair_kerning
;
IDWriteFontCollection
*
collection
;
...
...
@@ -124,6 +124,11 @@ struct layout_range_bool {
BOOL
value
;
};
struct
layout_range_effect
{
struct
layout_range_header
h
;
IUnknown
*
effect
;
};
enum
layout_run_kind
{
LAYOUT_RUN_REGULAR
,
LAYOUT_RUN_INLINE
...
...
@@ -153,7 +158,6 @@ struct layout_run {
struct
inline_object_run
object
;
struct
regular_layout_run
regular
;
}
u
;
IUnknown
*
effect
;
};
struct
layout_effective_run
{
...
...
@@ -170,6 +174,7 @@ struct layout_effective_run {
struct
layout_effective_inline
{
struct
list
entry
;
IDWriteInlineObject
*
object
;
IUnknown
*
effect
;
FLOAT
origin_x
;
FLOAT
origin_y
;
BOOL
is_sideways
;
...
...
@@ -207,6 +212,7 @@ struct dwrite_textlayout {
FLOAT
maxwidth
;
FLOAT
maxheight
;
struct
list
strike_ranges
;
struct
list
effects
;
struct
list
ranges
;
struct
list
runs
;
/* lists ready to use by Draw() */
...
...
@@ -601,7 +607,6 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
r
->
u
.
object
.
object
=
range
->
object
;
r
->
u
.
object
.
length
=
get_clipped_range_length
(
layout
,
range
);
r
->
effect
=
range
->
effect
;
list_add_tail
(
&
layout
->
runs
,
&
r
->
entry
);
continue
;
}
...
...
@@ -661,7 +666,6 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
}
range
=
get_layout_range_by_pos
(
layout
,
run
->
descr
.
textPosition
);
r
->
effect
=
range
->
effect
;
hr
=
IDWriteFontCollection_FindFamilyName
(
range
->
collection
,
range
->
fontfamily
,
&
index
,
&
exists
);
if
(
FAILED
(
hr
)
||
!
exists
)
{
...
...
@@ -844,6 +848,25 @@ 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
);
return
((
struct
layout_range_effect
*
)
h
)
->
effect
;
}
/* Effective run is built from consecutive clusters of a single nominal run, 'first_cluster' is 0 based cluster index,
'cluster_count' indicates how many clusters to add, including first one. */
static
HRESULT
layout_add_effective_run
(
struct
dwrite_textlayout
*
layout
,
const
struct
layout_run
*
r
,
UINT32
first_cluster
,
...
...
@@ -867,6 +890,10 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
different ranges which differ in reading direction). */
inlineobject
->
is_sideways
=
FALSE
;
inlineobject
->
is_rtl
=
FALSE
;
/* effect assigned from start position and on is used for inline objects */
inlineobject
->
effect
=
layout_get_effect_from_pos
(
layout
,
layout
->
clusters
[
first_cluster
].
position
);
list_add_tail
(
&
layout
->
inlineobjects
,
&
inlineobject
->
entry
);
return
S_OK
;
}
...
...
@@ -970,19 +997,6 @@ static HRESULT layout_set_line_metrics(struct dwrite_textlayout *layout, DWRITE_
return
S_OK
;
}
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
BOOL
layout_get_strikethrough_from_pos
(
struct
dwrite_textlayout
*
layout
,
UINT32
pos
)
{
struct
layout_range_header
*
h
=
get_layout_range_header_by_pos
(
&
layout
->
strike_ranges
,
pos
);
...
...
@@ -1090,6 +1104,7 @@ static HRESULT layout_compute_effective_runs(struct dwrite_textlayout *layout)
static
BOOL
is_same_layout_attrvalue
(
struct
layout_range_header
const
*
h
,
enum
layout_range_attr_kind
attr
,
struct
layout_range_attr_value
*
value
)
{
struct
layout_range_effect
const
*
range_effect
=
(
struct
layout_range_effect
*
)
h
;
struct
layout_range_bool
const
*
range_bool
=
(
struct
layout_range_bool
*
)
h
;
struct
layout_range
const
*
range
=
(
struct
layout_range
*
)
h
;
...
...
@@ -1105,7 +1120,7 @@ static BOOL is_same_layout_attrvalue(struct layout_range_header const *h, enum l
case
LAYOUT_RANGE_ATTR_INLINE
:
return
range
->
object
==
value
->
u
.
object
;
case
LAYOUT_RANGE_ATTR_EFFECT
:
return
range
->
effect
==
value
->
u
.
effect
;
return
range
_effect
->
effect
==
value
->
u
.
effect
;
case
LAYOUT_RANGE_ATTR_UNDERLINE
:
return
range
->
underline
==
value
->
u
.
underline
;
case
LAYOUT_RANGE_ATTR_STRIKETHROUGH
:
...
...
@@ -1138,7 +1153,6 @@ static inline BOOL is_same_layout_attributes(struct layout_range_header const *h
left
->
stretch
==
right
->
stretch
&&
left
->
fontsize
==
right
->
fontsize
&&
left
->
object
==
right
->
object
&&
left
->
effect
==
right
->
effect
&&
left
->
underline
==
right
->
underline
&&
left
->
pair_kerning
==
right
->
pair_kerning
&&
left
->
collection
==
right
->
collection
&&
...
...
@@ -1151,6 +1165,12 @@ static inline BOOL is_same_layout_attributes(struct layout_range_header const *h
struct
layout_range_bool
const
*
right
=
(
struct
layout_range_bool
const
*
)
hright
;
return
left
->
value
==
right
->
value
;
}
case
LAYOUT_RANGE_EFFECT
:
{
struct
layout_range_effect
const
*
left
=
(
struct
layout_range_effect
const
*
)
hleft
;
struct
layout_range_effect
const
*
right
=
(
struct
layout_range_effect
const
*
)
hright
;
return
left
->
effect
==
right
->
effect
;
}
default:
FIXME
(
"unknown range kind %d
\n
"
,
hleft
->
kind
);
return
FALSE
;
...
...
@@ -1182,7 +1202,6 @@ static struct layout_range_header *alloc_layout_range(struct dwrite_textlayout *
range
->
stretch
=
layout
->
format
.
stretch
;
range
->
fontsize
=
layout
->
format
.
fontsize
;
range
->
object
=
NULL
;
range
->
effect
=
NULL
;
range
->
underline
=
FALSE
;
range
->
pair_kerning
=
FALSE
;
...
...
@@ -1211,6 +1230,17 @@ static struct layout_range_header *alloc_layout_range(struct dwrite_textlayout *
h
=
&
range
->
h
;
break
;
}
case
LAYOUT_RANGE_EFFECT
:
{
struct
layout_range_effect
*
range
;
range
=
heap_alloc
(
sizeof
(
*
range
));
if
(
!
range
)
return
NULL
;
range
->
effect
=
NULL
;
h
=
&
range
->
h
;
break
;
}
default:
FIXME
(
"unknown range kind %d
\n
"
,
kind
);
return
NULL
;
...
...
@@ -1244,8 +1274,6 @@ static struct layout_range_header *alloc_layout_range_from(struct layout_range_h
/* update refcounts */
if
(
range
->
object
)
IDWriteInlineObject_AddRef
(
range
->
object
);
if
(
range
->
effect
)
IUnknown_AddRef
(
range
->
effect
);
if
(
range
->
collection
)
IDWriteFontCollection_AddRef
(
range
->
collection
);
ret
=
&
range
->
h
;
...
...
@@ -1260,6 +1288,17 @@ static struct layout_range_header *alloc_layout_range_from(struct layout_range_h
ret
=
&
strike
->
h
;
break
;
}
case
LAYOUT_RANGE_EFFECT
:
{
struct
layout_range_effect
*
effect
=
heap_alloc
(
sizeof
(
*
effect
));
if
(
!
effect
)
return
NULL
;
*
effect
=
*
(
struct
layout_range_effect
*
)
h
;
if
(
effect
->
effect
)
IUnknown_AddRef
(
effect
->
effect
);
ret
=
&
effect
->
h
;
break
;
}
default:
FIXME
(
"unknown range kind %d
\n
"
,
h
->
kind
);
return
NULL
;
...
...
@@ -1274,16 +1313,28 @@ static void free_layout_range(struct layout_range_header *h)
if
(
!
h
)
return
;
if
(
h
->
kind
==
LAYOUT_RANGE_REGULAR
)
{
switch
(
h
->
kind
)
{
case
LAYOUT_RANGE_REGULAR
:
{
struct
layout_range
*
range
=
(
struct
layout_range
*
)
h
;
if
(
range
->
object
)
IDWriteInlineObject_Release
(
range
->
object
);
if
(
range
->
effect
)
IUnknown_Release
(
range
->
effect
);
if
(
range
->
collection
)
IDWriteFontCollection_Release
(
range
->
collection
);
heap_free
(
range
->
fontfamily
);
break
;
}
case
LAYOUT_RANGE_EFFECT
:
{
struct
layout_range_effect
*
effect
=
(
struct
layout_range_effect
*
)
h
;
if
(
effect
->
effect
)
IUnknown_Release
(
effect
->
effect
);
break
;
}
default:
;
}
heap_free
(
h
);
...
...
@@ -1302,6 +1353,11 @@ static void free_layout_ranges_list(struct dwrite_textlayout *layout)
list_remove
(
&
cur
->
entry
);
free_layout_range
(
cur
);
}
LIST_FOR_EACH_ENTRY_SAFE
(
cur
,
cur2
,
&
layout
->
effects
,
struct
layout_range_header
,
entry
)
{
list_remove
(
&
cur
->
entry
);
free_layout_range
(
cur
);
}
}
static
struct
layout_range_header
*
find_outer_range
(
struct
list
*
ranges
,
const
DWRITE_TEXT_RANGE
*
range
)
...
...
@@ -1351,6 +1407,7 @@ static inline BOOL set_layout_range_iface_attr(IUnknown **dest, IUnknown *value)
static
BOOL
set_layout_range_attrval
(
struct
layout_range_header
*
h
,
enum
layout_range_attr_kind
attr
,
struct
layout_range_attr_value
*
value
)
{
struct
layout_range_effect
*
dest_effect
=
(
struct
layout_range_effect
*
)
h
;
struct
layout_range_bool
*
dest_bool
=
(
struct
layout_range_bool
*
)
h
;
struct
layout_range
*
dest
=
(
struct
layout_range
*
)
h
;
...
...
@@ -1377,7 +1434,7 @@ static BOOL set_layout_range_attrval(struct layout_range_header *h, enum layout_
changed
=
set_layout_range_iface_attr
((
IUnknown
**
)
&
dest
->
object
,
(
IUnknown
*
)
value
->
u
.
object
);
break
;
case
LAYOUT_RANGE_ATTR_EFFECT
:
changed
=
set_layout_range_iface_attr
((
IUnknown
**
)
&
dest
->
effect
,
(
IUnknown
*
)
value
->
u
.
effect
);
changed
=
set_layout_range_iface_attr
((
IUnknown
**
)
&
dest
_effect
->
effect
,
(
IUnknown
*
)
value
->
u
.
effect
);
break
;
case
LAYOUT_RANGE_ATTR_UNDERLINE
:
changed
=
dest
->
underline
!=
value
->
u
.
underline
;
...
...
@@ -1444,7 +1501,6 @@ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layo
case
LAYOUT_RANGE_ATTR_STYLE
:
case
LAYOUT_RANGE_ATTR_STRETCH
:
case
LAYOUT_RANGE_ATTR_FONTSIZE
:
case
LAYOUT_RANGE_ATTR_EFFECT
:
case
LAYOUT_RANGE_ATTR_INLINE
:
case
LAYOUT_RANGE_ATTR_UNDERLINE
:
case
LAYOUT_RANGE_ATTR_PAIR_KERNING
:
...
...
@@ -1456,6 +1512,9 @@ static HRESULT set_layout_range_attr(struct dwrite_textlayout *layout, enum layo
case
LAYOUT_RANGE_ATTR_STRIKETHROUGH
:
ranges
=
&
layout
->
strike_ranges
;
break
;
case
LAYOUT_RANGE_ATTR_EFFECT
:
ranges
=
&
layout
->
effects
;
break
;
default:
FIXME
(
"unknown attr kind %d
\n
"
,
attr
);
return
E_FAIL
;
...
...
@@ -2191,14 +2250,11 @@ static HRESULT WINAPI dwritetextlayout_GetDrawingEffect(IDWriteTextLayout2 *ifac
UINT32
position
,
IUnknown
**
effect
,
DWRITE_TEXT_RANGE
*
r
)
{
struct
dwrite_textlayout
*
This
=
impl_from_IDWriteTextLayout2
(
iface
);
struct
layout_range
*
range
;
struct
layout_range
_effect
*
range
;
TRACE
(
"(%p)->(%u %p %p)
\n
"
,
This
,
position
,
effect
,
r
);
if
(
position
>=
This
->
len
)
return
S_OK
;
range
=
get_layout_range_by_pos
(
This
,
position
);
range
=
(
struct
layout_range_effect
*
)
get_layout_range_header_by_pos
(
&
This
->
effects
,
position
);
*
effect
=
range
->
effect
;
if
(
*
effect
)
IUnknown_AddRef
(
*
effect
);
...
...
@@ -2297,7 +2353,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
DWRITE_MEASURING_MODE_NATURAL
,
&
glyph_run
,
&
descr
,
run
->
run
->
effect
);
NULL
);
}
/* 2. Inline objects */
...
...
@@ -2309,7 +2365,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
inlineobject
->
object
,
inlineobject
->
is_sideways
,
inlineobject
->
is_rtl
,
run
->
run
->
effect
);
inlineobject
->
effect
);
}
/* TODO: 3. Underlines */
...
...
@@ -2321,7 +2377,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
s
->
run
->
origin_x
,
s
->
run
->
origin_y
,
&
s
->
s
,
s
->
run
->
run
->
effect
);
NULL
);
}
return
S_OK
;
...
...
@@ -3254,7 +3310,7 @@ static HRESULT layout_format_from_textformat(struct dwrite_textlayout *layout, I
static
HRESULT
init_textlayout
(
const
WCHAR
*
str
,
UINT32
len
,
IDWriteTextFormat
*
format
,
FLOAT
maxwidth
,
FLOAT
maxheight
,
struct
dwrite_textlayout
*
layout
)
{
struct
layout_range_header
*
range
,
*
strike
;
struct
layout_range_header
*
range
,
*
strike
,
*
effect
;
DWRITE_TEXT_RANGE
r
=
{
0
,
~
0u
};
HRESULT
hr
;
...
...
@@ -3282,6 +3338,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
list_init
(
&
layout
->
runs
);
list_init
(
&
layout
->
ranges
);
list_init
(
&
layout
->
strike_ranges
);
list_init
(
&
layout
->
effects
);
memset
(
&
layout
->
format
,
0
,
sizeof
(
layout
->
format
));
layout
->
gdicompatible
=
FALSE
;
...
...
@@ -3301,15 +3358,18 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
range
=
alloc_layout_range
(
layout
,
&
r
,
LAYOUT_RANGE_REGULAR
);
strike
=
alloc_layout_range
(
layout
,
&
r
,
LAYOUT_RANGE_STRIKETHROUGH
);
if
(
!
range
||
!
strike
)
{
effect
=
alloc_layout_range
(
layout
,
&
r
,
LAYOUT_RANGE_EFFECT
);
if
(
!
range
||
!
strike
||
!
effect
)
{
free_layout_range
(
range
);
free_layout_range
(
strike
);
free_layout_range
(
effect
);
hr
=
E_OUTOFMEMORY
;
goto
fail
;
}
list_add_head
(
&
layout
->
ranges
,
&
range
->
entry
);
list_add_head
(
&
layout
->
strike_ranges
,
&
strike
->
entry
);
list_add_head
(
&
layout
->
effects
,
&
effect
->
entry
);
return
S_OK
;
fail:
...
...
dlls/dwrite/tests/layout.c
View file @
b7fb00e9
...
...
@@ -215,18 +215,39 @@ static void _expect_ref(IUnknown* obj, ULONG ref, int line)
ok_
(
__FILE__
,
line
)(
rc
-
1
==
ref
,
"expected refcount %d, got %d
\n
"
,
ref
,
rc
-
1
);
}
enum
drawcall_modifiers_kind
{
DRAW_EFFECT
=
0x1000
};
enum
drawcall_kind
{
DRAW_GLYPHRUN
=
0
,
DRAW_UNDERLINE
,
DRAW_STRIKETHROUGH
,
DRAW_INLINE
,
DRAW_LAST_KIND
DRAW_GLYPHRUN
=
0
,
DRAW_UNDERLINE
=
1
,
DRAW_STRIKETHROUGH
=
2
,
DRAW_INLINE
=
3
,
DRAW_LAST_KIND
=
4
,
DRAW_TOTAL_KINDS
=
5
,
DRAW_KINDS_MASK
=
0xff
};
static
const
char
*
get_draw_kind_name
(
enum
drawcall_kind
kind
)
static
const
char
*
get_draw_kind_name
(
unsigned
short
kind
)
{
static
const
char
*
kind_names
[]
=
{
"GLYPH_RUN"
,
"UNDERLINE"
,
"STRIKETHROUGH"
,
"INLINE"
,
"END_OF_SEQ"
};
return
kind
>
DRAW_LAST_KIND
?
"unknown"
:
kind_names
[
kind
];
static
const
char
*
kind_names
[]
=
{
"GLYPH_RUN"
,
"UNDERLINE"
,
"STRIKETHROUGH"
,
"INLINE"
,
"END_OF_SEQ"
,
"GLYPH_RUN|EFFECT"
,
"UNDERLINE|EFFECT"
,
"STRIKETHROUGH|EFFECT"
,
"INLINE|EFFECT"
,
"END_OF_SEQ"
};
if
((
kind
&
DRAW_KINDS_MASK
)
>
DRAW_LAST_KIND
)
return
"unknown"
;
return
(
kind
&
DRAW_EFFECT
)
?
kind_names
[(
kind
&
DRAW_KINDS_MASK
)
+
DRAW_TOTAL_KINDS
]
:
kind_names
[
kind
];
}
struct
drawcall_entry
{
...
...
@@ -242,7 +263,7 @@ struct drawcall_sequence
};
struct
drawtestcontext
{
enum
drawcall_kind
kind
;
unsigned
short
kind
;
BOOL
todo
;
int
*
failcount
;
const
char
*
file
;
...
...
@@ -327,7 +348,7 @@ static void ok_sequence_(struct drawcall_sequence **seq, int sequence_index,
ok_
(
file
,
line
)
(
0
,
"%s: call %s was expected, but got call %s instead
\n
"
,
context
,
get_draw_kind_name
(
expected
->
kind
),
get_draw_kind_name
(
actual
->
kind
));
}
else
if
(
expected
->
kind
==
DRAW_GLYPHRUN
)
{
else
if
(
(
expected
->
kind
&
DRAW_KINDS_MASK
)
==
DRAW_GLYPHRUN
)
{
int
cmp
=
lstrcmpW
(
expected
->
string
,
actual
->
string
);
if
(
cmp
!=
0
&&
todo
)
{
failcount
++
;
...
...
@@ -424,7 +445,7 @@ static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
DWRITE_MEASURING_MODE
mode
,
DWRITE_GLYPH_RUN
const
*
run
,
DWRITE_GLYPH_RUN_DESCRIPTION
const
*
descr
,
IUnknown
*
drawing_
effect
)
IUnknown
*
effect
)
{
struct
drawcall_entry
entry
;
DWRITE_SCRIPT_ANALYSIS
sa
;
...
...
@@ -452,6 +473,8 @@ static HRESULT WINAPI testrenderer_DrawGlyphRun(IDWriteTextRenderer *iface,
}
entry
.
kind
=
DRAW_GLYPHRUN
;
if
(
effect
)
entry
.
kind
|=
DRAW_EFFECT
;
add_call
(
sequences
,
RENDERER_ID
,
&
entry
);
return
S_OK
;
}
...
...
@@ -461,10 +484,12 @@ static HRESULT WINAPI testrenderer_DrawUnderline(IDWriteTextRenderer *iface,
FLOAT
baselineOriginX
,
FLOAT
baselineOriginY
,
DWRITE_UNDERLINE
const
*
underline
,
IUnknown
*
drawing_
effect
)
IUnknown
*
effect
)
{
struct
drawcall_entry
entry
;
entry
.
kind
=
DRAW_UNDERLINE
;
if
(
effect
)
entry
.
kind
|=
DRAW_EFFECT
;
add_call
(
sequences
,
RENDERER_ID
,
&
entry
);
return
S_OK
;
}
...
...
@@ -474,10 +499,12 @@ static HRESULT WINAPI testrenderer_DrawStrikethrough(IDWriteTextRenderer *iface,
FLOAT
baselineOriginX
,
FLOAT
baselineOriginY
,
DWRITE_STRIKETHROUGH
const
*
strikethrough
,
IUnknown
*
drawing_
effect
)
IUnknown
*
effect
)
{
struct
drawcall_entry
entry
;
entry
.
kind
=
DRAW_STRIKETHROUGH
;
if
(
effect
)
entry
.
kind
|=
DRAW_EFFECT
;
add_call
(
sequences
,
RENDERER_ID
,
&
entry
);
return
S_OK
;
}
...
...
@@ -489,10 +516,12 @@ static HRESULT WINAPI testrenderer_DrawInlineObject(IDWriteTextRenderer *iface,
IDWriteInlineObject
*
object
,
BOOL
is_sideways
,
BOOL
is_rtl
,
IUnknown
*
drawing_
effect
)
IUnknown
*
effect
)
{
struct
drawcall_entry
entry
;
entry
.
kind
=
DRAW_INLINE
;
if
(
effect
)
entry
.
kind
|=
DRAW_EFFECT
;
add_call
(
sequences
,
RENDERER_ID
,
&
entry
);
return
S_OK
;
}
...
...
@@ -575,6 +604,36 @@ static IDWriteInlineObjectVtbl testinlineobjvtbl = {
static
IDWriteInlineObject
testinlineobj
=
{
&
testinlineobjvtbl
};
static
IDWriteInlineObject
testinlineobj2
=
{
&
testinlineobjvtbl
};
static
HRESULT
WINAPI
testeffect_QI
(
IUnknown
*
iface
,
REFIID
riid
,
void
**
obj
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
IUnknown_AddRef
(
iface
);
return
S_OK
;
}
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
testeffect_AddRef
(
IUnknown
*
iface
)
{
return
2
;
}
static
ULONG
WINAPI
testeffect_Release
(
IUnknown
*
iface
)
{
return
1
;
}
static
const
IUnknownVtbl
testeffectvtbl
=
{
testeffect_QI
,
testeffect_AddRef
,
testeffect_Release
};
static
IUnknown
testeffect
=
{
&
testeffectvtbl
};
static
void
test_CreateTextLayout
(
void
)
{
static
const
WCHAR
strW
[]
=
{
's'
,
't'
,
'r'
,
'i'
,
'n'
,
'g'
,
0
};
...
...
@@ -1156,7 +1215,7 @@ static void test_SetInlineObject(void)
static
const
struct
drawcall_entry
draw_seq
[]
=
{
{
DRAW_GLYPHRUN
,
{
's'
,
0
}
},
{
DRAW_GLYPHRUN
,
{
'r'
,
'i'
,
0
}
},
{
DRAW_GLYPHRUN
,
{
'n'
,
0
}
},
{
DRAW_GLYPHRUN
|
DRAW_EFFECT
,
{
'n'
,
0
}
},
{
DRAW_GLYPHRUN
,
{
'g'
,
0
}
},
{
DRAW_INLINE
},
{
DRAW_UNDERLINE
},
...
...
@@ -2438,6 +2497,153 @@ static void test_SetFlowDirection(void)
IDWriteFactory_Release
(
factory
);
}
static
const
struct
drawcall_entry
draweffect_seq
[]
=
{
{
DRAW_GLYPHRUN
|
DRAW_EFFECT
,
{
'a'
,
'e'
,
0x0300
,
0
}
},
{
DRAW_GLYPHRUN
,
{
'd'
,
0
}
},
{
DRAW_LAST_KIND
}
};
static
const
struct
drawcall_entry
draweffect2_seq
[]
=
{
{
DRAW_GLYPHRUN
|
DRAW_EFFECT
,
{
'a'
,
'e'
,
0
}
},
{
DRAW_GLYPHRUN
,
{
'c'
,
'd'
,
0
}
},
{
DRAW_LAST_KIND
}
};
static
const
struct
drawcall_entry
draweffect3_seq
[]
=
{
{
DRAW_INLINE
|
DRAW_EFFECT
},
{
DRAW_LAST_KIND
}
};
static
const
struct
drawcall_entry
draweffect4_seq
[]
=
{
{
DRAW_INLINE
},
{
DRAW_LAST_KIND
}
};
static
void
test_SetDrawingEffect
(
void
)
{
static
const
WCHAR
strW
[]
=
{
'a'
,
'e'
,
0x0300
,
'd'
,
0
};
/* accent grave */
static
const
WCHAR
str2W
[]
=
{
'a'
,
'e'
,
'c'
,
'd'
,
0
};
IDWriteInlineObject
*
sign
;
IDWriteTextFormat
*
format
;
IDWriteTextLayout
*
layout
;
IDWriteFactory
*
factory
;
DWRITE_TEXT_RANGE
r
;
IUnknown
*
unk
;
HRESULT
hr
;
factory
=
create_factory
();
hr
=
IDWriteFactory_CreateTextFormat
(
factory
,
tahomaW
,
NULL
,
DWRITE_FONT_WEIGHT_NORMAL
,
DWRITE_FONT_STYLE_NORMAL
,
DWRITE_FONT_STRETCH_NORMAL
,
10
.
0
,
enusW
,
&
format
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
/* string with combining mark */
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
strW
,
4
,
format
,
500
.
0
,
1000
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
/* set effect past the end of text */
r
.
startPosition
=
100
;
r
.
length
=
10
;
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
&
testeffect
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
r
.
startPosition
=
r
.
length
=
0
;
hr
=
IDWriteTextLayout_GetDrawingEffect
(
layout
,
101
,
&
unk
,
&
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
r
.
startPosition
==
100
&&
r
.
length
==
10
,
"got %u, %u
\n
"
,
r
.
startPosition
,
r
.
length
);
r
.
startPosition
=
r
.
length
=
0
;
unk
=
(
void
*
)
0xdeadbeef
;
hr
=
IDWriteTextLayout_GetDrawingEffect
(
layout
,
1000
,
&
unk
,
&
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
r
.
startPosition
==
110
&&
r
.
length
==
~
0u
-
110
,
"got %u, %u
\n
"
,
r
.
startPosition
,
r
.
length
);
ok
(
unk
==
NULL
,
"got %p
\n
"
,
unk
);
/* effect is applied to clusters, not individual text positions */
r
.
startPosition
=
0
;
r
.
length
=
2
;
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
&
testeffect
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
flush_sequence
(
sequences
,
RENDERER_ID
);
hr
=
IDWriteTextLayout_Draw
(
layout
,
NULL
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draweffect_seq
,
"effect draw test"
,
TRUE
);
IDWriteTextLayout_Release
(
layout
);
/* simple string */
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
str2W
,
4
,
format
,
500
.
0
,
1000
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
r
.
startPosition
=
0
;
r
.
length
=
2
;
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
&
testeffect
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
flush_sequence
(
sequences
,
RENDERER_ID
);
hr
=
IDWriteTextLayout_Draw
(
layout
,
NULL
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draweffect2_seq
,
"effect draw test 2"
,
TRUE
);
IDWriteTextLayout_Release
(
layout
);
/* Inline object - effect set for same range */
hr
=
IDWriteFactory_CreateEllipsisTrimmingSign
(
factory
,
format
,
&
sign
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
str2W
,
4
,
format
,
500
.
0
,
1000
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
r
.
startPosition
=
0
;
r
.
length
=
4
;
hr
=
IDWriteTextLayout_SetInlineObject
(
layout
,
sign
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
&
testeffect
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
flush_sequence
(
sequences
,
RENDERER_ID
);
hr
=
IDWriteTextLayout_Draw
(
layout
,
NULL
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draweffect3_seq
,
"effect draw test 3"
,
FALSE
);
/* now set effect somewhere inside a range replaced by inline object */
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
NULL
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
r
.
startPosition
=
1
;
r
.
length
=
1
;
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
&
testeffect
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
/* no effect is reported in this case */
flush_sequence
(
sequences
,
RENDERER_ID
);
hr
=
IDWriteTextLayout_Draw
(
layout
,
NULL
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draweffect4_seq
,
"effect draw test 4"
,
FALSE
);
r
.
startPosition
=
0
;
r
.
length
=
4
;
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
NULL
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
r
.
startPosition
=
0
;
r
.
length
=
1
;
hr
=
IDWriteTextLayout_SetDrawingEffect
(
layout
,
&
testeffect
,
r
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
/* first range position is all that matters for inline ranges */
flush_sequence
(
sequences
,
RENDERER_ID
);
hr
=
IDWriteTextLayout_Draw
(
layout
,
NULL
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draweffect3_seq
,
"effect draw test 5"
,
FALSE
);
IDWriteTextLayout_Release
(
layout
);
IDWriteInlineObject_Release
(
sign
);
IDWriteTextFormat_Release
(
format
);
IDWriteFactory_Release
(
factory
);
}
START_TEST
(
layout
)
{
static
const
WCHAR
ctrlstrW
[]
=
{
0x202a
,
0
};
...
...
@@ -2476,6 +2682,7 @@ START_TEST(layout)
test_SetStrikethrough
();
test_GetMetrics
();
test_SetFlowDirection
();
test_SetDrawingEffect
();
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