- Sync gdiplus with Wine 1.1.29

svn path=/trunk/; revision=42989
This commit is contained in:
Dmitry Chapyshev 2009-09-03 15:07:25 +00:00
parent 2b26c07762
commit 5a6e6bdf2a
10 changed files with 1905 additions and 503 deletions

View file

@ -288,6 +288,17 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
(*line)->rect.Width = fabs(startpoint->X - endpoint->X);
(*line)->rect.Height = fabs(startpoint->Y - endpoint->Y);
if ((*line)->rect.Width == 0)
{
(*line)->rect.X -= (*line)->rect.Height / 2.0f;
(*line)->rect.Width = (*line)->rect.Height;
}
else if ((*line)->rect.Height == 0)
{
(*line)->rect.Y -= (*line)->rect.Width / 2.0f;
(*line)->rect.Height = (*line)->rect.Width;
}
(*line)->blendcount = 1;
(*line)->blendfac = GdipAlloc(sizeof(REAL));
(*line)->blendpos = GdipAlloc(sizeof(REAL));
@ -686,9 +697,9 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
n_y + n_height > ((GpBitmap*)image)->height)
return InvalidParameter;
IPicture_get_Handle(image->picture, (OLE_HANDLE*)&hbm);
hbm = ((GpBitmap*)image)->hbitmap;
if(!hbm) return GenericError;
IPicture_get_CurDC(image->picture, &hdc);
hdc = ((GpBitmap*)image)->hdc;
bm_is_selected = (hdc != 0);
pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
@ -1342,6 +1353,13 @@ GpStatus WINGDIPAPI GdipSetPathGradientBlend(GpPathGradient *brush, GDIPCONST RE
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient *brush,
GDIPCONST ARGB *blend, GDIPCONST REAL *pos, INT count)
{
FIXME("(%p,%p,%p,%i): stub\n", brush, blend, pos, count);
return NotImplemented;
}
GpStatus WINGDIPAPI GdipSetPathGradientCenterColor(GpPathGradient *grad,
ARGB argb)
{
@ -1551,12 +1569,33 @@ GpStatus WINGDIPAPI GdipRotateTextureTransform(GpTexture* brush, REAL angle,
GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
REAL scale)
{
static int calls;
REAL factors[3];
REAL positions[3];
int num_points = 0;
if(!(calls++))
FIXME("not implemented\n");
TRACE("(%p,%.2f,%.2f)\n", brush, focus, scale);
return NotImplemented;
if (!brush) return InvalidParameter;
if (focus != 0.0)
{
factors[num_points] = 0.0;
positions[num_points] = 0.0;
num_points++;
}
factors[num_points] = scale;
positions[num_points] = focus;
num_points++;
if (focus != 1.0)
{
factors[num_points] = 0.0;
positions[num_points] = 1.0;
num_points++;
}
return GdipSetLineBlend(brush, factors, positions, num_points);
}
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,

View file

@ -399,6 +399,25 @@ BOOL lengthen_path(GpPath *path, INT len)
return TRUE;
}
void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride)
{
UINT x, y;
for (y=0; y<height; y++)
{
const BYTE *src=src_bits+y*src_stride;
BYTE *dst=dst_bits+y*dst_stride;
for (x=0; x<width; x++)
{
BYTE alpha=src[3];
*dst++ = *src++ * alpha / 255;
*dst++ = *src++ * alpha / 255;
*dst++ = *src++ * alpha / 255;
*dst++ = *src++;
}
}
}
/* recursive deletion of GpRegion nodes */
inline void delete_element(region_element* element)
{

View file

@ -27,6 +27,7 @@
<library>user32</library>
<library>gdi32</library>
<library>kernel32</library>
<library>windowscodecs</library>
<library>ntdll</library>
</module>
</group>

View file

@ -165,11 +165,11 @@
@ stdcall GdipDrawClosedCurveI(ptr ptr ptr long)
@ stdcall GdipDrawCurve2(ptr ptr ptr long long)
@ stdcall GdipDrawCurve2I(ptr ptr ptr long long)
@ stub GdipDrawCurve3
@ stub GdipDrawCurve3I
@ stdcall GdipDrawCurve3(ptr ptr ptr long long long long)
@ stdcall GdipDrawCurve3I(ptr ptr ptr long long long long)
@ stdcall GdipDrawCurve(ptr ptr ptr long)
@ stdcall GdipDrawCurveI(ptr ptr ptr long)
@ stub GdipDrawDriverString
@ stdcall GdipDrawDriverString(ptr ptr long ptr ptr ptr long ptr)
@ stdcall GdipDrawEllipse(ptr ptr long long long long)
@ stdcall GdipDrawEllipseI(ptr ptr long long long long)
@ stdcall GdipDrawImage(ptr ptr long long)
@ -291,7 +291,7 @@
@ stdcall GdipGetImageHeight(ptr ptr)
@ stdcall GdipGetImageHorizontalResolution(ptr ptr)
@ stub GdipGetImageItemData
@ stub GdipGetImagePalette
@ stdcall GdipGetImagePalette(ptr ptr long)
@ stdcall GdipGetImagePaletteSize(ptr ptr)
@ stdcall GdipGetImagePixelFormat(ptr ptr)
@ stdcall GdipGetImageRawFormat(ptr ptr)
@ -400,8 +400,8 @@
@ stub GdipGetTextureImage
@ stdcall GdipGetTextureTransform(ptr ptr)
@ stdcall GdipGetTextureWrapMode(ptr ptr)
@ stub GdipGetVisibleClipBounds
@ stub GdipGetVisibleClipBoundsI
@ stdcall GdipGetVisibleClipBounds(ptr ptr)
@ stdcall GdipGetVisibleClipBoundsI(ptr ptr)
@ stdcall GdipGetWorldTransform(ptr ptr)
@ stdcall GdipGraphicsClear(ptr long)
@ stub GdipGraphicsSetAbort
@ -429,18 +429,18 @@
@ stdcall GdipIsVisiblePathPointI(ptr long long ptr ptr)
@ stdcall GdipIsVisiblePoint(ptr long long ptr)
@ stdcall GdipIsVisiblePointI(ptr long long ptr)
@ stub GdipIsVisibleRect
@ stub GdipIsVisibleRectI
@ stub GdipIsVisibleRegionPoint
@ stub GdipIsVisibleRegionPointI
@ stub GdipIsVisibleRegionRect
@ stub GdipIsVisibleRegionRectI
@ stdcall GdipIsVisibleRect(ptr long long long long ptr)
@ stdcall GdipIsVisibleRectI(ptr long long long long ptr)
@ stdcall GdipIsVisibleRegionPoint(ptr long long ptr ptr)
@ stdcall GdipIsVisibleRegionPointI(ptr long long ptr ptr)
@ stdcall GdipIsVisibleRegionRect(ptr long long long long ptr ptr)
@ stdcall GdipIsVisibleRegionRectI(ptr long long long long ptr ptr)
@ stdcall GdipLoadImageFromFile(wstr ptr)
@ stdcall GdipLoadImageFromFileICM(wstr ptr)
@ stdcall GdipLoadImageFromStream(ptr ptr)
@ stdcall GdipLoadImageFromStreamICM(ptr ptr)
@ stdcall GdipMeasureCharacterRanges(ptr wstr long ptr ptr ptr long ptr)
@ stub GdipMeasureDriverString
@ stdcall GdipMeasureDriverString(ptr ptr long ptr ptr long ptr ptr)
@ stdcall GdipMeasureString(ptr wstr long ptr ptr ptr ptr ptr ptr)
@ stub GdipMultiplyLineTransform
@ stdcall GdipMultiplyMatrix(ptr ptr long)
@ -469,7 +469,7 @@
@ stub GdipRecordMetafile
@ stdcall GdipRecordMetafileFileName(wstr long long ptr long wstr ptr)
@ stdcall GdipRecordMetafileFileNameI(wstr long long ptr long wstr ptr)
@ stub GdipRecordMetafileI
@ stdcall GdipRecordMetafileI(long long ptr long wstr ptr)
@ stub GdipRecordMetafileStream
@ stub GdipRecordMetafileStreamI
@ stdcall GdipReleaseDC(ptr ptr)
@ -556,7 +556,7 @@
@ stdcall GdipSetPathGradientGammaCorrection(ptr long)
@ stub GdipSetPathGradientLinearBlend
@ stub GdipSetPathGradientPath
@ stub GdipSetPathGradientPresetBlend
@ stdcall GdipSetPathGradientPresetBlend(ptr ptr ptr long)
@ stdcall GdipSetPathGradientSigmaBlend(ptr long long)
@ stdcall GdipSetPathGradientSurroundColorsWithCount(ptr ptr ptr)
@ stub GdipSetPathGradientTransform

View file

@ -29,6 +29,7 @@
#include "objbase.h"
#include "ocidl.h"
#include "wine/list.h"
#include "gdiplus.h"
@ -67,6 +68,11 @@ static inline INT roundr(REAL x)
return (INT) floorf(x + 0.5);
}
static inline INT ceilr(REAL x)
{
return (INT) ceilf(x);
}
static inline REAL deg2rad(REAL degrees)
{
return M_PI * degrees / 180.0;
@ -74,6 +80,9 @@ static inline REAL deg2rad(REAL degrees)
extern const char *debugstr_rectf(CONST RectF* rc);
extern void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
BYTE *dst_bits, INT dst_stride, const BYTE *src_bits, INT src_stride);
struct GpPen{
UINT style;
GpUnit unit;
@ -109,6 +118,8 @@ struct GpGraphics{
BOOL busy; /* hdc handle obtained by GdipGetDC */
GpRegion *clip;
UINT textcontrast; /* not used yet. get/set only */
struct list containers;
GraphicsContainer contid; /* last-issued container ID */
};
struct GpBrush{
@ -214,14 +225,25 @@ struct GpBitmap{
ImageLockMode lockmode;
INT numlocks;
BYTE *bitmapbits; /* pointer to the buffer we passed in BitmapLockBits */
HBITMAP hbitmap;
HDC hdc;
BYTE *bits; /* actual image bits if this is a DIB */
INT stride; /* stride of bits if this is a DIB */
};
struct GpCachedBitmap{
GpImage *image;
};
struct color_key{
BOOL enabled;
ARGB low;
ARGB high;
};
struct GpImageAttributes{
WrapMode wrap;
struct color_key colorkeys[ColorAdjustTypeCount];
};
struct GpFont{

View file

@ -38,6 +38,7 @@
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
@ -941,6 +942,153 @@ GpStatus trace_path(GpGraphics *graphics, GpPath *path)
return result;
}
typedef struct _GraphicsContainerItem {
struct list entry;
GraphicsContainer contid;
SmoothingMode smoothing;
CompositingQuality compqual;
InterpolationMode interpolation;
CompositingMode compmode;
TextRenderingHint texthint;
REAL scale;
GpUnit unit;
PixelOffsetMode pixeloffset;
UINT textcontrast;
GpMatrix* worldtrans;
GpRegion* clip;
} GraphicsContainerItem;
static GpStatus init_container(GraphicsContainerItem** container,
GDIPCONST GpGraphics* graphics){
GpStatus sts;
*container = GdipAlloc(sizeof(GraphicsContainerItem));
if(!(*container))
return OutOfMemory;
(*container)->contid = graphics->contid + 1;
(*container)->smoothing = graphics->smoothing;
(*container)->compqual = graphics->compqual;
(*container)->interpolation = graphics->interpolation;
(*container)->compmode = graphics->compmode;
(*container)->texthint = graphics->texthint;
(*container)->scale = graphics->scale;
(*container)->unit = graphics->unit;
(*container)->textcontrast = graphics->textcontrast;
(*container)->pixeloffset = graphics->pixeloffset;
sts = GdipCloneMatrix(graphics->worldtrans, &(*container)->worldtrans);
if(sts != Ok){
GdipFree(*container);
*container = NULL;
return sts;
}
sts = GdipCloneRegion(graphics->clip, &(*container)->clip);
if(sts != Ok){
GdipDeleteMatrix((*container)->worldtrans);
GdipFree(*container);
*container = NULL;
return sts;
}
return Ok;
}
static void delete_container(GraphicsContainerItem* container){
GdipDeleteMatrix(container->worldtrans);
GdipDeleteRegion(container->clip);
GdipFree(container);
}
static GpStatus restore_container(GpGraphics* graphics,
GDIPCONST GraphicsContainerItem* container){
GpStatus sts;
GpMatrix *newTrans;
GpRegion *newClip;
sts = GdipCloneMatrix(container->worldtrans, &newTrans);
if(sts != Ok)
return sts;
sts = GdipCloneRegion(container->clip, &newClip);
if(sts != Ok){
GdipDeleteMatrix(newTrans);
return sts;
}
GdipDeleteMatrix(graphics->worldtrans);
graphics->worldtrans = newTrans;
GdipDeleteRegion(graphics->clip);
graphics->clip = newClip;
graphics->contid = container->contid - 1;
graphics->smoothing = container->smoothing;
graphics->compqual = container->compqual;
graphics->interpolation = container->interpolation;
graphics->compmode = container->compmode;
graphics->texthint = container->texthint;
graphics->scale = container->scale;
graphics->unit = container->unit;
graphics->textcontrast = container->textcontrast;
graphics->pixeloffset = container->pixeloffset;
return Ok;
}
static GpStatus get_graphics_bounds(GpGraphics* graphics, GpRectF* rect)
{
RECT wnd_rect;
if(graphics->hwnd) {
if(!GetClientRect(graphics->hwnd, &wnd_rect))
return GenericError;
rect->X = wnd_rect.left;
rect->Y = wnd_rect.top;
rect->Width = wnd_rect.right - wnd_rect.left;
rect->Height = wnd_rect.bottom - wnd_rect.top;
}else{
rect->X = 0;
rect->Y = 0;
rect->Width = GetDeviceCaps(graphics->hdc, HORZRES);
rect->Height = GetDeviceCaps(graphics->hdc, VERTRES);
}
return Ok;
}
/* on success, rgn will contain the region of the graphics object which
* is visible after clipping has been applied */
static GpStatus get_visible_clip_region(GpGraphics *graphics, GpRegion *rgn)
{
GpStatus stat;
GpRectF rectf;
GpRegion* tmp;
if((stat = get_graphics_bounds(graphics, &rectf)) != Ok)
return stat;
if((stat = GdipCreateRegion(&tmp)) != Ok)
return stat;
if((stat = GdipCombineRegionRect(tmp, &rectf, CombineModeReplace)) != Ok)
goto end;
if((stat = GdipCombineRegionRegion(tmp, graphics->clip, CombineModeIntersect)) != Ok)
goto end;
stat = GdipCombineRegionRegion(rgn, tmp, CombineModeReplace);
end:
GdipDeleteRegion(tmp);
return stat;
}
GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
{
TRACE("(%p, %p)\n", hdc, graphics);
@ -955,7 +1103,7 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
TRACE("(%p, %p, %p)\n", hdc, hDevice, graphics);
if(hDevice != NULL) {
FIXME("Don't know how to hadle parameter hDevice\n");
FIXME("Don't know how to handle parameter hDevice\n");
return NotImplemented;
}
@ -991,6 +1139,8 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
(*graphics)->scale = 1.0;
(*graphics)->busy = FALSE;
(*graphics)->textcontrast = 4;
list_init(&(*graphics)->containers);
(*graphics)->contid = 0;
return Ok;
}
@ -1155,6 +1305,7 @@ GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR * filename,
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
{
GraphicsContainerItem *cont, *next;
TRACE("(%p)\n", graphics);
if(!graphics) return InvalidParameter;
@ -1163,6 +1314,11 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
if(graphics->owndc)
ReleaseDC(graphics->hwnd, graphics->hdc);
LIST_FOR_EACH_ENTRY_SAFE(cont, next, &graphics->containers, GraphicsContainerItem, entry){
list_remove(&cont->entry);
delete_container(cont);
}
GdipDeleteRegion(graphics->clip);
GdipDeleteMatrix(graphics->worldtrans);
GdipFree(graphics);
@ -1423,7 +1579,7 @@ GpStatus WINGDIPAPI GdipDrawCurveI(GpGraphics *graphics, GpPen *pen,
TRACE("(%p, %p, %p, %d)\n", graphics, pen, points, count);
if(!points || count <= 0)
if(!points)
return InvalidParameter;
pointsF = GdipAlloc(sizeof(GpPointF)*count);
@ -1459,7 +1615,13 @@ GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics *graphics, GpPen *pen,
if(graphics->busy)
return ObjectBusy;
if(count < 2)
return InvalidParameter;
pt = GdipAlloc(len_pt * sizeof(GpPointF));
if(!pt)
return OutOfMemory;
tension = tension * TENSION_CONST;
calc_curve_bezier_endp(points[0].X, points[0].Y, points[1].X, points[1].Y,
@ -1508,7 +1670,7 @@ GpStatus WINGDIPAPI GdipDrawCurve2I(GpGraphics *graphics, GpPen *pen,
TRACE("(%p, %p, %p, %d, %.2f)\n", graphics, pen, points, count, tension);
if(!points || count <= 0)
if(!points)
return InvalidParameter;
pointsF = GdipAlloc(sizeof(GpPointF)*count);
@ -1526,6 +1688,36 @@ GpStatus WINGDIPAPI GdipDrawCurve2I(GpGraphics *graphics, GpPen *pen,
return ret;
}
GpStatus WINGDIPAPI GdipDrawCurve3(GpGraphics *graphics, GpPen *pen,
GDIPCONST GpPointF *points, INT count, INT offset, INT numberOfSegments,
REAL tension)
{
TRACE("(%p, %p, %p, %d, %d, %d, %.2f)\n", graphics, pen, points, count, offset, numberOfSegments, tension);
if(offset >= count || numberOfSegments > count - offset - 1 || numberOfSegments <= 0){
return InvalidParameter;
}
return GdipDrawCurve2(graphics, pen, points + offset, numberOfSegments + 1, tension);
}
GpStatus WINGDIPAPI GdipDrawCurve3I(GpGraphics *graphics, GpPen *pen,
GDIPCONST GpPoint *points, INT count, INT offset, INT numberOfSegments,
REAL tension)
{
TRACE("(%p, %p, %p, %d, %d, %d, %.2f)\n", graphics, pen, points, count, offset, numberOfSegments, tension);
if(count < 0){
return OutOfMemory;
}
if(offset >= count || numberOfSegments > count - offset - 1 || numberOfSegments <= 0){
return InvalidParameter;
}
return GdipDrawCurve2I(graphics, pen, points + offset, numberOfSegments + 1, tension);
}
GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x,
REAL y, REAL width, REAL height)
{
@ -1569,39 +1761,34 @@ GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x,
GpStatus WINGDIPAPI GdipDrawImage(GpGraphics *graphics, GpImage *image, REAL x, REAL y)
{
UINT width, height;
GpPointF points[3];
TRACE("(%p, %p, %.2f, %.2f)\n", graphics, image, x, y);
/* IPicture::Render uses LONG coords */
return GdipDrawImageI(graphics,image,roundr(x),roundr(y));
}
GpStatus WINGDIPAPI GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x,
INT y)
{
UINT width, height, srcw, srch;
TRACE("(%p, %p, %d, %d)\n", graphics, image, x, y);
if(!graphics || !image)
return InvalidParameter;
GdipGetImageWidth(image, &width);
GdipGetImageHeight(image, &height);
srcw = width * (((REAL) INCH_HIMETRIC) /
((REAL) GetDeviceCaps(graphics->hdc, LOGPIXELSX)));
srch = height * (((REAL) INCH_HIMETRIC) /
((REAL) GetDeviceCaps(graphics->hdc, LOGPIXELSY)));
/* FIXME: we should use the graphics and image dpi, somehow */
if(image->type != ImageTypeMetafile){
y += height;
height *= -1;
}
points[0].X = points[2].X = x;
points[0].Y = points[1].Y = y;
points[1].X = x + width;
points[2].Y = y + height;
IPicture_Render(image->picture, graphics->hdc, x, y, width, height,
0, 0, srcw, srch, NULL);
return GdipDrawImagePointsRect(graphics, image, points, 3, 0, 0, width, height,
UnitPixel, NULL, NULL, NULL);
}
return Ok;
GpStatus WINGDIPAPI GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x,
INT y)
{
TRACE("(%p, %p, %d, %d)\n", graphics, image, x, y);
return GdipDrawImage(graphics, image, (REAL)x, (REAL)y);
}
GpStatus WINGDIPAPI GdipDrawImagePointRect(GpGraphics *graphics, GpImage *image,
@ -1651,6 +1838,11 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
if(!graphics || !image || !points || count != 3)
return InvalidParameter;
memcpy(ptf, points, 3 * sizeof(GpPointF));
transform_and_round_points(graphics, pti, ptf, 3);
if (image->picture)
{
if(srcUnit == UnitInch)
dx = dy = (REAL) INCH_HIMETRIC;
else if(srcUnit == UnitPixel){
@ -1662,9 +1854,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
else
return NotImplemented;
memcpy(ptf, points, 3 * sizeof(GpPointF));
transform_and_round_points(graphics, pti, ptf, 3);
/* IPicture renders bitmaps with the y-axis reversed
* FIXME: flipping for unknown image type might not be correct. */
if(image->type != ImageTypeMetafile){
@ -1683,6 +1872,94 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
callback(callbackData);
return GenericError;
}
}
else if (image->type == ImageTypeBitmap && ((GpBitmap*)image)->hbitmap)
{
HDC hdc;
GpBitmap* bitmap = (GpBitmap*)image;
int temp_hdc=0, temp_bitmap=0;
HBITMAP hbitmap, old_hbm=NULL;
if (srcUnit == UnitInch)
dx = dy = 96.0; /* FIXME: use the image resolution */
else if (srcUnit == UnitPixel)
dx = dy = 1.0;
else
return NotImplemented;
if (bitmap->format == PixelFormat32bppARGB)
{
BITMAPINFOHEADER bih;
BYTE *temp_bits;
/* we need a bitmap with premultiplied alpha */
hdc = CreateCompatibleDC(0);
temp_hdc = 1;
temp_bitmap = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bitmap->width;
bih.biHeight = -bitmap->height;
bih.biPlanes = 1;
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
hbitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS,
(void**)&temp_bits, NULL, 0);
convert_32bppARGB_to_32bppPARGB(bitmap->width, bitmap->height,
temp_bits, bitmap->width*4, bitmap->bits, bitmap->stride);
}
else
{
hbitmap = bitmap->hbitmap;
hdc = bitmap->hdc;
temp_hdc = (hdc == 0);
}
if (temp_hdc)
{
if (!hdc) hdc = CreateCompatibleDC(0);
old_hbm = SelectObject(hdc, hbitmap);
}
if (bitmap->format == PixelFormat32bppARGB || bitmap->format == PixelFormat32bppPARGB)
{
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255;
bf.AlphaFormat = AC_SRC_ALPHA;
GdiAlphaBlend(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, bf);
}
else
{
StretchBlt(graphics->hdc, pti[0].x, pti[0].y, pti[1].x-pti[0].x, pti[2].y-pti[0].y,
hdc, srcx*dx, srcy*dy, srcwidth*dx, srcheight*dy, SRCCOPY);
}
if (temp_hdc)
{
SelectObject(hdc, old_hbm);
DeleteDC(hdc);
}
if (temp_bitmap)
DeleteObject(hbitmap);
}
else
{
ERR("GpImage with no IPicture or HBITMAP?!\n");
return NotImplemented;
}
return Ok;
}
@ -2090,8 +2367,10 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
WCHAR* stringdup;
REAL angle, ang_cos, ang_sin, rel_width, rel_height;
INT sum = 0, height = 0, offsety = 0, fit, fitcpy, save_state, i, j, lret, nwidth,
nheight;
nheight, lineend;
SIZE size;
POINT drawbase;
UINT drawflags;
RECT drawcoord;
TRACE("(%p, %s, %i, %p, %s, %p, %p)\n", graphics, debugstr_wn(string, length),
@ -2183,10 +2462,10 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
pt[1].X = 1.0;
pt[1].Y = 0.0;
GdipTransformMatrixPoints(graphics->worldtrans, pt, 2);
angle = gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
ang_cos = cos(angle);
ang_sin = sin(angle);
lfw.lfEscapement = lfw.lfOrientation = -roundr((angle / M_PI) * 1800.0);
lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0);
gdifont = CreateFontIndirectW(&lfw);
DeleteObject(SelectObject(graphics->hdc, CreateFontIndirectW(&lfw)));
@ -2201,17 +2480,35 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
length = j;
if (!format || format->align == StringAlignmentNear)
{
drawbase.x = corners[0].x;
drawbase.y = corners[0].y;
drawflags = DT_NOCLIP | DT_EXPANDTABS;
}
else if (format->align == StringAlignmentCenter)
{
drawbase.x = (corners[0].x + corners[1].x)/2;
drawbase.y = (corners[0].y + corners[1].y)/2;
drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_CENTER;
}
else /* (format->align == StringAlignmentFar) */
{
drawbase.x = corners[1].x;
drawbase.y = corners[1].y;
drawflags = DT_NOCLIP | DT_EXPANDTABS | DT_RIGHT;
}
while(sum < length){
drawcoord.left = corners[0].x + roundr(ang_sin * (REAL) height);
drawcoord.top = corners[0].y + roundr(ang_cos * (REAL) height);
drawcoord.left = drawcoord.right = drawbase.x + roundr(ang_sin * (REAL) height);
drawcoord.top = drawcoord.bottom = drawbase.y + roundr(ang_cos * (REAL) height);
GetTextExtentExPointW(graphics->hdc, stringdup + sum, length - sum,
nwidth, &fit, NULL, &size);
fitcpy = fit;
if(fit == 0){
DrawTextW(graphics->hdc, stringdup + sum, 1, &drawcoord, DT_NOCLIP |
DT_EXPANDTABS);
DrawTextW(graphics->hdc, stringdup + sum, 1, &drawcoord, drawflags);
break;
}
@ -2221,7 +2518,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
/* Line break code (may look strange, but it imitates windows). */
if(lret < fit)
fit = lret; /* this is not an off-by-one error */
lineend = fit = lret; /* this is not an off-by-one error */
else if(fit < (length - sum)){
if(*(stringdup + sum + fit) == ' ')
while(*(stringdup + sum + fit) == ' ')
@ -2238,9 +2535,15 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
break;
}
}
lineend = fit;
while(*(stringdup + sum + lineend - 1) == ' ' ||
*(stringdup + sum + lineend - 1) == '\t')
lineend--;
}
DrawTextW(graphics->hdc, stringdup + sum, min(length - sum, fit),
&drawcoord, DT_NOCLIP | DT_EXPANDTABS);
else
lineend = fit;
DrawTextW(graphics->hdc, stringdup + sum, min(length - sum, lineend),
&drawcoord, drawflags);
sum += fit + (lret < fitcpy ? 1 : 0);
height += size.cy;
@ -2349,12 +2652,14 @@ GpStatus WINGDIPAPI GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, brush->gdibrush);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
transform_and_round_points(graphics, pti, ptf, 2);
BeginPath(graphics->hdc);
Ellipse(graphics->hdc, pti[0].x, pti[0].y, pti[1].x, pti[1].y);
EndPath(graphics->hdc);
brush_fill_path(graphics, brush);
RestoreDC(graphics->hdc, save_state);
@ -2421,10 +2726,12 @@ GpStatus WINGDIPAPI GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x,
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, brush->gdibrush);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
BeginPath(graphics->hdc);
draw_pie(graphics, x, y, width, height, startAngle, sweepAngle);
EndPath(graphics->hdc);
brush_fill_path(graphics, brush);
RestoreDC(graphics->hdc, save_state);
@ -2467,13 +2774,16 @@ GpStatus WINGDIPAPI GdipFillPolygon(GpGraphics *graphics, GpBrush *brush,
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, brush->gdibrush);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
SetPolyFillMode(graphics->hdc, (fillMode == FillModeAlternate ? ALTERNATE
: WINDING));
transform_and_round_points(graphics, pti, ptf, count);
BeginPath(graphics->hdc);
Polygon(graphics->hdc, pti, count);
EndPath(graphics->hdc);
brush_fill_path(graphics, brush);
RestoreDC(graphics->hdc, save_state);
@ -2514,13 +2824,16 @@ GpStatus WINGDIPAPI GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, brush->gdibrush);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
SetPolyFillMode(graphics->hdc, (fillMode == FillModeAlternate ? ALTERNATE
: WINDING));
transform_and_round_points(graphics, pti, ptf, count);
BeginPath(graphics->hdc);
Polygon(graphics->hdc, pti, count);
EndPath(graphics->hdc);
brush_fill_path(graphics, brush);
RestoreDC(graphics->hdc, save_state);
@ -2613,12 +2926,14 @@ GpStatus WINGDIPAPI GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush,
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, brush->gdibrush);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
transform_and_round_points(graphics, pti, ptf, 4);
BeginPath(graphics->hdc);
Polygon(graphics->hdc, pti, 4);
EndPath(graphics->hdc);
brush_fill_path(graphics, brush);
RestoreDC(graphics->hdc, save_state);
@ -2682,6 +2997,7 @@ GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
INT save_state;
GpStatus status;
HRGN hrgn;
RECT rc;
TRACE("(%p, %p, %p)\n", graphics, brush, region);
@ -2697,9 +3013,17 @@ GpStatus WINGDIPAPI GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SelectObject(graphics->hdc, GetStockObject(NULL_PEN));
FillRgn(graphics->hdc, hrgn, brush->gdibrush);
ExtSelectClipRgn(graphics->hdc, hrgn, RGN_AND);
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
{
BeginPath(graphics->hdc);
Rectangle(graphics->hdc, rc.left, rc.top, rc.right, rc.bottom);
EndPath(graphics->hdc);
brush_fill_path(graphics, brush);
}
RestoreDC(graphics->hdc, save_state);
@ -2912,6 +3236,56 @@ GpStatus WINGDIPAPI GdipGetTextRenderingHint(GpGraphics *graphics,
return Ok;
}
GpStatus WINGDIPAPI GdipGetVisibleClipBounds(GpGraphics *graphics, GpRectF *rect)
{
GpRegion *clip_rgn;
GpStatus stat;
TRACE("(%p, %p)\n", graphics, rect);
if(!graphics || !rect)
return InvalidParameter;
if(graphics->busy)
return ObjectBusy;
/* intersect window and graphics clipping regions */
if((stat = GdipCreateRegion(&clip_rgn)) != Ok)
return stat;
if((stat = get_visible_clip_region(graphics, clip_rgn)) != Ok)
goto cleanup;
/* get bounds of the region */
stat = GdipGetRegionBounds(clip_rgn, graphics, rect);
cleanup:
GdipDeleteRegion(clip_rgn);
return stat;
}
GpStatus WINGDIPAPI GdipGetVisibleClipBoundsI(GpGraphics *graphics, GpRect *rect)
{
GpRectF rectf;
GpStatus stat;
TRACE("(%p, %p)\n", graphics, rect);
if(!graphics || !rect)
return InvalidParameter;
if((stat = GdipGetVisibleClipBounds(graphics, &rectf)) == Ok)
{
rect->X = roundr(rectf.X);
rect->Y = roundr(rectf.Y);
rect->Width = roundr(rectf.Width);
rect->Height = roundr(rectf.Height);
}
return stat;
}
GpStatus WINGDIPAPI GdipGetWorldTransform(GpGraphics *graphics, GpMatrix *matrix)
{
TRACE("(%p, %p)\n", graphics, matrix);
@ -2930,7 +3304,7 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
{
GpSolidFill *brush;
GpStatus stat;
RECT rect;
GpRectF wnd_rect;
TRACE("(%p, %x)\n", graphics, color);
@ -2943,18 +3317,13 @@ GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
if((stat = GdipCreateSolidFill(color, &brush)) != Ok)
return stat;
if(graphics->hwnd){
if(!GetWindowRect(graphics->hwnd, &rect)){
if((stat = get_graphics_bounds(graphics, &wnd_rect)) != Ok){
GdipDeleteBrush((GpBrush*)brush);
return GenericError;
return stat;
}
GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, (REAL)(rect.right - rect.left),
(REAL)(rect.bottom - rect.top));
}
else
GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, (REAL)GetDeviceCaps(graphics->hdc, HORZRES),
(REAL)GetDeviceCaps(graphics->hdc, VERTRES));
GdipFillRectangle(graphics, (GpBrush*)brush, wnd_rect.X, wnd_rect.Y,
wnd_rect.Width, wnd_rect.Height);
GdipDeleteBrush((GpBrush*)brush);
@ -2973,7 +3342,11 @@ GpStatus WINGDIPAPI GdipIsClipEmpty(GpGraphics *graphics, BOOL *res)
GpStatus WINGDIPAPI GdipIsVisiblePoint(GpGraphics *graphics, REAL x, REAL y, BOOL *result)
{
FIXME("(%p, %.2f, %.2f, %p) stub\n", graphics, x, y, result);
GpStatus stat;
GpRegion* rgn;
GpPointF pt;
TRACE("(%p, %.2f, %.2f, %p)\n", graphics, x, y, result);
if(!graphics || !result)
return InvalidParameter;
@ -2981,12 +3354,37 @@ GpStatus WINGDIPAPI GdipIsVisiblePoint(GpGraphics *graphics, REAL x, REAL y, BOO
if(graphics->busy)
return ObjectBusy;
return NotImplemented;
pt.X = x;
pt.Y = y;
if((stat = GdipTransformPoints(graphics, CoordinateSpaceDevice,
CoordinateSpaceWorld, &pt, 1)) != Ok)
return stat;
if((stat = GdipCreateRegion(&rgn)) != Ok)
return stat;
if((stat = get_visible_clip_region(graphics, rgn)) != Ok)
goto cleanup;
stat = GdipIsVisibleRegionPoint(rgn, pt.X, pt.Y, graphics, result);
cleanup:
GdipDeleteRegion(rgn);
return stat;
}
GpStatus WINGDIPAPI GdipIsVisiblePointI(GpGraphics *graphics, INT x, INT y, BOOL *result)
{
FIXME("(%p, %d, %d, %p) stub\n", graphics, x, y, result);
return GdipIsVisiblePoint(graphics, (REAL)x, (REAL)y, result);
}
GpStatus WINGDIPAPI GdipIsVisibleRect(GpGraphics *graphics, REAL x, REAL y, REAL width, REAL height, BOOL *result)
{
GpStatus stat;
GpRegion* rgn;
GpPointF pts[2];
TRACE("(%p %.2f %.2f %.2f %.2f %p)\n", graphics, x, y, width, height, result);
if(!graphics || !result)
return InvalidParameter;
@ -2994,7 +3392,34 @@ GpStatus WINGDIPAPI GdipIsVisiblePointI(GpGraphics *graphics, INT x, INT y, BOOL
if(graphics->busy)
return ObjectBusy;
return NotImplemented;
pts[0].X = x;
pts[0].Y = y;
pts[1].X = x + width;
pts[1].Y = y + height;
if((stat = GdipTransformPoints(graphics, CoordinateSpaceDevice,
CoordinateSpaceWorld, pts, 2)) != Ok)
return stat;
pts[1].X -= pts[0].X;
pts[1].Y -= pts[0].Y;
if((stat = GdipCreateRegion(&rgn)) != Ok)
return stat;
if((stat = get_visible_clip_region(graphics, rgn)) != Ok)
goto cleanup;
stat = GdipIsVisibleRegionRect(rgn, pts[0].X, pts[0].Y, pts[1].X, pts[1].Y, graphics, result);
cleanup:
GdipDeleteRegion(rgn);
return stat;
}
GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y, INT width, INT height, BOOL *result)
{
return GdipIsVisibleRect(graphics, (REAL)x, (REAL)y, (REAL)width, (REAL)height, result);
}
GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics,
@ -3023,7 +3448,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
HFONT oldfont;
WCHAR* stringdup;
INT sum = 0, height = 0, fit, fitcpy, max_width = 0, i, j, lret, nwidth,
nheight;
nheight, lineend;
SIZE size;
TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics,
@ -3076,7 +3501,7 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
/* Line break code (may look strange, but it imitates windows). */
if(lret < fit)
fit = lret; /* this is not an off-by-one error */
lineend = fit = lret; /* this is not an off-by-one error */
else if(fit < (length - sum)){
if(*(stringdup + sum + fit) == ' ')
while(*(stringdup + sum + fit) == ' ')
@ -3093,9 +3518,15 @@ GpStatus WINGDIPAPI GdipMeasureString(GpGraphics *graphics,
break;
}
}
lineend = fit;
while(*(stringdup + sum + lineend - 1) == ' ' ||
*(stringdup + sum + lineend - 1) == '\t')
lineend--;
}
else
lineend = fit;
GetTextExtentExPointW(graphics->hdc, stringdup + sum, fit,
GetTextExtentExPointW(graphics->hdc, stringdup + sum, lineend,
nwidth, &j, NULL, &size);
sum += fit + (lret < fitcpy ? 1 : 0);
@ -3159,15 +3590,7 @@ GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
GpStatus WINGDIPAPI GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state)
{
static int calls;
if(!graphics)
return InvalidParameter;
if(!(calls++))
FIXME("graphics state not implemented\n");
return Ok;
return GdipEndContainer(graphics, state);
}
GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
@ -3186,26 +3609,27 @@ GpStatus WINGDIPAPI GdipRotateWorldTransform(GpGraphics *graphics, REAL angle,
GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state)
{
static int calls;
if(!graphics || !state)
return InvalidParameter;
if(!(calls++))
FIXME("graphics state not implemented\n");
*state = 0xdeadbeef;
return Ok;
return GdipBeginContainer2(graphics, state);
}
GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics *graphics, GraphicsContainer *state)
GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics *graphics,
GraphicsContainer *state)
{
FIXME("(%p, %p)\n", graphics, state);
GraphicsContainerItem *container;
GpStatus sts;
TRACE("(%p, %p)\n", graphics, state);
if(!graphics || !state)
return InvalidParameter;
*state = 0xdeadbeef;
sts = init_container(&container, graphics);
if(sts != Ok)
return sts;
list_add_head(&graphics->containers, &container->entry);
*state = graphics->contid = container->contid;
return Ok;
}
@ -3227,13 +3651,40 @@ GpStatus WINGDIPAPI GdipComment(GpGraphics *graphics, UINT sizeData, GDIPCONST B
return NotImplemented;
}
GpStatus WINGDIPAPI GdipEndContainer(GpGraphics *graphics, GraphicsState state)
GpStatus WINGDIPAPI GdipEndContainer(GpGraphics *graphics, GraphicsContainer state)
{
FIXME("(%p, 0x%x)\n", graphics, state);
GpStatus sts;
GraphicsContainerItem *container, *container2;
if(!graphics || !state)
TRACE("(%p, %x)\n", graphics, state);
if(!graphics)
return InvalidParameter;
LIST_FOR_EACH_ENTRY(container, &graphics->containers, GraphicsContainerItem, entry){
if(container->contid == state)
break;
}
/* did not find a matching container */
if(&container->entry == &graphics->containers)
return Ok;
sts = restore_container(graphics, container);
if(sts != Ok)
return sts;
/* remove all of the containers on top of the found container */
LIST_FOR_EACH_ENTRY_SAFE(container, container2, &graphics->containers, GraphicsContainerItem, entry){
if(container->contid == state)
break;
list_remove(&container->entry);
delete_container(container);
}
list_remove(&container->entry);
delete_container(container);
return Ok;
}
@ -3839,3 +4290,37 @@ GpStatus WINGDIPAPI GdipTranslateClipI(GpGraphics *graphics, INT dx, INT dy)
return GdipTranslateRegion(graphics->clip, (REAL)dx, (REAL)dy);
}
/*****************************************************************************
* GdipMeasureDriverString [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipMeasureDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length,
GDIPCONST GpFont *font, GDIPCONST PointF *positions,
INT flags, GDIPCONST GpMatrix *matrix, RectF *boundingBox)
{
FIXME("(%p %p %d %p %p %d %p %p): stub\n", graphics, text, length, font, positions, flags, matrix, boundingBox);
return NotImplemented;
}
/*****************************************************************************
* GdipDrawDriverString [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length,
GDIPCONST GpFont *font, GDIPCONST GpBrush *brush,
GDIPCONST PointF *positions, INT flags,
GDIPCONST GpMatrix *matrix )
{
FIXME("(%p %p %d %p %p %p %d %p): stub\n", graphics, text, length, font, brush, positions, flags, matrix);
return NotImplemented;
}
/*****************************************************************************
* GdipRecordMetafileI [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipRecordMetafileI(HDC hdc, EmfType type, GDIPCONST GpRect *frameRect,
MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
{
FIXME("(%p %d %p %d %p %p): stub\n", hdc, type, frameRect, frameUnit, desc, metafile);
return NotImplemented;
}

File diff suppressed because it is too large Load diff

View file

@ -68,15 +68,16 @@ GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
GpStatus WINGDIPAPI GdipSetImageAttributesColorKeys(GpImageAttributes *imageattr,
ColorAdjustType type, BOOL enableFlag, ARGB colorLow, ARGB colorHigh)
{
static int calls;
TRACE("(%p,%u,%i,%08x,%08x)\n", imageattr, type, enableFlag, colorLow, colorHigh);
if(!imageattr)
if(!imageattr || type >= ColorAdjustTypeCount)
return InvalidParameter;
if(!(calls++))
FIXME("not implemented\n");
imageattr->colorkeys[type].enabled = enableFlag;
imageattr->colorkeys[type].low = colorLow;
imageattr->colorkeys[type].high = colorHigh;
return NotImplemented;
return Ok;
}
GpStatus WINGDIPAPI GdipSetImageAttributesColorMatrix(GpImageAttributes *imageattr,

View file

@ -579,51 +579,63 @@ GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRe
*/
GpStatus WINGDIPAPI GdipCreateRegionHrgn(HRGN hrgn, GpRegion **region)
{
union {
RGNDATA data;
char buf[sizeof(RGNDATAHEADER) + sizeof(RECT)];
} rdata;
DWORD size;
GpRectF rectf;
GpPath *path;
LPRGNDATA buf;
LPRECT rect;
GpStatus stat;
GpPath* path;
GpRegion* local;
int i;
TRACE("(%p, %p)\n", hrgn, region);
if(!region || !(size = GetRegionData(hrgn, 0, NULL)))
return InvalidParameter;
if(size > sizeof(RGNDATAHEADER) + sizeof(RECT)){
FIXME("Only simple rect regions supported.\n");
*region = NULL;
return NotImplemented;
}
buf = GdipAlloc(size);
if(!buf)
return OutOfMemory;
if(!GetRegionData(hrgn, sizeof(rdata), &rdata.data))
if(!GetRegionData(hrgn, size, buf)){
GdipFree(buf);
return GenericError;
}
/* return empty region */
if(IsRectEmpty(&rdata.data.rdh.rcBound)){
stat = GdipCreateRegion(region);
if(stat == Ok)
GdipSetEmpty(*region);
if(buf->rdh.nCount == 0){
if((stat = GdipCreateRegion(&local)) != Ok){
GdipFree(buf);
return stat;
}
if((stat = GdipSetEmpty(local)) != Ok){
GdipFree(buf);
GdipDeleteRegion(local);
return stat;
}
*region = local;
GdipFree(buf);
return Ok;
}
if((stat = GdipCreatePath(FillModeAlternate, &path)) != Ok){
GdipFree(buf);
return stat;
}
rectf.X = (REAL)rdata.data.rdh.rcBound.left;
rectf.Y = (REAL)rdata.data.rdh.rcBound.top;
rectf.Width = (REAL)rdata.data.rdh.rcBound.right - rectf.X;
rectf.Height = (REAL)rdata.data.rdh.rcBound.bottom - rectf.Y;
stat = GdipCreatePath(FillModeAlternate, &path);
if(stat != Ok)
rect = (LPRECT)buf->Buffer;
for(i = 0; i < buf->rdh.nCount; i++){
if((stat = GdipAddPathRectangle(path, (REAL)rect->left, (REAL)rect->top,
(REAL)(rect->right - rect->left), (REAL)(rect->bottom - rect->top))) != Ok){
GdipFree(buf);
GdipDeletePath(path);
return stat;
GdipAddPathRectangle(path, rectf.X, rectf.Y, rectf.Width, rectf.Height);
}
rect++;
}
stat = GdipCreateRegionPath(path, region);
GdipDeletePath(path);
GdipFree(buf);
GdipDeletePath(path);
return stat;
}
@ -657,7 +669,8 @@ GpStatus WINGDIPAPI GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
if(!region || !graphics || !rect)
return InvalidParameter;
status = GdipGetRegionHRgn(region, graphics, &hrgn);
/* Contrary to MSDN, native ignores the graphics transform. */
status = GdipGetRegionHRgn(region, NULL, &hrgn);
if(status != Ok)
return status;
@ -1114,6 +1127,92 @@ GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics,
return Ok;
}
/*****************************************************************************
* GdipIsVisibleRegionRect [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipIsVisibleRegionRect(GpRegion* region, REAL x, REAL y, REAL w, REAL h, GpGraphics *graphics, BOOL *res)
{
HRGN hrgn;
GpStatus stat;
RECT rect;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %p, %p)\n", region, x, y, w, h, graphics, res);
if(!region || !res)
return InvalidParameter;
if((stat = GdipGetRegionHRgn(region, NULL, &hrgn)) != Ok)
return stat;
/* infinite */
if(!hrgn){
*res = TRUE;
return Ok;
}
rect.left = ceilr(x);
rect.top = ceilr(y);
rect.right = ceilr(x + w);
rect.bottom = ceilr(y + h);
*res = RectInRegion(hrgn, &rect);
DeleteObject(hrgn);
return Ok;
}
/*****************************************************************************
* GdipIsVisibleRegionRectI [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipIsVisibleRegionRectI(GpRegion* region, INT x, INT y, INT w, INT h, GpGraphics *graphics, BOOL *res)
{
TRACE("(%p, %d, %d, %d, %d, %p, %p)\n", region, x, y, w, h, graphics, res);
if(!region || !res)
return InvalidParameter;
return GdipIsVisibleRegionRect(region, (REAL)x, (REAL)y, (REAL)w, (REAL)h, graphics, res);
}
/*****************************************************************************
* GdipIsVisibleRegionPoint [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipIsVisibleRegionPoint(GpRegion* region, REAL x, REAL y, GpGraphics *graphics, BOOL *res)
{
HRGN hrgn;
GpStatus stat;
TRACE("(%p, %.2f, %.2f, %p, %p)\n", region, x, y, graphics, res);
if(!region || !res)
return InvalidParameter;
if((stat = GdipGetRegionHRgn(region, NULL, &hrgn)) != Ok)
return stat;
/* infinite */
if(!hrgn){
*res = TRUE;
return Ok;
}
*res = PtInRegion(hrgn, roundr(x), roundr(y));
DeleteObject(hrgn);
return Ok;
}
/*****************************************************************************
* GdipIsVisibleRegionPointI [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipIsVisibleRegionPointI(GpRegion* region, INT x, INT y, GpGraphics *graphics, BOOL *res)
{
TRACE("(%p, %d, %d, %p, %p)\n", region, x, y, graphics, res);
return GdipIsVisibleRegionPoint(region, (REAL)x, (REAL)y, graphics, res);
}
/*****************************************************************************
* GdipSetEmpty [GDIPLUS.@]
*/

