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
5137aaa9
Commit
5137aaa9
authored
Jul 29, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jul 29, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dwrite: Implement parameter validation for CreateAlphaTexture().
parent
b50416aa
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
220 additions
and
31 deletions
+220
-31
font.c
dlls/dwrite/font.c
+78
-31
font.c
dlls/dwrite/tests/font.c
+142
-0
No files found.
dlls/dwrite/font.c
View file @
5137aaa9
...
...
@@ -2911,75 +2911,122 @@ static ULONG WINAPI glyphrunanalysis_Release(IDWriteGlyphRunAnalysis *iface)
return
ref
;
}
static
HRESULT
WINAPI
glyphrunanalysis_GetAlphaTextureBounds
(
IDWriteGlyphRunAnalysis
*
iface
,
DWRITE_TEXTURE_TYPE
type
,
RECT
*
bounds
)
static
void
glyphrunanalysis_get_texturebounds
(
struct
dwrite_glyphrunanalysis
*
analysis
,
RECT
*
bounds
)
{
struct
dwrite_glyphrunanalysis
*
This
=
impl_from_IDWriteGlyphRunAnalysis
(
iface
);
IDWriteFontFace2
*
fontface2
;
BOOL
nohint
,
is_rtl
;
FLOAT
origin_x
;
HRESULT
hr
;
UINT32
i
;
TRACE
(
"(%p)->(%d %p)
\n
"
,
This
,
type
,
bounds
);
if
((
UINT32
)
type
>
DWRITE_TEXTURE_CLEARTYPE_3x1
)
{
memset
(
bounds
,
0
,
sizeof
(
*
bounds
));
return
E_INVALIDARG
;
}
if
((
type
==
DWRITE_TEXTURE_ALIASED_1x1
&&
This
->
rendering_mode
!=
DWRITE_RENDERING_MODE_ALIASED
)
||
(
type
==
DWRITE_TEXTURE_CLEARTYPE_3x1
&&
This
->
rendering_mode
==
DWRITE_RENDERING_MODE_ALIASED
))
{
memset
(
bounds
,
0
,
sizeof
(
*
bounds
));
return
S_OK
;
}
if
(
This
->
ready
&
RUNANALYSIS_BOUNDS
)
{
*
bounds
=
This
->
bounds
;
return
S_OK
;
if
(
analysis
->
ready
&
RUNANALYSIS_BOUNDS
)
{
*
bounds
=
analysis
->
bounds
;
return
;
}
if
(
Th
is
->
run
.
isSideways
)
if
(
analys
is
->
run
.
isSideways
)
FIXME
(
"sideways runs are not supported.
\n
"
);
hr
=
IDWriteFontFace_QueryInterface
(
Th
is
->
run
.
fontFace
,
&
IID_IDWriteFontFace2
,
(
void
**
)
&
fontface2
);
hr
=
IDWriteFontFace_QueryInterface
(
analys
is
->
run
.
fontFace
,
&
IID_IDWriteFontFace2
,
(
void
**
)
&
fontface2
);
if
(
FAILED
(
hr
))
WARN
(
"failed to get IDWriteFontFace2, 0x%08x
\n
"
,
hr
);
nohint
=
This
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL
||
Th
is
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
nohint
=
analysis
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL
||
analys
is
->
rendering_mode
==
DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
;
/* Start with empty bounds at (0,0) origin, returned bounds are not translated back to (0,0), e.g. for
RTL run negative left bound is returned, same goes for vertical direction - top bound will be negative
for any non-zero glyph ascender */
origin_x
=
0
.
0
;
is_rtl
=
Th
is
->
run
.
bidiLevel
&
1
;
for
(
i
=
0
;
i
<
Th
is
->
run
.
glyphCount
;
i
++
)
{
const
DWRITE_GLYPH_OFFSET
*
offset
=
&
Th
is
->
offsets
[
i
];
FLOAT
advance
=
Th
is
->
advances
[
i
];
is_rtl
=
analys
is
->
run
.
bidiLevel
&
1
;
for
(
i
=
0
;
i
<
analys
is
->
run
.
glyphCount
;
i
++
)
{
const
DWRITE_GLYPH_OFFSET
*
offset
=
&
analys
is
->
offsets
[
i
];
FLOAT
advance
=
analys
is
->
advances
[
i
];
RECT
bbox
;
freetype_get_glyph_bbox
(
fontface2
,
This
->
run
.
fontEmSize
*
This
->
ppdip
,
Th
is
->
run
.
glyphIndices
[
i
],
nohint
,
&
bbox
);
freetype_get_glyph_bbox
(
fontface2
,
analysis
->
run
.
fontEmSize
*
analysis
->
ppdip
,
analys
is
->
run
.
glyphIndices
[
i
],
nohint
,
&
bbox
);
if
(
is_rtl
)
OffsetRect
(
&
bbox
,
origin_x
-
offset
->
advanceOffset
-
advance
,
-
offset
->
ascenderOffset
);
else
OffsetRect
(
&
bbox
,
origin_x
+
offset
->
advanceOffset
,
offset
->
ascenderOffset
);
UnionRect
(
&
This
->
bounds
,
&
Th
is
->
bounds
,
&
bbox
);
UnionRect
(
&
analysis
->
bounds
,
&
analys
is
->
bounds
,
&
bbox
);
origin_x
+=
is_rtl
?
-
advance
:
advance
;
}
IDWriteFontFace2_Release
(
fontface2
);
This
->
ready
|=
RUNANALYSIS_BOUNDS
;
*
bounds
=
This
->
bounds
;
analysis
->
ready
|=
RUNANALYSIS_BOUNDS
;
*
bounds
=
analysis
->
bounds
;
}
static
HRESULT
WINAPI
glyphrunanalysis_GetAlphaTextureBounds
(
IDWriteGlyphRunAnalysis
*
iface
,
DWRITE_TEXTURE_TYPE
type
,
RECT
*
bounds
)
{
struct
dwrite_glyphrunanalysis
*
This
=
impl_from_IDWriteGlyphRunAnalysis
(
iface
);
TRACE
(
"(%p)->(%d %p)
\n
"
,
This
,
type
,
bounds
);
if
((
UINT32
)
type
>
DWRITE_TEXTURE_CLEARTYPE_3x1
)
{
memset
(
bounds
,
0
,
sizeof
(
*
bounds
));
return
E_INVALIDARG
;
}
if
((
type
==
DWRITE_TEXTURE_ALIASED_1x1
&&
This
->
rendering_mode
!=
DWRITE_RENDERING_MODE_ALIASED
)
||
(
type
==
DWRITE_TEXTURE_CLEARTYPE_3x1
&&
This
->
rendering_mode
==
DWRITE_RENDERING_MODE_ALIASED
))
{
memset
(
bounds
,
0
,
sizeof
(
*
bounds
));
return
S_OK
;
}
glyphrunanalysis_get_texturebounds
(
This
,
bounds
);
return
S_OK
;
}
static
HRESULT
WINAPI
glyphrunanalysis_CreateAlphaTexture
(
IDWriteGlyphRunAnalysis
*
iface
,
DWRITE_TEXTURE_TYPE
type
,
RECT
const
*
bounds
,
BYTE
*
alphaValues
,
UINT32
bufferS
ize
)
RECT
const
*
bounds
,
BYTE
*
bitmap
,
UINT32
s
ize
)
{
struct
dwrite_glyphrunanalysis
*
This
=
impl_from_IDWriteGlyphRunAnalysis
(
iface
);
FIXME
(
"(%p)->(%d %p %p %u): stub
\n
"
,
This
,
type
,
bounds
,
alphaValues
,
bufferSize
);
UINT32
required
;
RECT
runbounds
;
FIXME
(
"(%p)->(%d %s %p %u): stub
\n
"
,
This
,
type
,
wine_dbgstr_rect
(
bounds
),
bitmap
,
size
);
if
(
!
bounds
||
!
bitmap
||
(
UINT32
)
type
>
DWRITE_TEXTURE_CLEARTYPE_3x1
)
return
E_INVALIDARG
;
/* make sure buffer is large enough for requested texture type */
required
=
(
bounds
->
right
-
bounds
->
left
)
*
(
bounds
->
bottom
-
bounds
->
top
);
if
(
type
==
DWRITE_TEXTURE_CLEARTYPE_3x1
)
required
*=
3
;
if
(
size
<
required
)
return
E_NOT_SUFFICIENT_BUFFER
;
/* validate requested texture type with rendering mode */
switch
(
This
->
rendering_mode
)
{
case
DWRITE_RENDERING_MODE_ALIASED
:
if
(
type
!=
DWRITE_TEXTURE_ALIASED_1x1
)
return
DWRITE_E_UNSUPPORTEDOPERATION
;
break
;
case
DWRITE_RENDERING_MODE_GDI_CLASSIC
:
case
DWRITE_RENDERING_MODE_GDI_NATURAL
:
case
DWRITE_RENDERING_MODE_NATURAL
:
case
DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
:
if
(
type
!=
DWRITE_TEXTURE_CLEARTYPE_3x1
)
return
DWRITE_E_UNSUPPORTEDOPERATION
;
break
;
default:
;
}
glyphrunanalysis_get_texturebounds
(
This
,
&
runbounds
);
/* special case when there's nothing to return */
if
(
!
IntersectRect
(
&
runbounds
,
&
runbounds
,
bounds
))
{
memset
(
bitmap
,
0
,
size
);
return
S_OK
;
}
return
E_NOTIMPL
;
}
...
...
dlls/dwrite/tests/font.c
View file @
5137aaa9
...
...
@@ -4449,6 +4449,147 @@ static void test_GetAlphaBlendParams(void)
IDWriteFactory_Release
(
factory
);
}
static
void
test_CreateAlphaTexture
(
void
)
{
IDWriteGlyphRunAnalysis
*
analysis
;
DWRITE_GLYPH_METRICS
metrics
;
DWRITE_GLYPH_OFFSET
offset
;
IDWriteFontFace
*
fontface
;
IDWriteFactory
*
factory
;
DWRITE_GLYPH_RUN
run
;
UINT32
ch
,
size
;
BYTE
buff
[
1024
];
RECT
bounds
,
r
;
FLOAT
advance
;
UINT16
glyph
;
HRESULT
hr
;
factory
=
create_factory
();
fontface
=
create_fontface
(
factory
);
ch
=
'A'
;
glyph
=
0
;
hr
=
IDWriteFontFace_GetGlyphIndices
(
fontface
,
&
ch
,
1
,
&
glyph
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
glyph
>
0
,
"got %u
\n
"
,
glyph
);
hr
=
IDWriteFontFace_GetDesignGlyphMetrics
(
fontface
,
&
glyph
,
1
,
&
metrics
,
FALSE
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
advance
=
metrics
.
advanceWidth
;
offset
.
advanceOffset
=
0
.
0
;
offset
.
ascenderOffset
=
0
.
0
;
run
.
fontFace
=
fontface
;
run
.
fontEmSize
=
24
.
0
;
run
.
glyphCount
=
1
;
run
.
glyphIndices
=
&
glyph
;
run
.
glyphAdvances
=
&
advance
;
run
.
glyphOffsets
=
&
offset
;
run
.
isSideways
=
FALSE
;
run
.
bidiLevel
=
0
;
hr
=
IDWriteFactory_CreateGlyphRunAnalysis
(
factory
,
&
run
,
1
.
0
,
NULL
,
DWRITE_RENDERING_MODE_NATURAL
,
DWRITE_MEASURING_MODE_NATURAL
,
0
.
0
,
0
.
0
,
&
analysis
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
SetRectEmpty
(
&
bounds
);
hr
=
IDWriteGlyphRunAnalysis_GetAlphaTextureBounds
(
analysis
,
DWRITE_TEXTURE_CLEARTYPE_3x1
,
&
bounds
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
!
IsRectEmpty
(
&
bounds
),
"got empty rect
\n
"
);
size
=
(
bounds
.
right
-
bounds
.
left
)
*
(
bounds
.
bottom
-
bounds
.
top
)
*
3
;
ok
(
sizeof
(
buff
)
>=
size
,
"required %u
\n
"
,
size
);
/* invalid type value */
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_CLEARTYPE_3x1
+
1
,
&
bounds
,
buff
,
sizeof
(
buff
));
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
bounds
,
buff
,
2
);
ok
(
hr
==
E_NOT_SUFFICIENT_BUFFER
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
/* vista version allows texture type mismatch, mark it broken for now */
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
bounds
,
buff
,
sizeof
(
buff
));
ok
(
hr
==
DWRITE_E_UNSUPPORTEDOPERATION
||
broken
(
hr
==
S_OK
),
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
||
broken
(
buff
[
0
]
==
0
),
"got %1x
\n
"
,
buff
[
0
]);
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_CLEARTYPE_3x1
,
&
bounds
,
buff
,
size
-
1
);
ok
(
hr
==
E_NOT_SUFFICIENT_BUFFER
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
IDWriteGlyphRunAnalysis_Release
(
analysis
);
hr
=
IDWriteFactory_CreateGlyphRunAnalysis
(
factory
,
&
run
,
1
.
0
,
NULL
,
DWRITE_RENDERING_MODE_ALIASED
,
DWRITE_MEASURING_MODE_GDI_CLASSIC
,
0
.
0
,
0
.
0
,
&
analysis
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
SetRectEmpty
(
&
bounds
);
hr
=
IDWriteGlyphRunAnalysis_GetAlphaTextureBounds
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
bounds
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
!
IsRectEmpty
(
&
bounds
),
"got empty rect
\n
"
);
size
=
(
bounds
.
right
-
bounds
.
left
)
*
(
bounds
.
bottom
-
bounds
.
top
);
ok
(
sizeof
(
buff
)
>=
size
,
"required %u
\n
"
,
size
);
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
NULL
,
buff
,
sizeof
(
buff
));
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
NULL
,
NULL
,
sizeof
(
buff
));
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
NULL
,
buff
,
0
);
ok
(
hr
==
E_INVALIDARG
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
/* buffer size is not enough */
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
bounds
,
buff
,
size
-
1
);
ok
(
hr
==
E_NOT_SUFFICIENT_BUFFER
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
/* request texture for rectangle that doesn't intersect */
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
r
=
bounds
;
OffsetRect
(
&
r
,
(
bounds
.
right
-
bounds
.
left
)
*
2
,
0
);
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
r
,
buff
,
sizeof
(
buff
));
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0
,
"got %1x
\n
"
,
buff
[
0
]);
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
r
=
bounds
;
OffsetRect
(
&
r
,
(
bounds
.
right
-
bounds
.
left
)
*
2
,
0
);
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
r
,
buff
,
sizeof
(
buff
));
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0
,
"got %1x
\n
"
,
buff
[
0
]);
/* request texture for rectangle that doesn't intersect, small buffer */
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
r
=
bounds
;
OffsetRect
(
&
r
,
(
bounds
.
right
-
bounds
.
left
)
*
2
,
0
);
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_ALIASED_1x1
,
&
r
,
buff
,
size
-
1
);
ok
(
hr
==
E_NOT_SUFFICIENT_BUFFER
,
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
,
"got %1x
\n
"
,
buff
[
0
]);
/* vista version allows texture type mismatch, mark it broken for now */
memset
(
buff
,
0xcf
,
sizeof
(
buff
));
hr
=
IDWriteGlyphRunAnalysis_CreateAlphaTexture
(
analysis
,
DWRITE_TEXTURE_CLEARTYPE_3x1
,
&
bounds
,
buff
,
sizeof
(
buff
));
ok
(
hr
==
DWRITE_E_UNSUPPORTEDOPERATION
||
broken
(
hr
==
S_OK
),
"got 0x%08x
\n
"
,
hr
);
ok
(
buff
[
0
]
==
0xcf
||
broken
(
buff
[
0
]
==
0
),
"got %1x
\n
"
,
buff
[
0
]);
IDWriteGlyphRunAnalysis_Release
(
analysis
);
IDWriteFontFace_Release
(
fontface
);
IDWriteFactory_Release
(
factory
);
}
START_TEST
(
font
)
{
IDWriteFactory
*
factory
;
...
...
@@ -4497,6 +4638,7 @@ START_TEST(font)
test_GetGdiCompatibleGlyphAdvances
();
test_GetRecommendedRenderingMode
();
test_GetAlphaBlendParams
();
test_CreateAlphaTexture
();
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