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
870fdaf6
Commit
870fdaf6
authored
Mar 03, 2011
by
Vincent Povirk
Committed by
Alexandre Julliard
Mar 10, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gdiplus: Read drawn bitmaps in one step instead of using getpixel.
parent
a7f95eeb
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
163 additions
and
37 deletions
+163
-37
graphics.c
dlls/gdiplus/graphics.c
+163
-37
No files found.
dlls/gdiplus/graphics.c
View file @
870fdaf6
...
...
@@ -414,6 +414,95 @@ static void apply_image_attributes(const GpImageAttributes *attributes, LPBYTE d
}
}
/* Given a bitmap and its source rectangle, find the smallest rectangle in the
* bitmap that contains all the pixels we may need to draw it. */
static
void
get_bitmap_sample_size
(
InterpolationMode
interpolation
,
WrapMode
wrap
,
GpBitmap
*
bitmap
,
REAL
srcx
,
REAL
srcy
,
REAL
srcwidth
,
REAL
srcheight
,
GpRect
*
rect
)
{
INT
left
,
top
,
right
,
bottom
;
switch
(
interpolation
)
{
case
InterpolationModeHighQualityBilinear
:
case
InterpolationModeHighQualityBicubic
:
/* FIXME: Include a greater range for the prefilter? */
case
InterpolationModeBicubic
:
case
InterpolationModeBilinear
:
left
=
(
INT
)(
floorf
(
srcx
));
top
=
(
INT
)(
floorf
(
srcy
));
right
=
(
INT
)(
ceilf
(
srcx
+
srcwidth
));
bottom
=
(
INT
)(
ceilf
(
srcy
+
srcheight
));
break
;
case
InterpolationModeNearestNeighbor
:
default:
left
=
roundr
(
srcx
);
top
=
roundr
(
srcy
);
right
=
roundr
(
srcx
+
srcwidth
);
bottom
=
roundr
(
srcy
+
srcheight
);
break
;
}
if
(
wrap
==
WrapModeClamp
)
{
if
(
left
<
0
)
left
=
0
;
if
(
top
<
0
)
top
=
0
;
if
(
right
>=
bitmap
->
width
)
right
=
bitmap
->
width
-
1
;
if
(
bottom
>=
bitmap
->
height
)
bottom
=
bitmap
->
height
-
1
;
}
else
{
/* In some cases we can make the rectangle smaller here, but the logic
* is hard to get right, and tiling suggests we're likely to use the
* entire source image. */
if
(
left
<
0
||
right
>=
bitmap
->
width
)
{
left
=
0
;
right
=
bitmap
->
width
-
1
;
}
if
(
top
<
0
||
bottom
>=
bitmap
->
height
)
{
top
=
0
;
bottom
=
bitmap
->
height
-
1
;
}
}
rect
->
X
=
left
;
rect
->
Y
=
top
;
rect
->
Width
=
right
-
left
+
1
;
rect
->
Height
=
bottom
-
top
+
1
;
}
static
ARGB
sample_bitmap_pixel
(
GDIPCONST
GpRect
*
src_rect
,
LPBYTE
bits
,
UINT
width
,
UINT
height
,
INT
x
,
INT
y
,
GDIPCONST
GpImageAttributes
*
attributes
)
{
static
int
fixme
[
4
];
switch
(
attributes
->
wrap
)
{
default:
if
(
!
fixme
[
attributes
->
wrap
]
++
)
FIXME
(
"not implemented for wrap mode %i
\n
"
,
attributes
->
wrap
);
case
WrapModeClamp
:
if
(
x
<
0
||
y
<
0
||
x
>=
width
||
y
>=
height
)
return
attributes
->
outside_color
;
break
;
}
if
(
x
<
src_rect
->
X
||
y
<
src_rect
->
Y
||
x
>=
src_rect
->
X
+
src_rect
->
Width
||
y
>=
src_rect
->
Y
+
src_rect
->
Height
)
{
ERR
(
"out of range pixel requested
\n
"
);
return
0xffcd0084
;
}
return
((
DWORD
*
)(
bits
))[(
x
-
src_rect
->
X
)
+
(
y
-
src_rect
->
Y
)
*
src_rect
->
Width
];
}
static
void
brush_fill_path
(
GpGraphics
*
graphics
,
GpBrush
*
brush
)
{
switch
(
brush
->
bt
)
...
...
@@ -2309,16 +2398,25 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
if
(
use_software
)
{
RECT
src_area
,
dst_area
;
int
i
,
x
,
y
,
stride
;
RECT
dst_area
;
GpRect
src_area
;
int
i
,
x
,
y
,
src_stride
,
dst_stride
;
GpMatrix
*
dst_to_src
;
REAL
m11
,
m12
,
m21
,
m22
,
mdx
,
mdy
;
LPBYTE
data
;
LPBYTE
src_data
,
dst_data
;
BitmapData
lockeddata
;
InterpolationMode
interpolation
=
graphics
->
interpolation
;
GpPointF
dst_to_src_points
[
3
]
=
{{
0
.
0
,
0
.
0
},
{
1
.
0
,
0
.
0
},
{
0
.
0
,
1
.
0
}};
REAL
x_dx
,
x_dy
,
y_dx
,
y_dy
;
static
const
GpImageAttributes
defaultImageAttributes
=
{
WrapModeClamp
,
0
,
FALSE
};
if
(
!
imageAttributes
)
imageAttributes
=
&
defaultImageAttributes
;
src
_area
.
left
=
srcx
*
dx
;
src
_area
.
top
=
srcy
*
dy
;
src
_area
.
right
=
(
srcx
+
srcwidth
)
*
dx
;
src
_area
.
bottom
=
(
srcy
+
srcheight
)
*
dy
;
src
x
=
srcx
*
dx
;
src
y
=
srcy
*
dy
;
src
width
=
srcwidth
*
dx
;
src
height
=
srcheight
*
dy
;
dst_area
.
left
=
dst_area
.
right
=
pti
[
0
].
x
;
dst_area
.
top
=
dst_area
.
bottom
=
pti
[
0
].
y
;
...
...
@@ -2347,65 +2445,93 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
return
stat
;
}
data
=
GdipAlloc
(
sizeof
(
ARGB
)
*
(
dst_area
.
right
-
dst_area
.
left
)
*
(
dst_area
.
bottom
-
dst_area
.
top
));
if
(
!
data
)
dst_data
=
GdipAlloc
(
sizeof
(
ARGB
)
*
(
dst_area
.
right
-
dst_area
.
left
)
*
(
dst_area
.
bottom
-
dst_area
.
top
));
if
(
!
dst_data
)
{
GdipDeleteMatrix
(
dst_to_src
);
return
OutOfMemory
;
}
dst_stride
=
sizeof
(
ARGB
)
*
(
dst_area
.
right
-
dst_area
.
left
);
get_bitmap_sample_size
(
interpolation
,
imageAttributes
->
wrap
,
bitmap
,
srcx
,
srcy
,
srcwidth
,
srcheight
,
&
src_area
);
src_data
=
GdipAlloc
(
sizeof
(
ARGB
)
*
src_area
.
Width
*
src_area
.
Height
);
if
(
!
src_data
)
{
GdipFree
(
dst_data
);
GdipDeleteMatrix
(
dst_to_src
);
return
OutOfMemory
;
}
src_stride
=
sizeof
(
ARGB
)
*
src_area
.
Width
;
/* Read the bits we need from the source bitmap into an ARGB buffer. */
lockeddata
.
Width
=
src_area
.
Width
;
lockeddata
.
Height
=
src_area
.
Height
;
lockeddata
.
Stride
=
src_stride
;
lockeddata
.
PixelFormat
=
PixelFormat32bppARGB
;
lockeddata
.
Scan0
=
src_data
;
stride
=
sizeof
(
ARGB
)
*
(
dst_area
.
right
-
dst_area
.
left
);
stat
=
GdipBitmapLockBits
(
bitmap
,
&
src_area
,
ImageLockModeRead
|
ImageLockModeUserInputBuf
,
PixelFormat32bppARGB
,
&
lockeddata
);
if
(
stat
==
Ok
)
stat
=
GdipBitmapUnlockBits
(
bitmap
,
&
lockeddata
);
if
(
imageAttributes
&&
(
imageAttributes
->
wrap
!=
WrapModeClamp
||
imageAttributes
->
outside_color
!=
0x00000000
||
imageAttributes
->
clamp
))
if
(
stat
!=
Ok
)
{
static
int
fixme
;
if
(
!
fixme
++
)
FIXME
(
"Image wrap mode not implemented
\n
"
);
if
(
src_data
!=
dst_data
)
GdipFree
(
src_data
);
GdipFree
(
dst_data
);
GdipDeleteMatrix
(
dst_to_src
);
return
OutOfMemory
;
}
/* Transform the bits as needed to the destination. */
GdipTransformMatrixPoints
(
dst_to_src
,
dst_to_src_points
,
3
);
x_dx
=
dst_to_src_points
[
1
].
X
-
dst_to_src_points
[
0
].
X
;
x_dy
=
dst_to_src_points
[
1
].
Y
-
dst_to_src_points
[
0
].
Y
;
y_dx
=
dst_to_src_points
[
2
].
X
-
dst_to_src_points
[
0
].
X
;
y_dy
=
dst_to_src_points
[
2
].
Y
-
dst_to_src_points
[
0
].
Y
;
for
(
x
=
dst_area
.
left
;
x
<
dst_area
.
right
;
x
++
)
{
for
(
y
=
dst_area
.
top
;
y
<
dst_area
.
bottom
;
y
++
)
{
GpPointF
src_pointf
;
int
src_x
,
src_y
;
ARGB
*
src_color
;
src_pointf
.
X
=
x
;
src_pointf
.
Y
=
y
;
INT
src_x
,
src_y
;
ARGB
*
dst_color
;
GdipTransformMatrixPoints
(
dst_to_src
,
&
src_pointf
,
1
);
src_pointf
.
X
=
dst_to_src_points
[
0
].
X
+
x
*
x_dx
+
y
*
y_dx
;
src_pointf
.
Y
=
dst_to_src_points
[
0
].
Y
+
x
*
x_dy
+
y
*
y_dy
;
src_x
=
roundr
(
src_pointf
.
X
);
src_y
=
roundr
(
src_pointf
.
Y
);
src_color
=
(
ARGB
*
)(
data
+
stride
*
(
y
-
dst_area
.
top
)
+
sizeof
(
ARGB
)
*
(
x
-
dst_area
.
left
));
dst_color
=
(
ARGB
*
)(
dst_data
+
dst_
stride
*
(
y
-
dst_area
.
top
)
+
sizeof
(
ARGB
)
*
(
x
-
dst_area
.
left
));
if
(
src_x
<
src_area
.
left
||
src_x
>=
src_area
.
right
||
src_y
<
src_area
.
top
||
src_y
>=
src_area
.
bottom
)
*
src_color
=
0
;
if
(
src_pointf
.
X
>=
srcx
&&
src_pointf
.
X
<
srcx
+
srcwidth
&&
src_pointf
.
Y
>=
srcy
&&
src_pointf
.
Y
<
srcy
+
srcheight
)
*
dst_color
=
sample_bitmap_pixel
(
&
src_area
,
src_data
,
bitmap
->
width
,
bitmap
->
height
,
src_x
,
src_y
,
imageAttributes
);
else
GdipBitmapGetPixel
(
bitmap
,
src_x
,
src_y
,
src_color
)
;
*
dst_color
=
0
;
}
}
GdipDeleteMatrix
(
dst_to_src
);
if
(
imageAttributes
)
{
apply_image_attributes
(
imageAttributes
,
data
,
dst_area
.
right
-
dst_area
.
left
,
dst_area
.
bottom
-
dst_area
.
top
,
stride
,
ColorAdjustTypeBitmap
);
}
GdipFree
(
src_data
);
apply_image_attributes
(
imageAttributes
,
dst_data
,
dst_area
.
right
-
dst_area
.
left
,
dst_area
.
bottom
-
dst_area
.
top
,
dst_stride
,
ColorAdjustTypeBitmap
);
stat
=
alpha_blend_pixels
(
graphics
,
dst_area
.
left
,
dst_area
.
top
,
d
ata
,
dst_area
.
right
-
dst_area
.
left
,
dst_area
.
bottom
-
dst_area
.
top
,
stride
);
d
st_data
,
dst_area
.
right
-
dst_area
.
left
,
dst_area
.
bottom
-
dst_area
.
top
,
dst_
stride
);
GdipFree
(
data
);
GdipFree
(
d
st_d
ata
);
return
stat
;
}
...
...
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