View file

@ -39,11 +39,15 @@ GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap*,R
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap*,REAL);
/* Bitmap */
GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap*,CGpEffect*,RECT*,BOOL,VOID**,INT*);
GpStatus WINGDIPAPI GdipBitmapCreateApplyEffect(GpBitmap**,INT,CGpEffect*,RECT*,RECT*,GpBitmap**,BOOL,VOID**,INT*);
GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap*,INT,INT,ARGB*);
GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap*,GDIPCONST GpRect*,UINT,
PixelFormat,BitmapData*);
GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap*,INT,INT,ARGB);
GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap*,BitmapData*);
GpStatus WINGDIPAPI GdipCloneBitmapArea(REAL,REAL,REAL,REAL,PixelFormat,GpBitmap*,GpBitmap**);
GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT,INT,INT,INT,PixelFormat,GpBitmap*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromFile(GDIPCONST WCHAR*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromFileICM(GDIPCONST WCHAR*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO*,VOID*,GpBitmap**);
@ -55,6 +59,9 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT,INT,INT,PixelFormat,BYTE*,
GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromStream(IStream*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateBitmapFromStreamICM(IStream*,GpBitmap**);
GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap*,HBITMAP*,ARGB);
GpStatus WINGDIPAPI GdipCreateHICONFromBitmap(GpBitmap*,HICON*);
GpStatus WINGDIPAPI GdipDeleteEffect(CGpEffect*);
/* Brush */
GpStatus WINGDIPAPI GdipCloneBrush(GpBrush*,GpBrush**);
@ -118,6 +125,11 @@ GpStatus WINGDIPAPI GdipIsStyleAvailable(GDIPCONST GpFontFamily *, INT, BOOL*);
/* Graphics */
GpStatus WINGDIPAPI GdipFlush(GpGraphics*, GpFlushIntention);
GpStatus WINGDIPAPI GdipBeginContainer(GpGraphics*,GDIPCONST GpRectF*,GDIPCONST GpRectF*,GpUnit,GraphicsContainer*);
GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics*,GraphicsContainer*);
GpStatus WINGDIPAPI GdipBeginContainerI(GpGraphics*,GDIPCONST GpRect*,GDIPCONST GpRect*,GpUnit,GraphicsContainer*);
GpStatus WINGDIPAPI GdipEndContainer(GpGraphics*,GraphicsContainer);
GpStatus WINGDIPAPI GdipComment(GpGraphics*,UINT,GDIPCONST BYTE*);
GpStatus WINGDIPAPI GdipCreateFromHDC(HDC,GpGraphics**);
GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC,HANDLE,GpGraphics**);
GpStatus WINGDIPAPI GdipCreateFromHWND(HWND,GpGraphics**);
@ -137,10 +149,16 @@ GpStatus WINGDIPAPI GdipDrawCurve(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipDrawCurveI(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipDrawCurve2(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT,REAL);
GpStatus WINGDIPAPI GdipDrawCurve2I(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT,REAL);
GpStatus WINGDIPAPI GdipDrawCurve3(GpGraphics*,GpPen*,GDIPCONST GpPointF*,INT,INT,INT,REAL);
GpStatus WINGDIPAPI GdipDrawCurve3I(GpGraphics*,GpPen*,GDIPCONST GpPoint*,INT,INT,INT,REAL);
GpStatus WINGDIPAPI GdipDrawEllipse(GpGraphics*,GpPen*,REAL,REAL,REAL,REAL);
GpStatus WINGDIPAPI GdipDrawEllipseI(GpGraphics*,GpPen*,INT,INT,INT,INT);
GpStatus WINGDIPAPI GdipDrawImage(GpGraphics*,GpImage*,REAL,REAL);
GpStatus WINGDIPAPI GdipDrawImageI(GpGraphics*,GpImage*,INT,INT);
GpStatus WINGDIPAPI GdipDrawImagePointRect(GpGraphics*,GpImage*,REAL,REAL,REAL,REAL,REAL,REAL,GpUnit);
GpStatus WINGDIPAPI GdipDrawImagePointRectI(GpGraphics*,GpImage*,INT,INT,INT,INT,INT,INT,GpUnit);
GpStatus WINGDIPAPI GdipDrawImagePoints(GpGraphics*,GpImage*,GDIPCONST GpPointF*,INT);
GpStatus WINGDIPAPI GdipDrawImagePointsI(GpGraphics*,GpImage*,GDIPCONST GpPoint*,INT);
GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics*,GpImage*,
GDIPCONST GpPointF*,INT,REAL,REAL,REAL,REAL,GpUnit,
GDIPCONST GpImageAttributes*,DrawImageAbort,VOID*);
@ -210,9 +228,13 @@ GpStatus WINGDIPAPI GdipGetTextContrast(GpGraphics*,UINT*);
GpStatus WINGDIPAPI GdipGetTextRenderingHint(GpGraphics*,TextRenderingHint*);
GpStatus WINGDIPAPI GdipGetWorldTransform(GpGraphics*,GpMatrix*);
GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics*,ARGB);
GpStatus WINGDIPAPI GdipGetVisibleClipBounds(GpGraphics*,GpRectF*);
GpStatus WINGDIPAPI GdipGetVisibleClipBoundsI(GpGraphics*,GpRect*);
GpStatus WINGDIPAPI GdipIsClipEmpty(GpGraphics*, BOOL*);
GpStatus WINGDIPAPI GdipIsVisiblePoint(GpGraphics*,REAL,REAL,BOOL*);
GpStatus WINGDIPAPI GdipIsVisiblePointI(GpGraphics*,INT,INT,BOOL*);
GpStatus WINGDIPAPI GdipIsVisibleRect(GpGraphics*,REAL,REAL,REAL,REAL,BOOL*);
GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics*,INT,INT,INT,INT,BOOL*);
GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics*, GDIPCONST WCHAR*,
INT, GDIPCONST GpFont*, GDIPCONST RectF*, GDIPCONST GpStringFormat*, INT,
GpRegion**);
@ -281,6 +303,8 @@ GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath*,REAL,REAL,REAL,REAL);
GpStatus WINGDIPAPI GdipAddPathRectangleI(GpPath*,INT,INT,INT,INT);
GpStatus WINGDIPAPI GdipAddPathRectangles(GpPath*,GDIPCONST GpRectF*,INT);
GpStatus WINGDIPAPI GdipAddPathRectanglesI(GpPath*,GDIPCONST GpRect*,INT);
GpStatus WINGDIPAPI GdipAddPathString(GpPath*,GDIPCONST WCHAR*,INT,GDIPCONST GpFontFamily*,INT,REAL,GDIPCONST RectF*,GDIPCONST GpStringFormat*);
GpStatus WINGDIPAPI GdipAddPathStringI(GpPath*,GDIPCONST WCHAR*,INT,GDIPCONST GpFontFamily*,INT,REAL,GDIPCONST Rect*,GDIPCONST GpStringFormat*);
GpStatus WINGDIPAPI GdipClearPathMarkers(GpPath*);
GpStatus WINGDIPAPI GdipClonePath(GpPath*,GpPath**);
GpStatus WINGDIPAPI GdipClosePathFigure(GpPath*);
@ -317,6 +341,7 @@ GpStatus WINGDIPAPI GdipTransformPath(GpPath*,GpMatrix*);
GpStatus WINGDIPAPI GdipCloneImage(GpImage*, GpImage**);
GpStatus WINGDIPAPI GdipCloneImageAttributes(GDIPCONST GpImageAttributes*,GpImageAttributes**);
GpStatus WINGDIPAPI GdipDisposeImage(GpImage*);
GpStatus WINGDIPAPI GdipEmfToWmfBits(HENHMETAFILE,UINT,LPBYTE,INT,INT);
GpStatus WINGDIPAPI GdipFindFirstImageItem(GpImage*,ImageItemData*);
GpStatus WINGDIPAPI GdipFindNextImageItem(GpImage*,ImageItemData*);
GpStatus WINGDIPAPI GdipGetAllPropertyItems(GpImage*,UINT,UINT,PropertyItem*);
@ -326,6 +351,7 @@ GpStatus WINGDIPAPI GdipGetImageFlags(GpImage*,UINT*);
GpStatus WINGDIPAPI GdipGetImageHeight(GpImage*,UINT*);
GpStatus WINGDIPAPI GdipGetImageHorizontalResolution(GpImage*,REAL*);
GpStatus WINGDIPAPI GdipGetImageItemData(GpImage*,ImageItemData*);
GpStatus WINGDIPAPI GdipGetImagePalette(GpImage*,ColorPalette*,INT);
GpStatus WINGDIPAPI GdipGetImagePixelFormat(GpImage*,PixelFormat*);
GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage*,GUID*);
GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage*,UINT,UINT,GpImage**,GetThumbnailImageAbort,VOID*);
@ -389,6 +415,7 @@ GpStatus WINGDIPAPI GdipGetLineBlendCount(GpLineGradient*,INT*);
GpStatus WINGDIPAPI GdipSetLineColors(GpLineGradient*,ARGB,ARGB);
GpStatus WINGDIPAPI GdipSetLineGammaCorrection(GpLineGradient*,BOOL);
GpStatus WINGDIPAPI GdipSetLineSigmaBlend(GpLineGradient*,REAL,REAL);
GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient*,REAL,REAL);
GpStatus WINGDIPAPI GdipSetLineWrapMode(GpLineGradient*,GpWrapMode);
/* Matrix */
@ -424,6 +451,8 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE,BOOL,
GDIPCONST WmfPlaceableFileHeader*,GpMetafile**);
GpStatus WINGDIPAPI GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR*, GDIPCONST WmfPlaceableFileHeader*,
GpMetafile**);
GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR*,GpMetafile**);
GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream*,GpMetafile**);
GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile*,UINT);
/* MetafileHeader */
@ -539,6 +568,10 @@ GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *, GpGraphics *, HRGN *);
GpStatus WINGDIPAPI GdipIsEmptyRegion(GpRegion *, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsEqualRegion(GpRegion *, GpRegion *, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsInfiniteRegion(GpRegion *, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsVisibleRegionPoint(GpRegion *, REAL, REAL, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsVisibleRegionPointI(GpRegion *, INT, INT, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsVisibleRegionRect(GpRegion *, REAL, REAL, REAL, REAL, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipIsVisibleRegionRectI(GpRegion *, INT, INT, INT, INT, GpGraphics *, BOOL *);
GpStatus WINGDIPAPI GdipSetEmpty(GpRegion *);
GpStatus WINGDIPAPI GdipSetInfinite(GpRegion *);
GpStatus WINGDIPAPI GdipTransformRegion(GpRegion *, GpMatrix *);