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
c8b0c803
Commit
c8b0c803
authored
Jul 20, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jul 20, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Round centered alignment shift for compatible layouts.
parent
a718a9a5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
112 additions
and
15 deletions
+112
-15
layout.c
dlls/dwrite/layout.c
+68
-15
layout.c
dlls/dwrite/tests/layout.c
+44
-0
No files found.
dlls/dwrite/layout.c
View file @
c8b0c803
...
...
@@ -255,7 +255,7 @@ struct dwrite_textlayout {
DWRITE_MEASURING_MODE
measuringmode
;
/* gdi-compatible layout specifics */
FLOAT
pixels_per_
dip
;
FLOAT
pp
dip
;
DWRITE_MATRIX
transform
;
};
...
...
@@ -281,6 +281,11 @@ struct dwrite_typography {
UINT32
count
;
};
struct
dwrite_vec
{
FLOAT
x
;
FLOAT
y
;
};
static
const
IDWriteTextFormat1Vtbl
dwritetextformatvtbl
;
static
void
release_format_data
(
struct
dwrite_textformat_data
*
data
)
...
...
@@ -816,7 +821,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
if
(
is_layout_gdi_compatible
(
layout
))
hr
=
IDWriteTextAnalyzer_GetGdiCompatibleGlyphPlacements
(
analyzer
,
run
->
descr
.
string
,
run
->
descr
.
clusterMap
,
text_props
,
run
->
descr
.
stringLength
,
run
->
run
.
glyphIndices
,
glyph_props
,
run
->
glyphcount
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
p
ixels_per_
dip
,
&
layout
->
transform
,
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
p
p
dip
,
&
layout
->
transform
,
layout
->
measuringmode
==
DWRITE_MEASURING_MODE_GDI_NATURAL
,
run
->
run
.
isSideways
,
run
->
run
.
bidiLevel
&
1
,
&
run
->
sa
,
run
->
descr
.
localeName
,
NULL
,
NULL
,
0
,
run
->
advances
,
run
->
offsets
);
else
...
...
@@ -845,7 +850,7 @@ static HRESULT layout_compute_runs(struct dwrite_textlayout *layout)
if
(
is_layout_gdi_compatible
(
layout
))
{
hr
=
IDWriteFontFace_GetGdiCompatibleMetrics
(
run
->
run
.
fontFace
,
run
->
run
.
fontEmSize
,
layout
->
p
ixels_per_
dip
,
layout
->
p
p
dip
,
&
layout
->
transform
,
&
fontmetrics
);
if
(
FAILED
(
hr
))
...
...
@@ -1063,7 +1068,7 @@ static HRESULT layout_add_effective_run(struct dwrite_textlayout *layout, const
HRESULT
hr
=
IDWriteFontFace_GetGdiCompatibleMetrics
(
r
->
u
.
regular
.
run
.
fontFace
,
r
->
u
.
regular
.
run
.
fontEmSize
,
layout
->
p
ixels_per_
dip
,
layout
->
p
p
dip
,
&
layout
->
transform
,
&
metrics
);
if
(
FAILED
(
hr
))
...
...
@@ -1166,6 +1171,43 @@ static FLOAT layout_get_line_width(struct dwrite_textlayout *layout,
return
width
;
}
static
inline
BOOL
should_skip_transform
(
const
DWRITE_MATRIX
*
m
,
FLOAT
*
det
)
{
*
det
=
m
->
m11
*
m
->
m22
-
m
->
m12
*
m
->
m21
;
/* on certain conditions we can skip transform */
return
(
!
memcmp
(
m
,
&
identity
,
sizeof
(
*
m
))
||
fabsf
(
*
det
)
<=
1e-10
f
);
}
static
inline
void
layout_apply_snapping
(
struct
dwrite_vec
*
vec
,
BOOL
skiptransform
,
FLOAT
ppdip
,
const
DWRITE_MATRIX
*
m
,
FLOAT
det
)
{
if
(
!
skiptransform
)
{
FLOAT
vec2
[
2
];
/* apply transform */
vec
->
x
*=
ppdip
;
vec
->
y
*=
ppdip
;
vec2
[
0
]
=
m
->
m11
*
vec
->
x
+
m
->
m21
*
vec
->
y
+
m
->
dx
;
vec2
[
1
]
=
m
->
m12
*
vec
->
x
+
m
->
m22
*
vec
->
y
+
m
->
dy
;
/* snap */
vec2
[
0
]
=
floorf
(
vec2
[
0
]
+
0
.
5
f
);
vec2
[
1
]
=
floorf
(
vec2
[
1
]
+
0
.
5
f
);
/* apply inverted transform, we don't care about X component at this point */
vec
->
x
=
(
m
->
m22
*
vec2
[
0
]
-
m
->
m21
*
vec2
[
1
]
+
m
->
m21
*
m
->
dy
-
m
->
m22
*
m
->
dx
)
/
det
;
vec
->
x
/=
ppdip
;
vec
->
y
=
(
-
m
->
m12
*
vec2
[
0
]
+
m
->
m11
*
vec2
[
1
]
-
(
m
->
m11
*
m
->
dy
-
m
->
m12
*
m
->
dx
))
/
det
;
vec
->
y
/=
ppdip
;
}
else
{
vec
->
x
=
floorf
(
vec
->
x
*
ppdip
+
0
.
5
f
)
/
ppdip
;
vec
->
y
=
floorf
(
vec
->
y
*
ppdip
+
0
.
5
f
)
/
ppdip
;
}
}
static
void
layout_apply_leading_alignment
(
struct
dwrite_textlayout
*
layout
)
{
BOOL
is_rtl
=
layout
->
format
.
readingdir
==
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
;
...
...
@@ -1219,19 +1261,35 @@ static void layout_apply_trailing_alignment(struct dwrite_textlayout *layout)
layout
->
metrics
.
left
=
is_rtl
?
0
.
0
:
layout
->
metrics
.
layoutWidth
-
layout
->
metrics
.
width
;
}
static
inline
FLOAT
layout_get_centered_shift
(
struct
dwrite_textlayout
*
layout
,
BOOL
skiptransform
,
FLOAT
width
,
FLOAT
det
)
{
if
(
is_layout_gdi_compatible
(
layout
))
{
struct
dwrite_vec
vec
=
{
layout
->
metrics
.
layoutWidth
-
width
,
0
.
0
};
layout_apply_snapping
(
&
vec
,
skiptransform
,
layout
->
ppdip
,
&
layout
->
transform
,
det
);
return
floorf
(
vec
.
x
/
2
.
0
f
);
}
else
return
(
layout
->
metrics
.
layoutWidth
-
width
)
/
2
.
0
f
;
}
static
void
layout_apply_centered_alignment
(
struct
dwrite_textlayout
*
layout
)
{
BOOL
is_rtl
=
layout
->
format
.
readingdir
==
DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
;
struct
layout_effective_inline
*
inrun
;
struct
layout_effective_run
*
erun
;
BOOL
skiptransform
;
UINT32
line
;
FLOAT
det
;
erun
=
layout_get_next_erun
(
layout
,
NULL
);
inrun
=
layout_get_next_inline_run
(
layout
,
NULL
);
skiptransform
=
should_skip_transform
(
&
layout
->
transform
,
&
det
);
for
(
line
=
0
;
line
<
layout
->
metrics
.
lineCount
;
line
++
)
{
FLOAT
width
=
layout_get_line_width
(
layout
,
erun
,
inrun
,
line
);
FLOAT
shift
=
(
layout
->
metrics
.
layoutWidth
-
width
)
/
2
.
0
;
FLOAT
shift
=
layout_get_centered_shift
(
layout
,
skiptransform
,
width
,
det
)
;
if
(
is_rtl
)
shift
*=
-
1
.
0
;
...
...
@@ -2795,13 +2853,8 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
(
m
.
m11
*
m
.
m22
!=
0
.
0
&&
(
m
.
m12
!=
0
.
0
||
m
.
m21
!=
0
.
0
))
||
(
m
.
m12
*
m
.
m21
!=
0
.
0
&&
(
m
.
m11
!=
0
.
0
||
m
.
m22
!=
0
.
0
)))
disabled
=
TRUE
;
else
{
det
=
m
.
m11
*
m
.
m22
-
m
.
m12
*
m
.
m21
;
/* on certain conditions we can skip transform */
if
(
!
memcmp
(
&
m
,
&
identity
,
sizeof
(
m
))
||
fabsf
(
det
)
<=
1e-10
f
)
skiptransform
=
TRUE
;
}
else
skiptransform
=
should_skip_transform
(
&
m
,
&
det
);
}
#define SNAP_COORD(x) renderer_apply_snapping((x), skiptransform, ppdip, det, &m)
...
...
@@ -3901,7 +3954,7 @@ static HRESULT init_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *
layout
->
metrics
.
layoutHeight
=
maxheight
;
layout
->
measuringmode
=
DWRITE_MEASURING_MODE_NATURAL
;
layout
->
p
ixels_per_
dip
=
0
.
0
;
layout
->
p
p
dip
=
0
.
0
;
memset
(
&
layout
->
transform
,
0
,
sizeof
(
layout
->
transform
));
layout
->
str
=
heap_strdupnW
(
str
,
len
);
...
...
@@ -3956,7 +4009,7 @@ HRESULT create_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFormat *forma
}
HRESULT
create_gdicompat_textlayout
(
const
WCHAR
*
str
,
UINT32
len
,
IDWriteTextFormat
*
format
,
FLOAT
maxwidth
,
FLOAT
maxheight
,
FLOAT
p
ixels_per_
dip
,
const
DWRITE_MATRIX
*
transform
,
BOOL
use_gdi_natural
,
IDWriteTextLayout
**
ret
)
FLOAT
p
p
dip
,
const
DWRITE_MATRIX
*
transform
,
BOOL
use_gdi_natural
,
IDWriteTextLayout
**
ret
)
{
struct
dwrite_textlayout
*
layout
;
HRESULT
hr
;
...
...
@@ -3971,7 +4024,7 @@ HRESULT create_gdicompat_textlayout(const WCHAR *str, UINT32 len, IDWriteTextFor
layout
->
measuringmode
=
use_gdi_natural
?
DWRITE_MEASURING_MODE_GDI_NATURAL
:
DWRITE_MEASURING_MODE_GDI_CLASSIC
;
/* set gdi-specific properties */
layout
->
p
ixels_per_dip
=
pixels_per_
dip
;
layout
->
p
pdip
=
pp
dip
;
layout
->
transform
=
transform
?
*
transform
:
identity
;
*
ret
=
(
IDWriteTextLayout
*
)
&
layout
->
IDWriteTextLayout2_iface
;
...
...
dlls/dwrite/tests/layout.c
View file @
c8b0c803
...
...
@@ -1402,6 +1402,7 @@ static void test_Draw(void)
IDWriteTextLayout
*
layout
;
DWRITE_TEXT_RANGE
range
;
IDWriteFactory
*
factory
;
DWRITE_TEXT_METRICS
tm
;
DWRITE_MATRIX
m
;
HRESULT
hr
;
...
...
@@ -1516,6 +1517,24 @@ static void test_Draw(void)
hr
=
IDWriteTextLayout_Draw
(
layout
,
&
ctxt
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draw_single_run_seq
,
"draw test 7"
,
FALSE
);
/* text alignment keeps pixel-aligned origin */
hr
=
IDWriteTextLayout_GetMetrics
(
layout
,
&
tm
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
tm
.
width
==
floorf
(
tm
.
width
),
"got %f
\n
"
,
tm
.
width
);
hr
=
IDWriteTextLayout_SetMaxWidth
(
layout
,
tm
.
width
+
3
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IDWriteTextLayout_SetTextAlignment
(
layout
,
DWRITE_TEXT_ALIGNMENT_CENTER
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ctxt
.
originX
=
ctxt
.
originY
=
0
.
0
;
flush_sequence
(
sequences
,
RENDERER_ID
);
hr
=
IDWriteTextLayout_Draw
(
layout
,
&
ctxt
,
&
testrenderer
,
0
.
0
,
0
.
0
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok_sequence
(
sequences
,
RENDERER_ID
,
draw_single_run_seq
,
"draw test 7"
,
FALSE
);
ok
(
ctxt
.
originX
!=
0
.
0
&&
ctxt
.
originX
==
floorf
(
ctxt
.
originX
),
"got %f
\n
"
,
ctxt
.
originX
);
IDWriteTextLayout_Release
(
layout
);
ctxt
.
gdicompat
=
TRUE
;
...
...
@@ -1874,6 +1893,31 @@ todo_wine
IDWriteTextLayout_Release
(
layout
);
/* compare natural cluster width with gdi layout */
hr
=
IDWriteFactory_CreateTextLayout
(
factory
,
str4W
,
1
,
format
,
100
.
0
,
100
.
0
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
count
=
0
;
memset
(
metrics
,
0
,
sizeof
(
metrics
));
hr
=
IDWriteTextLayout_GetClusterMetrics
(
layout
,
metrics
,
1
,
&
count
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
count
==
1
,
"got %u
\n
"
,
count
);
ok
(
metrics
[
0
].
width
!=
floorf
(
metrics
[
0
].
width
),
"got %f
\n
"
,
metrics
[
0
].
width
);
IDWriteTextLayout_Release
(
layout
);
hr
=
IDWriteFactory_CreateGdiCompatibleTextLayout
(
factory
,
str4W
,
1
,
format
,
100
.
0
,
100
.
0
,
1
.
0
,
NULL
,
FALSE
,
&
layout
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
count
=
0
;
memset
(
metrics
,
0
,
sizeof
(
metrics
));
hr
=
IDWriteTextLayout_GetClusterMetrics
(
layout
,
metrics
,
1
,
&
count
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
count
==
1
,
"got %u
\n
"
,
count
);
ok
(
metrics
[
0
].
width
==
floorf
(
metrics
[
0
].
width
),
"got %f
\n
"
,
metrics
[
0
].
width
);
IDWriteTextLayout_Release
(
layout
);
IDWriteInlineObject_Release
(
trimm
);
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