mirror of
https://github.com/reactos/reactos.git
synced 2025-02-20 15:35:04 +00:00
[gdiplus]
- Update to current Wine sources - Now routes BMP drawing to gdi instead of doing ole32 magic (bug #3412) svn path=/trunk/; revision=44308
This commit is contained in:
parent
8e09c97596
commit
7171029029
6 changed files with 614 additions and 224 deletions
|
@ -143,7 +143,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
}
|
||||
case BrushTypeLinearGradient:{
|
||||
GpLineGradient *dest, *src;
|
||||
INT count;
|
||||
INT count, pcount;
|
||||
|
||||
dest = GdipAlloc(sizeof(GpLineGradient));
|
||||
if(!dest) return OutOfMemory;
|
||||
|
@ -157,11 +157,20 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
count = dest->blendcount;
|
||||
dest->blendfac = GdipAlloc(count * sizeof(REAL));
|
||||
dest->blendpos = GdipAlloc(count * sizeof(REAL));
|
||||
pcount = dest->pblendcount;
|
||||
if (pcount)
|
||||
{
|
||||
dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB));
|
||||
dest->pblendpos = GdipAlloc(pcount * sizeof(REAL));
|
||||
}
|
||||
|
||||
if (!dest->blendfac || !dest->blendpos)
|
||||
if (!dest->blendfac || !dest->blendpos ||
|
||||
(pcount && (!dest->pblendcolor || !dest->pblendpos)))
|
||||
{
|
||||
GdipFree(dest->blendfac);
|
||||
GdipFree(dest->blendpos);
|
||||
GdipFree(dest->pblendcolor);
|
||||
GdipFree(dest->pblendpos);
|
||||
DeleteObject(dest->brush.gdibrush);
|
||||
GdipFree(dest);
|
||||
return OutOfMemory;
|
||||
|
@ -170,6 +179,12 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
|
||||
memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
|
||||
|
||||
if (pcount)
|
||||
{
|
||||
memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB));
|
||||
memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL));
|
||||
}
|
||||
|
||||
*clone = &dest->brush;
|
||||
break;
|
||||
}
|
||||
|
@ -189,19 +204,38 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
|
|||
return Ok;
|
||||
}
|
||||
|
||||
static LONG HatchStyleToHatch(HatchStyle hatchstyle)
|
||||
{
|
||||
switch (hatchstyle)
|
||||
{
|
||||
case HatchStyleHorizontal: return HS_HORIZONTAL;
|
||||
case HatchStyleVertical: return HS_VERTICAL;
|
||||
case HatchStyleForwardDiagonal: return HS_FDIAGONAL;
|
||||
case HatchStyleBackwardDiagonal: return HS_BDIAGONAL;
|
||||
case HatchStyleCross: return HS_CROSS;
|
||||
case HatchStyleDiagonalCross: return HS_DIAGCROSS;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
static const char HatchBrushes[][8] = {
|
||||
{ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */
|
||||
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */
|
||||
{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */
|
||||
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */
|
||||
{ 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */
|
||||
{ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */
|
||||
{ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */
|
||||
{ 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */
|
||||
{ 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */
|
||||
{ 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */
|
||||
{ 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */
|
||||
{ 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */
|
||||
{ 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */
|
||||
{ 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */
|
||||
{ 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */
|
||||
{ 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */
|
||||
{ 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */
|
||||
{ 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */
|
||||
{ 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */
|
||||
{ 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */
|
||||
{ 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */
|
||||
{ 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */
|
||||
{ 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */
|
||||
{ 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */
|
||||
{ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */
|
||||
{ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */
|
||||
{ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */
|
||||
{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */
|
||||
{ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */
|
||||
{ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* GdipCreateHatchBrush [GDIPLUS.@]
|
||||
|
@ -209,6 +243,7 @@ static LONG HatchStyleToHatch(HatchStyle hatchstyle)
|
|||
GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush)
|
||||
{
|
||||
COLORREF fgcol = ARGB2COLORREF(forecol);
|
||||
GpStatus stat = Ok;
|
||||
|
||||
TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush);
|
||||
|
||||
|
@ -217,37 +252,79 @@ GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, AR
|
|||
*brush = GdipAlloc(sizeof(GpHatch));
|
||||
if (!*brush) return OutOfMemory;
|
||||
|
||||
switch (hatchstyle)
|
||||
if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
|
||||
{
|
||||
case HatchStyleHorizontal:
|
||||
case HatchStyleVertical:
|
||||
case HatchStyleForwardDiagonal:
|
||||
case HatchStyleBackwardDiagonal:
|
||||
case HatchStyleCross:
|
||||
case HatchStyleDiagonalCross:
|
||||
/* Brushes that map to BS_HATCHED */
|
||||
(*brush)->brush.lb.lbStyle = BS_HATCHED;
|
||||
(*brush)->brush.lb.lbColor = fgcol;
|
||||
(*brush)->brush.lb.lbHatch = HatchStyleToHatch(hatchstyle);
|
||||
break;
|
||||
HBITMAP hbmp;
|
||||
HDC hdc;
|
||||
BITMAPINFOHEADER bmih;
|
||||
DWORD* bits;
|
||||
int x, y;
|
||||
|
||||
default:
|
||||
FIXME("Unimplemented hatch style %d\n", hatchstyle);
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
||||
(*brush)->brush.lb.lbStyle = BS_SOLID;
|
||||
(*brush)->brush.lb.lbColor = fgcol;
|
||||
(*brush)->brush.lb.lbHatch = 0;
|
||||
break;
|
||||
if (hdc)
|
||||
{
|
||||
bmih.biSize = sizeof(bmih);
|
||||
bmih.biWidth = 8;
|
||||
bmih.biHeight = 8;
|
||||
bmih.biPlanes = 1;
|
||||
bmih.biBitCount = 32;
|
||||
bmih.biCompression = BI_RGB;
|
||||
bmih.biSizeImage = 0;
|
||||
|
||||
hbmp = CreateDIBSection(hdc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
|
||||
if (hbmp)
|
||||
{
|
||||
for (y=0; y<8; y++)
|
||||
for (x=0; x<8; x++)
|
||||
if ((HatchBrushes[hatchstyle][y] & (0x80 >> x)) != 0)
|
||||
bits[y*8+x] = forecol;
|
||||
else
|
||||
bits[y*8+x] = backcol;
|
||||
}
|
||||
else
|
||||
stat = GenericError;
|
||||
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
else
|
||||
stat = GenericError;
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
(*brush)->brush.lb.lbStyle = BS_PATTERN;
|
||||
(*brush)->brush.lb.lbColor = 0;
|
||||
(*brush)->brush.lb.lbHatch = (ULONG_PTR)hbmp;
|
||||
(*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
|
||||
|
||||
DeleteObject(hbmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FIXME("Unimplemented hatch style %d\n", hatchstyle);
|
||||
|
||||
(*brush)->brush.lb.lbStyle = BS_SOLID;
|
||||
(*brush)->brush.lb.lbColor = fgcol;
|
||||
(*brush)->brush.lb.lbHatch = 0;
|
||||
(*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
|
||||
}
|
||||
|
||||
if (stat == Ok)
|
||||
{
|
||||
(*brush)->brush.bt = BrushTypeHatchFill;
|
||||
(*brush)->forecol = forecol;
|
||||
(*brush)->backcol = backcol;
|
||||
(*brush)->hatchstyle = hatchstyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
GdipFree(*brush);
|
||||
*brush = NULL;
|
||||
}
|
||||
|
||||
(*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb);
|
||||
(*brush)->brush.bt = BrushTypeHatchFill;
|
||||
(*brush)->forecol = forecol;
|
||||
(*brush)->backcol = backcol;
|
||||
(*brush)->hatchstyle = hatchstyle;
|
||||
|
||||
return Ok;
|
||||
return stat;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -316,6 +393,10 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
|
|||
(*line)->blendfac[0] = 1.0f;
|
||||
(*line)->blendpos[0] = 1.0f;
|
||||
|
||||
(*line)->pblendcolor = NULL;
|
||||
(*line)->pblendpos = NULL;
|
||||
(*line)->pblendcount = 0;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -762,7 +843,7 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image,
|
|||
|
||||
/* image is flipped */
|
||||
if(pbmi->bmiHeader.biHeight > 0){
|
||||
dibits += pbmi->bmiHeader.biSizeImage;
|
||||
dibits += image_stride * (pbmi->bmiHeader.biHeight - 1);
|
||||
image_stride *= -1;
|
||||
textbits += stride * (n_height - 1);
|
||||
stride *= -1;
|
||||
|
@ -893,6 +974,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush)
|
|||
case BrushTypeLinearGradient:
|
||||
GdipFree(((GpLineGradient*)brush)->blendfac);
|
||||
GdipFree(((GpLineGradient*)brush)->blendpos);
|
||||
GdipFree(((GpLineGradient*)brush)->pblendcolor);
|
||||
GdipFree(((GpLineGradient*)brush)->pblendpos);
|
||||
break;
|
||||
case BrushTypeTextureFill:
|
||||
GdipDeleteMatrix(((GpTexture*)brush)->transform);
|
||||
|
@ -1600,6 +1683,69 @@ GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus,
|
|||
|
||||
GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush,
|
||||
GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count)
|
||||
{
|
||||
ARGB *new_color;
|
||||
REAL *new_pos;
|
||||
TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count);
|
||||
|
||||
if (!brush || !blend || !positions || count < 2 ||
|
||||
positions[0] != 0.0f || positions[count-1] != 1.0f)
|
||||
{
|
||||
return InvalidParameter;
|
||||
}
|
||||
|
||||
new_color = GdipAlloc(count * sizeof(ARGB));
|
||||
new_pos = GdipAlloc(count * sizeof(REAL));
|
||||
if (!new_color || !new_pos)
|
||||
{
|
||||
GdipFree(new_color);
|
||||
GdipFree(new_pos);
|
||||
return OutOfMemory;
|
||||
}
|
||||
|
||||
memcpy(new_color, blend, sizeof(ARGB) * count);
|
||||
memcpy(new_pos, positions, sizeof(REAL) * count);
|
||||
|
||||
GdipFree(brush->pblendcolor);
|
||||
GdipFree(brush->pblendpos);
|
||||
|
||||
brush->pblendcolor = new_color;
|
||||
brush->pblendpos = new_pos;
|
||||
brush->pblendcount = count;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush,
|
||||
ARGB *blend, REAL* positions, INT count)
|
||||
{
|
||||
if (!brush || !blend || !positions || count < 2)
|
||||
return InvalidParameter;
|
||||
|
||||
if (brush->pblendcount == 0)
|
||||
return GenericError;
|
||||
|
||||
if (count < brush->pblendcount)
|
||||
return InsufficientBuffer;
|
||||
|
||||
memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount);
|
||||
memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush,
|
||||
INT *count)
|
||||
{
|
||||
if (!brush || !count)
|
||||
return InvalidParameter;
|
||||
|
||||
*count = brush->pblendcount;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush)
|
||||
{
|
||||
static int calls;
|
||||
|
||||
|
@ -1620,6 +1766,17 @@ GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
|
|||
return NotImplemented;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy,
|
||||
GpMatrixOrder order)
|
||||
{
|
||||
static int calls;
|
||||
|
||||
if(!(calls++))
|
||||
FIXME("not implemented\n");
|
||||
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush,
|
||||
REAL dx, REAL dy, GpMatrixOrder order)
|
||||
{
|
||||
|
|
|
@ -86,7 +86,7 @@ Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput
|
|||
input->DebugEventCallback, input->SuppressBackgroundThread,
|
||||
input->SuppressExternalCodecs);
|
||||
|
||||
if(input->GdiplusVersion != 1)
|
||||
if(input->GdiplusVersion < 1 || input->GdiplusVersion > 2)
|
||||
return UnsupportedGdiplusVersion;
|
||||
|
||||
if(input->SuppressBackgroundThread){
|
||||
|
@ -211,38 +211,37 @@ static void unstretch_angle(REAL * angle, REAL rad_x, REAL rad_y)
|
|||
INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
|
||||
REAL startAngle, REAL sweepAngle)
|
||||
{
|
||||
INT i, count;
|
||||
INT i;
|
||||
REAL end_angle, start_angle, endAngle;
|
||||
|
||||
endAngle = startAngle + sweepAngle;
|
||||
unstretch_angle(&startAngle, x2 / 2.0, y2 / 2.0);
|
||||
unstretch_angle(&endAngle, x2 / 2.0, y2 / 2.0);
|
||||
|
||||
count = ceilf(fabs(endAngle - startAngle) / M_PI_2) * 3 + 1;
|
||||
/* don't make more than a full circle */
|
||||
count = min(MAX_ARC_PTS, count);
|
||||
|
||||
if(count == 1)
|
||||
return 0;
|
||||
if(!points)
|
||||
return count;
|
||||
|
||||
/* start_angle and end_angle are the iterative variables */
|
||||
start_angle = startAngle;
|
||||
|
||||
for(i = 0; i < count - 1; i += 3){
|
||||
for(i = 0; i < MAX_ARC_PTS - 1; i += 3){
|
||||
/* check if we've overshot the end angle */
|
||||
if( sweepAngle > 0.0 )
|
||||
{
|
||||
if (start_angle >= endAngle) break;
|
||||
end_angle = min(start_angle + M_PI_2, endAngle);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (start_angle <= endAngle) break;
|
||||
end_angle = max(start_angle - M_PI_2, endAngle);
|
||||
}
|
||||
|
||||
add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0);
|
||||
if (points)
|
||||
add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0);
|
||||
|
||||
start_angle += M_PI_2 * (sweepAngle < 0.0 ? -1.0 : 1.0);
|
||||
}
|
||||
|
||||
return count;
|
||||
if (i == 0) return 0;
|
||||
else return i+1;
|
||||
}
|
||||
|
||||
COLORREF ARGB2COLORREF(ARGB color)
|
||||
|
@ -419,7 +418,7 @@ void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height,
|
|||
}
|
||||
|
||||
/* recursive deletion of GpRegion nodes */
|
||||
inline void delete_element(region_element* element)
|
||||
void delete_element(region_element* element)
|
||||
{
|
||||
switch(element->type)
|
||||
{
|
||||
|
|
|
@ -304,8 +304,8 @@
|
|||
@ stdcall GdipGetLineBlendCount(ptr ptr)
|
||||
@ stdcall GdipGetLineColors(ptr ptr)
|
||||
@ stdcall GdipGetLineGammaCorrection(ptr ptr)
|
||||
@ stub GdipGetLinePresetBlend
|
||||
@ stub GdipGetLinePresetBlendCount
|
||||
@ stdcall GdipGetLinePresetBlend(ptr ptr ptr long)
|
||||
@ stdcall GdipGetLinePresetBlendCount(ptr ptr)
|
||||
@ stdcall GdipGetLineRect(ptr ptr)
|
||||
@ stdcall GdipGetLineRectI(ptr ptr)
|
||||
@ stdcall GdipGetLineSpacing(ptr long ptr)
|
||||
|
@ -476,7 +476,7 @@
|
|||
@ stdcall GdipRemovePropertyItem(ptr long)
|
||||
@ stdcall GdipResetClip(ptr)
|
||||
@ stub GdipResetImageAttributes
|
||||
@ stub GdipResetLineTransform
|
||||
@ stdcall GdipResetLineTransform(ptr)
|
||||
@ stub GdipResetPageTransform
|
||||
@ stdcall GdipResetPath(ptr)
|
||||
@ stub GdipResetPathGradientTransform
|
||||
|
@ -496,7 +496,7 @@
|
|||
@ stdcall GdipSaveGraphics(ptr ptr)
|
||||
@ stdcall GdipSaveImageToFile(ptr ptr ptr ptr)
|
||||
@ stdcall GdipSaveImageToStream(ptr ptr ptr ptr)
|
||||
@ stub GdipScaleLineTransform
|
||||
@ stdcall GdipScaleLineTransform(ptr long long long)
|
||||
@ stdcall GdipScaleMatrix(ptr long long long)
|
||||
@ stub GdipScalePathGradientTransform
|
||||
@ stdcall GdipScalePenTransform(ptr long long long)
|
||||
|
|
|
@ -61,7 +61,7 @@ extern BOOL lengthen_path(GpPath *path, INT len);
|
|||
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path);
|
||||
|
||||
typedef struct region_element region_element;
|
||||
extern inline void delete_element(region_element *element);
|
||||
extern void delete_element(region_element *element);
|
||||
|
||||
static inline INT roundr(REAL x)
|
||||
{
|
||||
|
@ -166,6 +166,9 @@ struct GpLineGradient{
|
|||
REAL* blendfac; /* blend factors */
|
||||
REAL* blendpos; /* blend positions */
|
||||
INT blendcount;
|
||||
ARGB* pblendcolor; /* preset blend colors */
|
||||
REAL* pblendpos; /* preset blend positions */
|
||||
INT pblendcount;
|
||||
};
|
||||
|
||||
struct GpTexture{
|
||||
|
@ -208,6 +211,7 @@ struct GpAdustableArrowCap{
|
|||
struct GpImage{
|
||||
IPicture* picture;
|
||||
ImageType type;
|
||||
GUID format;
|
||||
UINT flags;
|
||||
};
|
||||
|
||||
|
|
|
@ -220,7 +220,27 @@ static ARGB blend_line_gradient(GpLineGradient* brush, REAL position)
|
|||
blendfac = (left_blendfac * (right_blendpos - position) +
|
||||
right_blendfac * (position - left_blendpos)) / range;
|
||||
}
|
||||
return blend_colors(brush->startcolor, brush->endcolor, blendfac);
|
||||
|
||||
if (brush->pblendcount == 0)
|
||||
return blend_colors(brush->startcolor, brush->endcolor, blendfac);
|
||||
else
|
||||
{
|
||||
int i=1;
|
||||
ARGB left_blendcolor, right_blendcolor;
|
||||
REAL left_blendpos, right_blendpos;
|
||||
|
||||
/* locate the blend colors surrounding this position */
|
||||
while (blendfac > brush->pblendpos[i])
|
||||
i++;
|
||||
|
||||
/* interpolate between the blend colors */
|
||||
left_blendpos = brush->pblendpos[i-1];
|
||||
left_blendcolor = brush->pblendcolor[i-1];
|
||||
right_blendpos = brush->pblendpos[i];
|
||||
right_blendcolor = brush->pblendcolor[i];
|
||||
blendfac = (blendfac - left_blendpos) / (right_blendpos - left_blendpos);
|
||||
return blend_colors(left_blendcolor, right_blendcolor, blendfac);
|
||||
}
|
||||
}
|
||||
|
||||
static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
|
||||
|
@ -1235,6 +1255,7 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete,
|
|||
|
||||
|
||||
(*metafile)->image.type = ImageTypeMetafile;
|
||||
memcpy(&(*metafile)->image.format, &ImageFormatWMF, sizeof(GUID));
|
||||
(*metafile)->bounds.X = ((REAL) placeable->BoundingBox.Left) / ((REAL) placeable->Inch);
|
||||
(*metafile)->bounds.Y = ((REAL) placeable->BoundingBox.Right) / ((REAL) placeable->Inch);
|
||||
(*metafile)->bounds.Width = ((REAL) (placeable->BoundingBox.Right
|
||||
|
@ -1795,16 +1816,25 @@ GpStatus WINGDIPAPI GdipDrawImagePointRect(GpGraphics *graphics, GpImage *image,
|
|||
REAL x, REAL y, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
|
||||
GpUnit srcUnit)
|
||||
{
|
||||
FIXME("(%p, %p, %f, %f, %f, %f, %f, %f, %d): stub\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit);
|
||||
return NotImplemented;
|
||||
GpPointF points[3];
|
||||
TRACE("(%p, %p, %f, %f, %f, %f, %f, %f, %d)\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit);
|
||||
|
||||
points[0].X = points[2].X = x;
|
||||
points[0].Y = points[1].Y = y;
|
||||
|
||||
/* FIXME: convert image coordinates to Graphics coordinates? */
|
||||
points[1].X = x + srcwidth;
|
||||
points[2].Y = y + srcheight;
|
||||
|
||||
return GdipDrawImagePointsRect(graphics, image, points, 3, srcx, srcy,
|
||||
srcwidth, srcheight, srcUnit, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipDrawImagePointRectI(GpGraphics *graphics, GpImage *image,
|
||||
INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight,
|
||||
GpUnit srcUnit)
|
||||
{
|
||||
FIXME("(%p, %p, %d, %d, %d, %d, %d, %d, %d): stub\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit);
|
||||
return NotImplemented;
|
||||
return GdipDrawImagePointRect(graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit);
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipDrawImagePoints(GpGraphics *graphics, GpImage *image,
|
||||
|
@ -1854,15 +1884,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
|||
else
|
||||
return NotImplemented;
|
||||
|
||||
/* IPicture renders bitmaps with the y-axis reversed
|
||||
* FIXME: flipping for unknown image type might not be correct. */
|
||||
if(image->type != ImageTypeMetafile){
|
||||
INT temp;
|
||||
temp = pti[0].y;
|
||||
pti[0].y = pti[2].y;
|
||||
pti[2].y = temp;
|
||||
}
|
||||
|
||||
if(IPicture_Render(image->picture, graphics->hdc,
|
||||
pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y,
|
||||
srcx * dx, srcy * dy,
|
||||
|
@ -2362,7 +2383,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||
HFONT gdifont;
|
||||
LOGFONTW lfw;
|
||||
TEXTMETRICW textmet;
|
||||
GpPointF pt[2], rectcpy[4];
|
||||
GpPointF pt[3], rectcpy[4];
|
||||
POINT corners[4];
|
||||
WCHAR* stringdup;
|
||||
REAL angle, ang_cos, ang_sin, rel_width, rel_height;
|
||||
|
@ -2409,6 +2430,21 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||
SetBkMode(graphics->hdc, TRANSPARENT);
|
||||
SetTextColor(graphics->hdc, brush->lb.lbColor);
|
||||
|
||||
pt[0].X = 0.0;
|
||||
pt[0].Y = 0.0;
|
||||
pt[1].X = 1.0;
|
||||
pt[1].Y = 0.0;
|
||||
pt[2].X = 0.0;
|
||||
pt[2].Y = 1.0;
|
||||
GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3);
|
||||
angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X));
|
||||
ang_cos = cos(angle);
|
||||
ang_sin = sin(angle);
|
||||
rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+
|
||||
(pt[1].X-pt[0].X)*(pt[1].X-pt[0].X));
|
||||
rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+
|
||||
(pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
|
||||
|
||||
rectcpy[3].X = rectcpy[0].X = rect->X;
|
||||
rectcpy[1].Y = rectcpy[0].Y = rect->Y + offsety;
|
||||
rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width;
|
||||
|
@ -2416,30 +2452,14 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||
transform_and_round_points(graphics, corners, rectcpy, 4);
|
||||
|
||||
if (roundr(rect->Width) == 0)
|
||||
{
|
||||
rel_width = 1.0;
|
||||
nwidth = INT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) +
|
||||
(corners[1].y - corners[0].y) * (corners[1].y - corners[0].y))
|
||||
/ rect->Width;
|
||||
nwidth = roundr(rel_width * rect->Width);
|
||||
}
|
||||
|
||||
if (roundr(rect->Height) == 0)
|
||||
{
|
||||
rel_height = 1.0;
|
||||
nheight = INT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
rel_height = sqrt((corners[2].x - corners[1].x) * (corners[2].x - corners[1].x) +
|
||||
(corners[2].y - corners[1].y) * (corners[2].y - corners[1].y))
|
||||
/ rect->Height;
|
||||
nheight = roundr(rel_height * rect->Height);
|
||||
}
|
||||
|
||||
if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0)
|
||||
{
|
||||
|
@ -2457,14 +2477,6 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
|
|||
lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height);
|
||||
lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width);
|
||||
|
||||
pt[0].X = 0.0;
|
||||
pt[0].Y = 0.0;
|
||||
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));
|
||||
ang_cos = cos(angle);
|
||||
ang_sin = sin(angle);
|
||||
lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0);
|
||||
|
||||
gdifont = CreateFontIndirectW(&lfw);
|
||||
|
|
|
@ -94,36 +94,321 @@ GpStatus WINGDIPAPI GdipBitmapCreateApplyEffect(GpBitmap** inputBitmaps,
|
|||
return NotImplemented;
|
||||
}
|
||||
|
||||
static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*r = *g = *b = row[x*2+1];
|
||||
*a = 255;
|
||||
}
|
||||
|
||||
static inline void getpixel_16bppRGB555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
WORD pixel = *((WORD*)(row)+x);
|
||||
*r = (pixel>>7&0xf8)|(pixel>>12&0x7);
|
||||
*g = (pixel>>2&0xf8)|(pixel>>6&0x7);
|
||||
*b = (pixel<<3&0xf8)|(pixel>>2&0x7);
|
||||
*a = 255;
|
||||
}
|
||||
|
||||
static inline void getpixel_16bppRGB565(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
WORD pixel = *((WORD*)(row)+x);
|
||||
*r = (pixel>>8&0xf8)|(pixel>>13&0x7);
|
||||
*g = (pixel>>3&0xfc)|(pixel>>9&0x3);
|
||||
*b = (pixel<<3&0xf8)|(pixel>>2&0x7);
|
||||
*a = 255;
|
||||
}
|
||||
|
||||
static inline void getpixel_16bppARGB1555(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
WORD pixel = *((WORD*)(row)+x);
|
||||
*r = (pixel>>7&0xf8)|(pixel>>12&0x7);
|
||||
*g = (pixel>>2&0xf8)|(pixel>>6&0x7);
|
||||
*b = (pixel<<3&0xf8)|(pixel>>2&0x7);
|
||||
if ((pixel&0x8000) == 0x8000)
|
||||
*a = 255;
|
||||
else
|
||||
*a = 0;
|
||||
}
|
||||
|
||||
static inline void getpixel_24bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*r = row[x*3+2];
|
||||
*g = row[x*3+1];
|
||||
*b = row[x*3];
|
||||
*a = 255;
|
||||
}
|
||||
|
||||
static inline void getpixel_32bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*r = row[x*4+2];
|
||||
*g = row[x*4+1];
|
||||
*b = row[x*4];
|
||||
*a = 255;
|
||||
}
|
||||
|
||||
static inline void getpixel_32bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*r = row[x*4+2];
|
||||
*g = row[x*4+1];
|
||||
*b = row[x*4];
|
||||
*a = row[x*4+3];
|
||||
}
|
||||
|
||||
static inline void getpixel_32bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*a = row[x*4+3];
|
||||
if (*a == 0)
|
||||
*r = *g = *b = 0;
|
||||
else
|
||||
{
|
||||
*r = row[x*4+2] * 255 / *a;
|
||||
*g = row[x*4+1] * 255 / *a;
|
||||
*b = row[x*4] * 255 / *a;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void getpixel_48bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*r = row[x*6+5];
|
||||
*g = row[x*6+3];
|
||||
*b = row[x*6+1];
|
||||
*a = 255;
|
||||
}
|
||||
|
||||
static inline void getpixel_64bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*r = row[x*8+5];
|
||||
*g = row[x*8+3];
|
||||
*b = row[x*8+1];
|
||||
*a = row[x*8+7];
|
||||
}
|
||||
|
||||
static inline void getpixel_64bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a,
|
||||
const BYTE *row, UINT x)
|
||||
{
|
||||
*a = row[x*8+7];
|
||||
if (*a == 0)
|
||||
*r = *g = *b = 0;
|
||||
else
|
||||
{
|
||||
*r = row[x*8+5] * 255 / *a;
|
||||
*g = row[x*8+3] * 255 / *a;
|
||||
*b = row[x*8+1] * 255 / *a;
|
||||
}
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y,
|
||||
ARGB *color)
|
||||
{
|
||||
static int calls;
|
||||
BYTE r, g, b, a;
|
||||
BYTE *row;
|
||||
TRACE("%p %d %d %p\n", bitmap, x, y, color);
|
||||
|
||||
if(!bitmap || !color)
|
||||
if(!bitmap || !color ||
|
||||
x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
|
||||
return InvalidParameter;
|
||||
|
||||
if(!(calls++))
|
||||
FIXME("not implemented\n");
|
||||
row = bitmap->bits+bitmap->stride*y;
|
||||
|
||||
*color = 0xdeadbeef;
|
||||
switch (bitmap->format)
|
||||
{
|
||||
case PixelFormat16bppGrayScale:
|
||||
getpixel_16bppGrayScale(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat16bppRGB555:
|
||||
getpixel_16bppRGB555(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat16bppRGB565:
|
||||
getpixel_16bppRGB565(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat16bppARGB1555:
|
||||
getpixel_16bppARGB1555(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat24bppRGB:
|
||||
getpixel_24bppRGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat32bppRGB:
|
||||
getpixel_32bppRGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat32bppARGB:
|
||||
getpixel_32bppARGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat32bppPARGB:
|
||||
getpixel_32bppPARGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat48bppRGB:
|
||||
getpixel_48bppRGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat64bppARGB:
|
||||
getpixel_64bppARGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
case PixelFormat64bppPARGB:
|
||||
getpixel_64bppPARGB(&r,&g,&b,&a,row,x);
|
||||
break;
|
||||
default:
|
||||
FIXME("not implemented for format 0x%x\n", bitmap->format);
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
return NotImplemented;
|
||||
*color = a<<24|r<<16|g<<8|b;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
*((WORD*)(row)+x) = (r+g+b)*85;
|
||||
}
|
||||
|
||||
static inline void setpixel_16bppRGB555(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
*((WORD*)(row)+x) = (r<<7&0x7c00)|
|
||||
(g<<2&0x03e0)|
|
||||
(b>>3&0x001f);
|
||||
}
|
||||
|
||||
static inline void setpixel_16bppRGB565(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
*((WORD*)(row)+x) = (r<<8&0xf800)|
|
||||
(g<<3&0x07e0)|
|
||||
(b>>3&0x001f);
|
||||
}
|
||||
|
||||
static inline void setpixel_16bppARGB1555(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
*((WORD*)(row)+x) = (a<<8&0x8000)|
|
||||
(r<<7&0x7c00)|
|
||||
(g<<2&0x03e0)|
|
||||
(b>>3&0x001f);
|
||||
}
|
||||
|
||||
static inline void setpixel_24bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
row[x*3+2] = r;
|
||||
row[x*3+1] = g;
|
||||
row[x*3] = b;
|
||||
}
|
||||
|
||||
static inline void setpixel_32bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
*((DWORD*)(row)+x) = (r<<16)|(g<<8)|b;
|
||||
}
|
||||
|
||||
static inline void setpixel_32bppARGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
*((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b;
|
||||
}
|
||||
|
||||
static inline void setpixel_32bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
r = r * a / 255;
|
||||
g = g * a / 255;
|
||||
b = b * a / 255;
|
||||
*((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b;
|
||||
}
|
||||
|
||||
static inline void setpixel_48bppRGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
row[x*6+5] = row[x*6+4] = r;
|
||||
row[x*6+3] = row[x*6+2] = g;
|
||||
row[x*6+1] = row[x*6] = b;
|
||||
}
|
||||
|
||||
static inline void setpixel_64bppARGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
UINT64 a64=a, r64=r, g64=g, b64=b;
|
||||
*((UINT64*)(row)+x) = (a64<<56)|(a64<<48)|(r64<<40)|(r64<<32)|(g64<<24)|(g64<<16)|(b64<<8)|b64;
|
||||
}
|
||||
|
||||
static inline void setpixel_64bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a,
|
||||
BYTE *row, UINT x)
|
||||
{
|
||||
UINT64 a64, r64, g64, b64;
|
||||
a64 = a * 257;
|
||||
r64 = r * a / 255;
|
||||
g64 = g * a / 255;
|
||||
b64 = b * a / 255;
|
||||
*((UINT64*)(row)+x) = (a64<<48)|(r64<<32)|(g64<<16)|b64;
|
||||
}
|
||||
|
||||
GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y,
|
||||
ARGB color)
|
||||
{
|
||||
static int calls;
|
||||
BYTE a, r, g, b;
|
||||
BYTE *row;
|
||||
TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color);
|
||||
|
||||
if(!bitmap)
|
||||
if(!bitmap || x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height)
|
||||
return InvalidParameter;
|
||||
|
||||
if(!(calls++))
|
||||
FIXME("not implemented\n");
|
||||
a = color>>24;
|
||||
r = color>>16;
|
||||
g = color>>8;
|
||||
b = color;
|
||||
|
||||
return NotImplemented;
|
||||
row = bitmap->bits + bitmap->stride * y;
|
||||
|
||||
switch (bitmap->format)
|
||||
{
|
||||
case PixelFormat16bppGrayScale:
|
||||
setpixel_16bppGrayScale(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat16bppRGB555:
|
||||
setpixel_16bppRGB555(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat16bppRGB565:
|
||||
setpixel_16bppRGB565(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat16bppARGB1555:
|
||||
setpixel_16bppARGB1555(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat24bppRGB:
|
||||
setpixel_24bppRGB(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat32bppRGB:
|
||||
setpixel_32bppRGB(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat32bppARGB:
|
||||
setpixel_32bppARGB(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat32bppPARGB:
|
||||
setpixel_32bppPARGB(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat48bppRGB:
|
||||
setpixel_48bppRGB(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat64bppARGB:
|
||||
setpixel_64bppARGB(r,g,b,a,row,x);
|
||||
break;
|
||||
case PixelFormat64bppPARGB:
|
||||
setpixel_64bppPARGB(r,g,b,a,row,x);
|
||||
break;
|
||||
default:
|
||||
FIXME("not implemented for format 0x%x\n", bitmap->format);
|
||||
return NotImplemented;
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
/* This function returns a pointer to an array of pixels that represents the
|
||||
|
@ -413,6 +698,8 @@ GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
|
|||
GdipDisposeImage(*cloneImage);
|
||||
*cloneImage = NULL;
|
||||
}
|
||||
else memcpy(&(*cloneImage)->format, &image->format, sizeof(GUID));
|
||||
|
||||
return stat;
|
||||
}
|
||||
else
|
||||
|
@ -645,11 +932,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap)
|
|||
TRACE("%p, %p\n", hicon, bitmap);
|
||||
|
||||
if(!bitmap || !GetIconInfo(hicon, &iinfo))
|
||||
{
|
||||
DeleteObject(iinfo.hbmColor);
|
||||
DeleteObject(iinfo.hbmMask);
|
||||
return InvalidParameter;
|
||||
}
|
||||
|
||||
/* get the size of the icon */
|
||||
ret = GetObjectA(iinfo.hbmColor ? iinfo.hbmColor : iinfo.hbmMask, sizeof(bm), &bm);
|
||||
|
@ -858,6 +1141,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
|
|||
}
|
||||
|
||||
(*bitmap)->image.type = ImageTypeBitmap;
|
||||
memcpy(&(*bitmap)->image.format, &ImageFormatMemoryBMP, sizeof(GUID));
|
||||
(*bitmap)->image.flags = ImageFlagsNone;
|
||||
(*bitmap)->width = width;
|
||||
(*bitmap)->height = height;
|
||||
|
@ -1144,23 +1428,11 @@ GpStatus WINGDIPAPI GdipGetImagePixelFormat(GpImage *image, PixelFormat *format)
|
|||
|
||||
GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage *image, GUID *format)
|
||||
{
|
||||
static int calls;
|
||||
|
||||
if(!image || !format)
|
||||
return InvalidParameter;
|
||||
|
||||
if(!(calls++))
|
||||
FIXME("stub\n");
|
||||
memcpy(format, &image->format, sizeof(GUID));
|
||||
|
||||
/* FIXME: should be detected from embedded picture or stored separately */
|
||||
switch (image->type)
|
||||
{
|
||||
case ImageTypeBitmap: *format = ImageFormatBMP; break;
|
||||
case ImageTypeMetafile: *format = ImageFormatEMF; break;
|
||||
default:
|
||||
WARN("unknown type %u\n", image->type);
|
||||
*format = ImageFormatUndefined;
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -1507,107 +1779,39 @@ static GpStatus decode_image_icon(IStream* stream, REFCLSID clsid, GpImage **ima
|
|||
return decode_image_wic(stream, &CLSID_WICIcoDecoder, image);
|
||||
}
|
||||
|
||||
static GpStatus decode_image_bmp(IStream* stream, REFCLSID clsid, GpImage **image)
|
||||
{
|
||||
GpStatus status;
|
||||
GpBitmap* bitmap;
|
||||
|
||||
status = decode_image_wic(stream, &CLSID_WICBmpDecoder, image);
|
||||
|
||||
bitmap = (GpBitmap*)*image;
|
||||
|
||||
if (status == Ok && bitmap->format == PixelFormat32bppARGB)
|
||||
{
|
||||
/* WIC supports bmp files with alpha, but gdiplus does not */
|
||||
bitmap->format = PixelFormat32bppRGB;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, GpImage **image)
|
||||
{
|
||||
return decode_image_wic(stream, &CLSID_WICJpegDecoder, image);
|
||||
}
|
||||
|
||||
static GpStatus decode_image_png(IStream* stream, REFCLSID clsid, GpImage **image)
|
||||
{
|
||||
return decode_image_wic(stream, &CLSID_WICPngDecoder, image);
|
||||
}
|
||||
|
||||
static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, GpImage **image)
|
||||
{
|
||||
return decode_image_wic(stream, &CLSID_WICGifDecoder, image);
|
||||
}
|
||||
|
||||
static GpStatus decode_image_olepicture_bitmap(IStream* stream, REFCLSID clsid, GpImage **image)
|
||||
{
|
||||
IPicture *pic;
|
||||
BITMAPINFO *pbmi;
|
||||
BITMAPCOREHEADER* bmch;
|
||||
HBITMAP hbm;
|
||||
HDC hdc;
|
||||
|
||||
TRACE("%p %p\n", stream, image);
|
||||
|
||||
if(!stream || !image)
|
||||
return InvalidParameter;
|
||||
|
||||
if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
|
||||
(LPVOID*) &pic) != S_OK){
|
||||
TRACE("Could not load picture\n");
|
||||
return GenericError;
|
||||
}
|
||||
|
||||
pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||
if (!pbmi)
|
||||
return OutOfMemory;
|
||||
*image = GdipAlloc(sizeof(GpBitmap));
|
||||
if(!*image){
|
||||
GdipFree(pbmi);
|
||||
return OutOfMemory;
|
||||
}
|
||||
(*image)->type = ImageTypeBitmap;
|
||||
|
||||
(*((GpBitmap**) image))->width = ipicture_pixel_width(pic);
|
||||
(*((GpBitmap**) image))->height = ipicture_pixel_height(pic);
|
||||
|
||||
/* get the pixel format */
|
||||
IPicture_get_Handle(pic, (OLE_HANDLE*)&hbm);
|
||||
IPicture_get_CurDC(pic, &hdc);
|
||||
|
||||
(*((GpBitmap**) image))->hbitmap = hbm;
|
||||
(*((GpBitmap**) image))->hdc = hdc;
|
||||
(*((GpBitmap**) image))->bits = NULL;
|
||||
|
||||
bmch = (BITMAPCOREHEADER*) (&pbmi->bmiHeader);
|
||||
bmch->bcSize = sizeof(BITMAPCOREHEADER);
|
||||
|
||||
if(!hdc){
|
||||
HBITMAP old;
|
||||
hdc = CreateCompatibleDC(0);
|
||||
old = SelectObject(hdc, hbm);
|
||||
GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
|
||||
SelectObject(hdc, old);
|
||||
DeleteDC(hdc);
|
||||
}
|
||||
else
|
||||
GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS);
|
||||
|
||||
switch(bmch->bcBitCount)
|
||||
{
|
||||
case 1:
|
||||
(*((GpBitmap**) image))->format = PixelFormat1bppIndexed;
|
||||
break;
|
||||
case 4:
|
||||
(*((GpBitmap**) image))->format = PixelFormat4bppIndexed;
|
||||
break;
|
||||
case 8:
|
||||
(*((GpBitmap**) image))->format = PixelFormat8bppIndexed;
|
||||
break;
|
||||
case 16:
|
||||
(*((GpBitmap**) image))->format = PixelFormat16bppRGB565;
|
||||
break;
|
||||
case 24:
|
||||
(*((GpBitmap**) image))->format = PixelFormat24bppRGB;
|
||||
break;
|
||||
case 32:
|
||||
(*((GpBitmap**) image))->format = PixelFormat32bppRGB;
|
||||
break;
|
||||
case 48:
|
||||
(*((GpBitmap**) image))->format = PixelFormat48bppRGB;
|
||||
break;
|
||||
default:
|
||||
FIXME("Bit depth %d is not fully supported yet\n", bmch->bcBitCount);
|
||||
(*((GpBitmap**) image))->format = (bmch->bcBitCount << 8) | PixelFormatGDI;
|
||||
break;
|
||||
}
|
||||
|
||||
GdipFree(pbmi);
|
||||
|
||||
(*image)->picture = pic;
|
||||
(*image)->flags = ImageFlagsNone;
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, GpImage **image)
|
||||
{
|
||||
IPicture *pic;
|
||||
|
@ -1715,7 +1919,15 @@ GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream* stream, GpImage **image)
|
|||
if (FAILED(hr)) return hresult_to_status(hr);
|
||||
|
||||
/* call on the image decoder to do the real work */
|
||||
return codec->decode_func(stream, &codec->info.Clsid, image);
|
||||
stat = codec->decode_func(stream, &codec->info.Clsid, image);
|
||||
|
||||
/* take note of the original data format */
|
||||
if (stat == Ok)
|
||||
{
|
||||
memcpy(&(*image)->format, &codec->info.FormatID, sizeof(GUID));
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
/* FIXME: no ICM */
|
||||
|
@ -1915,6 +2127,12 @@ static GpStatus encode_image_BMP(GpImage *image, IStream* stream,
|
|||
return encode_image_WIC(image, stream, &CLSID_WICBmpEncoder, params);
|
||||
}
|
||||
|
||||
static GpStatus encode_image_png(GpImage *image, IStream* stream,
|
||||
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
|
||||
{
|
||||
return encode_image_WIC(image, stream, &CLSID_WICPngEncoder, params);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GdipSaveImageToStream [GDIPLUS.@]
|
||||
*/
|
||||
|
@ -2051,7 +2269,7 @@ static const struct image_codec codecs[NUM_CODECS] = {
|
|||
/* SigMask */ bmp_sig_mask,
|
||||
},
|
||||
encode_image_BMP,
|
||||
decode_image_olepicture_bitmap
|
||||
decode_image_bmp
|
||||
},
|
||||
{
|
||||
{ /* JPEG */
|
||||
|
@ -2138,15 +2356,15 @@ static const struct image_codec codecs[NUM_CODECS] = {
|
|||
/* FormatDescription */ png_format,
|
||||
/* FilenameExtension */ png_extension,
|
||||
/* MimeType */ png_mimetype,
|
||||
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
||||
/* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
|
||||
/* Version */ 1,
|
||||
/* SigCount */ 1,
|
||||
/* SigSize */ 8,
|
||||
/* SigPattern */ png_sig_pattern,
|
||||
/* SigMask */ png_sig_mask,
|
||||
},
|
||||
NULL,
|
||||
decode_image_olepicture_bitmap
|
||||
encode_image_png,
|
||||
decode_image_png
|
||||
},
|
||||
{
|
||||
{ /* ICO */
|
||||
|
|
Loading…
Reference in a new issue