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
cb4e8819
Commit
cb4e8819
authored
Dec 26, 2014
by
Nikolay Sivov
Committed by
Alexandre Julliard
Dec 28, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Update breakpoints in case of inline objects.
parent
83aafaaa
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
19 deletions
+90
-19
layout.c
dlls/dwrite/layout.c
+90
-19
No files found.
dlls/dwrite/layout.c
View file @
cb4e8819
...
@@ -121,7 +121,8 @@ struct dwrite_textlayout {
...
@@ -121,7 +121,8 @@ struct dwrite_textlayout {
struct
list
runs
;
struct
list
runs
;
BOOL
recompute
;
BOOL
recompute
;
DWRITE_LINE_BREAKPOINT
*
breakpoints
;
DWRITE_LINE_BREAKPOINT
*
nominal_breakpoints
;
DWRITE_LINE_BREAKPOINT
*
actual_breakpoints
;
};
};
struct
dwrite_textformat
{
struct
dwrite_textformat
{
...
@@ -226,6 +227,70 @@ static void free_layout_runs(struct dwrite_textlayout *layout)
...
@@ -226,6 +227,70 @@ static void free_layout_runs(struct dwrite_textlayout *layout)
}
}
}
}
/* should only be called for ranges with inline objects */
static
inline
DWRITE_BREAK_CONDITION
override_break_condition
(
DWRITE_BREAK_CONDITION
existingbreak
,
DWRITE_BREAK_CONDITION
newbreak
)
{
switch
(
existingbreak
)
{
case
DWRITE_BREAK_CONDITION_NEUTRAL
:
return
newbreak
;
case
DWRITE_BREAK_CONDITION_CAN_BREAK
:
return
newbreak
==
DWRITE_BREAK_CONDITION_NEUTRAL
?
existingbreak
:
newbreak
;
/* let's keep stronger conditions as is */
case
DWRITE_BREAK_CONDITION_MAY_NOT_BREAK
:
case
DWRITE_BREAK_CONDITION_MUST_BREAK
:
break
;
default:
ERR
(
"unknown break condition %d
\n
"
,
existingbreak
);
}
return
existingbreak
;
}
static
HRESULT
layout_update_breakpoints_range
(
struct
dwrite_textlayout
*
layout
,
const
struct
layout_range
*
cur
)
{
DWRITE_BREAK_CONDITION
before
,
after
;
HRESULT
hr
;
UINT32
i
;
hr
=
IDWriteInlineObject_GetBreakConditions
(
cur
->
object
,
&
before
,
&
after
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
!
layout
->
actual_breakpoints
)
{
layout
->
actual_breakpoints
=
heap_alloc
(
sizeof
(
DWRITE_LINE_BREAKPOINT
)
*
layout
->
len
);
if
(
!
layout
->
actual_breakpoints
)
return
E_OUTOFMEMORY
;
}
memcpy
(
layout
->
actual_breakpoints
,
layout
->
nominal_breakpoints
,
sizeof
(
DWRITE_LINE_BREAKPOINT
)
*
layout
->
len
);
for
(
i
=
cur
->
range
.
startPosition
;
i
<
cur
->
range
.
length
+
cur
->
range
.
startPosition
;
i
++
)
{
UINT32
j
=
i
+
cur
->
range
.
startPosition
;
if
(
i
==
0
)
{
if
(
j
)
layout
->
actual_breakpoints
[
j
].
breakConditionBefore
=
layout
->
actual_breakpoints
[
j
-
1
].
breakConditionAfter
=
override_break_condition
(
layout
->
actual_breakpoints
[
j
-
1
].
breakConditionAfter
,
before
);
else
layout
->
actual_breakpoints
[
j
].
breakConditionBefore
=
before
;
layout
->
actual_breakpoints
[
j
].
breakConditionAfter
=
DWRITE_BREAK_CONDITION_MAY_NOT_BREAK
;
}
layout
->
actual_breakpoints
[
j
].
isWhitespace
=
0
;
layout
->
actual_breakpoints
[
j
].
isSoftHyphen
=
0
;
if
(
i
==
cur
->
range
.
length
-
1
)
{
layout
->
actual_breakpoints
[
j
].
breakConditionBefore
=
DWRITE_BREAK_CONDITION_MAY_NOT_BREAK
;
if
(
j
<
layout
->
len
-
1
)
layout
->
actual_breakpoints
[
j
].
breakConditionAfter
=
layout
->
actual_breakpoints
[
j
+
1
].
breakConditionAfter
=
override_break_condition
(
layout
->
actual_breakpoints
[
j
+
1
].
breakConditionAfter
,
before
);
else
layout
->
actual_breakpoints
[
j
].
breakConditionAfter
=
before
;
}
}
return
S_OK
;
}
static
HRESULT
layout_compute_runs
(
struct
dwrite_textlayout
*
layout
)
static
HRESULT
layout_compute_runs
(
struct
dwrite_textlayout
*
layout
)
{
{
IDWriteTextAnalyzer
*
analyzer
;
IDWriteTextAnalyzer
*
analyzer
;
...
@@ -240,8 +305,12 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
...
@@ -240,8 +305,12 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
LIST_FOR_EACH_ENTRY
(
cur
,
&
layout
->
ranges
,
struct
layout_range
,
entry
)
{
LIST_FOR_EACH_ENTRY
(
cur
,
&
layout
->
ranges
,
struct
layout_range
,
entry
)
{
/* inline objects override actual text in a range */
/* inline objects override actual text in a range */
if
(
cur
->
object
)
if
(
cur
->
object
)
{
hr
=
layout_update_breakpoints_range
(
layout
,
cur
);
if
(
FAILED
(
hr
))
return
hr
;
continue
;
continue
;
}
/* initial splitting by script */
/* initial splitting by script */
hr
=
IDWriteTextAnalyzer_AnalyzeScript
(
analyzer
,
&
layout
->
IDWriteTextAnalysisSource_iface
,
hr
=
IDWriteTextAnalyzer_AnalyzeScript
(
analyzer
,
&
layout
->
IDWriteTextAnalysisSource_iface
,
...
@@ -267,24 +336,13 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
...
@@ -267,24 +336,13 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
if
(
!
layout
->
recompute
)
if
(
!
layout
->
recompute
)
return
S_OK
;
return
S_OK
;
hr
=
layout_compute_runs
(
layout
);
if
(
TRACE_ON
(
dwrite
))
{
struct
layout_run
*
cur
;
LIST_FOR_EACH_ENTRY
(
cur
,
&
layout
->
runs
,
struct
layout_run
,
entry
)
{
TRACE
(
"run [%u,%u], len %u, bidilevel %u
\n
"
,
cur
->
descr
.
textPosition
,
cur
->
descr
.
textPosition
+
cur
->
descr
.
stringLength
-
1
,
cur
->
descr
.
stringLength
,
cur
->
run
.
bidiLevel
);
}
}
/* nominal breakpoints are evaluated only once, because string never changes */
/* nominal breakpoints are evaluated only once, because string never changes */
if
(
!
layout
->
breakpoints
)
{
if
(
!
layout
->
nominal_
breakpoints
)
{
IDWriteTextAnalyzer
*
analyzer
;
IDWriteTextAnalyzer
*
analyzer
;
HRESULT
hr
;
HRESULT
hr
;
layout
->
breakpoints
=
heap_alloc
(
sizeof
(
DWRITE_LINE_BREAKPOINT
)
*
layout
->
len
);
layout
->
nominal_
breakpoints
=
heap_alloc
(
sizeof
(
DWRITE_LINE_BREAKPOINT
)
*
layout
->
len
);
if
(
!
layout
->
breakpoints
)
if
(
!
layout
->
nominal_
breakpoints
)
return
E_OUTOFMEMORY
;
return
E_OUTOFMEMORY
;
hr
=
get_textanalyzer
(
&
analyzer
);
hr
=
get_textanalyzer
(
&
analyzer
);
...
@@ -296,6 +354,17 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
...
@@ -296,6 +354,17 @@ static HRESULT layout_compute(struct dwrite_textlayout *layout)
IDWriteTextAnalyzer_Release
(
analyzer
);
IDWriteTextAnalyzer_Release
(
analyzer
);
}
}
hr
=
layout_compute_runs
(
layout
);
if
(
TRACE_ON
(
dwrite
))
{
struct
layout_run
*
cur
;
LIST_FOR_EACH_ENTRY
(
cur
,
&
layout
->
runs
,
struct
layout_run
,
entry
)
{
TRACE
(
"run [%u,%u], len %u, bidilevel %u
\n
"
,
cur
->
descr
.
textPosition
,
cur
->
descr
.
textPosition
+
cur
->
descr
.
stringLength
-
1
,
cur
->
descr
.
stringLength
,
cur
->
run
.
bidiLevel
);
}
}
layout
->
recompute
=
FALSE
;
layout
->
recompute
=
FALSE
;
return
hr
;
return
hr
;
}
}
...
@@ -695,7 +764,8 @@ static ULONG WINAPI dwritetextlayout_Release(IDWriteTextLayout2 *iface)
...
@@ -695,7 +764,8 @@ static ULONG WINAPI dwritetextlayout_Release(IDWriteTextLayout2 *iface)
free_layout_ranges_list
(
This
);
free_layout_ranges_list
(
This
);
free_layout_runs
(
This
);
free_layout_runs
(
This
);
release_format_data
(
&
This
->
format
);
release_format_data
(
&
This
->
format
);
heap_free
(
This
->
breakpoints
);
heap_free
(
This
->
nominal_breakpoints
);
heap_free
(
This
->
actual_breakpoints
);
heap_free
(
This
->
str
);
heap_free
(
This
->
str
);
heap_free
(
This
);
heap_free
(
This
);
}
}
...
@@ -1601,7 +1671,7 @@ static HRESULT WINAPI dwritetextlayout_sink_SetLineBreakpoints(IDWriteTextAnalys
...
@@ -1601,7 +1671,7 @@ static HRESULT WINAPI dwritetextlayout_sink_SetLineBreakpoints(IDWriteTextAnalys
if
(
position
+
length
>
layout
->
len
)
if
(
position
+
length
>
layout
->
len
)
return
E_FAIL
;
return
E_FAIL
;
memcpy
(
&
layout
->
breakpoints
[
position
],
breakpoints
,
length
*
sizeof
(
DWRITE_LINE_BREAKPOINT
));
memcpy
(
&
layout
->
nominal_
breakpoints
[
position
],
breakpoints
,
length
*
sizeof
(
DWRITE_LINE_BREAKPOINT
));
return
S_OK
;
return
S_OK
;
}
}
...
@@ -1833,7 +1903,8 @@ HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *forma
...
@@ -1833,7 +1903,8 @@ HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *forma
This
->
maxwidth
=
maxwidth
;
This
->
maxwidth
=
maxwidth
;
This
->
maxheight
=
maxheight
;
This
->
maxheight
=
maxheight
;
This
->
recompute
=
TRUE
;
This
->
recompute
=
TRUE
;
This
->
breakpoints
=
NULL
;
This
->
nominal_breakpoints
=
NULL
;
This
->
actual_breakpoints
=
NULL
;
layout_format_from_textformat
(
This
,
format
);
layout_format_from_textformat
(
This
,
format
);
list_init
(
&
This
->
runs
);
list_init
(
&
This
->
runs
);
...
...
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