mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:53:40 +00:00
[GDIPLUS] Sync with Wine Staging 3.9. CORE-14656
This commit is contained in:
parent
4b8fbca3f7
commit
6619d0261f
11 changed files with 253 additions and 100 deletions
|
@ -261,7 +261,7 @@ static const char HatchBrushes[][8] = {
|
||||||
|
|
||||||
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
|
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
|
||||||
{
|
{
|
||||||
if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
|
if (hatchstyle < ARRAY_SIZE(HatchBrushes))
|
||||||
{
|
{
|
||||||
*result = HatchBrushes[hatchstyle];
|
*result = HatchBrushes[hatchstyle];
|
||||||
return Ok;
|
return Ok;
|
||||||
|
@ -1715,6 +1715,18 @@ GpStatus WINGDIPAPI GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GpStatus WINGDIPAPI GdipSetPathGradientPath(GpPathGradient *grad, GDIPCONST GpPath *path)
|
||||||
|
{
|
||||||
|
static int calls;
|
||||||
|
|
||||||
|
TRACE("(%p, %p)\n", grad, path);
|
||||||
|
|
||||||
|
if (!(calls++))
|
||||||
|
FIXME("not implemented\n");
|
||||||
|
|
||||||
|
return NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
|
GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
|
||||||
REAL focus, REAL scale)
|
REAL focus, REAL scale)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -38,11 +39,20 @@ GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap* from,
|
||||||
if(!from || !to)
|
if(!from || !to)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
*to = heap_alloc_zero(sizeof(GpCustomLineCap));
|
if (from->type == CustomLineCapTypeDefault)
|
||||||
if(!*to) return OutOfMemory;
|
*to = heap_alloc_zero(sizeof(GpCustomLineCap));
|
||||||
|
else
|
||||||
|
*to = heap_alloc_zero(sizeof(GpAdjustableArrowCap));
|
||||||
|
|
||||||
memcpy(*to, from, sizeof(GpCustomLineCap));
|
if (!*to)
|
||||||
|
return OutOfMemory;
|
||||||
|
|
||||||
|
if (from->type == CustomLineCapTypeDefault)
|
||||||
|
**to = *from;
|
||||||
|
else
|
||||||
|
*(GpAdjustableArrowCap *)*to = *(GpAdjustableArrowCap *)from;
|
||||||
|
|
||||||
|
/* Duplicate path data */
|
||||||
(*to)->pathdata.Points = heap_alloc_zero(from->pathdata.Count * sizeof(PointF));
|
(*to)->pathdata.Points = heap_alloc_zero(from->pathdata.Count * sizeof(PointF));
|
||||||
(*to)->pathdata.Types = heap_alloc_zero(from->pathdata.Count);
|
(*to)->pathdata.Types = heap_alloc_zero(from->pathdata.Count);
|
||||||
|
|
||||||
|
@ -62,12 +72,44 @@ GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap* from,
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GpStatus init_custom_linecap(GpCustomLineCap *cap, GpPathData *pathdata, BOOL fill, GpLineCap basecap,
|
||||||
|
REAL base_inset)
|
||||||
|
{
|
||||||
|
cap->fill = fill;
|
||||||
|
|
||||||
|
cap->pathdata.Points = heap_alloc_zero(pathdata->Count * sizeof(PointF));
|
||||||
|
cap->pathdata.Types = heap_alloc_zero(pathdata->Count);
|
||||||
|
|
||||||
|
if ((!cap->pathdata.Types || !cap->pathdata.Points) && pathdata->Count)
|
||||||
|
{
|
||||||
|
heap_free(cap->pathdata.Points);
|
||||||
|
heap_free(cap->pathdata.Types);
|
||||||
|
cap->pathdata.Points = NULL;
|
||||||
|
cap->pathdata.Types = NULL;
|
||||||
|
return OutOfMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pathdata->Points)
|
||||||
|
memcpy(cap->pathdata.Points, pathdata->Points, pathdata->Count * sizeof(PointF));
|
||||||
|
if (pathdata->Types)
|
||||||
|
memcpy(cap->pathdata.Types, pathdata->Types, pathdata->Count);
|
||||||
|
cap->pathdata.Count = pathdata->Count;
|
||||||
|
|
||||||
|
cap->inset = base_inset;
|
||||||
|
cap->cap = basecap;
|
||||||
|
cap->join = LineJoinMiter;
|
||||||
|
cap->scale = 1.0;
|
||||||
|
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Sometimes when fillPath is non-null and stroke path is null, the native
|
/* FIXME: Sometimes when fillPath is non-null and stroke path is null, the native
|
||||||
* version of this function returns NotImplemented. I cannot figure out why. */
|
* version of this function returns NotImplemented. I cannot figure out why. */
|
||||||
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath,
|
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath,
|
||||||
GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
|
GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
|
||||||
{
|
{
|
||||||
GpPathData *pathdata;
|
GpPathData *pathdata;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
TRACE("%p %p %d %f %p\n", fillPath, strokePath, baseCap, baseInset, customCap);
|
TRACE("%p %p %d %f %p\n", fillPath, strokePath, baseCap, baseInset, customCap);
|
||||||
|
|
||||||
|
@ -77,37 +119,18 @@ GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath
|
||||||
*customCap = heap_alloc_zero(sizeof(GpCustomLineCap));
|
*customCap = heap_alloc_zero(sizeof(GpCustomLineCap));
|
||||||
if(!*customCap) return OutOfMemory;
|
if(!*customCap) return OutOfMemory;
|
||||||
|
|
||||||
(*customCap)->type = CustomLineCapTypeDefault;
|
if (strokePath)
|
||||||
if(strokePath){
|
|
||||||
(*customCap)->fill = FALSE;
|
|
||||||
pathdata = &strokePath->pathdata;
|
pathdata = &strokePath->pathdata;
|
||||||
}
|
else
|
||||||
else{
|
|
||||||
(*customCap)->fill = TRUE;
|
|
||||||
pathdata = &fillPath->pathdata;
|
pathdata = &fillPath->pathdata;
|
||||||
}
|
|
||||||
|
|
||||||
(*customCap)->pathdata.Points = heap_alloc_zero(pathdata->Count * sizeof(PointF));
|
stat = init_custom_linecap(*customCap, pathdata, fillPath != NULL, baseCap, baseInset);
|
||||||
(*customCap)->pathdata.Types = heap_alloc_zero(pathdata->Count);
|
if (stat != Ok)
|
||||||
|
{
|
||||||
if((!(*customCap)->pathdata.Types || !(*customCap)->pathdata.Points) &&
|
|
||||||
pathdata->Count){
|
|
||||||
heap_free((*customCap)->pathdata.Points);
|
|
||||||
heap_free((*customCap)->pathdata.Types);
|
|
||||||
heap_free(*customCap);
|
heap_free(*customCap);
|
||||||
return OutOfMemory;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy((*customCap)->pathdata.Points, pathdata->Points, pathdata->Count
|
|
||||||
* sizeof(PointF));
|
|
||||||
memcpy((*customCap)->pathdata.Types, pathdata->Types, pathdata->Count);
|
|
||||||
(*customCap)->pathdata.Count = pathdata->Count;
|
|
||||||
|
|
||||||
(*customCap)->inset = baseInset;
|
|
||||||
(*customCap)->cap = baseCap;
|
|
||||||
(*customCap)->join = LineJoinMiter;
|
|
||||||
(*customCap)->scale = 1.0;
|
|
||||||
|
|
||||||
TRACE("<-- %p\n", *customCap);
|
TRACE("<-- %p\n", *customCap);
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
|
@ -257,111 +280,175 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap *customCap, CustomL
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arrowcap_update_path(GpAdjustableArrowCap *cap)
|
||||||
|
{
|
||||||
|
static const BYTE types_filled[] =
|
||||||
|
{
|
||||||
|
PathPointTypeStart, PathPointTypeLine, PathPointTypeLine, PathPointTypeLine | PathPointTypeCloseSubpath
|
||||||
|
};
|
||||||
|
static const BYTE types_unfilled[] =
|
||||||
|
{
|
||||||
|
PathPointTypeStart, PathPointTypeLine, PathPointTypeLine
|
||||||
|
};
|
||||||
|
GpPointF *points;
|
||||||
|
|
||||||
|
assert(cap->cap.pathdata.Count == 3 || cap->cap.pathdata.Count == 4);
|
||||||
|
|
||||||
|
points = cap->cap.pathdata.Points;
|
||||||
|
if (cap->cap.fill)
|
||||||
|
{
|
||||||
|
memcpy(cap->cap.pathdata.Types, types_filled, sizeof(types_filled));
|
||||||
|
cap->cap.pathdata.Count = 4;
|
||||||
|
points[0].X = -cap->width / 2.0;
|
||||||
|
points[0].Y = -cap->height;
|
||||||
|
points[1].X = 0.0;
|
||||||
|
points[1].Y = 0.0;
|
||||||
|
points[2].X = cap->width / 2.0;
|
||||||
|
points[2].Y = -cap->height;
|
||||||
|
points[3].X = 0.0;
|
||||||
|
points[3].Y = -cap->height - cap->middle_inset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(cap->cap.pathdata.Types, types_unfilled, sizeof(types_unfilled));
|
||||||
|
cap->cap.pathdata.Count = 3;
|
||||||
|
points[0].X = -cap->width / 4.0;
|
||||||
|
points[0].Y = -cap->height / 2.0;
|
||||||
|
points[1].X = 0.0;
|
||||||
|
points[1].Y = 0.0;
|
||||||
|
points[2].X = cap->width / 4.0;
|
||||||
|
points[2].Y = -cap->height / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cap->width == 0.0)
|
||||||
|
cap->cap.inset = 0.0;
|
||||||
|
else
|
||||||
|
cap->cap.inset = cap->height / cap->width;
|
||||||
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill,
|
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill,
|
||||||
GpAdjustableArrowCap **cap)
|
GpAdjustableArrowCap **cap)
|
||||||
{
|
{
|
||||||
static int calls;
|
GpPathData pathdata;
|
||||||
|
GpStatus stat;
|
||||||
|
|
||||||
TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
|
TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
*cap = heap_alloc_zero(sizeof(**cap));
|
||||||
|
if (!*cap)
|
||||||
|
return OutOfMemory;
|
||||||
|
|
||||||
|
/* We'll need 4 points at most. */
|
||||||
|
pathdata.Count = 4;
|
||||||
|
pathdata.Points = NULL;
|
||||||
|
pathdata.Types = NULL;
|
||||||
|
stat = init_custom_linecap(&(*cap)->cap, &pathdata, fill, LineCapTriangle, width != 0.0 ? height / width : 0.0);
|
||||||
|
if (stat != Ok)
|
||||||
|
{
|
||||||
|
heap_free(*cap);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*cap)->cap.type = CustomLineCapTypeAdjustableArrow;
|
||||||
|
(*cap)->height = height;
|
||||||
|
(*cap)->width = width;
|
||||||
|
(*cap)->middle_inset = 0.0;
|
||||||
|
arrowcap_update_path(*cap);
|
||||||
|
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fill)
|
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fill)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", cap, fill);
|
TRACE("(%p,%p)\n", cap, fill);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap || !fill)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
*fill = cap->cap.fill;
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height)
|
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", cap, height);
|
TRACE("(%p,%p)\n", cap, height);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap || !height)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
*height = cap->height;
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL* middle)
|
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL* middle)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", cap, middle);
|
TRACE("(%p,%p)\n", cap, middle);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap || !middle)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
*middle = cap->middle_inset;
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL* width)
|
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL* width)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", cap, width);
|
TRACE("(%p,%p)\n", cap, width);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap || !width)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
*width = cap->width;
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fill)
|
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fill)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%i)\n", cap, fill);
|
TRACE("(%p,%i)\n", cap, fill);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
cap->cap.fill = fill;
|
||||||
|
arrowcap_update_path(cap);
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height)
|
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%0.2f)\n", cap, height);
|
TRACE("(%p,%0.2f)\n", cap, height);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
cap->height = height;
|
||||||
|
arrowcap_update_path(cap);
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL middle)
|
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL middle)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%0.2f)\n", cap, middle);
|
TRACE("(%p,%0.2f)\n", cap, middle);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
cap->middle_inset = middle;
|
||||||
|
arrowcap_update_path(cap);
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL width)
|
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL width)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%0.2f)\n", cap, width);
|
TRACE("(%p,%0.2f)\n", cap, width);
|
||||||
|
|
||||||
if(!(calls++))
|
if (!cap)
|
||||||
FIXME("not implemented\n");
|
return InvalidParameter;
|
||||||
|
|
||||||
return NotImplemented;
|
cap->width = width;
|
||||||
|
arrowcap_update_path(cap);
|
||||||
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1367,7 +1367,7 @@ static int match_name_table_language( const tt_name_record *name, LANGID lang )
|
||||||
case TT_PLATFORM_MACINTOSH:
|
case TT_PLATFORM_MACINTOSH:
|
||||||
if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
|
if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
|
||||||
name_lang = GET_BE_WORD(name->language_id);
|
name_lang = GET_BE_WORD(name->language_id);
|
||||||
if (name_lang >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
|
if (name_lang >= ARRAY_SIZE(mac_langid_table)) return 0;
|
||||||
name_lang = mac_langid_table[name_lang];
|
name_lang = mac_langid_table[name_lang];
|
||||||
break;
|
break;
|
||||||
case TT_PLATFORM_APPLE_UNICODE:
|
case TT_PLATFORM_APPLE_UNICODE:
|
||||||
|
@ -1377,7 +1377,7 @@ static int match_name_table_language( const tt_name_record *name, LANGID lang )
|
||||||
case TT_APPLE_ID_ISO_10646:
|
case TT_APPLE_ID_ISO_10646:
|
||||||
case TT_APPLE_ID_UNICODE_2_0:
|
case TT_APPLE_ID_UNICODE_2_0:
|
||||||
name_lang = GET_BE_WORD(name->language_id);
|
name_lang = GET_BE_WORD(name->language_id);
|
||||||
if (name_lang >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
|
if (name_lang >= ARRAY_SIZE(mac_langid_table)) return 0;
|
||||||
name_lang = mac_langid_table[name_lang];
|
name_lang = mac_langid_table[name_lang];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -534,7 +534,7 @@
|
||||||
534 stdcall GdipSetPathGradientFocusScales(ptr float float)
|
534 stdcall GdipSetPathGradientFocusScales(ptr float float)
|
||||||
535 stdcall GdipSetPathGradientGammaCorrection(ptr long)
|
535 stdcall GdipSetPathGradientGammaCorrection(ptr long)
|
||||||
536 stdcall GdipSetPathGradientLinearBlend(ptr float float)
|
536 stdcall GdipSetPathGradientLinearBlend(ptr float float)
|
||||||
537 stub GdipSetPathGradientPath
|
537 stdcall GdipSetPathGradientPath(ptr ptr)
|
||||||
538 stdcall GdipSetPathGradientPresetBlend(ptr ptr ptr long)
|
538 stdcall GdipSetPathGradientPresetBlend(ptr ptr ptr long)
|
||||||
539 stdcall GdipSetPathGradientSigmaBlend(ptr float float)
|
539 stdcall GdipSetPathGradientSigmaBlend(ptr float float)
|
||||||
540 stdcall GdipSetPathGradientSurroundColorsWithCount(ptr ptr ptr)
|
540 stdcall GdipSetPathGradientSurroundColorsWithCount(ptr ptr ptr)
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#include "gdiplus.h"
|
#include "gdiplus.h"
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
|
|
||||||
#define GP_DEFAULT_PENSTYLE (PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_FLAT | PS_JOIN_MITER)
|
#define GP_DEFAULT_PENSTYLE (PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_FLAT | PS_JOIN_MITER)
|
||||||
#define MAX_ARC_PTS (13)
|
#define MAX_ARC_PTS (13)
|
||||||
#define MAX_DASHLEN (16) /* this is a limitation of gdi */
|
#define MAX_DASHLEN (16) /* this is a limitation of gdi */
|
||||||
|
@ -341,6 +343,9 @@ struct GpCustomLineCap{
|
||||||
|
|
||||||
struct GpAdjustableArrowCap{
|
struct GpAdjustableArrowCap{
|
||||||
GpCustomLineCap cap;
|
GpCustomLineCap cap;
|
||||||
|
REAL middle_inset;
|
||||||
|
REAL height;
|
||||||
|
REAL width;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GpImage{
|
struct GpImage{
|
||||||
|
|
|
@ -353,15 +353,20 @@ static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn)
|
||||||
GpRegion *rgn;
|
GpRegion *rgn;
|
||||||
GpMatrix transform;
|
GpMatrix transform;
|
||||||
GpStatus stat;
|
GpStatus stat;
|
||||||
|
BOOL identity;
|
||||||
|
|
||||||
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceDevice, &transform);
|
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceDevice, &transform);
|
||||||
|
|
||||||
|
if (stat == Ok)
|
||||||
|
stat = GdipIsMatrixIdentity(&transform, &identity);
|
||||||
|
|
||||||
if (stat == Ok)
|
if (stat == Ok)
|
||||||
stat = GdipCloneRegion(graphics->clip, &rgn);
|
stat = GdipCloneRegion(graphics->clip, &rgn);
|
||||||
|
|
||||||
if (stat == Ok)
|
if (stat == Ok)
|
||||||
{
|
{
|
||||||
stat = GdipTransformRegion(rgn, &transform);
|
if (!identity)
|
||||||
|
stat = GdipTransformRegion(rgn, &transform);
|
||||||
|
|
||||||
if (stat == Ok)
|
if (stat == Ok)
|
||||||
stat = GdipGetRegionHRgn(rgn, NULL, hrgn);
|
stat = GdipGetRegionHRgn(rgn, NULL, hrgn);
|
||||||
|
@ -1695,9 +1700,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
|
||||||
ptf[3].X = x2 - dbig;
|
ptf[3].X = x2 - dbig;
|
||||||
ptf[2].X = x2 + dsmall;
|
ptf[2].X = x2 + dsmall;
|
||||||
|
|
||||||
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 4);
|
||||||
|
|
||||||
round_points(pt, ptf, 3);
|
round_points(pt, ptf, 4);
|
||||||
|
|
||||||
Polygon(graphics->hdc, pt, 4);
|
Polygon(graphics->hdc, pt, 4);
|
||||||
|
|
||||||
|
@ -1735,9 +1740,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
|
||||||
ptf[1].X = x2 + dx;
|
ptf[1].X = x2 + dx;
|
||||||
ptf[1].Y = y2 + dy;
|
ptf[1].Y = y2 + dy;
|
||||||
|
|
||||||
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 2);
|
||||||
|
|
||||||
round_points(pt, ptf, 3);
|
round_points(pt, ptf, 2);
|
||||||
|
|
||||||
Ellipse(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
|
Ellipse(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
|
||||||
|
|
||||||
|
@ -1781,9 +1786,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
|
||||||
ptf[3].X = x2 + dx;
|
ptf[3].X = x2 + dx;
|
||||||
ptf[3].Y = y2 + dy;
|
ptf[3].Y = y2 + dy;
|
||||||
|
|
||||||
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 4);
|
||||||
|
|
||||||
round_points(pt, ptf, 3);
|
round_points(pt, ptf, 4);
|
||||||
|
|
||||||
Pie(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y, pt[2].x,
|
Pie(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y, pt[2].x,
|
||||||
pt[2].y, pt[3].x, pt[3].y);
|
pt[2].y, pt[3].x, pt[3].y);
|
||||||
|
@ -1793,6 +1798,13 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
|
||||||
if(!custom)
|
if(!custom)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (custom->type == CustomLineCapTypeAdjustableArrow)
|
||||||
|
{
|
||||||
|
GpAdjustableArrowCap *arrow = (GpAdjustableArrowCap *)custom;
|
||||||
|
if (arrow->cap.fill && arrow->height <= 0.0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
count = custom->pathdata.Count;
|
count = custom->pathdata.Count;
|
||||||
custptf = heap_alloc_zero(count * sizeof(PointF));
|
custptf = heap_alloc_zero(count * sizeof(PointF));
|
||||||
custpt = heap_alloc_zero(count * sizeof(POINT));
|
custpt = heap_alloc_zero(count * sizeof(POINT));
|
||||||
|
@ -1810,9 +1822,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap cap, REAL s
|
||||||
GdipTranslateMatrix(&matrix, x2, y2, MatrixOrderAppend);
|
GdipTranslateMatrix(&matrix, x2, y2, MatrixOrderAppend);
|
||||||
GdipTransformMatrixPoints(&matrix, custptf, count);
|
GdipTransformMatrixPoints(&matrix, custptf, count);
|
||||||
|
|
||||||
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, ptf, 3);
|
gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice, CoordinateSpaceWorld, custptf, count);
|
||||||
|
|
||||||
round_points(pt, ptf, 3);
|
round_points(custpt, custptf, count);
|
||||||
|
|
||||||
for(i = 0; i < count; i++)
|
for(i = 0; i < count; i++)
|
||||||
tp[i] = convert_path_point_type(custom->pathdata.Types[i]);
|
tp[i] = convert_path_point_type(custom->pathdata.Types[i]);
|
||||||
|
@ -6469,9 +6481,12 @@ GpStatus WINGDIPAPI GdipSetClipRect(GpGraphics *graphics, REAL x, REAL y,
|
||||||
if (status == Ok)
|
if (status == Ok)
|
||||||
{
|
{
|
||||||
GpMatrix world_to_device;
|
GpMatrix world_to_device;
|
||||||
|
BOOL identity;
|
||||||
|
|
||||||
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
|
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
|
||||||
status = GdipTransformRegion(region, &world_to_device);
|
status = GdipIsMatrixIdentity(&world_to_device, &identity);
|
||||||
|
if (status == Ok && !identity)
|
||||||
|
status = GdipTransformRegion(region, &world_to_device);
|
||||||
if (status == Ok)
|
if (status == Ok)
|
||||||
status = GdipCombineRegionRegion(graphics->clip, region, mode);
|
status = GdipCombineRegionRegion(graphics->clip, region, mode);
|
||||||
|
|
||||||
|
@ -6520,9 +6535,12 @@ GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics *graphics, GpRegion *region,
|
||||||
if (status == Ok)
|
if (status == Ok)
|
||||||
{
|
{
|
||||||
GpMatrix world_to_device;
|
GpMatrix world_to_device;
|
||||||
|
BOOL identity;
|
||||||
|
|
||||||
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
|
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
|
||||||
status = GdipTransformRegion(clip, &world_to_device);
|
status = GdipIsMatrixIdentity(&world_to_device, &identity);
|
||||||
|
if (status == Ok && !identity)
|
||||||
|
status = GdipTransformRegion(clip, &world_to_device);
|
||||||
if (status == Ok)
|
if (status == Ok)
|
||||||
status = GdipCombineRegionRegion(graphics->clip, clip, mode);
|
status = GdipCombineRegionRegion(graphics->clip, clip, mode);
|
||||||
|
|
||||||
|
|
|
@ -2560,7 +2560,7 @@ static UINT vt_to_itemtype(UINT vt)
|
||||||
{ VT_BLOB, PropertyTagTypeUndefined }
|
{ VT_BLOB, PropertyTagTypeUndefined }
|
||||||
};
|
};
|
||||||
UINT i;
|
UINT i;
|
||||||
for (i = 0; i < sizeof(vt2type)/sizeof(vt2type[0]); i++)
|
for (i = 0; i < ARRAY_SIZE(vt2type); i++)
|
||||||
{
|
{
|
||||||
if (vt2type[i].vt == vt) return vt2type[i].type;
|
if (vt2type[i].vt == vt) return vt2type[i].type;
|
||||||
}
|
}
|
||||||
|
@ -3460,10 +3460,10 @@ static void png_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI
|
||||||
{
|
{
|
||||||
if (name.vt == VT_LPSTR)
|
if (name.vt == VT_LPSTR)
|
||||||
{
|
{
|
||||||
for (j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++)
|
for (j = 0; j < ARRAY_SIZE(keywords); j++)
|
||||||
if (!strcmp(keywords[j].name, name.u.pszVal))
|
if (!strcmp(keywords[j].name, name.u.pszVal))
|
||||||
break;
|
break;
|
||||||
if (j < sizeof(keywords)/sizeof(keywords[0]) && !keywords[j].seen)
|
if (j < ARRAY_SIZE(keywords) && !keywords[j].seen)
|
||||||
{
|
{
|
||||||
keywords[j].seen = TRUE;
|
keywords[j].seen = TRUE;
|
||||||
item = create_prop(keywords[j].propid, &value);
|
item = create_prop(keywords[j].propid, &value);
|
||||||
|
@ -4586,7 +4586,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream* stream,
|
||||||
encode_image_func encode_image;
|
encode_image_func encode_image;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
TRACE("%p %p %s %p\n", image, stream, wine_dbgstr_guid(clsid), params);
|
TRACE("%p, %p, %s, %p\n", image, stream, wine_dbgstr_guid(clsid), params);
|
||||||
|
|
||||||
if(!image || !stream)
|
if(!image || !stream)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
|
@ -606,7 +606,7 @@ void METAFILE_Free(GpMetafile *metafile)
|
||||||
if (metafile->record_stream)
|
if (metafile->record_stream)
|
||||||
IStream_Release(metafile->record_stream);
|
IStream_Release(metafile->record_stream);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(metafile->objtable)/sizeof(metafile->objtable[0]); i++)
|
for (i = 0; i < ARRAY_SIZE(metafile->objtable); i++)
|
||||||
metafile_free_object_table_entry(metafile, i);
|
metafile_free_object_table_entry(metafile, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -460,17 +460,12 @@ GpStatus WINGDIPAPI GdipGetPenTransform(GpPen *pen, GpMatrix *matrix)
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy, GpMatrixOrder order)
|
GpStatus WINGDIPAPI GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy, GpMatrixOrder order)
|
||||||
{
|
{
|
||||||
static int calls;
|
|
||||||
|
|
||||||
TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, dx, dy, order);
|
TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, dx, dy, order);
|
||||||
|
|
||||||
if(!pen)
|
if(!pen)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
if(!(calls++))
|
return GdipTranslateMatrix(&pen->transform, dx, dy, order);
|
||||||
FIXME("not implemented\n");
|
|
||||||
|
|
||||||
return NotImplemented;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrixOrder order)
|
GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrixOrder order)
|
||||||
|
|
|
@ -1398,10 +1398,46 @@ static GpStatus transform_region_element(region_element* element, GpMatrix *matr
|
||||||
return Ok;
|
return Ok;
|
||||||
case RegionDataRect:
|
case RegionDataRect:
|
||||||
{
|
{
|
||||||
/* We can't transform a rectangle, so convert it to a path. */
|
|
||||||
GpRegion *new_region;
|
GpRegion *new_region;
|
||||||
GpPath *path;
|
GpPath *path;
|
||||||
|
|
||||||
|
if (matrix->matrix[1] == 0.0 && matrix->matrix[2] == 0.0)
|
||||||
|
{
|
||||||
|
GpPointF points[2];
|
||||||
|
|
||||||
|
points[0].X = element->elementdata.rect.X;
|
||||||
|
points[0].Y = element->elementdata.rect.Y;
|
||||||
|
points[1].X = element->elementdata.rect.X + element->elementdata.rect.Width;
|
||||||
|
points[1].Y = element->elementdata.rect.Y + element->elementdata.rect.Height;
|
||||||
|
|
||||||
|
stat = GdipTransformMatrixPoints(matrix, points, 2);
|
||||||
|
if (stat != Ok)
|
||||||
|
return stat;
|
||||||
|
|
||||||
|
if (points[0].X > points[1].X)
|
||||||
|
{
|
||||||
|
REAL temp;
|
||||||
|
temp = points[0].X;
|
||||||
|
points[0].X = points[1].X;
|
||||||
|
points[1].X = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points[0].Y > points[1].Y)
|
||||||
|
{
|
||||||
|
REAL temp;
|
||||||
|
temp = points[0].Y;
|
||||||
|
points[0].Y = points[1].Y;
|
||||||
|
points[1].Y = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
element->elementdata.rect.X = points[0].X;
|
||||||
|
element->elementdata.rect.Y = points[0].Y;
|
||||||
|
element->elementdata.rect.Width = points[1].X - points[0].X;
|
||||||
|
element->elementdata.rect.Height = points[1].Y - points[0].Y;
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We can't rotate/shear a rectangle, so convert it to a path. */
|
||||||
stat = GdipCreatePath(FillModeAlternate, &path);
|
stat = GdipCreatePath(FillModeAlternate, &path);
|
||||||
if (stat == Ok)
|
if (stat == Ok)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-3.3
|
||||||
reactos/dll/win32/faultrep # Synced to WineStaging-2.9
|
reactos/dll/win32/faultrep # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/fontsub # Synced to WineStaging-2.9
|
reactos/dll/win32/fontsub # Synced to WineStaging-2.9
|
||||||
reactos/dll/win32/fusion # Synced to WineStaging-3.3
|
reactos/dll/win32/fusion # Synced to WineStaging-3.3
|
||||||
reactos/dll/win32/gdiplus # Synced to WineStaging-3.3
|
reactos/dll/win32/gdiplus # Synced to WineStaging-3.9
|
||||||
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-3.3
|
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-3.3
|
||||||
reactos/dll/win32/hlink # Synced to WineStaging-3.3
|
reactos/dll/win32/hlink # Synced to WineStaging-3.3
|
||||||
reactos/dll/win32/hnetcfg # Synced to WineStaging-3.3
|
reactos/dll/win32/hnetcfg # Synced to WineStaging-3.3
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue