Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
8303199c
Commit
8303199c
authored
Mar 30, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Mar 30, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Initial implementation of DetermineMinWidth().
parent
ee698506
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
9 deletions
+97
-9
layout.c
dlls/dwrite/layout.c
+65
-8
layout.c
dlls/dwrite/tests/layout.c
+32
-1
No files found.
dlls/dwrite/layout.c
View file @
8303199c
/*
* Text format and layout
*
* Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
* Copyright 2012, 2014
-2015
Nikolay Sivov for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -121,6 +121,12 @@ struct layout_run {
DWRITE_GLYPH_OFFSET
*
offsets
;
};
enum
layout_recompute_mask
{
RECOMPUTE_NOMINAL_RUNS
=
1
<<
0
,
RECOMPUTE_MINIMAL_WIDTH
=
1
<<
1
,
RECOMPUTE_EVERYTHING
=
0xffff
};
struct
dwrite_textlayout
{
IDWriteTextLayout2
IDWriteTextLayout2_iface
;
IDWriteTextFormat1
IDWriteTextFormat1_iface
;
...
...
@@ -135,13 +141,14 @@ struct dwrite_textlayout {
FLOAT
maxheight
;
struct
list
ranges
;
struct
list
runs
;
BOOL
recompute
;
USHORT
recompute
;
DWRITE_LINE_BREAKPOINT
*
nominal_breakpoints
;
DWRITE_LINE_BREAKPOINT
*
actual_breakpoints
;
DWRITE_CLUSTER_METRICS
*
clusters
;
UINT32
clusters_count
;
FLOAT
minwidth
;
/* gdi-compatible layout specifics */
BOOL
gdicompatible
;
...
...
@@ -586,7 +593,7 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
{
HRESULT
hr
;
if
(
!
layout
->
recompute
)
if
(
!
(
layout
->
recompute
&
RECOMPUTE_NOMINAL_RUNS
)
)
return
S_OK
;
/* nominal breakpoints are evaluated only once, because string never changes */
...
...
@@ -618,7 +625,7 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
}
}
layout
->
recompute
=
FALSE
;
layout
->
recompute
&=
~
RECOMPUTE_NOMINAL_RUNS
;
return
hr
;
}
...
...
@@ -998,7 +1005,7 @@ done:
if
(
changed
)
{
struct
list
*
next
,
*
i
;
layout
->
recompute
=
TRUE
;
layout
->
recompute
=
RECOMPUTE_EVERYTHING
;
i
=
list_head
(
ranges
);
while
((
next
=
list_next
(
ranges
,
i
)))
{
struct
layout_range
*
next_range
=
LIST_ENTRY
(
next
,
struct
layout_range
,
entry
);
...
...
@@ -1743,11 +1750,60 @@ static HRESULT WINAPI dwritetextlayout_GetClusterMetrics(IDWriteTextLayout2 *ifa
return
max_count
>=
This
->
clusters_count
?
S_OK
:
E_NOT_SUFFICIENT_BUFFER
;
}
/* Only to be used with DetermineMinWidth() to find the longest cluster sequence that we don't want to try
too hard to break. */
static
inline
BOOL
is_terminal_cluster
(
struct
dwrite_textlayout
*
layout
,
UINT32
index
)
{
if
(
layout
->
clusters
[
index
].
isWhitespace
||
layout
->
clusters
[
index
].
isNewline
||
(
index
==
layout
->
clusters_count
-
1
))
return
TRUE
;
/* check next one */
return
(
index
<
layout
->
clusters_count
-
1
)
&&
layout
->
clusters
[
index
+
1
].
isWhitespace
;
}
static
HRESULT
WINAPI
dwritetextlayout_DetermineMinWidth
(
IDWriteTextLayout2
*
iface
,
FLOAT
*
min_width
)
{
struct
dwrite_textlayout
*
This
=
impl_from_IDWriteTextLayout2
(
iface
);
FIXME
(
"(%p)->(%p): stub
\n
"
,
This
,
min_width
);
return
E_NOTIMPL
;
FLOAT
width
;
HRESULT
hr
;
UINT32
i
;
TRACE
(
"(%p)->(%p)
\n
"
,
This
,
min_width
);
if
(
!
min_width
)
return
E_INVALIDARG
;
if
(
!
(
This
->
recompute
&
RECOMPUTE_MINIMAL_WIDTH
))
goto
width_done
;
*
min_width
=
0
.
0
;
hr
=
layout_compute
(
This
);
if
(
FAILED
(
hr
))
return
hr
;
for
(
i
=
0
;
i
<
This
->
clusters_count
;)
{
if
(
is_terminal_cluster
(
This
,
i
))
{
width
=
This
->
clusters
[
i
].
width
;
i
++
;
}
else
{
width
=
0
.
0
;
while
(
!
is_terminal_cluster
(
This
,
i
))
{
width
+=
This
->
clusters
[
i
].
width
;
i
++
;
}
/* count last one too */
width
+=
This
->
clusters
[
i
].
width
;
}
if
(
width
>
This
->
minwidth
)
This
->
minwidth
=
width
;
}
This
->
recompute
&=
~
RECOMPUTE_MINIMAL_WIDTH
;
width_done:
*
min_width
=
This
->
minwidth
;
return
S_OK
;
}
static
HRESULT
WINAPI
dwritetextlayout_HitTestPoint
(
IDWriteTextLayout2
*
iface
,
...
...
@@ -2579,11 +2635,12 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
layout
->
len
=
len
;
layout
->
maxwidth
=
maxwidth
;
layout
->
maxheight
=
maxheight
;
layout
->
recompute
=
TRUE
;
layout
->
recompute
=
RECOMPUTE_EVERYTHING
;
layout
->
nominal_breakpoints
=
NULL
;
layout
->
actual_breakpoints
=
NULL
;
layout
->
clusters_count
=
0
;
layout
->
clusters
=
NULL
;
layout
->
minwidth
=
0
.
0
;
list_init
(
&
layout
->
runs
);
list_init
(
&
layout
->
ranges
);
memset
(
&
layout
->
format
,
0
,
sizeof
(
layout
->
format
));
...
...
dlls/dwrite/tests/layout.c
View file @
8303199c
/*
* Text layout/format tests
*
* Copyright 2012, 2014 Nikolay Sivov for CodeWeavers
* Copyright 2012, 2014
-2015
Nikolay Sivov for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -1297,6 +1297,36 @@ if (hr == S_OK) {
IDWriteFactory_Release
(
factory
);
}
static
void
test_DetermineMinWidth
(
void
)
{
static
const
WCHAR
strW
[]
=
{
'a'
,
'b'
,
'c'
,
'd'
,
0
};
IDWriteTextFormat
*
format
;
IDWriteTextLayout
*
layout
;
IDWriteFactory
*
factory
;
FLOAT
minwidth
;
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
);
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
strW
,
lstrlenW
(
strW
),
format
,
1000
.
0
,
1000
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_DetermineMinWidth
(
layout
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
minwidth
=
0
.
0
;
hr
=
IDWriteTextLayout_DetermineMinWidth
(
layout
,
&
minwidth
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
minwidth
>
0
.
0
,
"got %.2f
\n
"
,
minwidth
);
IDWriteTextLayout_Release
(
layout
);
IDWriteTextFormat_Release
(
format
);
}
START_TEST
(
layout
)
{
IDWriteFactory
*
factory
;
...
...
@@ -1323,6 +1353,7 @@ START_TEST(layout)
test_SetPairKerning
();
test_SetVerticalGlyphOrientation
();
test_fallback
();
test_DetermineMinWidth
();
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