You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
13521 lines
286 KiB
13521 lines
286 KiB
/**************************************************************************\
|
|
*
|
|
* Copyright (c) 1998 Microsoft Corporation
|
|
*
|
|
* Module Name:
|
|
*
|
|
* flatapi.cpp
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Flat GDI+ API wrappers
|
|
*
|
|
* Revision History:
|
|
*
|
|
* 12/13/1998 davidx
|
|
* Created it.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hpp"
|
|
#include "GdiplusFlat.h"
|
|
#include "gpverp.h"
|
|
|
|
#if DBG
|
|
#include <mmsystem.h>
|
|
#endif
|
|
|
|
extern "C" {
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
// CheckParameter(p)
|
|
//
|
|
// If p evaluates to FALSE, then we currently assert. In future,
|
|
// we can simply return an invalid parameter status which throws
|
|
// an exception.
|
|
//
|
|
// CheckObjectBusy(p)
|
|
//
|
|
// Not implemented. Bails out if object is currently being used.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// !!!: Only include NULL & IsValid checks in checked builds?
|
|
//
|
|
// !!!: Instead of deleting object, call a Dispose() method, so far
|
|
// only Bitmap supports this.
|
|
//
|
|
// !!!: Lock Matrix objects, what about color?
|
|
//
|
|
// !! Better error checking. For 'I' APIs which convert from Point to PointI,
|
|
// etc. Verify count & point are valid first.
|
|
//
|
|
// !! Change ObjectLock to mutable memory and GetObjectLock() to a const member.
|
|
//
|
|
|
|
#define CheckParameter(cond) \
|
|
if (! (cond)) \
|
|
return InvalidParameter;
|
|
|
|
#define CheckParameterValid(obj) \
|
|
if (!(obj) || !((obj)->IsValid())) \
|
|
return InvalidParameter;
|
|
|
|
#define CheckOptionalParameterValid(obj) \
|
|
if ((obj) && (!(obj)->IsValid())) \
|
|
return InvalidParameter;
|
|
|
|
#define CheckObjectBusy(obj) \
|
|
GpLock lock##obj(obj->GetObjectLock()); \
|
|
if (!(lock##obj).IsValid()) \
|
|
return ObjectBusy;
|
|
|
|
#define CheckOptionalObjectBusy(obj) \
|
|
GpLock lock##obj(obj ? obj->GetObjectLock() : NULL); \
|
|
if (obj && (!(lock##obj).IsValid())) \
|
|
return ObjectBusy;
|
|
|
|
// We should put an assert in here so that we stop in the debugger if anyone
|
|
// does this.
|
|
|
|
#define CheckObjectBusyForDelete(obj) \
|
|
GpLock lock##obj(obj->GetObjectLock()); \
|
|
if (!(lock##obj).IsValid()) \
|
|
{ \
|
|
WARNING(("Silent memory leak deleting object %p.", obj)); \
|
|
WARNING(("Object lock held by another thread."));\
|
|
WARNING(("Incorrect synchronization by the calling application."));\
|
|
return ObjectBusy; \
|
|
} \
|
|
lock##obj.MakePermanentLock();
|
|
|
|
#define CheckColorParameter(color) \
|
|
;
|
|
|
|
#define LazilyInitializeGdiplus
|
|
|
|
#define CheckGdiplusInitialized \
|
|
{ GdiplusStartupCriticalSection critsec; \
|
|
if (Globals::LibraryInitRefCount <= 0) \
|
|
return GdiplusNotInitialized; \
|
|
}
|
|
|
|
#define CheckGdiplusInitialized_ReturnNULL \
|
|
{ GdiplusStartupCriticalSection critsec; \
|
|
if (Globals::LibraryInitRefCount <= 0) \
|
|
return NULL; \
|
|
}
|
|
|
|
|
|
#define MaskPixelFormat(pixel) (pixel & 0xFFFFFF)
|
|
|
|
|
|
#if DBG
|
|
|
|
// This class asserts that GDI+ is in an initialized state, to be used in
|
|
// our entry-point functions in a debug build.
|
|
//
|
|
// We assert both at the start and the end of the call, and we make sure that
|
|
// we don't hold the critical section for the duration of the API (else this
|
|
// would serialize all our calls on debug builds.)
|
|
|
|
class InitAsserter
|
|
{
|
|
public:
|
|
InitAsserter() {
|
|
GdiplusStartupCriticalSection critsec;
|
|
ASSERTMSG(Globals::LibraryInitRefCount > 0, ("GDI+ API called before GdiplusStartup/after GdiplusShutdown."));
|
|
}
|
|
~InitAsserter() {
|
|
GdiplusStartupCriticalSection critsec;
|
|
ASSERTMSG(Globals::LibraryInitRefCount > 0, ("GDI+ API called before GdiplusStartup/after GdiplusShutdown."));
|
|
}
|
|
};
|
|
#endif
|
|
|
|
#ifdef GP_ENABLE_MONITORS
|
|
#ifdef GP_RELEASE_BUILD
|
|
#define DEFINE_MONITOR(a)
|
|
#else
|
|
#define DEFINE_MONITOR(a) GpBlockMonitor blockMonitor(MONITOR(a));
|
|
#endif
|
|
#else
|
|
#define DEFINE_MONITOR(a)
|
|
#endif
|
|
|
|
// Define this to do something on each API entry point.
|
|
// This is a debugging aid for complex instruction streams (e.g. Office)
|
|
// [agodfrey] Well, it just became more than a mere debugging aid...
|
|
// [asecchia] Now it's definitely more than a debugging aid...
|
|
// FPUStateSaver was being forgotten on many of our APIs so
|
|
// it's now in here and therefore will be included in all of
|
|
// our APIs (except Startup and Shutdown).
|
|
|
|
#if DBG
|
|
#define API_ENTRY(a) \
|
|
DEFINE_MONITOR(a) \
|
|
LazilyInitializeGdiplus; \
|
|
VERBOSE(("GDI+ API " #a)); \
|
|
InitAsserter __initAsserter; \
|
|
FPUStateSaver fps;
|
|
|
|
#define API_ENTRY_NO_INITCHECK(a) \
|
|
DEFINE_MONITOR(a) \
|
|
VERBOSE(("GDI+ API ", #a));
|
|
#else
|
|
|
|
#define API_ENTRY(a) \
|
|
DEFINE_MONITOR(a) \
|
|
LazilyInitializeGdiplus;\
|
|
FPUStateSaver fps;
|
|
|
|
#define API_ENTRY_NO_INITCHECK(a) \
|
|
DEFINE_MONITOR(a)
|
|
#endif
|
|
|
|
GdiplusStartupOutput gStartupOutput = {
|
|
NotificationStartup,
|
|
NotificationShutdown
|
|
};
|
|
|
|
GpStatus WINAPI
|
|
GdiplusStartup(
|
|
OUT ULONG_PTR *token,
|
|
const GdiplusStartupInput *input,
|
|
OUT GdiplusStartupOutput *output)
|
|
{
|
|
API_ENTRY_NO_INITCHECK(GdiplusStartup);
|
|
|
|
if ( (!token)
|
|
|| (!input)
|
|
|| (input->SuppressBackgroundThread && !output))
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
if (input->GdiplusVersion != 1)
|
|
{
|
|
return UnsupportedGdiplusVersion;
|
|
}
|
|
|
|
GdiplusStartupCriticalSection critsec;
|
|
|
|
// Should never happen, because GdiplusShutdown won't decrement below zero.
|
|
|
|
if (Globals::LibraryInitRefCount == 0)
|
|
{
|
|
// Note: We can't allocate anything before this point
|
|
|
|
GpStatus ret = InternalGdiplusStartup(input);
|
|
|
|
if (ret != Ok) return ret;
|
|
|
|
Globals::LibraryInitToken = GenerateInitToken();
|
|
}
|
|
|
|
ASSERT(Globals::LibraryInitRefCount >= 0);
|
|
|
|
*token = Globals::LibraryInitToken + Globals::LibraryInitRefCount;
|
|
Globals::LibraryInitRefCount++;
|
|
|
|
if (input->SuppressBackgroundThread)
|
|
{
|
|
*output = gStartupOutput;
|
|
}
|
|
return Ok;
|
|
}
|
|
|
|
VOID WINAPI
|
|
GdiplusShutdown(
|
|
ULONG_PTR token)
|
|
{
|
|
API_ENTRY_NO_INITCHECK(GdiplusShutdown);
|
|
|
|
GdiplusStartupCriticalSection critsec;
|
|
|
|
// Should never happen, because we won't decrement below zero.
|
|
|
|
ASSERT(Globals::LibraryInitRefCount >= 0);
|
|
|
|
if (Globals::LibraryInitRefCount == 0)
|
|
{
|
|
// Return - i.e. ignore the extra shutdown call
|
|
|
|
RIP(("Too many calls to GdiplusShutdown"));
|
|
return;
|
|
}
|
|
|
|
if (Globals::LibraryInitRefCount == 1)
|
|
{
|
|
// Shut down for real
|
|
|
|
Globals::LibraryInitToken = 0;
|
|
|
|
InternalGdiplusShutdown();
|
|
|
|
// No allocation/deallocation can happen after this point
|
|
}
|
|
else if (token == Globals::LibraryInitToken)
|
|
{
|
|
// The first client to initialize is shutting down; we must clean up
|
|
// after this one since it defines certain global behavior.
|
|
|
|
Globals::UserDebugEventProc = NULL;
|
|
}
|
|
|
|
Globals::LibraryInitRefCount--;
|
|
}
|
|
|
|
GpStatus WINAPI
|
|
GdiplusNotificationHook(
|
|
OUT ULONG_PTR *token)
|
|
{
|
|
API_ENTRY(GdiplusNotificationHook);
|
|
|
|
{
|
|
GdiplusStartupCriticalSection critsec;
|
|
|
|
// It's illegal to call this API if you're using a background thread.
|
|
|
|
if (Globals::ThreadNotify)
|
|
{
|
|
return GenericError;
|
|
}
|
|
}
|
|
|
|
return NotificationStartup(token);
|
|
}
|
|
|
|
VOID WINAPI
|
|
GdiplusNotificationUnhook(
|
|
ULONG_PTR token)
|
|
{
|
|
API_ENTRY(GdiplusNotificationUnhook);
|
|
|
|
{
|
|
GdiplusStartupCriticalSection critsec;
|
|
|
|
// It's illegal to call this API if you're using a background thread.
|
|
|
|
if (Globals::ThreadNotify)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
NotificationShutdown(token);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePath(GpFillMode fillMode, GpPath **outPath)
|
|
{
|
|
API_ENTRY(GdipCreatePath);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(outPath);
|
|
|
|
GpPath * path;
|
|
|
|
path = (GpPath *) InterlockedExchangePointer((PVOID *) &Globals::PathLookAside, NULL);
|
|
|
|
if(path != NULL)
|
|
{
|
|
path->GetObjectLock()->Reset();
|
|
path->Reset(fillMode);
|
|
}
|
|
else
|
|
{
|
|
path = new (GpPathTag, TRUE) GpPath(fillMode);
|
|
}
|
|
|
|
|
|
if (CheckValid(path))
|
|
{
|
|
*outPath = path;
|
|
return Ok;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePath2(
|
|
GDIPCONST GpPointF* points,
|
|
GDIPCONST BYTE* types,
|
|
INT count,
|
|
GpFillMode fillMode,
|
|
GpPath **path
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePath2);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(path && points && types);
|
|
|
|
*path = new (GpPathTag, TRUE) GpPath(points, types, count, fillMode);
|
|
|
|
if (CheckValid(*path))
|
|
{
|
|
return Ok;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePath2I(
|
|
GDIPCONST GpPoint* points,
|
|
GDIPCONST BYTE* types,
|
|
INT count,
|
|
GpFillMode fillMode,
|
|
GpPath **path
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePath2I);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(path && points && types);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
*path = new (GpPathTag, TRUE) GpPath(pointsF, types, count, fillMode);
|
|
|
|
if (CheckValid(*path))
|
|
{
|
|
return Ok;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipClonePath(
|
|
GpPath* path,
|
|
GpPath** clonepath
|
|
)
|
|
{
|
|
API_ENTRY(GdipClonePath);
|
|
CheckParameter(clonepath);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
*clonepath = path->Clone();
|
|
|
|
if (*clonepath)
|
|
{
|
|
// Make sure we tag this allocation as an API allocation
|
|
GpTagMalloc(*clonepath, GpPathTag, TRUE);
|
|
return Ok;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeletePath(
|
|
GpPath* path
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeletePath);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
|
|
CheckParameter(path);
|
|
CheckObjectBusyForDelete(path);
|
|
|
|
path = (GpPath *) InterlockedExchangePointer((PVOID *) &Globals::PathLookAside, path);
|
|
|
|
if(path != NULL)
|
|
{
|
|
delete path;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetPath(
|
|
GpPath* path
|
|
)
|
|
{
|
|
API_ENTRY(GdipResetPath);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->Reset();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPointCount(
|
|
GpPath* path,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPointCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
*count = path->GetPointCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathTypes(
|
|
GpPath* path,
|
|
BYTE* types,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathTypes);
|
|
CheckParameter(types && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
INT pathCount;
|
|
|
|
pathCount = path->GetPointCount();
|
|
|
|
if (pathCount > count)
|
|
return InsufficientBuffer;
|
|
|
|
if (pathCount < 0)
|
|
return GenericError;
|
|
|
|
GpMemcpy(types, path->GetPathTypes(), pathCount);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathPoints(
|
|
GpPath* path,
|
|
GpPointF* points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathPoints);
|
|
// NOTE: Race condition between GetPointCount() & GetPathPoints()
|
|
// we need a manually invokable lock here.
|
|
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
INT pathCount;
|
|
|
|
pathCount = path->GetPointCount();
|
|
|
|
if (pathCount > count)
|
|
return InsufficientBuffer;
|
|
|
|
if (pathCount < 0)
|
|
return GenericError;
|
|
|
|
GpMemcpy(points, path->GetPathPoints(), pathCount*sizeof(GpPointF));
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathPointsI(
|
|
GpPath* path,
|
|
GpPoint* points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathPointsI);
|
|
// NOTE: Race condition between GetPointCount() & GetPathPoints()
|
|
// we need a manually invokable lock here.
|
|
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
INT pathCount;
|
|
|
|
pathCount = path->GetPointCount();
|
|
|
|
if (pathCount > count)
|
|
return InsufficientBuffer;
|
|
|
|
if (pathCount < 0)
|
|
return GenericError;
|
|
|
|
|
|
GDIPCONST GpPointF *pointsF = path->GetPathPoints();
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
points[i].X = GpRound(pointsF[i].X);
|
|
points[i].Y = GpRound(pointsF[i].Y);
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathFillMode(
|
|
GpPath *path,
|
|
GpFillMode *fillmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathFillMode);
|
|
CheckParameter(fillmode);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
*fillmode = (GpFillMode)path->GetFillMode();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathFillMode(
|
|
GpPath *path,
|
|
GpFillMode fillmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathFillMode);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
path->SetFillMode(fillmode);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathData(
|
|
GpPath *path,
|
|
GpPathData* pathData
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathData);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->SetPathData(pathData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathData(
|
|
GpPath *path,
|
|
GpPathData* pathData
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathData);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->GetPathData(pathData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipStartPathFigure(
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipStartPathFigure);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
path->StartFigure();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipClosePathFigure(
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipClosePathFigure);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->CloseFigure();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipClosePathFigures(
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipClosePathFigures);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->CloseFigures();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathMarker(
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathMarker);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->SetMarker();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipClearPathMarkers(
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipClearPathMarkers);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->ClearMarkers();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipReversePath(
|
|
GpPath* path
|
|
)
|
|
{
|
|
API_ENTRY(GdipReversePath);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->Reverse();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathLastPoint(
|
|
GpPath* path,
|
|
GpPointF* lastPoint
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathLastPoint);
|
|
CheckParameter(lastPoint);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->GetLastPoint(lastPoint);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathLine(
|
|
GpPath *path,
|
|
REAL x1,
|
|
REAL y1,
|
|
REAL x2,
|
|
REAL y2
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathLine);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddLine(x1, y1, x2, y2);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathLineI(
|
|
GpPath *path,
|
|
INT x1,
|
|
INT y1,
|
|
INT x2,
|
|
INT y2
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathLineI);
|
|
return GdipAddPathLine(path, TOREAL(x1), TOREAL(y1), TOREAL(x2), TOREAL(y2));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathLine2(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipAddPathLine2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddLines(points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathLine2I(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipAddPathLine2I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathLine2(path, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathArc(
|
|
GpPath *path,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathArc);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddArc(
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
startAngle,
|
|
sweepAngle
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathArcI(
|
|
GpPath *path,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathArcI);
|
|
return GdipAddPathArc(path,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
TOREAL(width),
|
|
TOREAL(height),
|
|
startAngle,
|
|
sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathBezier(
|
|
GpPath *path,
|
|
REAL x1,
|
|
REAL y1,
|
|
REAL x2,
|
|
REAL y2,
|
|
REAL x3,
|
|
REAL y3,
|
|
REAL x4,
|
|
REAL y4
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathBezier);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddBezier(x1,
|
|
y1,
|
|
x2,
|
|
y2,
|
|
x3,
|
|
y3,
|
|
x4,
|
|
y4);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathBezierI(
|
|
GpPath *path,
|
|
INT x1,
|
|
INT y1,
|
|
INT x2,
|
|
INT y2,
|
|
INT x3,
|
|
INT y3,
|
|
INT x4,
|
|
INT y4
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathBezierI);
|
|
return GdipAddPathBezier(path,
|
|
TOREAL(x1),
|
|
TOREAL(y1),
|
|
TOREAL(x2),
|
|
TOREAL(y2),
|
|
TOREAL(x3),
|
|
TOREAL(y3),
|
|
TOREAL(x4),
|
|
TOREAL(y4));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathBeziers(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathBeziers);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddBeziers(points, count);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathBeziersI(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathBeziersI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathBeziers(path, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathCurve(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathCurve);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddCurve(points, count);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathCurveI(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathCurveI);
|
|
CheckParameter(points && count > 0);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathCurve(path, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathCurve2(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathCurve2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
INT offset = 0;
|
|
INT numOfSegments = count - 1;
|
|
|
|
return path->AddCurve(points, count, tension, offset, numOfSegments);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathCurve2I(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathCurve2I);
|
|
CheckParameter(points && count > 0);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathCurve2(path, pointsF, count, tension);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathCurve3(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
INT offset,
|
|
INT numberOfSegments,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathCurve3);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddCurve(points, count, tension, offset, numberOfSegments);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathCurve3I(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
INT offset,
|
|
INT numberOfSegments,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathCurve3I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathCurve3(path, pointsF, count, offset, numberOfSegments, tension);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathClosedCurve(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathClosedCurve);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddClosedCurve(points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathClosedCurveI(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathClosedCurveI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathClosedCurve(path, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathClosedCurve2(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathClosedCurve2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddClosedCurve(points, count, tension);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathClosedCurve2I(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathClosedCurve2I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathClosedCurve2(path, pointsF, count, tension);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathRectangle(
|
|
GpPath *path,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathRectangle);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
|
|
return path->AddRect(rect);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathRectangleI(
|
|
GpPath *path,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathRectangleI);
|
|
return GdipAddPathRectangle(path, TOREAL(x), TOREAL(y), TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathRectangles(
|
|
GpPath *path,
|
|
GDIPCONST GpRectF *rects,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathRectangles);
|
|
CheckParameter(rects && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddRects(rects, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathRectanglesI(
|
|
GpPath *path,
|
|
GDIPCONST GpRect *rects,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathRectanglesI);
|
|
StackBuffer buffer;
|
|
|
|
GpRectF *rectsF = (GpRectF*) buffer.GetBuffer(count*sizeof(GpRectF));
|
|
|
|
if(!rectsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
rectsF[i].X = TOREAL(rects[i].X);
|
|
rectsF[i].Y = TOREAL(rects[i].Y);
|
|
rectsF[i].Width = TOREAL(rects[i].Width);
|
|
rectsF[i].Height = TOREAL(rects[i].Height);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathRectangles(path, rectsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathEllipse(
|
|
GpPath* path,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathEllipse);
|
|
// Idea: What about just putting "GpRectF rect" as the parameter,
|
|
// no copying, the stack image should match the structure
|
|
// avoiding an additional copy.
|
|
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
|
|
return path->AddEllipse(rect);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathEllipseI(
|
|
GpPath* path,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathEllipseI);
|
|
return GdipAddPathEllipse(path, TOREAL(x), TOREAL(y), TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathPie(
|
|
GpPath *path,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathPie);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddPie(x, y, width, height, startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathPieI(
|
|
GpPath *path,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathPieI);
|
|
return GdipAddPathPie(path,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
TOREAL(width),
|
|
TOREAL(height),
|
|
startAngle,
|
|
sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathPolygon(
|
|
GpPath *path,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathPolygon);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddPolygon(points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathPolygonI(
|
|
GpPath *path,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathPolygonI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipAddPathPolygon(path, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathPath(
|
|
GpPath *path,
|
|
GDIPCONST GpPath* addingPath,
|
|
BOOL connect
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathPath);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
return path->AddPath(addingPath, connect);
|
|
}
|
|
|
|
static inline
|
|
EmptyString(const WCHAR * string, INT length)
|
|
{
|
|
return (length == 0 || length == -1 && string[0] == 0);
|
|
}
|
|
|
|
static inline
|
|
void SetEmptyRectF(RectF * boundingBox)
|
|
{
|
|
boundingBox->X = boundingBox->Y = boundingBox->Width = boundingBox->Height = 0.0;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathString(
|
|
GpPath *path,
|
|
GDIPCONST WCHAR *string,
|
|
INT length,
|
|
GDIPCONST GpFontFamily *family,
|
|
INT style,
|
|
REAL emSize,
|
|
GDIPCONST RectF *layoutRect,
|
|
GDIPCONST GpStringFormat *format
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathString);
|
|
|
|
CheckParameter(string && layoutRect);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
if (EmptyString(string, length))
|
|
{
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
CheckOptionalParameterValid(format);
|
|
|
|
return path->AddString(
|
|
string,
|
|
length,
|
|
family,
|
|
style,
|
|
emSize,
|
|
layoutRect,
|
|
format
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipAddPathStringI(
|
|
GpPath *path,
|
|
GDIPCONST WCHAR *string,
|
|
INT length,
|
|
GDIPCONST GpFontFamily *family,
|
|
INT style,
|
|
REAL emSize,
|
|
GDIPCONST Rect *layoutRect,
|
|
GDIPCONST GpStringFormat *format
|
|
)
|
|
{
|
|
API_ENTRY(GdipAddPathStringI);
|
|
CheckParameter(layoutRect);
|
|
|
|
// Not necessary to check all paramaters - they are validated
|
|
// in the called function.
|
|
|
|
GpRectF rectf(TOREAL(layoutRect->X), TOREAL(layoutRect->Y),
|
|
TOREAL(layoutRect->Width), TOREAL(layoutRect->Height));
|
|
|
|
return GdipAddPathString(path, string, length, family, style, emSize,
|
|
&rectf, format);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFlattenPath(
|
|
GpPath *path,
|
|
GpMatrix* matrix,
|
|
REAL flatness
|
|
)
|
|
{
|
|
API_ENTRY(GdipFlattenPath);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
|
|
return path->Flatten(matrix, flatness);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipWindingModeOutline(
|
|
GpPath *path,
|
|
GpMatrix *matrix,
|
|
REAL flatness
|
|
)
|
|
{
|
|
API_ENTRY(GdipWindingModeOutline);
|
|
|
|
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
return path->ComputeWindingModeOutline(matrix, flatness);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipWidenPath(
|
|
GpPath *path,
|
|
GpPen *pen,
|
|
GpMatrix *matrix,
|
|
REAL flatness
|
|
)
|
|
{
|
|
API_ENTRY(GdipWidenPath);
|
|
|
|
|
|
CheckParameterValid(path);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(path);
|
|
CheckObjectBusy(pen);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
return path->Widen(pen, matrix, flatness);
|
|
}
|
|
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipWarpPath(
|
|
GpPath *path,
|
|
GpMatrix* matrix,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL srcx,
|
|
REAL srcy,
|
|
REAL srcwidth,
|
|
REAL srcheight,
|
|
WarpMode warpMode,
|
|
REAL flatness
|
|
)
|
|
{
|
|
API_ENTRY(GdipWarpPath);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckParameter(points && count > 0);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
GpRectF srcRect(srcx, srcy, srcwidth, srcheight);
|
|
|
|
|
|
// The flatness parameter is not implemented yet.
|
|
|
|
return path->WarpAndFlattenSelf(matrix, points, count, srcRect, warpMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTransformPath(
|
|
GpPath *path,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipTransformPath);
|
|
if(matrix == NULL)
|
|
return Ok; // No need to transform.
|
|
|
|
CheckParameterValid(path);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(path);
|
|
CheckObjectBusy(matrix);
|
|
|
|
path->Transform(matrix);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathWorldBounds(
|
|
GpPath* path,
|
|
GpRectF* bounds,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GDIPCONST GpPen *pen
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathWorldBounds);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckParameter(bounds);
|
|
CheckOptionalParameterValid(pen);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(pen);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
|
|
// matrix and pen can be NULL.
|
|
// So don't use CheckParameter for matrix and pen.
|
|
|
|
GpStatus status = Ok;
|
|
|
|
if(pen == NULL)
|
|
status = path->GetBounds(bounds, const_cast<GpMatrix*>(matrix));
|
|
else
|
|
status = path->GetBounds(bounds,
|
|
const_cast<GpMatrix*>(matrix),
|
|
const_cast<GpPen*>(pen)->GetDevicePen());
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathWorldBoundsI(
|
|
GpPath* path,
|
|
GpRect* bounds,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GDIPCONST GpPen *pen)
|
|
{
|
|
API_ENTRY(GdipGetPathWorldBoundsI);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckParameter(bounds);
|
|
CheckOptionalParameterValid(pen);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(pen);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
// matrix and pen can be NULL.
|
|
// So don't use CheckParameter for matrix and pen.
|
|
|
|
GpStatus status = Ok;
|
|
|
|
if(pen == NULL)
|
|
status = path->GetBounds(bounds, const_cast<GpMatrix*>(matrix));
|
|
else
|
|
status = path->GetBounds(bounds,
|
|
const_cast<GpMatrix*>(matrix),
|
|
const_cast<GpPen*>(pen)->GetDevicePen());
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisiblePathPoint(
|
|
GpPath* path,
|
|
REAL x,
|
|
REAL y,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisiblePathPoint);
|
|
CheckParameter(result);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
GpPointF pt(x, y);
|
|
GpMatrix worldToDevice;
|
|
|
|
|
|
Status status = Ok;
|
|
|
|
if(graphics)
|
|
{
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
|
|
status = path->IsVisible(&pt, result, &worldToDevice);
|
|
}
|
|
else
|
|
status = path->IsVisible(&pt, result); // Use the default.
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisiblePathPointI(
|
|
GpPath* path,
|
|
INT x,
|
|
INT y,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisiblePathPointI);
|
|
return GdipIsVisiblePathPoint(path,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
graphics,
|
|
result);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsOutlineVisiblePathPoint(
|
|
GpPath* path,
|
|
REAL x,
|
|
REAL y,
|
|
GpPen *pen,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsOutlineVisiblePathPoint);
|
|
CheckParameter(result);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
GpPointF pt(x, y);
|
|
GpMatrix worldToDevice;
|
|
|
|
|
|
Status status = Ok;
|
|
|
|
if(graphics)
|
|
{
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
|
|
REAL dpiX = graphics->GetDpiX();
|
|
REAL dpiY = graphics->GetDpiY();
|
|
|
|
status = path->IsOutlineVisible(&pt, result, pen,
|
|
&worldToDevice, dpiX, dpiY);
|
|
}
|
|
else
|
|
status = path->IsOutlineVisible(&pt, result, pen); // Use the default.
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsOutlineVisiblePathPointI(
|
|
GpPath* path,
|
|
INT x,
|
|
INT y,
|
|
GpPen *pen,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsOutlineVisiblePathPointI);
|
|
return GdipIsOutlineVisiblePathPoint(path,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
pen,
|
|
graphics,
|
|
result);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipCreatePathIter(
|
|
GpPathIterator **iterator,
|
|
GpPath* path
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePathIter);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(iterator);
|
|
|
|
*iterator = new GpPathIterator(path);
|
|
|
|
if (CheckValid(*iterator))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeletePathIter(
|
|
GpPathIterator *iterator
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeletePathIter);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(iterator);
|
|
CheckObjectBusyForDelete(iterator);
|
|
|
|
delete iterator;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterNextSubpath(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
INT* startIndex,
|
|
INT* endIndex,
|
|
BOOL* isClosed)
|
|
{
|
|
API_ENTRY(GdipPathIterNextSubpath);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
CheckParameter(startIndex);
|
|
CheckParameter(endIndex);
|
|
CheckParameter(isClosed);
|
|
|
|
*resultCount = iterator->NextSubpath(startIndex, endIndex, isClosed);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterNextSubpathPath(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
GpPath* path,
|
|
BOOL* isClosed)
|
|
{
|
|
API_ENTRY(GdipPathIterNextSubpathPath);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
CheckParameter(isClosed);
|
|
|
|
*resultCount = iterator->NextSubpath(path, isClosed);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterNextPathType(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
BYTE* pathType,
|
|
INT* startIndex,
|
|
INT* endIndex
|
|
)
|
|
{
|
|
API_ENTRY(GdipPathIterNextPathType);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
CheckParameter(pathType);
|
|
CheckParameter(startIndex);
|
|
CheckParameter(endIndex);
|
|
|
|
*resultCount = iterator->NextPathType(pathType, startIndex, endIndex);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterNextMarker(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
INT* startIndex,
|
|
INT* endIndex)
|
|
{
|
|
API_ENTRY(GdipPathIterNextMarker);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
CheckParameter(startIndex);
|
|
CheckParameter(endIndex);
|
|
|
|
*resultCount = iterator->NextMarker(startIndex, endIndex);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterNextMarkerPath(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
GpPath* path)
|
|
{
|
|
API_ENTRY(GdipPathIterNextMarkerPath);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
|
|
*resultCount = iterator->NextMarker(path);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterGetCount(
|
|
GpPathIterator* iterator,
|
|
INT* count
|
|
)
|
|
{
|
|
API_ENTRY(GdipPathIterGetCount);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(count);
|
|
|
|
*count = iterator->GetCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterGetSubpathCount(
|
|
GpPathIterator* iterator,
|
|
INT* count
|
|
)
|
|
{
|
|
API_ENTRY(GdipPathIterGetSubpathCount);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(count);
|
|
|
|
*count = iterator->GetSubpathCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterIsValid(
|
|
GpPathIterator* iterator,
|
|
BOOL* valid
|
|
)
|
|
{
|
|
API_ENTRY(GdipPathIterIsValid);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(valid);
|
|
|
|
*valid = iterator->IsValid();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterHasCurve(
|
|
GpPathIterator* iterator,
|
|
BOOL* hasCurve
|
|
)
|
|
{
|
|
API_ENTRY(GdipPathIterHasCurve);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(hasCurve);
|
|
|
|
*hasCurve = iterator->HasCurve();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterRewind(
|
|
GpPathIterator* iterator
|
|
)
|
|
{
|
|
API_ENTRY(GdipPathIterRewind);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
|
|
iterator->Rewind();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterEnumerate(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
GpPointF *points,
|
|
BYTE *types,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipPathIterEnumerate);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
CheckParameter(points);
|
|
CheckParameter(types);
|
|
|
|
*resultCount = iterator->Enumerate(points, types, count);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipPathIterCopyData(
|
|
GpPathIterator* iterator,
|
|
INT* resultCount,
|
|
GpPointF* points,
|
|
BYTE* types,
|
|
INT startIndex,
|
|
INT endIndex)
|
|
{
|
|
API_ENTRY(GdipPathIterCopyData);
|
|
CheckParameterValid(iterator);
|
|
CheckObjectBusy(iterator);
|
|
CheckParameter(resultCount);
|
|
CheckParameter(points);
|
|
CheckParameter(types);
|
|
|
|
*resultCount = iterator->CopyData(points, types, startIndex, endIndex);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMatrix(GpMatrix **matrix)
|
|
{
|
|
API_ENTRY(GdipCreateMatrix);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(matrix);
|
|
|
|
*matrix = new GpMatrix();
|
|
|
|
if (CheckValid(*matrix))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMatrix2(
|
|
REAL m11,
|
|
REAL m12,
|
|
REAL m21,
|
|
REAL m22,
|
|
REAL dx,
|
|
REAL dy,
|
|
GpMatrix ** outMatrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMatrix2);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(outMatrix);
|
|
|
|
GpMatrix * matrix;
|
|
|
|
matrix = (GpMatrix *) InterlockedExchangePointer((PVOID *) &Globals::MatrixLookAside, NULL);
|
|
|
|
if(matrix == NULL)
|
|
{
|
|
matrix = new GpMatrix(m11, m12, m21, m22, dx, dy);
|
|
}
|
|
else
|
|
{
|
|
matrix->GetObjectLock()->Reset();
|
|
matrix->SetMatrix(m11, m12, m21, m22, dx, dy);
|
|
}
|
|
|
|
if (CheckValid(matrix))
|
|
{
|
|
*outMatrix = matrix;
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMatrix3(
|
|
GDIPCONST GpRectF *rect,
|
|
GDIPCONST GpPointF *dstplg,
|
|
GpMatrix **matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMatrix3);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(matrix && rect && dstplg);
|
|
|
|
*matrix = new GpMatrix(dstplg, *rect);
|
|
|
|
if (CheckValid(*matrix))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMatrix3I(
|
|
GDIPCONST GpRect *rect,
|
|
GDIPCONST GpPoint *dstplg,
|
|
GpMatrix **matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMatrix3I);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
GpRectF rectf(TOREAL(rect->X), TOREAL(rect->Y), TOREAL(rect->Width), TOREAL(rect->Height));
|
|
GpPointF dstplgf[3] = { GpPointF(TOREAL(dstplg[0].X), TOREAL(dstplg[0].Y)),
|
|
GpPointF(TOREAL(dstplg[1].X), TOREAL(dstplg[1].Y)),
|
|
GpPointF(TOREAL(dstplg[2].X), TOREAL(dstplg[2].Y)) };
|
|
|
|
return GdipCreateMatrix3(&rectf, dstplgf, matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneMatrix(
|
|
GpMatrix *matrix,
|
|
GpMatrix **clonematrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneMatrix);
|
|
CheckParameter(clonematrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
*clonematrix = matrix->Clone();
|
|
|
|
if (CheckValid(*clonematrix))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteMatrix(
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeleteMatrix);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(matrix);
|
|
CheckObjectBusyForDelete(matrix);
|
|
|
|
if(matrix != NULL)
|
|
{
|
|
|
|
matrix = (GpMatrix *) InterlockedExchangePointer((PVOID *) &Globals::MatrixLookAside, (PVOID) matrix);
|
|
|
|
if(matrix != NULL)
|
|
{
|
|
delete matrix;
|
|
}
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetMatrixElements(
|
|
GpMatrix *matrix,
|
|
REAL m11,
|
|
REAL m12,
|
|
REAL m21,
|
|
REAL m22,
|
|
REAL dx,
|
|
REAL dy
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetMatrixElements);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
REAL m[6] = { m11, m12, m21, m22, dx, dy };
|
|
|
|
matrix->SetMatrix((REAL*) &m);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMultiplyMatrix(
|
|
GpMatrix *matrix,
|
|
GpMatrix *matrix2,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipMultiplyMatrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameterValid(matrix2);
|
|
CheckObjectBusy(matrix2);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
if (order == MatrixOrderPrepend)
|
|
matrix->Prepend(*matrix2);
|
|
else
|
|
matrix->Append(*matrix2);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateMatrix(
|
|
GpMatrix *matrix,
|
|
REAL offsetX,
|
|
REAL offsetY,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateMatrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
matrix->Translate(offsetX, offsetY, order);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipScaleMatrix(
|
|
GpMatrix *matrix,
|
|
REAL scaleX,
|
|
REAL scaleY,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipScaleMatrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
matrix->Scale(scaleX, scaleY, order);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRotateMatrix(
|
|
GpMatrix *matrix,
|
|
REAL angle,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipRotateMatrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
matrix->Rotate(angle, order);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipShearMatrix(
|
|
GpMatrix *matrix,
|
|
REAL shearX,
|
|
REAL shearY,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipShearMatrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
matrix->Shear(shearX, shearY, order);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipInvertMatrix(GpMatrix *matrix)
|
|
{
|
|
API_ENTRY(GdipInvertMatrix);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return matrix->Invert();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTransformMatrixPoints(
|
|
GpMatrix *matrix,
|
|
GpPointF *pts,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipTransformMatrixPoints);
|
|
CheckParameter(pts && count > 0);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
matrix->Transform(pts, count);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTransformMatrixPointsI(
|
|
GpMatrix *matrix,
|
|
GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipTransformMatrixPointsI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipTransformMatrixPoints(matrix, pointsF, count);
|
|
|
|
// convert back, rounding is a problem...
|
|
|
|
if (status == Ok)
|
|
{
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
points[i].X = GpRound(pointsF[i].X);
|
|
points[i].Y = GpRound(pointsF[i].Y);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipVectorTransformMatrixPoints(
|
|
GpMatrix *matrix,
|
|
GpPointF *pointsF,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipVectorTransformMatrixPoints);
|
|
CheckParameter(pointsF && count > 0);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
matrix->VectorTransform(pointsF, count);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipVectorTransformMatrixPointsI(
|
|
GpMatrix *matrix,
|
|
GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipVectorTransformMatrixPointsI);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
matrix->VectorTransform(pointsF, count);
|
|
|
|
// convert back, rounding is a problem...
|
|
|
|
|
|
for (i=0; i<count; i++)
|
|
{
|
|
points[i].X = GpRound(pointsF[i].X);
|
|
points[i].Y = GpRound(pointsF[i].Y);
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetMatrixElements(
|
|
GDIPCONST GpMatrix *matrix,
|
|
REAL *m
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMatrixElements);
|
|
CheckParameter(m);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
matrix->GetMatrix(m);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsMatrixInvertible(
|
|
GDIPCONST GpMatrix *matrix,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsMatrixInvertible);
|
|
CheckParameter(result);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
*result = matrix->IsInvertible();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsMatrixIdentity(
|
|
GDIPCONST GpMatrix *matrix,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsMatrixIdentity);
|
|
CheckParameter(result);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
*result = matrix->IsIdentity();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsMatrixEqual(
|
|
GDIPCONST GpMatrix *matrix,
|
|
GDIPCONST GpMatrix *matrix2,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsMatrixEqual);
|
|
CheckParameter(result);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
if (matrix != matrix2)
|
|
{
|
|
CheckParameterValid(matrix2);
|
|
CheckObjectBusy(matrix2);
|
|
|
|
*result = matrix->IsEqual(matrix2);
|
|
}
|
|
else
|
|
{
|
|
*result = TRUE;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateRegion(
|
|
GpRegion **region
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateRegion);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(region);
|
|
|
|
*region = new GpRegion();
|
|
|
|
if (CheckValid(*region))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateRegionRect(
|
|
GDIPCONST GpRectF *rect,
|
|
GpRegion **region
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateRegionRect);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(region && rect);
|
|
|
|
*region = new GpRegion(rect);
|
|
|
|
if (CheckValid(*region))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateRegionRectI(
|
|
GDIPCONST GpRect *rect,
|
|
GpRegion **region
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateRegionRectI);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
GpRectF rectf(TOREAL(rect->X),
|
|
TOREAL(rect->Y),
|
|
TOREAL(rect->Width),
|
|
TOREAL(rect->Height));
|
|
|
|
return GdipCreateRegionRect(&rectf, region);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateRegionPath(
|
|
GpPath *path,
|
|
GpRegion **region
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateRegionPath);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(region);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
*region = new GpRegion(path);
|
|
|
|
if (CheckValid(*region))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateRegionRgnData(
|
|
GDIPCONST BYTE *regionData,
|
|
INT size,
|
|
GpRegion **region
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateRegionRgnData);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(regionData);
|
|
CheckParameter(region);
|
|
|
|
*region = new GpRegion(regionData, size);
|
|
|
|
if (CheckValid(*region))
|
|
return Ok;
|
|
else
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateRegionHrgn(
|
|
HRGN hRgn,
|
|
GpRegion **region
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateRegionHrgn);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(region && hRgn && (GetObjectTypeInternal(hRgn) == OBJ_REGION));
|
|
|
|
*region = new GpRegion(hRgn);
|
|
|
|
if (CheckValid(*region))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneRegion(
|
|
GpRegion *region,
|
|
GpRegion **cloneregion
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneRegion);
|
|
CheckParameter(cloneregion);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
*cloneregion = new GpRegion(region);
|
|
|
|
if (CheckValid(*cloneregion))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteRegion(
|
|
GpRegion *region
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeleteRegion);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(region);
|
|
CheckObjectBusyForDelete(region);
|
|
|
|
delete region;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetInfinite(
|
|
GpRegion *region
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetInfinite);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
region->SetInfinite();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetEmpty(
|
|
GpRegion *region
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetEmpty);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
region->SetEmpty();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCombineRegionRect(
|
|
GpRegion * region,
|
|
GDIPCONST GpRectF * rect,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipCombineRegionRect);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
return region->Combine(rect, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCombineRegionRectI(
|
|
GpRegion * region,
|
|
GDIPCONST GpRect * rect,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipCombineRegionRectI);
|
|
GpRectF rectf(TOREAL(rect->X),
|
|
TOREAL(rect->Y),
|
|
TOREAL(rect->Width),
|
|
TOREAL(rect->Height));
|
|
|
|
return GdipCombineRegionRect(region, &rectf, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCombineRegionPath(
|
|
GpRegion * region,
|
|
GpPath * path,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipCombineRegionPath);
|
|
CheckParameterValid(region);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(region);
|
|
CheckObjectBusy(path);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
return region->Combine(path, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCombineRegionRegion(
|
|
GpRegion * region,
|
|
GpRegion * region2,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipCombineRegionRegion);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(region2);
|
|
CheckObjectBusy(region2);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
return region->Combine(region2, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateRegion(
|
|
GpRegion *region,
|
|
REAL dx,
|
|
REAL dy
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateRegion);
|
|
CheckParameter(region);
|
|
CheckParameterValid(region);
|
|
|
|
region->Offset(dx, dy);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateRegionI(
|
|
GpRegion *region,
|
|
INT dx,
|
|
INT dy
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateRegionI);
|
|
return GdipTranslateRegion(region, TOREAL(dx), TOREAL(dy));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTransformRegion(
|
|
GpRegion *region,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipTransformRegion);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
return region->Transform(matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionBounds(
|
|
GpRegion *region,
|
|
GpGraphics *graphics,
|
|
GpRectF *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionBounds);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
return region->GetBounds(graphics, rect);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionBoundsI(
|
|
GpRegion *region,
|
|
GpGraphics *graphics,
|
|
GpRect *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionBoundsI);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
GpRectF rectF;
|
|
GpStatus status = region->GetBounds(graphics, &rectF);
|
|
|
|
if (status == Ok)
|
|
{
|
|
rect->X = GpRound(rectF.X);
|
|
rect->Y = GpRound(rectF.Y);
|
|
rect->Width = GpRound(rectF.Width);
|
|
rect->Height = GpRound(rectF.Height);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionHRgn(
|
|
GpRegion *region,
|
|
GpGraphics *graphics, // can be NULL
|
|
HRGN *hRgn
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionHRgn);
|
|
CheckParameter(hRgn);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
|
|
if (graphics != NULL)
|
|
{
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
return region->GetHRgn(graphics, hRgn);
|
|
}
|
|
return region->GetHRgn((GpGraphics*)NULL, hRgn);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsEmptyRegion(
|
|
GpRegion *region,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsEmptyRegion);
|
|
CheckParameter(result);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
GpMatrix worldToDevice;
|
|
|
|
Status status;
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
|
|
status = region->IsEmpty(&worldToDevice, result);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsInfiniteRegion(
|
|
GpRegion *region,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsInfiniteRegion);
|
|
CheckParameter(result);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
GpMatrix worldToDevice;
|
|
|
|
Status status;
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
|
|
status = region->IsInfinite(&worldToDevice, result);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsEqualRegion(
|
|
GpRegion *region,
|
|
GpRegion *region2,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsEqualRegion);
|
|
CheckParameter(result);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
Status status;
|
|
|
|
if (region != region2)
|
|
{
|
|
CheckParameterValid(region2);
|
|
CheckObjectBusy(region2);
|
|
|
|
|
|
GpMatrix worldToDevice;
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
|
|
status = region->IsEqual(region2, &worldToDevice, result);
|
|
}
|
|
else
|
|
{
|
|
*result = TRUE;
|
|
status = Ok;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionDataSize(
|
|
GpRegion * region,
|
|
UINT * bufferSize
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionDataSize);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(bufferSize);
|
|
|
|
|
|
if ((*bufferSize = region->GetExternalDataSize()) > 0)
|
|
{
|
|
return Ok;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionData(
|
|
GpRegion * region,
|
|
BYTE * buffer,
|
|
UINT bufferSize,
|
|
UINT * sizeFilled
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionData);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(buffer);
|
|
CheckParameter(bufferSize > 0);
|
|
|
|
|
|
UINT filled = bufferSize;
|
|
|
|
GpStatus status = region->GetExternalData(buffer, filled);
|
|
|
|
ASSERT((INT)filled <= bufferSize);
|
|
if (sizeFilled != NULL)
|
|
{
|
|
*sizeFilled = filled;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleRegionPoint(
|
|
GpRegion *region,
|
|
REAL x,
|
|
REAL y,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleRegionPoint);
|
|
CheckParameter(result);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
|
|
Status status;
|
|
|
|
GpPointF pt(x, y);
|
|
GpMatrix worldToDevice;
|
|
|
|
if (graphics != NULL)
|
|
{
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
}
|
|
|
|
status = region->IsVisible(&pt, &worldToDevice, result);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleRegionPointI(
|
|
GpRegion *region,
|
|
INT x,
|
|
INT y,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleRegionPointI);
|
|
return GdipIsVisibleRegionPoint(region, TOREAL(x), TOREAL(y), graphics, result);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleRegionRect(
|
|
GpRegion *region,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleRegionRect);
|
|
CheckParameter(result);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
|
|
Status status;
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
GpMatrix worldToDevice;
|
|
|
|
if (graphics != NULL)
|
|
{
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetWorldToDeviceTransform(&worldToDevice);
|
|
}
|
|
|
|
status = region->IsVisible(&rect, &worldToDevice, result);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleRegionRectI(
|
|
GpRegion *region,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleRegionRectI);
|
|
return GdipIsVisibleRegionRect(region,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
TOREAL(width),
|
|
TOREAL(height),
|
|
graphics,
|
|
result);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionScansCount(
|
|
GpRegion *region,
|
|
UINT *count,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionScansCount);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(count);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
|
|
// !! Rewrite this API to be more efficient
|
|
return region->GetRegionScans((GpRect*)NULL,
|
|
(INT*)count,
|
|
matrix);
|
|
}
|
|
|
|
// If rects is NULL, return the count of rects in the region.
|
|
// Otherwise, assume rects is big enough to hold all the region rects
|
|
// and fill them in and return the number of rects filled in.
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionScans(
|
|
GpRegion *region,
|
|
GpRectF *rects, // NULL to just get the count
|
|
INT *count,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionScans);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(count);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
|
|
// !! Rewrite this API to verify IN count is sufficient
|
|
return region->GetRegionScans(rects, count, matrix);
|
|
}
|
|
|
|
// If rects is NULL, return the count of rects in the region.
|
|
// Otherwise, assume rects is big enough to hold all the region rects
|
|
// and fill them in and return the number of rects filled in.
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRegionScansI(
|
|
GpRegion *region,
|
|
GpRect *rects, // NULL to just get the count
|
|
INT *count,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRegionScansI);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(count);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
|
|
return region->GetRegionScans(rects, count, matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneBrush(
|
|
GpBrush *brush,
|
|
GpBrush **clonebrush
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneBrush);
|
|
CheckParameter(clonebrush);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*clonebrush = brush->Clone();
|
|
|
|
if (CheckValid(*clonebrush))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteBrush(
|
|
GpBrush *brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeleteBrush);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(brush);
|
|
CheckObjectBusyForDelete(brush);
|
|
|
|
delete brush;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetBrushType(
|
|
GpBrush *brush,
|
|
GpBrushType *type
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetBrushType);
|
|
CheckParameter(type);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*type = brush->GetBrushType();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateHatchBrush(
|
|
GpHatchStyle hatchstyle,
|
|
ARGB forecol,
|
|
ARGB backcol,
|
|
GpHatch **hatch
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateHatchBrush);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter((hatchstyle >= HatchStyleMin) && (hatchstyle <= HatchStyleMax));
|
|
CheckParameter(hatch);
|
|
CheckColorParameter(forecol);
|
|
CheckColorParameter(backcol);
|
|
|
|
GpColor fore(forecol);
|
|
GpColor back(backcol);
|
|
|
|
*hatch = new GpHatch(hatchstyle, fore, back);
|
|
|
|
if (CheckValid(*hatch))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetHatchStyle(
|
|
GpHatch *brush,
|
|
GpHatchStyle *hatchStyle
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetHatchStyle);
|
|
CheckParameter(hatchStyle);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*hatchStyle = brush->GetHatchStyle();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetHatchForegroundColor(
|
|
GpHatch *brush,
|
|
ARGB *argb
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetHatchForegroundColor);
|
|
CheckParameter(argb);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
GpColor foreColor;
|
|
|
|
GpStatus status = brush->GetForegroundColor((GpColor*)&foreColor);
|
|
|
|
*argb = foreColor.GetValue();
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetHatchBackgroundColor(
|
|
GpHatch *brush,
|
|
ARGB *argb
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetHatchBackgroundColor);
|
|
CheckParameter(argb);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
GpColor backColor;
|
|
|
|
GpStatus status = brush->GetBackgroundColor((GpColor*)&backColor);
|
|
|
|
*argb = backColor.GetValue();
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateTexture(
|
|
GpImage *image,
|
|
GpWrapMode wrapmode,
|
|
GpTexture **texture
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateTexture);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(texture);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
|
|
*texture = new GpTexture(image, wrapmode);
|
|
|
|
if (CheckValid(*texture))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateTexture2(
|
|
GpImage *image,
|
|
GpWrapMode wrapmode,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
GpTexture **texture
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateTexture2);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(texture);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
|
|
|
|
*texture = new GpTexture(image, wrapmode, rect);
|
|
|
|
if (CheckValid(*texture))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateTextureIA(
|
|
GpImage *image,
|
|
GDIPCONST GpImageAttributes *imageAttributes,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
GpTexture **texture
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateTextureIA);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(texture);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
|
|
|
|
*texture = new GpTexture(image, rect, imageAttributes);
|
|
|
|
if (CheckValid(*texture))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateTexture2I(
|
|
GpImage *image,
|
|
GpWrapMode wrapmode,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
GpTexture **texture
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateTexture2I);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
return GdipCreateTexture2(image,
|
|
wrapmode,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
TOREAL(width),
|
|
TOREAL(height),
|
|
texture);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateTextureIAI(
|
|
GpImage *image,
|
|
GDIPCONST GpImageAttributes *imageAttributes,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
GpTexture **texture
|
|
)
|
|
{
|
|
|
|
return GdipCreateTextureIA(image,
|
|
imageAttributes,
|
|
TOREAL(x),
|
|
TOREAL(y),
|
|
TOREAL(width),
|
|
TOREAL(height),
|
|
texture);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetTextureTransform(
|
|
GpTexture *brush,
|
|
GDIPCONST GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetTextureTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->SetTransform(*matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetTextureTransform(
|
|
GpTexture *brush,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetTextureTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->GetTransform(matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetTextureTransform(
|
|
GpTexture* brush)
|
|
{
|
|
API_ENTRY(GdipResetTextureTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->ResetTransform();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMultiplyTextureTransform(
|
|
GpTexture* brush,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GpMatrixOrder order)
|
|
{
|
|
API_ENTRY(GdipMultiplyTextureTransform);
|
|
if(matrix == NULL)
|
|
return Ok;
|
|
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->MultiplyTransform(*matrix, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateTextureTransform(
|
|
GpTexture* brush,
|
|
REAL dx,
|
|
REAL dy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateTextureTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->TranslateTransform(dx, dy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipScaleTextureTransform(
|
|
GpTexture* brush,
|
|
REAL sx,
|
|
REAL sy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipScaleTextureTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->ScaleTransform(sx, sy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRotateTextureTransform(
|
|
GpTexture* brush,
|
|
REAL angle,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipRotateTextureTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->RotateTransform(angle, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetTextureWrapMode(
|
|
GpTexture *brush,
|
|
GpWrapMode wrapmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetTextureWrapMode);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->SetWrapMode(wrapmode);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetTextureWrapMode(
|
|
GpTexture *brush,
|
|
GpWrapMode *wrapmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetTextureWrapMode);
|
|
CheckParameter(wrapmode);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*wrapmode = (GpWrapMode)brush->GetWrapMode();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetTextureImage(
|
|
GpTexture *brush,
|
|
GpImage **image
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetTextureImage);
|
|
// GetImage returns a pointer to the internal GpImage structure. Because
|
|
// we have to create a new Image wrapper around it and give it to the caller
|
|
// at the API level, we return a clone so they can throw it away without
|
|
// destroying our internal brush structure.
|
|
GpImage *imgtmp;
|
|
imgtmp = brush->GetImage();
|
|
*image = imgtmp->Clone();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateSolidFill(
|
|
ARGB color,
|
|
GpSolidFill **solidfill
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateSolidFill);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(solidfill);
|
|
CheckColorParameter(color);
|
|
|
|
*solidfill = new GpSolidFill(GpColor(color));
|
|
|
|
if (CheckValid(*solidfill))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetSolidFillColor(
|
|
GpSolidFill *brush,
|
|
ARGB color
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetSolidFillColor);
|
|
CheckColorParameter(color);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->SetColor(GpColor(color));
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetSolidFillColor(
|
|
GpSolidFill *brush,
|
|
ARGB *color
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetSolidFillColor);
|
|
CheckParameter(color);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*color = (brush->GetColor()).GetValue();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateLineBrush(
|
|
GDIPCONST GpPointF* point1,
|
|
GDIPCONST GpPointF* point2,
|
|
ARGB color1,
|
|
ARGB color2,
|
|
GpWrapMode wrapmode,
|
|
GpLineGradient **linegrad
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateLineBrush);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(linegrad && point1 && point2);
|
|
CheckColorParameter(color1);
|
|
CheckColorParameter(color2);
|
|
|
|
if(wrapmode == WrapModeClamp)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpColor c1(color1);
|
|
GpColor c2(color2);
|
|
|
|
*linegrad = new GpLineGradient(*point1, *point2, c1, c2, wrapmode);
|
|
|
|
if (CheckValid(*linegrad))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateLineBrushI(
|
|
GDIPCONST GpPoint* point1,
|
|
GDIPCONST GpPoint* point2,
|
|
ARGB color1,
|
|
ARGB color2,
|
|
GpWrapMode wrapmode,
|
|
GpLineGradient **linegrad
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateLineBrushI);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(color1);
|
|
CheckColorParameter(color2);
|
|
CheckParameter(point1 && point2);
|
|
|
|
if(wrapmode == WrapModeClamp)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpPointF point1F(TOREAL(point1->X), TOREAL(point1->Y));
|
|
GpPointF point2F(TOREAL(point2->X), TOREAL(point2->Y));
|
|
|
|
return GdipCreateLineBrush(&point1F,
|
|
&point2F,
|
|
color1,
|
|
color2,
|
|
wrapmode,
|
|
linegrad);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateLineBrushFromRect(
|
|
GDIPCONST GpRectF* rect,
|
|
ARGB color1,
|
|
ARGB color2,
|
|
LinearGradientMode mode,
|
|
GpWrapMode wrapmode,
|
|
GpLineGradient **linegrad)
|
|
{
|
|
API_ENTRY(GdipCreateLineBrushFromRect);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(color1);
|
|
CheckColorParameter(color2);
|
|
CheckParameter(linegrad && rect);
|
|
|
|
if(wrapmode == WrapModeClamp)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpColor c1(color1);
|
|
GpColor c2(color2);
|
|
|
|
*linegrad = new GpLineGradient(*rect, c1, c2, mode, wrapmode);
|
|
|
|
if (CheckValid(*linegrad))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateLineBrushFromRectI(
|
|
GDIPCONST GpRect* rect,
|
|
ARGB color1,
|
|
ARGB color2,
|
|
LinearGradientMode mode,
|
|
GpWrapMode wrapmode,
|
|
GpLineGradient **linegrad)
|
|
{
|
|
API_ENTRY(GdipCreateLineBrushFromRectI);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(color1);
|
|
CheckColorParameter(color2);
|
|
CheckParameter(rect);
|
|
|
|
if(wrapmode == WrapModeClamp)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpRectF rectF(TOREAL(rect->X),
|
|
TOREAL(rect->Y),
|
|
TOREAL(rect->Width),
|
|
TOREAL(rect->Height));
|
|
|
|
return GdipCreateLineBrushFromRect(&rectF,
|
|
color1,
|
|
color2,
|
|
mode,
|
|
wrapmode,
|
|
linegrad);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateLineBrushFromRectWithAngle(
|
|
GDIPCONST GpRectF* rect,
|
|
ARGB color1,
|
|
ARGB color2,
|
|
REAL angle,
|
|
BOOL isAngleScalable,
|
|
GpWrapMode wrapmode,
|
|
GpLineGradient **linegrad)
|
|
{
|
|
API_ENTRY(GdipCreateLineBrushFromRectWithAngle);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(color1);
|
|
CheckColorParameter(color2);
|
|
CheckParameter(linegrad && rect);
|
|
|
|
if(wrapmode == WrapModeClamp)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpColor c1(color1);
|
|
GpColor c2(color2);
|
|
|
|
*linegrad = new GpLineGradient(*rect, c1, c2, angle,
|
|
isAngleScalable, wrapmode);
|
|
|
|
if (CheckValid(*linegrad))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateLineBrushFromRectWithAngleI(
|
|
GDIPCONST GpRect* rect,
|
|
ARGB color1,
|
|
ARGB color2,
|
|
REAL angle,
|
|
BOOL isAngleScalable,
|
|
GpWrapMode wrapmode,
|
|
GpLineGradient **linegrad)
|
|
{
|
|
API_ENTRY(GdipCreateLineBrushFromRectWithAngleI);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(color1);
|
|
CheckColorParameter(color2);
|
|
CheckParameter(rect);
|
|
|
|
if(wrapmode == WrapModeClamp)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpRectF rectF(TOREAL(rect->X),
|
|
TOREAL(rect->Y),
|
|
TOREAL(rect->Width),
|
|
TOREAL(rect->Height));
|
|
|
|
return GdipCreateLineBrushFromRectWithAngle(&rectF,
|
|
color1,
|
|
color2,
|
|
angle,
|
|
isAngleScalable,
|
|
wrapmode,
|
|
linegrad);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineColors(
|
|
GpLineGradient *brush,
|
|
ARGB argb1,
|
|
ARGB argb2
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLineColors);
|
|
CheckColorParameter(argb1);
|
|
CheckColorParameter(argb2);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
GpColor c1(argb1);
|
|
GpColor c2(argb2);
|
|
|
|
brush->SetLineColors(c1, c2);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineColors(
|
|
GpLineGradient *brush,
|
|
ARGB *argb
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineColors);
|
|
CheckParameter(argb);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
GpColor colors[2];
|
|
brush->GetLineColors(&colors[0]);
|
|
|
|
argb[0] = colors[0].GetValue();
|
|
argb[1] = colors[1].GetValue();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineRect(
|
|
GpLineGradient *brush,
|
|
GpRectF *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineRect);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->GetRect(*rect);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineRectI(
|
|
GpLineGradient *brush,
|
|
GpRect *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineRectI);
|
|
CheckParameter(rect);
|
|
|
|
GpRectF rectF;
|
|
|
|
GpStatus status = GdipGetLineRect(brush, &rectF);
|
|
|
|
if (status == Ok)
|
|
{
|
|
|
|
rect->X = GpRound(rectF.X);
|
|
rect->Y = GpRound(rectF.Y);
|
|
rect->Width = GpRound(rectF.Width);
|
|
rect->Height = GpRound(rectF.Height);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineGammaCorrection(
|
|
GpLineGradient *brush,
|
|
BOOL useGammaCorrection
|
|
)
|
|
{
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->SetGammaCorrection(useGammaCorrection);
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineGammaCorrection(
|
|
GpLineGradient *brush,
|
|
BOOL *useGammaCorrection)
|
|
{
|
|
CheckParameter(useGammaCorrection);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*useGammaCorrection = brush->GetGammaCorrection();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineBlendCount(
|
|
GpLineGradient *brush,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineBlendCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*count = brush->GetBlendCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineBlend(
|
|
GpLineGradient *brush,
|
|
REAL *blend,
|
|
REAL *positions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineBlend);
|
|
CheckParameter(blend);
|
|
CheckParameter(positions);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->GetBlend(blend, positions, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineBlend(
|
|
GpLineGradient *brush,
|
|
GDIPCONST REAL *blend,
|
|
GDIPCONST REAL *positions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLineBlend);
|
|
CheckParameter(blend);
|
|
CheckParameter(positions);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetBlend(blend, positions, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLinePresetBlendCount(
|
|
GpLineGradient *brush,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLinePresetBlendCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*count = brush->GetPresetBlendCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLinePresetBlend(
|
|
GpLineGradient *brush,
|
|
ARGB *blend,
|
|
REAL *blendPositions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLinePresetBlend);
|
|
CheckParameter(blend);
|
|
CheckParameter(blendPositions);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
if (count <= 0)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
if (count < brush->GetPresetBlendCount())
|
|
{
|
|
return InsufficientBuffer;
|
|
}
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpColor* gpcolors = (GpColor*) buffer.GetBuffer(count*sizeof(GpColor));
|
|
|
|
if(!gpcolors) return OutOfMemory;
|
|
|
|
if (gpcolors)
|
|
{
|
|
GpStatus status = brush->GetPresetBlend(gpcolors, blendPositions, count);
|
|
|
|
for(INT i = 0; i < count; i++)
|
|
{
|
|
blend[i] = gpcolors[i].GetValue();
|
|
}
|
|
|
|
return status;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLinePresetBlend(
|
|
GpLineGradient *brush,
|
|
GDIPCONST ARGB *blend,
|
|
GDIPCONST REAL *blendPositions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLinePresetBlend);
|
|
CheckParameter(blend);
|
|
CheckParameter(blendPositions);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
CheckParameter(count > 0)
|
|
|
|
// blend positions must start at 0.0 and end at 1.0
|
|
if (REALABS(blendPositions[0]) > REAL_EPSILON ||
|
|
REALABS(1.0f - blendPositions[count-1]) > REAL_EPSILON)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpColor* gpcolors = (GpColor*) buffer.GetBuffer(count*sizeof(GpColor));
|
|
|
|
if(!gpcolors) return OutOfMemory;
|
|
|
|
if(gpcolors)
|
|
{
|
|
for(INT i = 0; i < count; i++)
|
|
{
|
|
gpcolors[i].SetColor(blend[i]);
|
|
}
|
|
|
|
GpStatus status = brush->SetPresetBlend(gpcolors, blendPositions, count);
|
|
|
|
return status;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineSigmaBlend(
|
|
GpLineGradient *brush,
|
|
REAL focus,
|
|
REAL scale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLineSigmaBlend);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetSigmaBlend(focus, scale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineLinearBlend(
|
|
GpLineGradient *brush,
|
|
REAL focus,
|
|
REAL scale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLineLinearBlend);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetLinearBlend(focus, scale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineWrapMode(
|
|
GpLineGradient *brush,
|
|
GpWrapMode wrapmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLineWrapMode);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
GpStatus status = Ok;
|
|
|
|
if(wrapmode != WrapModeClamp)
|
|
brush->SetWrapMode(wrapmode);
|
|
else
|
|
status = InvalidParameter;
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineWrapMode(
|
|
GpLineGradient *brush,
|
|
GpWrapMode *wrapmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineWrapMode);
|
|
CheckParameter(wrapmode);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*wrapmode = (GpWrapMode)brush->GetWrapMode();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetLineTransform(
|
|
GpLineGradient *brush,
|
|
GDIPCONST GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetLineTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->SetTransform(*matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineTransform(
|
|
GpLineGradient *brush,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetLineTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->GetTransform(matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetLineTransform(
|
|
GpLineGradient* brush)
|
|
{
|
|
API_ENTRY(GdipResetLineTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->ResetTransform();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMultiplyLineTransform(
|
|
GpLineGradient* brush,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GpMatrixOrder order)
|
|
{
|
|
API_ENTRY(GdipMultiplyLineTransform);
|
|
if(matrix == NULL)
|
|
return Ok;
|
|
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->MultiplyTransform(*matrix, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateLineTransform(
|
|
GpLineGradient* brush,
|
|
REAL dx,
|
|
REAL dy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateLineTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->TranslateTransform(dx, dy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipScaleLineTransform(
|
|
GpLineGradient* brush,
|
|
REAL sx,
|
|
REAL sy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipScaleLineTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->ScaleTransform(sx, sy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRotateLineTransform(
|
|
GpLineGradient* brush,
|
|
REAL angle,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipRotateLineTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->RotateTransform(angle, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePathGradient(
|
|
GDIPCONST GpPointF* points,
|
|
INT count,
|
|
GpWrapMode wrapMode,
|
|
GpPathGradient **brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePathGradient);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(brush);
|
|
|
|
*brush = new GpPathGradient(points, count, wrapMode);
|
|
|
|
if (CheckValid(*brush))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePathGradientI(
|
|
GDIPCONST GpPoint* points,
|
|
INT count,
|
|
GpWrapMode wrapMode,
|
|
GpPathGradient **brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePathGradientI);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(points);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipCreatePathGradient(pointsF, count, wrapMode, brush);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePathGradientFromPath(
|
|
GDIPCONST GpPath* path,
|
|
GpPathGradient **brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePathGradientFromPath);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(brush);
|
|
|
|
*brush = new GpPathGradient(path);
|
|
|
|
if (CheckValid(*brush))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientCenterColor(
|
|
GpPathGradient *brush,
|
|
ARGB* color
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientCenterColor);
|
|
CheckParameter(color);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
GpColor center;
|
|
brush->GetCenterColor(¢er);
|
|
*color = center.GetValue();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientCenterColor(
|
|
GpPathGradient *brush,
|
|
ARGB color
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientCenterColor);
|
|
CheckColorParameter(color);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
GpColor center(color);
|
|
brush->SetCenterColor(center);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientSurroundColorsWithCount(
|
|
GpPathGradient *brush,
|
|
ARGB* colors,
|
|
INT* count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientSurroundColorsWithCount);
|
|
CheckParameter(colors);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
INT count1 = brush->GetNumberOfPoints();
|
|
|
|
if(*count < count1 || count1 <= 0)
|
|
return InvalidParameter;
|
|
|
|
count1 = min(*count, count1);
|
|
|
|
ARGB lastValue, nextValue;
|
|
|
|
INT n = 1;
|
|
|
|
for(INT i = 0; i < count1; i++)
|
|
{
|
|
GpColor color;
|
|
|
|
brush->GetSurroundColor(&color, i);
|
|
nextValue = color.GetValue();
|
|
colors[i] = nextValue;
|
|
|
|
if(i > 0)
|
|
{
|
|
if(nextValue != lastValue)
|
|
n = i + 1;
|
|
}
|
|
lastValue = nextValue;
|
|
}
|
|
|
|
*count = n;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientSurroundColorsWithCount(
|
|
GpPathGradient *brush,
|
|
GDIPCONST ARGB* colors,
|
|
INT* count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientSurroundColorsWithCount);
|
|
CheckParameter(colors);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
INT count1 = brush->GetNumberOfPoints();
|
|
|
|
INT minCount = min(*count, count1);
|
|
|
|
if(*count > count1 || minCount < 1)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GpColor *gpColors = new GpColor[count1];
|
|
|
|
if(NULL == gpColors)
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
|
|
INT i;
|
|
for(i = 0; i < minCount; i++)
|
|
{
|
|
gpColors[i].SetColor(colors[i]);
|
|
}
|
|
|
|
if(minCount < count1)
|
|
{
|
|
for(i = minCount; i < count1; i++)
|
|
{
|
|
gpColors[i].SetColor(colors[minCount - 1]);
|
|
}
|
|
}
|
|
|
|
*count = minCount;
|
|
GpStatus status = brush->SetSurroundColors(gpColors);
|
|
|
|
delete[] gpColors;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientPath(
|
|
GpPathGradient *brush,
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientPath);
|
|
return NotImplemented;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientPath(
|
|
GpPathGradient *brush,
|
|
GDIPCONST GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientPath);
|
|
return NotImplemented;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientCenterPoint(
|
|
GpPathGradient *brush,
|
|
GpPointF* point
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientCenterPoint);
|
|
CheckParameter(point);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->GetCenterPoint(point);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientCenterPointI(
|
|
GpPathGradient *brush,
|
|
GpPoint* point
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientCenterPointI);
|
|
CheckParameter(point);
|
|
|
|
GpPointF pointF;
|
|
|
|
GpStatus status = GdipGetPathGradientCenterPoint(brush, &pointF);
|
|
|
|
if (status == Ok)
|
|
{
|
|
|
|
point->X = GpRound(pointF.X);
|
|
point->Y = GpRound(pointF.Y);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientCenterPoint(
|
|
GpPathGradient *brush,
|
|
GDIPCONST GpPointF* point
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientCenterPoint);
|
|
CheckParameter(point);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetCenterPoint(*point);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientCenterPointI(
|
|
GpPathGradient *brush,
|
|
GDIPCONST GpPoint* point
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientCenterPointI);
|
|
CheckParameter(point);
|
|
|
|
GpPointF pointF(TOREAL(point->X), TOREAL(point->Y));
|
|
|
|
return GdipSetPathGradientCenterPoint(brush, &pointF);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientPointCount(
|
|
GpPathGradient *brush,
|
|
INT* count)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientPointCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*count = brush->GetNumberOfPoints();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientSurroundColorCount(
|
|
GpPathGradient *brush,
|
|
INT* count)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientSurroundColorCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*count = brush->GetNumberOfColors();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientRect(
|
|
GpPathGradient *brush,
|
|
GpRectF *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientRect);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->GetRect(*rect);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientRectI(
|
|
GpPathGradient *brush,
|
|
GpRect *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientRectI);
|
|
CheckParameter(rect);
|
|
|
|
GpRectF rectF;
|
|
|
|
GpStatus status = GdipGetPathGradientRect(brush, &rectF);
|
|
|
|
if (status == Ok)
|
|
{
|
|
|
|
rect->X = GpRound(rectF.X);
|
|
rect->Y = GpRound(rectF.Y);
|
|
rect->Width = GpRound(rectF.Width);
|
|
rect->Height = GpRound(rectF.Height);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientGammaCorrection(
|
|
GpPathGradient *brush,
|
|
BOOL useGammaCorrection
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientGammaCorrection);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->SetGammaCorrection(useGammaCorrection);
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientGammaCorrection(
|
|
GpPathGradient *brush,
|
|
BOOL *useGammaCorrection)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientGammaCorrection);
|
|
CheckParameter(useGammaCorrection);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*useGammaCorrection = brush->GetGammaCorrection();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientBlendCount(
|
|
GpPathGradient *brush,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientBlendCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*count = brush->GetBlendCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientBlend(
|
|
GpPathGradient *brush,
|
|
REAL *blend,
|
|
REAL *positions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientBlend);
|
|
CheckParameter(blend);
|
|
CheckParameter(positions);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->GetBlend(blend, positions, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientBlend(
|
|
GpPathGradient *brush,
|
|
GDIPCONST REAL *blend,
|
|
GDIPCONST REAL *positions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientBlend);
|
|
CheckParameter(blend);
|
|
CheckParameter(positions);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetBlend(blend, positions, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientPresetBlendCount(
|
|
GpPathGradient *brush,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientPresetBlendCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*count = brush->GetPresetBlendCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientPresetBlend(
|
|
GpPathGradient *brush,
|
|
ARGB *blend,
|
|
REAL *blendPositions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientPresetBlend);
|
|
CheckParameter(blend);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpColor* gpcolors = (GpColor*) buffer.GetBuffer(count*sizeof(GpColor));
|
|
|
|
if(!gpcolors) return OutOfMemory;
|
|
|
|
if (gpcolors)
|
|
{
|
|
GpStatus status = brush->GetPresetBlend(gpcolors, blendPositions, count);
|
|
|
|
for(INT i = 0; i < count; i++)
|
|
{
|
|
blend[i] = gpcolors[i].GetValue();
|
|
}
|
|
|
|
return status;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientPresetBlend(
|
|
GpPathGradient *brush,
|
|
GDIPCONST ARGB *blend,
|
|
GDIPCONST REAL *blendPositions,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientPresetBlend);
|
|
CheckParameter(blend);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
CheckParameter(count > 0);
|
|
|
|
// blend positions must start at 0.0 and end at 1.0
|
|
if (REALABS(blendPositions[0]) > REAL_EPSILON ||
|
|
REALABS(1.0f - blendPositions[count-1]) > REAL_EPSILON)
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpColor* gpcolors = (GpColor*) buffer.GetBuffer(count*sizeof(GpColor));
|
|
|
|
if(!gpcolors) return OutOfMemory;
|
|
|
|
if(gpcolors)
|
|
{
|
|
for(INT i = 0; i < count; i++)
|
|
{
|
|
gpcolors[i].SetColor(blend[i]);
|
|
}
|
|
|
|
GpStatus status = brush->SetPresetBlend(gpcolors, blendPositions, count);
|
|
|
|
return status;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientSigmaBlend(
|
|
GpPathGradient *brush,
|
|
REAL focus,
|
|
REAL scale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientSigmaBlend);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetSigmaBlend(focus, scale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientLinearBlend(
|
|
GpPathGradient *brush,
|
|
REAL focus,
|
|
REAL scale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientLinearBlend);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetLinearBlend(focus, scale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientWrapMode(
|
|
GpPathGradient *brush,
|
|
GpWrapMode *wrapmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientWrapMode);
|
|
CheckParameter(wrapmode);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
*wrapmode = (GpWrapMode)brush->GetWrapMode();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientWrapMode(
|
|
GpPathGradient *brush,
|
|
GpWrapMode wrapmode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientWrapMode);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
brush->SetWrapMode(wrapmode);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientTransform(
|
|
GpPathGradient *brush,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->GetTransform(matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientTransform(
|
|
GpPathGradient *brush,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->SetTransform(*matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetPathGradientTransform(
|
|
GpPathGradient* brush)
|
|
{
|
|
API_ENTRY(GdipResetPathGradientTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->ResetTransform();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMultiplyPathGradientTransform(
|
|
GpPathGradient* brush,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GpMatrixOrder order)
|
|
{
|
|
API_ENTRY(GdipMultiplyPathGradientTransform);
|
|
if(matrix == NULL)
|
|
return Ok;
|
|
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return brush->MultiplyTransform(*matrix, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslatePathGradientTransform(
|
|
GpPathGradient* brush,
|
|
REAL dx,
|
|
REAL dy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslatePathGradientTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->TranslateTransform(dx, dy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipScalePathGradientTransform(
|
|
GpPathGradient* brush,
|
|
REAL sx,
|
|
REAL sy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipScalePathGradientTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->ScaleTransform(sx, sy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRotatePathGradientTransform(
|
|
GpPathGradient* brush,
|
|
REAL angle,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipRotatePathGradientTransform);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return brush->RotateTransform(angle, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPathGradientFocusScales(
|
|
GpPathGradient *brush,
|
|
REAL* xScale,
|
|
REAL* yScale
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPathGradientFocusScales);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
CheckParameter(xScale);
|
|
CheckParameter(yScale);
|
|
|
|
return brush->GetFocusScales(xScale, yScale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPathGradientFocusScales(
|
|
GpPathGradient *brush,
|
|
REAL xScale,
|
|
REAL yScale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPathGradientFocusScales);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return brush->SetFocusScales(xScale, yScale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePen1(
|
|
ARGB color,
|
|
REAL width,
|
|
GpUnit unit,
|
|
GpPen ** outPen
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePen1);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(color);
|
|
CheckParameter(outPen);
|
|
|
|
// UnitDisplay is NOT valid; its only use is for Page Transforms
|
|
CheckParameter((unit >= UnitWorld) && (unit <= UnitMillimeter) && (unit != UnitDisplay));
|
|
|
|
GpPen * pen;
|
|
|
|
pen = (GpPen *) InterlockedExchangePointer((PVOID *) &Globals::PenLookAside, NULL);
|
|
|
|
if(pen == NULL)
|
|
{
|
|
pen = new GpPen(GpColor(color), width, unit);
|
|
}
|
|
else
|
|
{
|
|
pen->GetObjectLock()->Reset();
|
|
pen->Set(GpColor(color), width, unit);
|
|
}
|
|
|
|
if (CheckValid(pen))
|
|
{
|
|
*outPen = pen;
|
|
return Ok;
|
|
}
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreatePen2(
|
|
GpBrush *brush,
|
|
REAL width,
|
|
GpUnit unit,
|
|
GpPen **pen
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreatePen2);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(pen);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
// UnitDisplay is NOT valid; its only use is for Page Transforms
|
|
CheckParameter(
|
|
(unit >= UnitWorld) &&
|
|
(unit <= UnitMillimeter) &&
|
|
(unit != UnitDisplay)
|
|
);
|
|
|
|
*pen = new GpPen(brush, width, unit);
|
|
|
|
if (CheckValid(*pen))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipClonePen(
|
|
GpPen *pen,
|
|
GpPen **clonepen
|
|
)
|
|
{
|
|
API_ENTRY(GdipClonePen);
|
|
CheckParameter(clonepen);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*clonepen = pen->Clone();
|
|
|
|
if (CheckValid(*clonepen))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeletePen(
|
|
GpPen *pen
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeletePen);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(pen);
|
|
CheckObjectBusyForDelete(pen);
|
|
|
|
// !!! [asecchia] only use the pen lookaside for solid pens.
|
|
// it turns out that if we use pens containing TextureBrushes, we require
|
|
// the stream to remain valid for the lifetime of the pen object in the
|
|
// lookaside.
|
|
|
|
if(pen->IsSolid())
|
|
{
|
|
pen = (GpPen *) InterlockedExchangePointer((PVOID *) &Globals::PenLookAside, pen);
|
|
}
|
|
|
|
if(pen != NULL)
|
|
{
|
|
delete pen;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenWidth(
|
|
GpPen *pen,
|
|
REAL width
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenWidth);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetWidth(width);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenWidth(
|
|
GpPen *pen,
|
|
REAL *width
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenWidth);
|
|
CheckParameter(width);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*width = pen->GetWidth();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenUnit(
|
|
GpPen *pen,
|
|
GpUnit unit
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenUnit);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
// UnitDisplay is NOT valid; its only use is for Page Transforms
|
|
CheckParameter((unit >= UnitWorld) && (unit <= UnitMillimeter) && (unit != UnitDisplay));
|
|
|
|
pen->SetUnit(unit);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenUnit(
|
|
GpPen *pen,
|
|
GpUnit* unit
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenUnit);
|
|
CheckParameter(unit);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*unit = pen->GetUnit();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenLineCap197819(
|
|
GpPen *pen,
|
|
GpLineCap startCap,
|
|
GpLineCap endCap,
|
|
GpDashCap dashCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenLineCap197819);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetLineCap(startCap, endCap, dashCap);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenStartCap(
|
|
GpPen *pen,
|
|
GpLineCap startCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenStartCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetStartCap(startCap);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenEndCap(
|
|
GpPen *pen,
|
|
GpLineCap endCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenEndCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetEndCap(endCap);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenDashCap197819(
|
|
GpPen *pen,
|
|
GpDashCap dashCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenDashCap197819);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetDashCap(dashCap);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenStartCap(
|
|
GpPen *pen,
|
|
GpLineCap *startCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenStartCap);
|
|
CheckParameter(startCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*startCap = pen->GetStartCap();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenEndCap(
|
|
GpPen *pen,
|
|
GpLineCap *endCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenEndCap);
|
|
CheckParameter(endCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*endCap = pen->GetEndCap();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenDashCap197819(
|
|
GpPen *pen,
|
|
GpDashCap *dashCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenDashCap197819);
|
|
CheckParameter(dashCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*dashCap = pen->GetDashCap();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenLineJoin(
|
|
GpPen *pen,
|
|
GpLineJoin lineJoin
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenLineJoin);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetLineJoin(lineJoin);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenLineJoin(
|
|
GpPen *pen,
|
|
GpLineJoin *lineJoin
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenLineJoin);
|
|
CheckParameter(lineJoin);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*lineJoin = pen->GetLineJoin();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenCustomStartCap(
|
|
GpPen *pen,
|
|
GpCustomLineCap* customCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenCustomStartCap);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->SetCustomStartCap(customCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenCustomStartCap(
|
|
GpPen *pen,
|
|
GpCustomLineCap** customCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenCustomStartCap);
|
|
CheckParameter(customCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->GetCustomStartCap(customCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenCustomEndCap(
|
|
GpPen *pen,
|
|
GpCustomLineCap* customCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenCustomEndCap);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->SetCustomEndCap(customCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenCustomEndCap(
|
|
GpPen *pen,
|
|
GpCustomLineCap** customCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenCustomEndCap);
|
|
CheckParameter(customCap);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->GetCustomEndCap(customCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenMiterLimit(
|
|
GpPen *pen,
|
|
REAL miterLimit
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenMiterLimit);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetMiterLimit(miterLimit);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenMiterLimit(
|
|
GpPen *pen,
|
|
REAL *miterLimit
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenMiterLimit);
|
|
CheckParameter(miterLimit);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*miterLimit = pen->GetMiterLimit();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenMode(
|
|
GpPen *pen,
|
|
GpPenAlignment penMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenMode);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->SetPenAlignment(penMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenMode(
|
|
GpPen *pen,
|
|
GpPenAlignment *penMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenMode);
|
|
CheckParameter(penMode);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*penMode = pen->GetPenAlignment();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenTransform(
|
|
GpPen *pen,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenTransform);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return pen->SetTransform(*matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenTransform(
|
|
GpPen *pen,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenTransform);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return pen->GetTransform(matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetPenTransform(
|
|
GpPen *pen)
|
|
{
|
|
API_ENTRY(GdipResetPenTransform);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->ResetTransform();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMultiplyPenTransform(
|
|
GpPen *pen,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GpMatrixOrder order)
|
|
{
|
|
API_ENTRY(GdipMultiplyPenTransform);
|
|
if(matrix == NULL)
|
|
return Ok;
|
|
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return pen->MultiplyTransform(*matrix, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslatePenTransform(
|
|
GpPen* pen,
|
|
REAL dx,
|
|
REAL dy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslatePenTransform);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return pen->TranslateTransform(dx, dy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipScalePenTransform(
|
|
GpPen* pen,
|
|
REAL sx,
|
|
REAL sy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipScalePenTransform);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return pen->ScaleTransform(sx, sy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRotatePenTransform(
|
|
GpPen* pen,
|
|
REAL angle,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipRotatePenTransform);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return pen->RotateTransform(angle, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenColor(
|
|
GpPen *pen,
|
|
ARGB argb
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenColor);
|
|
CheckColorParameter(argb);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
GpColor color(argb);
|
|
|
|
return pen->SetColor(&color);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenColor(
|
|
GpPen *pen,
|
|
ARGB *argb
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenColor);
|
|
CheckParameter(argb);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
ARGB temp;
|
|
Status status = pen->GetColor(&temp);
|
|
*argb = temp;
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenBrushFill(
|
|
GpPen *pen,
|
|
GpBrush *brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenBrushFill);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
return pen->SetBrush(brush);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenBrushFill(
|
|
GpPen *pen,
|
|
GpBrush **brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenBrushFill);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameter(brush);
|
|
|
|
*brush = pen->GetClonedBrush();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenFillType(
|
|
GpPen *pen,
|
|
GpPenType* type
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenFillType);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameter(type);
|
|
|
|
*type = pen->GetPenType();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenDashStyle(
|
|
GpPen *pen,
|
|
GpDashStyle *dashstyle
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenDashStyle);
|
|
CheckParameter(dashstyle);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*dashstyle = (GpDashStyle)pen->GetDashStyle();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenDashStyle(
|
|
GpPen *pen,
|
|
GpDashStyle dashstyle
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenDashStyle);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetDashStyle(dashstyle);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenDashOffset(
|
|
GpPen *pen,
|
|
REAL *offset
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenDashOffset);
|
|
CheckParameter(offset);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*offset = pen->GetDashOffset();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenDashOffset(
|
|
GpPen *pen,
|
|
REAL offset
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenDashOffset);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
pen->SetDashOffset(offset);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenDashCount(
|
|
GpPen *pen,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenDashCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*count = pen->GetDashCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenDashArray(
|
|
GpPen *pen,
|
|
GDIPCONST REAL *dash,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenDashArray);
|
|
CheckParameter(dash);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->SetDashArray(dash, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenDashArray(
|
|
GpPen *pen,
|
|
REAL *dash,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenDashArray);
|
|
CheckParameter(dash);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->GetDashArray(dash, count);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenCompoundCount(
|
|
GpPen *pen,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenCompoundCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
*count = pen->GetCompoundCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPenCompoundArray(
|
|
GpPen *pen,
|
|
GDIPCONST REAL *compoundArray,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPenCompoundArray);
|
|
CheckParameter(compoundArray);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->SetCompoundArray(compoundArray, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPenCompoundArray(
|
|
GpPen *pen,
|
|
REAL *compoundArray,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPenCompoundArray);
|
|
CheckParameter(compoundArray);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
return pen->GetCompoundArray(compoundArray, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateCustomLineCap(
|
|
GpPath* fillPath,
|
|
GpPath* strokePath,
|
|
GpLineCap baseCap,
|
|
REAL baseInset,
|
|
GpCustomLineCap **customCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateCustomLineCap);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
// fillPath or strokePath can be NULL.
|
|
|
|
CheckParameter(customCap);
|
|
CheckParameter((fillPath != NULL) || (strokePath != NULL));
|
|
CheckOptionalParameterValid(fillPath);
|
|
CheckOptionalObjectBusy(fillPath);
|
|
CheckOptionalParameterValid(strokePath);
|
|
CheckOptionalObjectBusy(strokePath);
|
|
|
|
*customCap = new GpCustomLineCap(fillPath, strokePath, baseCap, baseInset);
|
|
|
|
if (*customCap)
|
|
{
|
|
if((*customCap)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
|
|
// This failed to create correctly. Retrieve the failure code.
|
|
|
|
GpStatus status = (*customCap)->GetCreationStatus();
|
|
delete *customCap;
|
|
*customCap = NULL;
|
|
return status;
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneCustomLineCap(
|
|
GpCustomLineCap *customCap,
|
|
GpCustomLineCap **newCustomCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneCustomLineCap);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
*newCustomCap = customCap->Clone();
|
|
|
|
if (*newCustomCap)
|
|
{
|
|
if((*newCustomCap)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
|
|
// This failed to create correctly. Retrieve the failure code.
|
|
|
|
GpStatus status = (*newCustomCap)->GetCreationStatus();
|
|
delete *newCustomCap;
|
|
*newCustomCap = NULL;
|
|
return status;
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCustomLineCapType(
|
|
GpCustomLineCap* customCap,
|
|
CustomLineCapType* type
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCustomLineCapType);
|
|
CheckParameter(type);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
*type = customCap->GetType();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteCustomLineCap(
|
|
GpCustomLineCap* customCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeleteCustomLineCap);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(customCap);
|
|
CheckObjectBusyForDelete(customCap);
|
|
|
|
delete customCap;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCustomLineCapStrokeCaps(
|
|
GpCustomLineCap* customCap,
|
|
GpLineCap startCap,
|
|
GpLineCap endCap)
|
|
{
|
|
API_ENTRY(GdipSetCustomLineCapStrokeCaps);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
return customCap->SetStrokeCaps(startCap, endCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCustomLineCapStrokeCaps(
|
|
GpCustomLineCap* customCap,
|
|
GpLineCap* startCap,
|
|
GpLineCap* endCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCustomLineCapStrokeCaps);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameter(startCap);
|
|
CheckParameter(endCap);
|
|
|
|
return customCap->GetStrokeCaps(startCap, endCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCustomLineCapStrokeJoin(
|
|
GpCustomLineCap* customCap,
|
|
GpLineJoin lineJoin
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetCustomLineCapStrokeJoin);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
return customCap->SetStrokeJoin(lineJoin);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCustomLineCapStrokeJoin(
|
|
GpCustomLineCap* customCap,
|
|
GpLineJoin* lineJoin
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCustomLineCapStrokeJoin);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameter(lineJoin);
|
|
|
|
return customCap->GetStrokeJoin(lineJoin);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCustomLineCapBaseCap(
|
|
GpCustomLineCap* customCap,
|
|
GpLineCap baseCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetCustomLineCapBaseCap);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
return customCap->SetBaseCap(baseCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCustomLineCapBaseCap(
|
|
GpCustomLineCap* customCap,
|
|
GpLineCap* baseCap
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCustomLineCapBaseCap);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameter(baseCap);
|
|
|
|
return customCap->GetBaseCap(baseCap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCustomLineCapBaseInset(
|
|
GpCustomLineCap* customCap,
|
|
REAL inset
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetCustomLineCapBaseInset);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
return customCap->SetBaseInset(inset);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCustomLineCapBaseInset(
|
|
GpCustomLineCap* customCap,
|
|
REAL* inset
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCustomLineCapBaseInset);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameter(inset);
|
|
|
|
return customCap->GetBaseInset(inset);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCustomLineCapWidthScale(
|
|
GpCustomLineCap* customCap,
|
|
REAL widthScale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetCustomLineCapWidthScale);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
|
|
return customCap->SetWidthScale(widthScale);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipGetCustomLineCapWidthScale(
|
|
GpCustomLineCap* customCap,
|
|
REAL* widthScale
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCustomLineCapWidthScale);
|
|
CheckParameterValid(customCap);
|
|
CheckObjectBusy(customCap);
|
|
CheckParameter(widthScale);
|
|
|
|
return customCap->GetWidthScale(widthScale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateAdjustableArrowCap(
|
|
REAL height,
|
|
REAL width,
|
|
BOOL isFilled,
|
|
GpAdjustableArrowCap **cap)
|
|
{
|
|
API_ENTRY(GdipCreateAdjustableArrowCap);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(cap);
|
|
|
|
*cap = new GpAdjustableArrowCap(height, width, isFilled);
|
|
|
|
if(*cap)
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetAdjustableArrowCapHeight(
|
|
GpAdjustableArrowCap* cap,
|
|
REAL height
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetAdjustableArrowCapHeight);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
|
|
return cap->SetHeight(height);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetAdjustableArrowCapHeight(
|
|
GpAdjustableArrowCap* cap,
|
|
REAL* height
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetAdjustableArrowCapHeight);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
CheckParameter(height);
|
|
|
|
*height = cap->GetHeight();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetAdjustableArrowCapWidth(
|
|
GpAdjustableArrowCap* cap,
|
|
REAL width
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetAdjustableArrowCapWidth);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
|
|
return cap->SetWidth(width);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetAdjustableArrowCapWidth(
|
|
GpAdjustableArrowCap* cap,
|
|
REAL* width
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetAdjustableArrowCapWidth);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
CheckParameter(width);
|
|
|
|
*width = cap->GetWidth();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetAdjustableArrowCapMiddleInset(
|
|
GpAdjustableArrowCap* cap,
|
|
REAL middleInset
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetAdjustableArrowCapMiddleInset);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
|
|
return cap->SetMiddleInset(middleInset);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetAdjustableArrowCapMiddleInset(
|
|
GpAdjustableArrowCap* cap,
|
|
REAL* middleInset
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetAdjustableArrowCapMiddleInset);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
CheckParameter(middleInset);
|
|
|
|
*middleInset = cap->GetMiddleInset();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetAdjustableArrowCapFillState(
|
|
GpAdjustableArrowCap* cap,
|
|
BOOL fillState
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetAdjustableArrowCapFillState);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
|
|
return cap->SetFillState(fillState);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetAdjustableArrowCapFillState(
|
|
GpAdjustableArrowCap* cap,
|
|
BOOL* fillState
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetAdjustableArrowCapFillState);
|
|
CheckParameterValid(cap);
|
|
CheckObjectBusy(cap);
|
|
CheckParameter(fillState);
|
|
|
|
*fillState = cap->IsFilled();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipLoadImageFromStream(
|
|
IStream* stream,
|
|
GpImage **image
|
|
)
|
|
{
|
|
API_ENTRY(GdipLoadImageFromStream);
|
|
CheckParameter(image && stream);
|
|
|
|
|
|
*image = GpImage::LoadImage(stream);
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*image)
|
|
{
|
|
if ((*image)->IsValid())
|
|
{
|
|
(*image)->SetICMConvert(FALSE);
|
|
return Ok;
|
|
}
|
|
(*image)->Dispose();
|
|
*image = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipLoadImageFromFile(
|
|
GDIPCONST WCHAR* filename,
|
|
GpImage** image
|
|
)
|
|
{
|
|
API_ENTRY(GdipLoadImageFromFile);
|
|
CheckParameter(image && filename);
|
|
|
|
|
|
*image = GpImage::LoadImage(filename);
|
|
|
|
if (*image)
|
|
{
|
|
if ((*image)->IsValid())
|
|
{
|
|
(*image)->SetICMConvert(FALSE);
|
|
return Ok;
|
|
}
|
|
(*image)->Dispose();
|
|
*image = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipLoadImageFromStreamICM(
|
|
IStream* stream,
|
|
GpImage **image
|
|
)
|
|
{
|
|
API_ENTRY(GdipLoadImageFromStreamICM);
|
|
CheckParameter(image && stream);
|
|
|
|
|
|
*image = GpImage::LoadImage(stream);
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*image)
|
|
{
|
|
if ((*image)->IsValid())
|
|
{
|
|
(*image)->SetICMConvert(TRUE);
|
|
return Ok;
|
|
}
|
|
(*image)->Dispose();
|
|
*image = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipLoadImageFromFileICM(
|
|
GDIPCONST WCHAR* filename,
|
|
GpImage** image
|
|
)
|
|
{
|
|
API_ENTRY(GdipLoadImageFromFileICM);
|
|
CheckParameter(image && filename);
|
|
|
|
|
|
*image = GpImage::LoadImage(filename);
|
|
|
|
if (*image)
|
|
{
|
|
if ((*image)->IsValid())
|
|
{
|
|
(*image)->SetICMConvert(TRUE);
|
|
return Ok;
|
|
}
|
|
(*image)->Dispose();
|
|
*image = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
return OutOfMemory;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetEncoderParameterListSize(
|
|
GpImage *image,
|
|
GDIPCONST CLSID *clsidEncoder,
|
|
UINT *size
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetEncoderParameterListSize);
|
|
CheckParameter(image && clsidEncoder);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->GetEncoderParameterListSize(const_cast<CLSID*>(clsidEncoder), size);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetEncoderParameterList(
|
|
GpImage *image,
|
|
GDIPCONST CLSID *clsidEncoder,
|
|
UINT size,
|
|
EncoderParameters *buffer
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetEncoderParameterList);
|
|
CheckParameter(image && clsidEncoder);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->GetEncoderParameterList(const_cast<CLSID*>(clsidEncoder), size, buffer);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSaveImageToStream(
|
|
GpImage *image,
|
|
IStream* stream,
|
|
GDIPCONST CLSID* clsidEncoder,
|
|
GDIPCONST EncoderParameters* encoderParams
|
|
)
|
|
{
|
|
API_ENTRY(GdipSaveImageToStream);
|
|
CheckParameter(image && stream && clsidEncoder);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->SaveToStream(stream,
|
|
const_cast<CLSID*>(clsidEncoder),
|
|
const_cast<EncoderParameters*>(encoderParams));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSaveImageToFile(
|
|
GpImage *image,
|
|
GDIPCONST WCHAR* filename,
|
|
GDIPCONST CLSID* clsidEncoder,
|
|
GDIPCONST EncoderParameters* encoderParams
|
|
)
|
|
{
|
|
API_ENTRY(GdipSaveImageToFile);
|
|
CheckParameter(image && filename && clsidEncoder);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->SaveToFile(filename,
|
|
const_cast<CLSID*>(clsidEncoder),
|
|
const_cast<EncoderParameters*>(encoderParams));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSaveAdd(
|
|
GpImage *image,
|
|
GDIPCONST EncoderParameters* encoderParams
|
|
)
|
|
{
|
|
API_ENTRY(GdipSaveAdd);
|
|
CheckParameter(image && encoderParams);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->SaveAdd(const_cast<EncoderParameters*>(encoderParams));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSaveAddImage(
|
|
GpImage* image,
|
|
GpImage* newImage,
|
|
GDIPCONST EncoderParameters* encoderParams
|
|
)
|
|
{
|
|
API_ENTRY(GdipSaveAddImage);
|
|
CheckParameter(image && newImage && encoderParams);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->SaveAdd(newImage, const_cast<EncoderParameters*>(encoderParams));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipImageGetFrameDimensionsCount(
|
|
GpImage* image,
|
|
UINT* count
|
|
)
|
|
{
|
|
API_ENTRY(GdipImageGetFrameDimensionsCount);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetFrameDimensionsCount(count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipImageGetFrameDimensionsList(
|
|
GpImage* image,
|
|
GUID* dimensionIDs,
|
|
UINT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipImageGetFrameDimensionsList);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetFrameDimensionsList(dimensionIDs, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipImageGetFrameCount(
|
|
GpImage* image,
|
|
GDIPCONST GUID* dimensionID,
|
|
UINT* count
|
|
)
|
|
{
|
|
API_ENTRY(GdipImageGetFrameCount);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetFrameCount(dimensionID, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipImageSelectActiveFrame(
|
|
GpImage* image,
|
|
GDIPCONST GUID* dimensionID,
|
|
UINT frameIndex
|
|
)
|
|
{
|
|
API_ENTRY(GdipImageSelectActiveFrame);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->SelectActiveFrame(dimensionID, frameIndex);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipImageRotateFlip(
|
|
GpImage* image,
|
|
RotateFlipType rfType
|
|
)
|
|
{
|
|
API_ENTRY(GdipImageRotateFlip);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->RotateFlip(rfType);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPropertyCount(
|
|
GpImage* image,
|
|
UINT* numOfProperty
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPropertyCount);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetPropertyCount(numOfProperty);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPropertyIdList(
|
|
GpImage* image,
|
|
UINT numOfProperty,
|
|
PROPID* list
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPropertyIdList);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetPropertyIdList(numOfProperty, list);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPropertyItemSize(
|
|
GpImage* image,
|
|
PROPID propId,
|
|
UINT* size
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPropertyItemSize);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetPropertyItemSize(propId, size);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPropertyItem(
|
|
GpImage* image,
|
|
PROPID propId,
|
|
UINT propSize,
|
|
PropertyItem* buffer
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPropertyItem);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetPropertyItem(propId, propSize, buffer);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPropertySize(
|
|
GpImage* image,
|
|
UINT* totalBufferSize,
|
|
UINT* numProperties
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPropertySize);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetPropertySize(totalBufferSize, numProperties);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetAllPropertyItems(
|
|
GpImage* image,
|
|
UINT totalBufferSize,
|
|
UINT numProperties,
|
|
PropertyItem* allItems
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetAllPropertyItems);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->GetAllPropertyItems(totalBufferSize, numProperties, allItems);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRemovePropertyItem(
|
|
GpImage* image,
|
|
PROPID propId
|
|
)
|
|
{
|
|
API_ENTRY(GdipRemovePropertyItem);
|
|
CheckParameter(image);
|
|
CheckObjectBusy(image);
|
|
return image->RemovePropertyItem(propId);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPropertyItem(
|
|
GpImage* image,
|
|
GDIPCONST PropertyItem* item
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPropertyItem);
|
|
CheckParameter(image && item);
|
|
CheckObjectBusy(image);
|
|
return image->SetPropertyItem(const_cast<PropertyItem*>(item));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneImage(
|
|
GpImage* image,
|
|
GpImage** cloneimage
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneImage);
|
|
CheckParameter(cloneimage);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
*cloneimage = image->Clone();
|
|
|
|
if (*cloneimage)
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
|
|
// !!!: There is no destructor to invoke. Leave it to Clone to
|
|
// verify correct creation.
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDisposeImage(
|
|
GpImage *image
|
|
)
|
|
{
|
|
API_ENTRY(GdipDisposeImage);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(image);
|
|
|
|
if (image->GetImageType() == ImageTypeMetafile)
|
|
{
|
|
// If the user still has the graphics associated with the metafile,
|
|
// then we have to lock it, to prevent them from using it while
|
|
// we're busy deleting the metafile object. The metafile dispose
|
|
// method will set the graphics to invalid, so the only thing
|
|
// they can do with the graphics is to delete it after this call.
|
|
|
|
GpMetafile * metafile = (GpMetafile *)image;
|
|
GpGraphics * g = metafile->PrivateAPIForGettingMetafileGraphicsContext();
|
|
CheckOptionalObjectBusy(g);
|
|
CheckObjectBusyForDelete(metafile);
|
|
metafile->Dispose();
|
|
return Ok;
|
|
}
|
|
|
|
CheckObjectBusyForDelete(image);
|
|
|
|
image->Dispose();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageGraphicsContext(
|
|
GpImage *image,
|
|
GpGraphics **graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageGraphicsContext);
|
|
CheckParameter(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
*graphics = image->GetGraphicsContext();
|
|
|
|
if (CheckValid(*graphics))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageBounds(
|
|
GpImage *image,
|
|
GpRectF *srcRect,
|
|
GpPageUnit *srcUnit
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageBounds);
|
|
CheckParameter(srcRect && srcUnit);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->GetBounds(srcRect, srcUnit);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageDimension(
|
|
GpImage *image,
|
|
REAL *width,
|
|
REAL *height
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageDimension);
|
|
CheckParameter(width && height);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->GetPhysicalDimension(width, height);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageWidth(
|
|
GpImage *image,
|
|
UINT *width
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageWidth);
|
|
CheckParameter(width);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
*width = imageinfo.Width;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageHeight(
|
|
GpImage *image,
|
|
UINT *height
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageHeight);
|
|
CheckParameter(height);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
*height = imageinfo.Height;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageHorizontalResolution(
|
|
GpImage *image,
|
|
REAL *resolution
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageHorizontalResolution);
|
|
CheckParameter(resolution);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
*resolution = (REAL) imageinfo.Xdpi;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageVerticalResolution(
|
|
GpImage *image,
|
|
REAL *resolution
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageVerticalResolution);
|
|
CheckParameter(resolution);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
*resolution = (REAL) imageinfo.Ydpi;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageFlags(
|
|
GpImage *image,
|
|
UINT *flags
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageFlags);
|
|
CheckParameter(flags);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
*flags = imageinfo.Flags;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageRawFormat(
|
|
GpImage *image,
|
|
GUID *format
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageRawFormat);
|
|
CheckParameter(format);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
*format = imageinfo.RawDataFormat;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImagePixelFormat(
|
|
GpImage *image,
|
|
PixelFormat *format
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImagePixelFormat);
|
|
CheckParameter(format);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
ImageInfo imageinfo;
|
|
|
|
GpStatus status = image->GetImageInfo(&imageinfo);
|
|
|
|
if (status == Ok)
|
|
{
|
|
//!!!need conversion to PixelFormat
|
|
*format = (PixelFormat) MaskPixelFormat(imageinfo.PixelFormat);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size)
|
|
{
|
|
API_ENTRY(GdipGetImagePalette);
|
|
CheckParameter(palette);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->GetPalette(palette, size);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipSetImagePalette(GpImage *image, GDIPCONST ColorPalette *palette)
|
|
{
|
|
API_ENTRY(GdipSetImagePalette);
|
|
CheckParameter(palette);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
return image->SetPalette(const_cast<ColorPalette*>(palette));
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipGetImagePaletteSize(GpImage *image, INT *size)
|
|
{
|
|
API_ENTRY(GdipGetImagePaletteSize);
|
|
|
|
CheckParameter(size);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
*size = image->GetPaletteSize();
|
|
|
|
// Note: image->GetPaletteSize() will return zero if and only if there is
|
|
// something wrong in the whole pipeline, like a bad image, out of memory etc.
|
|
|
|
if (*size == 0)
|
|
{
|
|
return GenericError;
|
|
}
|
|
else
|
|
{
|
|
return Ok;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageType(
|
|
GpImage* image,
|
|
ImageType* type
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageType);
|
|
CheckParameter(type);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
*type = (ImageType)image->GetImageType();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageThumbnail(
|
|
GpImage* image,
|
|
UINT thumbWidth,
|
|
UINT thumbHeight,
|
|
GpImage** thumbImage,
|
|
GetThumbnailImageAbort callback,
|
|
VOID * callbackData
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageThumbnail);
|
|
CheckParameter(thumbImage);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
*thumbImage = image->GetThumbnail(thumbWidth, thumbHeight, callback, callbackData);
|
|
|
|
if (*thumbImage)
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipImageForceValidation(GpImage* image)
|
|
{
|
|
API_ENTRY(GdipImageForceValidation);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
// Metafiles don't need a force decode
|
|
|
|
if (image->GetImageType() == ImageTypeBitmap)
|
|
return (static_cast<GpBitmap*>(image))->ForceValidation();
|
|
else
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromStream(
|
|
IStream* stream,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromStream);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap && stream);
|
|
|
|
*bitmap = NULL;
|
|
|
|
// See if the stream is a metafile
|
|
|
|
|
|
GpMetafile* metafile = new GpMetafile(stream);
|
|
|
|
if (metafile != NULL)
|
|
{
|
|
if (metafile->IsValid())
|
|
{
|
|
// If it is a {EMF, WMF} file, then we get a raster version of it
|
|
// Note: GetBitmap() might return NULL if there is anything wrong
|
|
// with the Metafile
|
|
|
|
*bitmap = metafile->GetBitmap();
|
|
metafile->Dispose();
|
|
goto SkipRasterImage;
|
|
}
|
|
|
|
metafile->Dispose();
|
|
}
|
|
|
|
if ( NULL == *bitmap )
|
|
{
|
|
// it's not a valid metafile -- it must be a bitmap
|
|
|
|
*bitmap = new GpBitmap(stream);
|
|
}
|
|
|
|
SkipRasterImage:
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
{
|
|
(*bitmap)->SetICMConvert(FALSE);
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromFile(
|
|
GDIPCONST WCHAR* filename,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromFile);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap && filename);
|
|
|
|
*bitmap = NULL;
|
|
|
|
|
|
// Try a metafile first always
|
|
GpMetafile* metafile;
|
|
metafile = new GpMetafile(filename);
|
|
|
|
if (metafile)
|
|
{
|
|
if (metafile->IsValid())
|
|
{
|
|
*bitmap = metafile->GetBitmap();
|
|
metafile->Dispose();
|
|
goto SkipRasterImage;
|
|
}
|
|
|
|
metafile->Dispose();
|
|
}
|
|
|
|
// If it is not a metafile, then check if this is a raster image
|
|
|
|
if ( NULL == *bitmap )
|
|
{
|
|
*bitmap = new GpBitmap(filename);
|
|
}
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
SkipRasterImage:
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
{
|
|
(*bitmap)->SetICMConvert(FALSE);
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromStreamICM(
|
|
IStream* stream,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromStreamICM);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap && stream);
|
|
|
|
*bitmap = NULL;
|
|
|
|
// See if the stream is a metafile
|
|
|
|
|
|
GpMetafile* metafile = new GpMetafile(stream);
|
|
|
|
if (metafile != NULL)
|
|
{
|
|
if (metafile->IsValid())
|
|
{
|
|
*bitmap = metafile->GetBitmap();
|
|
metafile->Dispose();
|
|
goto SkipRasterImage;
|
|
}
|
|
|
|
metafile->Dispose();
|
|
}
|
|
|
|
if ( NULL == *bitmap )
|
|
{
|
|
// it's not a valid metafile -- it must be a bitmap
|
|
*bitmap = new GpBitmap(stream);
|
|
}
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
SkipRasterImage:
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
{
|
|
(*bitmap)->SetICMConvert(TRUE);
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromFileICM(
|
|
GDIPCONST WCHAR* filename,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromFileICM);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap && filename);
|
|
|
|
// copied from GpImage::LoadImage
|
|
|
|
*bitmap = NULL;
|
|
|
|
|
|
// Try a metafile first always
|
|
GpMetafile* metafile;
|
|
metafile = new GpMetafile(filename);
|
|
|
|
if (metafile)
|
|
{
|
|
if (metafile->IsValid())
|
|
{
|
|
*bitmap = metafile->GetBitmap();
|
|
metafile->Dispose();
|
|
goto SkipRasterImage;
|
|
}
|
|
|
|
metafile->Dispose();
|
|
}
|
|
|
|
// If it is not a metafile, then check if this is a raster image
|
|
|
|
if ( NULL == *bitmap )
|
|
{
|
|
*bitmap = new GpBitmap(filename);
|
|
}
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
SkipRasterImage:
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
{
|
|
(*bitmap)->SetICMConvert(TRUE);
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromScan0(
|
|
INT width,
|
|
INT height,
|
|
INT stride,
|
|
PixelFormatID format,
|
|
BYTE* scan0,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromScan0);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
format = MaskPixelFormat(format);
|
|
|
|
|
|
if (scan0 == NULL)
|
|
{
|
|
*bitmap = new GpBitmap(width, height, format);
|
|
}
|
|
else
|
|
{
|
|
CheckParameter(stride);
|
|
*bitmap = new GpBitmap(width, height, stride, format, scan0);
|
|
}
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
return Ok;
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromGraphics(
|
|
INT width,
|
|
INT height,
|
|
GpGraphics* graphics,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromGraphics);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
//!!!TODO: temp use 32bpp argb
|
|
|
|
#ifdef NO_PREMULTIPLIED_ALPHA
|
|
*bitmap = new GpBitmap(width, height, PIXFMT_32BPP_ARGB, graphics);
|
|
#else
|
|
*bitmap = new GpBitmap(width, height, PIXFMT_32BPP_PARGB, graphics);
|
|
#endif
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
return Ok;
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromDirectDrawSurface(
|
|
IDirectDrawSurface7 * surface,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromDirectDrawSurface);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
CheckParameter(surface);
|
|
|
|
*bitmap = new GpBitmap(surface);
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
return Ok;
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromGdiDib(
|
|
GDIPCONST BITMAPINFO* gdiBitmapInfo,
|
|
VOID* gdiBitmapData,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromGdiDib);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
CheckParameter(gdiBitmapInfo);
|
|
CheckParameter(gdiBitmapData);
|
|
|
|
*bitmap = new GpBitmap(const_cast<BITMAPINFO*>(gdiBitmapInfo),
|
|
gdiBitmapData,
|
|
FALSE);
|
|
|
|
// !!! Can't use CheckValid() since destructor is protected.
|
|
|
|
if (*bitmap)
|
|
{
|
|
if ((*bitmap)->IsValid())
|
|
return Ok;
|
|
else
|
|
{
|
|
(*bitmap)->Dispose();
|
|
*bitmap = NULL;
|
|
return InvalidParameter;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromHBITMAP(
|
|
HBITMAP hbm,
|
|
HPALETTE hpal,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromHBITMAP);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
|
|
return GpBitmap::CreateFromHBITMAP(hbm, hpal, bitmap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateHBITMAPFromBitmap(
|
|
GpBitmap* bitmap,
|
|
HBITMAP* hbmReturn,
|
|
ARGB background
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateHBITMAPFromBitmap);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckColorParameter(background);
|
|
CheckParameter(hbmReturn);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
return bitmap->CreateHBITMAP(hbmReturn, background);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromHICON(
|
|
HICON hicon,
|
|
GpBitmap** bitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromHICON);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
|
|
return GpBitmap::CreateFromHICON(hicon, bitmap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateBitmapFromResource(HINSTANCE hInstance,
|
|
GDIPCONST WCHAR* lpBitmapName,
|
|
GpBitmap** bitmap)
|
|
{
|
|
API_ENTRY(GdipCreateBitmapFromResource);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(bitmap);
|
|
|
|
return GpBitmap::CreateFromResource(hInstance, const_cast<WCHAR*>(lpBitmapName), bitmap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateHICONFromBitmap(
|
|
GpBitmap* bitmap,
|
|
HICON* hiconReturn)
|
|
{
|
|
API_ENTRY(GdipCreateHICONFromBitmap);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(hiconReturn);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
return bitmap->CreateHICON(hiconReturn);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneBitmapArea(
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
PixelFormatID format,
|
|
GpBitmap *srcBitmap,
|
|
GpBitmap **dstBitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneBitmapArea);
|
|
format = MaskPixelFormat(format);
|
|
|
|
return GdipCloneBitmapAreaI(GpRound(x), GpRound(y),
|
|
GpRound(width), GpRound(height),
|
|
format, srcBitmap, dstBitmap);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneBitmapAreaI(
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
PixelFormatID format,
|
|
GpBitmap *srcBitmap,
|
|
GpBitmap **dstBitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneBitmapAreaI);
|
|
CheckParameter(dstBitmap);
|
|
CheckParameterValid(srcBitmap);
|
|
CheckObjectBusy(srcBitmap);
|
|
|
|
format = MaskPixelFormat(format);
|
|
|
|
GpRect rect(x, y, width, height);
|
|
|
|
*dstBitmap = srcBitmap->Clone(&rect, format);
|
|
|
|
if (*dstBitmap)
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBitmapLockBits(
|
|
GpBitmap* bitmap,
|
|
GDIPCONST GpRect* rect, // can be NULL
|
|
UINT flags,
|
|
PixelFormatID format,
|
|
BitmapData* lockedBitmapData
|
|
)
|
|
{
|
|
API_ENTRY(GdipBitmapLockBits);
|
|
CheckParameter(lockedBitmapData);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
format = MaskPixelFormat(format);
|
|
|
|
return bitmap->LockBits(rect, flags, format, lockedBitmapData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBitmapUnlockBits(
|
|
GpBitmap* bitmap,
|
|
BitmapData* lockedBitmapData
|
|
)
|
|
{
|
|
API_ENTRY(GdipBitmapUnlockBits);
|
|
CheckParameter(lockedBitmapData);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
return bitmap->UnlockBits(lockedBitmapData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBitmapGetPixel(
|
|
GpBitmap* bitmap,
|
|
INT x,
|
|
INT y,
|
|
ARGB *color
|
|
)
|
|
{
|
|
API_ENTRY(GdipBitmapGetPixel);
|
|
CheckParameter(color);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
ARGB temp;
|
|
Status status = bitmap->GetPixel(x, y, &temp);
|
|
*color = temp;
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBitmapSetPixel(
|
|
GpBitmap* bitmap,
|
|
INT x,
|
|
INT y,
|
|
ARGB color
|
|
)
|
|
{
|
|
API_ENTRY(GdipBitmapSetPixel);
|
|
CheckColorParameter(color);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
return bitmap->SetPixel(x, y, color);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBitmapSetResolution(
|
|
GpBitmap* bitmap,
|
|
REAL xdpi,
|
|
REAL ydpi
|
|
)
|
|
{
|
|
API_ENTRY(GdipBitmapSetResolution);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
return bitmap->SetResolution(xdpi, ydpi);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateImageAttributes(GpImageAttributes **imageattr)
|
|
{
|
|
API_ENTRY(GdipCreateImageAttributes);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(imageattr);
|
|
|
|
*imageattr = new GpImageAttributes();
|
|
|
|
if (*imageattr)
|
|
{
|
|
if ((*imageattr)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
(*imageattr)->Dispose();
|
|
*imageattr = NULL;
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneImageAttributes(
|
|
GDIPCONST GpImageAttributes *imageattr,
|
|
GpImageAttributes **cloneImageAttr
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneImageAttributes);
|
|
CheckParameter(cloneImageAttr);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
|
|
*cloneImageAttr = imageattr->Clone();
|
|
|
|
if (*cloneImageAttr)
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDisposeImageAttributes(
|
|
GpImageAttributes *imageattr
|
|
)
|
|
{
|
|
API_ENTRY(GdipDisposeImageAttributes);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(imageattr);
|
|
CheckObjectBusyForDelete(imageattr);
|
|
|
|
imageattr->Dispose();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesToIdentity(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesToIdentity);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->SetToIdentity(type);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetImageAttributes(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type
|
|
)
|
|
{
|
|
API_ENTRY(GdipResetImageAttributes);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->Reset(type);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesColorMatrix(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
GDIPCONST ColorMatrix* colorMatrix,
|
|
GDIPCONST ColorMatrix* grayMatrix,
|
|
ColorMatrixFlags flags
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesColorMatrix);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
// Note: GpImageAttributes::SetColorMatrix will validate
|
|
// colorMatrix since it may be valid to pass NULL
|
|
// (such as when enableFlag is FALSE).
|
|
|
|
return imageattr->SetColorMatrix(type,
|
|
enableFlag,
|
|
const_cast<ColorMatrix*>(colorMatrix),
|
|
const_cast<ColorMatrix*>(grayMatrix), flags);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesThreshold(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
REAL threshold
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesThreshold);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->SetThreshold(type, enableFlag, threshold);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesGamma(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
REAL gamma
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesGamma);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->SetGamma(type, enableFlag, gamma);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesNoOp(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesNoOp);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->SetNoOp(type, enableFlag);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesColorKeys(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
ARGB argbLow,
|
|
ARGB argbHigh
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesColorKeys);
|
|
CheckColorParameter(argbLow);
|
|
CheckColorParameter(argbHigh);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
Color colorLow(argbLow);
|
|
Color colorHigh(argbHigh);
|
|
|
|
return imageattr->SetColorKeys(type, enableFlag, &colorLow, &colorHigh);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesOutputChannel(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
ColorChannelFlags channelFlags
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesOutputChannel);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->SetOutputChannel(type, enableFlag, channelFlags);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesOutputChannelColorProfile(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
GDIPCONST WCHAR *colorProfileFilename)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesOutputChannelColorProfile);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
// Note: GpImageAttributes::SetOutputChannelProfile will validate
|
|
// colorProfileFilename since it may be valid to pass NULL
|
|
// (such as when enableFlag is FALSE).
|
|
|
|
return imageattr->SetOutputChannelProfile(type, enableFlag,
|
|
const_cast<WCHAR*>(colorProfileFilename));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesRemapTable(
|
|
GpImageAttributes *imageattr,
|
|
ColorAdjustType type,
|
|
BOOL enableFlag,
|
|
UINT mapSize,
|
|
GDIPCONST ColorMap *map
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesRemapTable);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
CheckParameter(ColorAdjustTypeIsValid(type));
|
|
|
|
return imageattr->SetRemapTable(type, enableFlag, mapSize, const_cast<ColorMap*>(map));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesCachedBackground(
|
|
GpImageAttributes *imageattr,
|
|
BOOL enableFlag
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesCachedBackground);
|
|
CheckParameterValid(imageattr);
|
|
CheckObjectBusy(imageattr);
|
|
|
|
return imageattr->SetCachedBackground(enableFlag);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetImageAttributesWrapMode(
|
|
GpImageAttributes *imageAttr,
|
|
WrapMode wrap,
|
|
ARGB argb,
|
|
BOOL clamp
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetImageAttributesWrapMode);
|
|
CheckColorParameter(argb);
|
|
CheckParameterValid(imageAttr);
|
|
CheckObjectBusy(imageAttr);
|
|
|
|
return imageAttr->SetWrapMode(wrap, argb, clamp);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipGetImageAttributesAdjustedPalette(
|
|
GpImageAttributes *imageAttr,
|
|
ColorPalette * colorPalette,
|
|
ColorAdjustType colorAdjustType
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetImageAttributesAdjustedPalette);
|
|
CheckParameterValid(imageAttr);
|
|
CheckObjectBusy(imageAttr);
|
|
CheckParameter((colorPalette != NULL) && (colorPalette->Count > 0));
|
|
CheckParameter((colorAdjustType >= ColorAdjustTypeBitmap) &&
|
|
(colorAdjustType < ColorAdjustTypeCount));
|
|
|
|
imageAttr->GetAdjustedPalette(colorPalette, colorAdjustType);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFromHDC(
|
|
HDC hdc,
|
|
GpGraphics** graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFromHDC);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(graphics);
|
|
|
|
|
|
*graphics = GpGraphics::GetFromHdc(hdc);
|
|
|
|
if (CheckValid(*graphics))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFromHDC2(
|
|
HDC hdc,
|
|
HANDLE hdevice,
|
|
GpGraphics** graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFromHDC2);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(graphics);
|
|
|
|
|
|
*graphics = GpGraphics::GetFromHdc(hdc, hdevice);
|
|
|
|
if (CheckValid(*graphics))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFromHWND(
|
|
HWND hwnd,
|
|
GpGraphics** graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFromHWND);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(graphics);
|
|
|
|
*graphics = GpGraphics::GetFromHwnd(hwnd);
|
|
|
|
if (CheckValid(*graphics))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFromHWNDICM(
|
|
HWND hwnd,
|
|
GpGraphics** graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFromHWNDICM);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(graphics);
|
|
|
|
*graphics = GpGraphics::GetFromHwnd(hwnd, IcmModeOn);
|
|
|
|
if (CheckValid(*graphics))
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteGraphics(
|
|
GpGraphics* graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeleteGraphics);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(graphics);
|
|
CheckObjectBusyForDelete(graphics);
|
|
|
|
|
|
delete graphics;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFlush(
|
|
GpGraphics* graphics,
|
|
GpFlushIntention intention
|
|
)
|
|
{
|
|
API_ENTRY(GdipFlush);
|
|
CheckParameter(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
graphics->Flush(intention);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetRenderingOrigin(
|
|
GpGraphics* graphics,
|
|
INT x,
|
|
INT y
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetRenderingOrigin);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->SetRenderingOrigin(x, y);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetRenderingOrigin(
|
|
GpGraphics *graphics,
|
|
INT *x,
|
|
INT *y
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetRenderingOrigin);
|
|
CheckParameter(x);
|
|
CheckParameter(y);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetRenderingOrigin(x, y);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCompositingMode(
|
|
GpGraphics* graphics,
|
|
CompositingMode newMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetCompositingMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->SetCompositingMode(newMode);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCompositingMode(
|
|
GpGraphics *graphics,
|
|
CompositingMode *mode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCompositingMode);
|
|
CheckParameter(mode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*mode = graphics->GetCompositingMode();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetCompositingQuality(
|
|
GpGraphics* graphics,
|
|
CompositingQuality newQuality
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetCompositingQuality);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->SetCompositingQuality(newQuality);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCompositingQuality(
|
|
GpGraphics *graphics,
|
|
CompositingQuality *quality
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetCompositingQuality);
|
|
CheckParameter(quality);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*quality = graphics->GetCompositingQuality();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetSmoothingMode(
|
|
GpGraphics* graphics,
|
|
SmoothingMode smoothingMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetSmoothingMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
// For now, have it so that a Rendering hint of 1
|
|
// means antialiasing ON and a Rendering Hint of 0
|
|
// means Off.
|
|
|
|
switch(smoothingMode)
|
|
{
|
|
case SmoothingModeDefault:
|
|
case SmoothingModeHighSpeed:
|
|
case SmoothingModeNone:
|
|
graphics->SetAntiAliasMode(FALSE);
|
|
break;
|
|
|
|
case SmoothingModeHighQuality:
|
|
case SmoothingModeAntiAlias:
|
|
graphics->SetAntiAliasMode(TRUE);
|
|
break;
|
|
|
|
default:
|
|
// unknown rendering mode
|
|
return InvalidParameter;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetSmoothingMode(
|
|
GpGraphics *graphics,
|
|
SmoothingMode *smoothingMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetSmoothingMode);
|
|
CheckParameter(smoothingMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
BOOL aaOn = graphics->GetAntiAliasMode();
|
|
|
|
if (aaOn)
|
|
{
|
|
*smoothingMode = SmoothingModeAntiAlias;
|
|
}
|
|
else
|
|
{
|
|
*smoothingMode = SmoothingModeNone;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPixelOffsetMode(
|
|
GpGraphics* graphics,
|
|
PixelOffsetMode newMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPixelOffsetMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter((newMode >= PixelOffsetModeDefault) &&
|
|
(newMode <= PixelOffsetModeHalf));
|
|
|
|
graphics->SetPixelOffsetMode(newMode);
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPixelOffsetMode(
|
|
GpGraphics *graphics,
|
|
PixelOffsetMode *pixelOffsetMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPixelOffsetMode);
|
|
CheckParameter(pixelOffsetMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*pixelOffsetMode = graphics->GetPixelOffsetMode();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetTextRenderingHint(
|
|
GpGraphics* graphics,
|
|
TextRenderingHint newMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetTextRenderingHint);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
// For now, have it so that a Rendering hint of 1
|
|
// means antialiasing ON and a Rendering Hint of 0
|
|
// means Off.
|
|
|
|
switch(newMode)
|
|
{
|
|
case TextRenderingHintSystemDefault:
|
|
case TextRenderingHintSingleBitPerPixelGridFit:
|
|
case TextRenderingHintSingleBitPerPixel:
|
|
case TextRenderingHintAntiAlias:
|
|
case TextRenderingHintAntiAliasGridFit:
|
|
case TextRenderingHintClearTypeGridFit:
|
|
graphics->SetTextRenderingHint(newMode);
|
|
break;
|
|
|
|
default:
|
|
// unknown rendering mode
|
|
return InvalidParameter;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetTextContrast(
|
|
GpGraphics* graphics,
|
|
UINT contrast
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetTextContrast);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->SetTextContrast(contrast);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetTextContrast(
|
|
GpGraphics* graphics,
|
|
UINT * contrast
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetTextContrast);
|
|
CheckParameter(contrast);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*contrast = graphics->GetTextContrast();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetTextRenderingHint(
|
|
GpGraphics *graphics,
|
|
TextRenderingHint *mode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetTextRenderingHint);
|
|
CheckParameter(mode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*mode = graphics->GetTextRenderingHint();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetInterpolationMode(
|
|
GpGraphics* graphics,
|
|
InterpolationMode interpolationMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetInterpolationMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter((interpolationMode >= InterpolationModeDefault) &&
|
|
(interpolationMode <= InterpolationModeHighQualityBicubic));
|
|
|
|
if(Globals::ForceBilinear)
|
|
{
|
|
if(interpolationMode != InterpolationModeNearestNeighbor)
|
|
{
|
|
interpolationMode = InterpolationModeBilinear;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(interpolationMode == InterpolationModeDefault ||
|
|
interpolationMode == InterpolationModeLowQuality)
|
|
{
|
|
interpolationMode = InterpolationModeBilinear;
|
|
}
|
|
else if(interpolationMode == InterpolationModeHighQuality)
|
|
{
|
|
interpolationMode = InterpolationModeHighQualityBicubic;
|
|
}
|
|
}
|
|
|
|
graphics->SetInterpolationMode(interpolationMode);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetInterpolationMode(
|
|
GpGraphics* graphics,
|
|
InterpolationMode *interpolationMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetInterpolationMode);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*interpolationMode = graphics->GetInterpolationMode();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetWorldTransform(
|
|
GpGraphics *graphics,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetWorldTransform);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
|
|
return graphics->SetWorldTransform(*matrix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetWorldTransform(
|
|
GpGraphics *graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipResetWorldTransform);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->ResetWorldTransform();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMultiplyWorldTransform(
|
|
GpGraphics *graphics,
|
|
GDIPCONST GpMatrix *matrix,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipMultiplyWorldTransform);
|
|
if(matrix == NULL)
|
|
return Ok;
|
|
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return graphics->MultiplyWorldTransform(*matrix, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateWorldTransform(
|
|
GpGraphics *graphics,
|
|
REAL dx,
|
|
REAL dy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateWorldTransform);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return graphics->TranslateWorldTransform(dx, dy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipScaleWorldTransform(
|
|
GpGraphics *graphics,
|
|
REAL sx,
|
|
REAL sy,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipScaleWorldTransform);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return graphics->ScaleWorldTransform(sx, sy, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRotateWorldTransform(
|
|
GpGraphics *graphics,
|
|
REAL angle,
|
|
GpMatrixOrder order
|
|
)
|
|
{
|
|
API_ENTRY(GdipRotateWorldTransform);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter(MatrixOrderIsValid(order));
|
|
|
|
return graphics->RotateWorldTransform(angle, order);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetWorldTransform(
|
|
GpGraphics *graphics,
|
|
GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetWorldTransform);
|
|
CheckParameter(matrix);
|
|
CheckObjectBusy(matrix);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetWorldTransform(*matrix);
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetPageTransform(
|
|
GpGraphics *graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipResetPageTransform);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->ResetPageTransform();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPageUnit(
|
|
GpGraphics* graphics,
|
|
GpPageUnit* unit
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPageUnit);
|
|
CheckParameter(unit);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*unit = graphics->GetPageUnit();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPageUnit(
|
|
GpGraphics* graphics,
|
|
GpPageUnit unit
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPageUnit);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
// PageUnit can't be world
|
|
CheckParameter((unit > UnitWorld) && (unit <= UnitMillimeter));
|
|
|
|
return graphics->SetPageUnit(unit);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetPageScale(
|
|
GpGraphics* graphics,
|
|
REAL* scale
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetPageScale);
|
|
CheckParameter(scale);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*scale = graphics->GetPageScale();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetPageScale(
|
|
GpGraphics* graphics,
|
|
REAL scale
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetPageScale);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->SetPageScale(scale);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetDpiX(
|
|
GpGraphics* graphics,
|
|
REAL* dpi
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetDpiX);
|
|
CheckParameter(dpi);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*dpi = graphics->GetDpiX();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetDpiY(
|
|
GpGraphics* graphics,
|
|
REAL* dpi
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetDpiY);
|
|
CheckParameter(dpi);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*dpi = graphics->GetDpiY();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTransformPoints(
|
|
GpGraphics *graphics,
|
|
GpCoordinateSpace destSpace,
|
|
GpCoordinateSpace srcSpace,
|
|
GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipTransformPoints);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->TransformPoints(points, count, srcSpace, destSpace);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTransformPointsI(
|
|
GpGraphics *graphics,
|
|
GpCoordinateSpace destSpace,
|
|
GpCoordinateSpace srcSpace,
|
|
GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipTransformPointsI);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
INT i;
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = graphics->TransformPoints(pointsF, count, srcSpace, destSpace);
|
|
|
|
for (i=0; i<count; i++)
|
|
{
|
|
points[i].X = GpRound(pointsF[i].X);
|
|
points[i].Y = GpRound(pointsF[i].Y);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
// GetNearestColor (for <= 8bpp surfaces)
|
|
//------------------------------------------------------------------------
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetNearestColor(
|
|
GpGraphics *graphics,
|
|
ARGB *argb
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetNearestColor);
|
|
CheckParameter(argb);
|
|
CheckColorParameter(*argb);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
ARGB temp = graphics->GetNearestColor(*argb);
|
|
*argb = temp;
|
|
return Ok;
|
|
}
|
|
|
|
// defined in Engine\render\Halftone.cpp
|
|
extern HPALETTE WINGDIPAPI GdipCreateHalftonePalette();
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawLine(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
REAL x1,
|
|
REAL y1,
|
|
REAL x2,
|
|
REAL y2
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawLine);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawLine(pen, x1, y1, x2, y2);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawLineI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
INT x1,
|
|
INT y1,
|
|
INT x2,
|
|
INT y2
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawLineI);
|
|
return GdipDrawLine(graphics, pen, TOREAL(x1), TOREAL(y1), TOREAL(x2), TOREAL(y2));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawLines(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawLines);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawLines(pen, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawLinesI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawLinesI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawLines(graphics, pen, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawArc(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawArc);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawArc(pen, x, y, width, height, startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawArcI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawArcI);
|
|
return GdipDrawArc(graphics, pen, TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height), startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawBezier(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
REAL x1,
|
|
REAL y1,
|
|
REAL x2,
|
|
REAL y2,
|
|
REAL x3,
|
|
REAL y3,
|
|
REAL x4,
|
|
REAL y4
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawBezier);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawBezier(pen, x1, y1, x2, y2, x3, y3, x4, y4);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawBezierI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
INT x1,
|
|
INT y1,
|
|
INT x2,
|
|
INT y2,
|
|
INT x3,
|
|
INT y3,
|
|
INT x4,
|
|
INT y4
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawBezierI);
|
|
return GdipDrawBezier(graphics, pen, TOREAL(x1), TOREAL(y1),
|
|
TOREAL(x2), TOREAL(y2), TOREAL(x3), TOREAL(y3),
|
|
TOREAL(x4), TOREAL(y4));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawBeziers(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawBeziers);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawBeziers(pen, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawBeziersI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawBeziersI);
|
|
|
|
// Must check these parameters because we use them before calling into
|
|
// GdipDrawBeziers
|
|
|
|
CheckParameter(points && count > 0);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF* pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawBeziers(graphics, pen, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawRectangle(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height)
|
|
{
|
|
API_ENTRY(GdipDrawRectangle);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawRect(pen, x, y, width, height);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawRectangleI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height)
|
|
{
|
|
API_ENTRY(GdipDrawRectangleI);
|
|
return GdipDrawRectangle(graphics, pen,
|
|
TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawRectangles(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpRectF *rects,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawRectangles);
|
|
CheckParameter(rects && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawRects(pen, rects, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawRectanglesI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpRect *rects,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawRectanglesI);
|
|
CheckParameter(rects && count > 0);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpRectF *rectsF = (GpRectF*) buffer.GetBuffer(count*sizeof(GpRectF));
|
|
|
|
if(!rectsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
rectsF[i].X = TOREAL(rects[i].X);
|
|
rectsF[i].Y = TOREAL(rects[i].Y);
|
|
rectsF[i].Width = TOREAL(rects[i].Width);
|
|
rectsF[i].Height = TOREAL(rects[i].Height);
|
|
}
|
|
|
|
GpStatus status = GdipDrawRectangles(graphics, pen, rectsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawEllipse(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawEllipse);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawEllipse(pen, x, y, width, height);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawEllipseI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawEllipseI);
|
|
return GdipDrawEllipse(graphics, pen,
|
|
TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawPie(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawPie);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawPie(pen, x, y, width, height, startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawPieI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawPieI);
|
|
return GdipDrawPie(graphics, pen,
|
|
TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height),
|
|
startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawPolygon(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipDrawPolygon);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawPolygon(pen, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawPolygonI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipDrawPolygonI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawPolygon(graphics, pen, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawPath(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GpPath *path)
|
|
{
|
|
API_ENTRY(GdipDrawPath);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
|
|
return graphics->DrawPath(pen, path);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawCurve(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCurve);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawCurve(pen, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawCurveI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCurveI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawCurve(graphics, pen, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawCurve2(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCurve2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawCurve(pen, points, count, tension, 0, count - 1);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawCurve2I(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCurve2I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawCurve2(graphics, pen, pointsF, count, tension);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawCurve3(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
INT offset,
|
|
INT numberOfSegments,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCurve3);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawCurve(pen, points, count, tension,
|
|
offset, numberOfSegments);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawCurve3I(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
INT offset,
|
|
INT numberOfSegments,
|
|
REAL tension
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCurve3I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawCurve3(graphics, pen, pointsF, count,
|
|
offset, numberOfSegments, tension);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawClosedCurve(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipDrawClosedCurve);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawClosedCurve(pen, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawClosedCurveI(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipDrawClosedCurveI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawClosedCurve(graphics, pen, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawClosedCurve2(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL tension)
|
|
{
|
|
API_ENTRY(GdipDrawClosedCurve2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(pen);
|
|
CheckObjectBusy(pen);
|
|
|
|
|
|
return graphics->DrawClosedCurve(pen, points, count, tension);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawClosedCurve2I(
|
|
GpGraphics *graphics,
|
|
GpPen *pen,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
REAL tension)
|
|
{
|
|
API_ENTRY(GdipDrawClosedCurve2I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawClosedCurve2(graphics, pen, pointsF, count, tension);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipGraphicsClear(
|
|
GpGraphics *graphics,
|
|
ARGB color)
|
|
{
|
|
API_ENTRY(GdipGraphicsClear);
|
|
CheckColorParameter(color);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->Clear(GpColor(color));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillRectangle(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height)
|
|
{
|
|
API_ENTRY(GdipFillRectangle);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillRect(fill, x, y, width, height);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillRectangleI(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height)
|
|
{
|
|
API_ENTRY(GdipFillRectangleI);
|
|
return GdipFillRectangle(graphics, fill, TOREAL(x), TOREAL(y), TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillRectangles(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpRectF *rects,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipFillRectangles);
|
|
CheckParameter(rects && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillRects(fill, rects, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillRectanglesI(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpRect *rects,
|
|
INT count)
|
|
{
|
|
API_ENTRY(GdipFillRectanglesI);
|
|
StackBuffer buffer;
|
|
|
|
GpRectF *rectsF = (GpRectF*) buffer.GetBuffer(count*sizeof(GpRectF));
|
|
|
|
if(!rectsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
rectsF[i].X = TOREAL(rects[i].X);
|
|
rectsF[i].Y = TOREAL(rects[i].Y);
|
|
rectsF[i].Width = TOREAL(rects[i].Width);
|
|
rectsF[i].Height = TOREAL(rects[i].Height);
|
|
}
|
|
|
|
GpStatus status = GdipFillRectangles(graphics, fill, rectsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPolygon(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
GpFillMode fillMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPolygon);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillPolygon(fill, points, count, fillMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPolygonI(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
GpFillMode fillMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPolygonI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipFillPolygon(graphics, fill, pointsF, count, fillMode);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPolygon2(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPolygon2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillPolygon(fill, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPolygon2I(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPolygon2I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipFillPolygon2(graphics, fill, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillEllipse(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillEllipse);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillEllipse(fill, x, y, width, height);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillEllipseI(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillEllipseI);
|
|
return GdipFillEllipse(graphics, fill, TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPie(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPie);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillPie(fill, x, y, width, height, startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPieI(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
REAL startAngle,
|
|
REAL sweepAngle
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPieI);
|
|
return GdipFillPie(graphics, fill, TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height), startAngle, sweepAngle);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillPath(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GpPath *path
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillPath);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
|
|
|
|
return graphics->FillPath(fill, path);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillClosedCurve(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillClosedCurve);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillClosedCurve(fill, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillClosedCurveI(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillClosedCurveI);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipFillClosedCurve(graphics, fill, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillClosedCurve2(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL tension,
|
|
GpFillMode fillMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillClosedCurve2);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
|
|
|
|
return graphics->FillClosedCurve(fill, points, count, tension, fillMode);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillClosedCurve2I(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
REAL tension,
|
|
GpFillMode fillMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillClosedCurve2I);
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipFillClosedCurve2(graphics, fill, pointsF, count, tension, fillMode);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipFillRegion(
|
|
GpGraphics *graphics,
|
|
GpBrush *fill,
|
|
GpRegion *region
|
|
)
|
|
{
|
|
API_ENTRY(GdipFillRegion);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(fill);
|
|
CheckObjectBusy(fill);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
|
|
|
|
return graphics->FillRegion(fill, region);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawString(
|
|
GpGraphics *graphics,
|
|
GDIPCONST WCHAR *string,
|
|
INT length,
|
|
GDIPCONST GpFont *font,
|
|
GDIPCONST RectF *layoutRect,
|
|
GDIPCONST GpStringFormat *stringFormat,
|
|
GDIPCONST GpBrush *brush
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawString);
|
|
CheckParameter(string && layoutRect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
if (EmptyString(string, length))
|
|
{
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
CheckOptionalParameterValid(stringFormat);
|
|
|
|
return graphics->DrawString(
|
|
string,
|
|
length,
|
|
font,
|
|
layoutRect,
|
|
stringFormat,
|
|
brush);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMeasureString(
|
|
GpGraphics *graphics,
|
|
GDIPCONST WCHAR *string,
|
|
INT length,
|
|
GDIPCONST GpFont *font,
|
|
GDIPCONST RectF *layoutRect,
|
|
GDIPCONST GpStringFormat *stringFormat,
|
|
RectF *boundingBox,
|
|
INT *codepointsFitted, // Optional parameter
|
|
INT *linesFilled // Optional parameter
|
|
)
|
|
{
|
|
API_ENTRY(GdipMeasureString);
|
|
CheckParameter(string && layoutRect && boundingBox);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
if (EmptyString(string, length))
|
|
{
|
|
SetEmptyRectF(boundingBox);
|
|
if (codepointsFitted)
|
|
*codepointsFitted = 0;
|
|
if (linesFilled)
|
|
*linesFilled = 0;
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
CheckOptionalParameterValid(stringFormat);
|
|
|
|
return graphics->MeasureString(
|
|
string,
|
|
length,
|
|
font,
|
|
layoutRect,
|
|
stringFormat,
|
|
boundingBox,
|
|
codepointsFitted,
|
|
linesFilled
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMeasureCharacterRanges(
|
|
GpGraphics *graphics,
|
|
GDIPCONST WCHAR *string,
|
|
INT length,
|
|
GDIPCONST GpFont *font,
|
|
GDIPCONST RectF &layoutRect,
|
|
GDIPCONST GpStringFormat *stringFormat,
|
|
INT regionCount,
|
|
GpRegion **regions
|
|
)
|
|
{
|
|
API_ENTRY(GdipMeasureCharacterRanges);
|
|
CheckParameter(string && (&layoutRect));
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(font);
|
|
CheckOptionalParameterValid(stringFormat);
|
|
CheckParameter(regions);
|
|
|
|
if (EmptyString(string, length))
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
GpStatus status = graphics->MeasureCharacterRanges(
|
|
string,
|
|
length,
|
|
font,
|
|
layoutRect,
|
|
stringFormat,
|
|
regionCount,
|
|
regions
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawDriverString(
|
|
GpGraphics *graphics,
|
|
GDIPCONST UINT16 *text,
|
|
INT length,
|
|
GDIPCONST GpFont *font,
|
|
GDIPCONST GpBrush *brush,
|
|
GDIPCONST PointF *positions,
|
|
INT flags,
|
|
GDIPCONST GpMatrix *matrix
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawDriverString);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(matrix);
|
|
CheckParameterValid(brush);
|
|
CheckObjectBusy(brush);
|
|
|
|
CheckParameter(text && positions);
|
|
|
|
if (length == -1 && !(flags & DriverStringOptionsCmapLookup))
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
if (EmptyString(text, length))
|
|
{
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
|
|
return graphics->DrawDriverString(
|
|
text,
|
|
length,
|
|
font,
|
|
brush,
|
|
positions,
|
|
flags,
|
|
matrix
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMeasureDriverString(
|
|
GpGraphics *graphics,
|
|
GDIPCONST UINT16 *text,
|
|
INT length,
|
|
GDIPCONST GpFont *font,
|
|
GDIPCONST PointF *positions,
|
|
INT flags,
|
|
GDIPCONST GpMatrix *matrix,
|
|
RectF *boundingBox
|
|
)
|
|
{
|
|
API_ENTRY(GdipMeasureDriverString);
|
|
GpStatus status;
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckOptionalParameterValid(matrix);
|
|
CheckOptionalObjectBusy(matrix);
|
|
|
|
CheckParameter(text && positions && boundingBox);
|
|
|
|
if (length == -1 && !(flags & DriverStringOptionsCmapLookup))
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
if (EmptyString(text, length))
|
|
{
|
|
SetEmptyRectF(boundingBox);
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
|
|
return graphics->MeasureDriverString(
|
|
text,
|
|
length,
|
|
font,
|
|
positions,
|
|
flags,
|
|
matrix,
|
|
boundingBox
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFamilyName(
|
|
GDIPCONST GpFontFamily *family,
|
|
WCHAR name[LF_FACESIZE],
|
|
LANGID language
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetFamilyName);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
|
|
return family->GetFamilyName(name, language);
|
|
}
|
|
|
|
/// end font/text stuff - move to end
|
|
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImage(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
REAL x,
|
|
REAL y
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImage);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
|
|
return graphics->DrawImage(image, x, y);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImageI(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
INT x,
|
|
INT y
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImageI);
|
|
return GdipDrawImage(graphics, image, TOREAL(x), TOREAL(y));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImageRect(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImageRect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
|
|
return graphics->DrawImage(image, x, y, width, height);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImageRectI(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImageRectI);
|
|
return GdipDrawImageRect(graphics, image, TOREAL(x), TOREAL(y), TOREAL(width), TOREAL(height));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImagePoints(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
GDIPCONST GpPointF *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImagePoints);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
|
|
|
|
return graphics->DrawImage(image, points, count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImagePointsI(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
GDIPCONST GpPoint *points,
|
|
INT count
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImagePointsI);
|
|
CheckParameter(points && count > 0);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawImagePoints(graphics, image, pointsF, count);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImagePointRect(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
REAL x,
|
|
REAL y,
|
|
REAL srcx,
|
|
REAL srcy,
|
|
REAL srcwidth,
|
|
REAL srcheight,
|
|
GpPageUnit srcUnit
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImagePointRect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
CheckParameter(SrcUnitIsValid((Unit)srcUnit));
|
|
|
|
// This additional check is required because we don't support the other
|
|
// source units in drawimage yet. RAID 311474
|
|
|
|
if(UnitPixel != srcUnit)
|
|
{
|
|
return NotImplemented;
|
|
}
|
|
|
|
GpRectF srcRect(srcx, srcy, srcwidth, srcheight);
|
|
|
|
|
|
return graphics->DrawImage(image, x, y, srcRect, srcUnit);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImagePointRectI(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
INT x,
|
|
INT y,
|
|
INT srcx,
|
|
INT srcy,
|
|
INT srcwidth,
|
|
INT srcheight,
|
|
GpPageUnit srcUnit
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImagePointRectI);
|
|
return GdipDrawImagePointRect(graphics, image, TOREAL(x), TOREAL(y), TOREAL(srcx),
|
|
TOREAL(srcy), TOREAL(srcwidth), TOREAL(srcheight),
|
|
srcUnit);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImageRectRect(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
REAL dstx,
|
|
REAL dsty,
|
|
REAL dstwidth,
|
|
REAL dstheight,
|
|
REAL srcx,
|
|
REAL srcy,
|
|
REAL srcwidth,
|
|
REAL srcheight,
|
|
GpPageUnit srcUnit,
|
|
GDIPCONST GpImageAttributes* imageAttributes,
|
|
DrawImageAbort callback,
|
|
VOID * callbackData
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImageRectRect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
CheckParameter(SrcUnitIsValid((Unit)srcUnit));
|
|
|
|
// This additional check is required because we don't support the other
|
|
// source units in drawimage yet. RAID 311474
|
|
|
|
if(UnitPixel != srcUnit)
|
|
{
|
|
return NotImplemented;
|
|
}
|
|
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
GpRectF srcrect(srcx, srcy, srcwidth, srcheight);
|
|
GpRectF destrect(dstx, dsty, dstwidth, dstheight);
|
|
|
|
|
|
return graphics->DrawImage(image, destrect, srcrect, srcUnit,
|
|
imageAttributes, callback, callbackData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImageRectRectI(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
INT dstx,
|
|
INT dsty,
|
|
INT dstwidth,
|
|
INT dstheight,
|
|
INT srcx,
|
|
INT srcy,
|
|
INT srcwidth,
|
|
INT srcheight,
|
|
GpPageUnit srcUnit,
|
|
GDIPCONST GpImageAttributes* imageAttributes,
|
|
DrawImageAbort callback,
|
|
VOID * callbackData
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImageRectRectI);
|
|
return GdipDrawImageRectRect(graphics, image, TOREAL(dstx), TOREAL(dsty),
|
|
TOREAL(dstwidth), TOREAL(dstheight),
|
|
TOREAL(srcx), TOREAL(srcy), TOREAL(srcwidth),
|
|
TOREAL(srcheight), srcUnit,
|
|
imageAttributes, callback, callbackData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImagePointsRect(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
GDIPCONST GpPointF *points,
|
|
INT count,
|
|
REAL srcx,
|
|
REAL srcy,
|
|
REAL srcwidth,
|
|
REAL srcheight,
|
|
GpPageUnit srcUnit,
|
|
GDIPCONST GpImageAttributes* imageAttributes,
|
|
DrawImageAbort callback,
|
|
VOID * callbackData
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImagePointsRect);
|
|
CheckParameter(points && count > 0);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(image);
|
|
CheckObjectBusy(image);
|
|
CheckParameter(SrcUnitIsValid((Unit)srcUnit));
|
|
|
|
// This additional check is required because we don't support the other
|
|
// source units in drawimage yet. RAID 311474
|
|
|
|
if(UnitPixel != srcUnit)
|
|
{
|
|
return NotImplemented;
|
|
}
|
|
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
GpRectF srcrect(srcx, srcy, srcwidth, srcheight);
|
|
|
|
|
|
return graphics->DrawImage(image, points, count, srcrect, srcUnit,
|
|
imageAttributes, callback, callbackData);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDrawImagePointsRectI(
|
|
GpGraphics *graphics,
|
|
GpImage *image,
|
|
GDIPCONST GpPoint *points,
|
|
INT count,
|
|
INT srcx,
|
|
INT srcy,
|
|
INT srcwidth,
|
|
INT srcheight,
|
|
GpPageUnit srcUnit,
|
|
GDIPCONST GpImageAttributes* imageAttributes,
|
|
DrawImageAbort callback,
|
|
VOID * callbackData
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawImagePointsRectI);
|
|
CheckParameter(points && count > 0);
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *pointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!pointsF) return OutOfMemory;
|
|
|
|
for (INT i=0; i<count; i++)
|
|
{
|
|
pointsF[i].X = TOREAL(points[i].X);
|
|
pointsF[i].Y = TOREAL(points[i].Y);
|
|
}
|
|
|
|
GpStatus status = GdipDrawImagePointsRect(
|
|
graphics,
|
|
image,
|
|
pointsF,
|
|
count,
|
|
TOREAL(srcx),
|
|
TOREAL(srcy),
|
|
TOREAL(srcwidth),
|
|
TOREAL(srcheight),
|
|
srcUnit,
|
|
imageAttributes,
|
|
callback,
|
|
callbackData
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileDestPoint(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST PointF & destPoint,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileDestPoint);
|
|
CheckParameter(callback);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
metafile->SetThreadId(GetCurrentThreadId());
|
|
return graphics->EnumerateMetafile(
|
|
metafile,
|
|
destPoint,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
metafile->SetThreadId(0);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileDestPointI(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST Point & destPoint,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileDestPointI);
|
|
GpPointF destPointF(TOREAL(destPoint.X), TOREAL(destPoint.Y));
|
|
|
|
return GdipEnumerateMetafileDestPoint(
|
|
graphics,
|
|
metafile,
|
|
destPointF,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileDestRect(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST RectF & destRect,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileDestRect);
|
|
CheckParameter(callback);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
metafile->SetThreadId(GetCurrentThreadId());
|
|
return graphics->EnumerateMetafile(
|
|
metafile,
|
|
destRect,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
metafile->SetThreadId(0);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileDestRectI(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST Rect & destRect,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileDestRectI);
|
|
GpRectF destRectF(TOREAL(destRect.X), TOREAL(destRect.Y),
|
|
TOREAL(destRect.Width), TOREAL(destRect.Height));
|
|
|
|
return GdipEnumerateMetafileDestRect(
|
|
graphics,
|
|
metafile,
|
|
destRectF,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileDestPoints(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST PointF * destPoints,
|
|
INT count,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileDestPoints);
|
|
CheckParameter(callback);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
metafile->SetThreadId(GetCurrentThreadId());
|
|
return graphics->EnumerateMetafile(
|
|
metafile,
|
|
destPoints,
|
|
count,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
metafile->SetThreadId(0);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileDestPointsI(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST Point * destPoints,
|
|
INT count,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileDestPointsI);
|
|
CheckParameter(destPoints && (count > 0));
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *destPointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!destPointsF) return OutOfMemory;
|
|
|
|
for (INT i = 0; i < count; i++)
|
|
{
|
|
destPointsF[i].X = TOREAL(destPoints[i].X);
|
|
destPointsF[i].Y = TOREAL(destPoints[i].Y);
|
|
}
|
|
|
|
return GdipEnumerateMetafileDestPoints(
|
|
graphics,
|
|
metafile,
|
|
destPointsF,
|
|
count,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileSrcRectDestPoint(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST PointF & destPoint,
|
|
GDIPCONST RectF & srcRect,
|
|
Unit srcUnit,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileSrcRectDestPoint);
|
|
CheckParameter(callback);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckParameter(SrcUnitIsValid((Unit)srcUnit));
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
metafile->SetThreadId(GetCurrentThreadId());
|
|
return graphics->EnumerateMetafile(
|
|
metafile,
|
|
destPoint,
|
|
srcRect,
|
|
srcUnit,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
metafile->SetThreadId(0);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileSrcRectDestPointI(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST Point & destPoint,
|
|
GDIPCONST Rect & srcRect,
|
|
Unit srcUnit,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileSrcRectDestPointI);
|
|
GpPointF destPointF(TOREAL(destPoint.X), TOREAL(destPoint.Y));
|
|
GpRectF srcRectF(TOREAL(srcRect.X), TOREAL(srcRect.Y),
|
|
TOREAL(srcRect.Width), TOREAL(srcRect.Height));
|
|
|
|
return GdipEnumerateMetafileSrcRectDestPoint(
|
|
graphics,
|
|
metafile,
|
|
destPointF,
|
|
srcRectF,
|
|
srcUnit,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileSrcRectDestRect(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST RectF & destRect,
|
|
GDIPCONST RectF & srcRect,
|
|
Unit srcUnit,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileSrcRectDestRect);
|
|
CheckParameter(callback);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckParameter(SrcUnitIsValid((Unit)srcUnit));
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
metafile->SetThreadId(GetCurrentThreadId());
|
|
return graphics->EnumerateMetafile(
|
|
metafile,
|
|
destRect,
|
|
srcRect,
|
|
srcUnit,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
metafile->SetThreadId(0);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileSrcRectDestRectI(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST Rect & destRect,
|
|
GDIPCONST Rect & srcRect,
|
|
Unit srcUnit,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileSrcRectDestRectI);
|
|
GpRectF destRectF(TOREAL(destRect.X), TOREAL(destRect.Y),
|
|
TOREAL(destRect.Width), TOREAL(destRect.Height));
|
|
GpRectF srcRectF(TOREAL(srcRect.X), TOREAL(srcRect.Y),
|
|
TOREAL(srcRect.Width), TOREAL(srcRect.Height));
|
|
|
|
return GdipEnumerateMetafileSrcRectDestRect(
|
|
graphics,
|
|
metafile,
|
|
destRectF,
|
|
srcRectF,
|
|
srcUnit,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileSrcRectDestPoints(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST PointF * destPoints,
|
|
INT count,
|
|
GDIPCONST RectF & srcRect,
|
|
Unit srcUnit,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileSrcRectDestPoints);
|
|
CheckParameter(callback);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckParameter(SrcUnitIsValid((Unit)srcUnit));
|
|
CheckOptionalParameterValid(imageAttributes);
|
|
CheckOptionalObjectBusy(imageAttributes);
|
|
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
metafile->SetThreadId(GetCurrentThreadId());
|
|
return graphics->EnumerateMetafile(
|
|
metafile,
|
|
destPoints,
|
|
count,
|
|
srcRect,
|
|
srcUnit,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
metafile->SetThreadId(0);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipEnumerateMetafileSrcRectDestPointsI(
|
|
GpGraphics * graphics,
|
|
GDIPCONST GpMetafile * metafile,
|
|
GDIPCONST Point * destPoints,
|
|
INT count,
|
|
GDIPCONST Rect & srcRect,
|
|
Unit srcUnit,
|
|
EnumerateMetafileProc callback,
|
|
VOID * callbackData,
|
|
GDIPCONST GpImageAttributes * imageAttributes
|
|
)
|
|
{
|
|
API_ENTRY(GdipEnumerateMetafileSrcRectDestPointsI);
|
|
CheckParameter(destPoints && (count > 0));
|
|
|
|
GpRectF srcRectF(TOREAL(srcRect.X), TOREAL(srcRect.Y),
|
|
TOREAL(srcRect.Width), TOREAL(srcRect.Height));
|
|
|
|
StackBuffer buffer;
|
|
|
|
GpPointF *destPointsF = (GpPointF*) buffer.GetBuffer(count*sizeof(GpPointF));
|
|
|
|
if(!destPointsF) return OutOfMemory;
|
|
|
|
for (INT i = 0; i < count; i++)
|
|
{
|
|
destPointsF[i].X = TOREAL(destPoints[i].X);
|
|
destPointsF[i].Y = TOREAL(destPoints[i].Y);
|
|
}
|
|
|
|
return GdipEnumerateMetafileSrcRectDestPoints(
|
|
graphics,
|
|
metafile,
|
|
destPointsF,
|
|
count,
|
|
srcRectF,
|
|
srcUnit,
|
|
callback,
|
|
callbackData,
|
|
imageAttributes
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipPlayMetafileRecord(
|
|
GDIPCONST GpMetafile * metafile,
|
|
EmfPlusRecordType recordType,
|
|
UINT flags,
|
|
UINT dataSize,
|
|
GDIPCONST BYTE * data
|
|
)
|
|
{
|
|
API_ENTRY(GdipPlayMetafileRecord);
|
|
CheckParameterValid(metafile);
|
|
CheckParameter(recordType);
|
|
|
|
// The metafile must be already locked by the enumerator
|
|
GpLock lockMetafile (metafile->GetObjectLock());
|
|
if (lockMetafile.IsValid())
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
// Only the current thread can play back records from this enumeration
|
|
if (GetCurrentThreadId() != metafile->GetThreadId())
|
|
{
|
|
return ObjectBusy;
|
|
}
|
|
|
|
|
|
return metafile->PlayRecord(recordType, flags, dataSize, data);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetClipGraphics(
|
|
GpGraphics * graphics,
|
|
GpGraphics * srcgraphics,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetClipGraphics);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(srcgraphics);
|
|
CheckObjectBusy(srcgraphics);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
|
|
return graphics->SetClip(srcgraphics, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetClipRect(
|
|
GpGraphics * graphics,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetClipRect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
|
|
|
|
return graphics->SetClip(rect, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetClipRectI(
|
|
GpGraphics * graphics,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetClipRectI);
|
|
return GdipSetClipRect(graphics, TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height), combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetClipPath(
|
|
GpGraphics * graphics,
|
|
GpPath * path,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetClipPath);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(path);
|
|
CheckObjectBusy(path);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
|
|
return graphics->SetClip(path, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetClipRegion(
|
|
GpGraphics * graphics,
|
|
GpRegion * region,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetClipRegion);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
|
|
return graphics->SetClip(region, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetClipHrgn(
|
|
GpGraphics * graphics,
|
|
HRGN hRgn,
|
|
CombineMode combineMode
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetClipHrgn);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter(hRgn && (GetObjectTypeInternal(hRgn) == OBJ_REGION));
|
|
CheckParameter(CombineModeIsValid(combineMode));
|
|
|
|
|
|
return graphics->SetClip(hRgn, combineMode);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipResetClip(
|
|
GpGraphics *graphics
|
|
)
|
|
{
|
|
API_ENTRY(GdipResetClip);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->ResetClip();
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateClip(
|
|
GpGraphics *graphics,
|
|
REAL dx,
|
|
REAL dy
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateClip);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
return graphics->OffsetClip(dx, dy);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTranslateClipI(
|
|
GpGraphics *graphics,
|
|
INT dx,
|
|
INT dy
|
|
)
|
|
{
|
|
API_ENTRY(GdipTranslateClipI);
|
|
return GdipTranslateClip(graphics, TOREAL(dx), TOREAL(dy));
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetClip(
|
|
GpGraphics *graphics,
|
|
GpRegion *region
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetClip);
|
|
CheckParameter(region);
|
|
CheckObjectBusy(region);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->GetClip(region);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetClipBounds(
|
|
GpGraphics *graphics,
|
|
GpRectF *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetClipBounds);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetClipBounds(*rect);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetClipBoundsI(
|
|
GpGraphics *graphics,
|
|
GpRect *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetClipBoundsI);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
RectF rectf;
|
|
|
|
graphics->GetClipBounds(rectf);
|
|
|
|
rect->X = GpRound(rectf.X);
|
|
rect->Y = GpRound(rectf.Y);
|
|
rect->Width = GpRound(rectf.Width);
|
|
rect->Height = GpRound(rectf.Height);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsClipEmpty(
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsClipEmpty);
|
|
CheckParameter(result);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*result = graphics->IsClipEmpty();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetVisibleClipBounds(
|
|
GpGraphics *graphics,
|
|
GpRectF *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetVisibleClipBounds);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->GetVisibleClipBounds(*rect);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetVisibleClipBoundsI(
|
|
GpGraphics *graphics,
|
|
GpRect *rect
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetVisibleClipBoundsI);
|
|
CheckParameter(rect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
RectF rectf;
|
|
|
|
graphics->GetVisibleClipBounds(rectf);
|
|
|
|
rect->X = GpRound(rectf.X);
|
|
rect->Y = GpRound(rectf.Y);
|
|
rect->Width = GpRound(rectf.Width);
|
|
rect->Height = GpRound(rectf.Height);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleClipEmpty(
|
|
GpGraphics *graphics,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleClipEmpty);
|
|
CheckParameter(result);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*result = graphics->IsVisibleClipEmpty();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisiblePoint(
|
|
GpGraphics *graphics,
|
|
REAL x,
|
|
REAL y,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisiblePoint);
|
|
CheckParameter(result);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
GpPointF pt(x,y);
|
|
|
|
|
|
*result = graphics->IsVisible(pt);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisiblePointI(
|
|
GpGraphics *graphics,
|
|
INT x,
|
|
INT y,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisiblePointI);
|
|
return GdipIsVisiblePoint(graphics, TOREAL(x), TOREAL(y), result);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleRect(
|
|
GpGraphics *graphics,
|
|
REAL x,
|
|
REAL y,
|
|
REAL width,
|
|
REAL height,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleRect);
|
|
CheckParameter(result);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
GpRectF rect(x, y, width, height);
|
|
|
|
|
|
*result = graphics->IsVisible(rect);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsVisibleRectI(
|
|
GpGraphics *graphics,
|
|
INT x,
|
|
INT y,
|
|
INT width,
|
|
INT height,
|
|
BOOL *result
|
|
)
|
|
{
|
|
API_ENTRY(GdipIsVisibleRectI);
|
|
return GdipIsVisibleRect(graphics, TOREAL(x), TOREAL(y),
|
|
TOREAL(width), TOREAL(height), result);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSaveGraphics(
|
|
GpGraphics *graphics,
|
|
GraphicsState *state
|
|
)
|
|
{
|
|
API_ENTRY(GdipSaveGraphics);
|
|
CheckParameter(state);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
*state = (GraphicsState)graphics->Save();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRestoreGraphics(
|
|
GpGraphics *graphics,
|
|
GraphicsState state
|
|
)
|
|
{
|
|
API_ENTRY(GdipRestoreGraphics);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->Restore((INT)state);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBeginContainer(
|
|
GpGraphics *graphics,
|
|
GDIPCONST GpRectF *dstrect,
|
|
GDIPCONST GpRectF *srcrect,
|
|
GpPageUnit unit,
|
|
GraphicsContainer *state
|
|
)
|
|
{
|
|
API_ENTRY(GdipBeginContainer);
|
|
CheckParameter(state && dstrect && srcrect);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameter(SrcUnitIsValid((Unit)unit));
|
|
|
|
|
|
*state = (GraphicsContainer)graphics->BeginContainer(*dstrect, *srcrect, unit);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBeginContainer2(
|
|
GpGraphics *graphics,
|
|
GraphicsContainer *state
|
|
)
|
|
{
|
|
API_ENTRY(GdipBeginContainer2);
|
|
CheckParameter(state);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
*state = (GraphicsContainer)graphics->BeginContainer();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipBeginContainerI(
|
|
GpGraphics *graphics,
|
|
GDIPCONST GpRect *dstrect,
|
|
GDIPCONST GpRect *srcrect,
|
|
GpPageUnit unit,
|
|
GraphicsContainer *state
|
|
)
|
|
{
|
|
API_ENTRY(GdipBeginContainerI);
|
|
GpRectF dstrectF(TOREAL(dstrect->X), TOREAL(dstrect->Y), TOREAL(dstrect->Width), TOREAL(dstrect->Height));
|
|
GpRectF srcrectF(TOREAL(srcrect->X), TOREAL(srcrect->Y), TOREAL(srcrect->Width), TOREAL(srcrect->Height));
|
|
|
|
return GdipBeginContainer(graphics, &dstrectF, &srcrectF, unit, state);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipEndContainer(
|
|
GpGraphics *graphics,
|
|
GraphicsContainer state
|
|
)
|
|
{
|
|
API_ENTRY(GdipEndContainer);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
graphics->EndContainer((INT)state);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetMetafileHeaderFromWmf(
|
|
HMETAFILE hWmf,
|
|
GDIPCONST WmfPlaceableFileHeader * wmfPlaceableFileHeader,
|
|
MetafileHeader * header
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMetafileHeaderFromWmf);
|
|
CheckParameter(hWmf && wmfPlaceableFileHeader);
|
|
|
|
|
|
return GetMetafileHeader(hWmf, wmfPlaceableFileHeader, *header);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetMetafileHeaderFromEmf(
|
|
HENHMETAFILE hEmf,
|
|
MetafileHeader * header
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMetafileHeaderFromEmf);
|
|
CheckParameter(hEmf);
|
|
|
|
|
|
return GetMetafileHeader(hEmf, *header);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetMetafileHeaderFromFile(
|
|
GDIPCONST WCHAR* filename,
|
|
MetafileHeader * header
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMetafileHeaderFromFile);
|
|
CheckParameter(filename);
|
|
|
|
|
|
return GetMetafileHeader(filename, *header);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetMetafileHeaderFromStream(
|
|
IStream * stream,
|
|
MetafileHeader * header
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMetafileHeaderFromStream);
|
|
CheckParameter(stream);
|
|
|
|
|
|
return GetMetafileHeader(stream, *header);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetMetafileHeaderFromMetafile(
|
|
GpMetafile * metafile,
|
|
MetafileHeader * header
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMetafileHeaderFromMetafile);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
|
|
|
|
metafile->GetHeader(*header);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetHemfFromMetafile(
|
|
GpMetafile * metafile,
|
|
HENHMETAFILE * hEmf
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetHemfFromMetafile);
|
|
CheckParameter(hEmf);
|
|
|
|
*hEmf = NULL; // init to NULL in case the metafile is busy or invalid (Windows bug 216941)
|
|
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
|
|
return metafile->GetHemf(hEmf);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateStreamOnFile(
|
|
GDIPCONST WCHAR * filename,
|
|
UINT access, // GENERIC_READ and/or GENERIC_WRITE
|
|
IStream ** stream
|
|
)
|
|
{
|
|
// We don't support this API anymore, simply return NotImplemented
|
|
/*
|
|
API_ENTRY(GdipCreateStreamOnFile);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(filename && stream);
|
|
CheckParameter((access & (GENERIC_READ | GENERIC_WRITE)) != 0);
|
|
|
|
if ((*stream = CreateStreamOnFile(filename, access)) != NULL)
|
|
{
|
|
return Ok;
|
|
}
|
|
return GenericError;
|
|
*/
|
|
return NotImplemented;
|
|
}
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMetafileFromWmf(
|
|
HMETAFILE hWmf,
|
|
BOOL deleteWmf,
|
|
GDIPCONST WmfPlaceableFileHeader * wmfPlaceableFileHeader, // can be NULL
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMetafileFromWmf);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(hWmf && metafile);
|
|
|
|
|
|
*metafile = new GpMetafile(hWmf, wmfPlaceableFileHeader, deleteWmf);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMetafileFromEmf(
|
|
HENHMETAFILE hEmf,
|
|
BOOL deleteEmf,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMetafileFromEmf);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(hEmf && metafile);
|
|
|
|
|
|
*metafile = new GpMetafile(hEmf, deleteEmf);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMetafileFromFile(
|
|
GDIPCONST WCHAR* filename,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMetafileFromFile);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(filename && metafile);
|
|
|
|
|
|
*metafile = new GpMetafile(filename);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMetafileFromWmfFile(
|
|
GDIPCONST WCHAR* filename,
|
|
GDIPCONST WmfPlaceableFileHeader * wmfPlaceableFileHeader, // can be NULL
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMetafileFromWmfFile);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(filename && metafile);
|
|
|
|
|
|
*metafile = new GpMetafile(filename, wmfPlaceableFileHeader);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateMetafileFromStream(
|
|
IStream * stream,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateMetafileFromStream);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(stream && metafile);
|
|
|
|
|
|
*metafile = new GpMetafile(stream);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRecordMetafile(
|
|
HDC referenceHdc,
|
|
EmfType type,
|
|
GDIPCONST GpRectF * frameRect,
|
|
MetafileFrameUnit frameUnit,
|
|
GDIPCONST WCHAR * description,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipRecordMetafile);
|
|
CheckParameter(referenceHdc && metafile);
|
|
CheckParameter(EmfTypeIsValid(type));
|
|
CheckParameter(MetafileFrameUnitIsValid(frameUnit));
|
|
|
|
|
|
*metafile = new GpMetafile(referenceHdc, type, frameRect, frameUnit, description);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRecordMetafileI(
|
|
HDC referenceHdc,
|
|
EmfType type,
|
|
GDIPCONST GpRect * frameRect,
|
|
MetafileFrameUnit frameUnit,
|
|
GDIPCONST WCHAR * description,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipRecordMetafileI);
|
|
CheckParameter(referenceHdc && frameRect);
|
|
CheckParameter(EmfTypeIsValid(type));
|
|
CheckParameter(MetafileFrameUnitIsValid(frameUnit));
|
|
|
|
GpRectF frameRectF(TOREAL(frameRect->X),
|
|
TOREAL(frameRect->Y),
|
|
TOREAL(frameRect->Width),
|
|
TOREAL(frameRect->Height));
|
|
|
|
return GdipRecordMetafile(referenceHdc,
|
|
type,
|
|
&frameRectF,
|
|
frameUnit,
|
|
description,
|
|
metafile);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRecordMetafileFileName(
|
|
GDIPCONST WCHAR* fileName,
|
|
HDC referenceHdc,
|
|
EmfType type,
|
|
GDIPCONST GpRectF * frameRect,
|
|
MetafileFrameUnit frameUnit,
|
|
GDIPCONST WCHAR * description,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipRecordMetafileFileName);
|
|
CheckParameter(fileName && referenceHdc && metafile);
|
|
CheckParameter(EmfTypeIsValid(type));
|
|
CheckParameter(MetafileFrameUnitIsValid(frameUnit));
|
|
|
|
|
|
*metafile = new GpMetafile(fileName, referenceHdc, type, frameRect, frameUnit, description);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRecordMetafileFileNameI(
|
|
GDIPCONST WCHAR* fileName,
|
|
HDC referenceHdc,
|
|
EmfType type,
|
|
GDIPCONST GpRect * frameRect,
|
|
MetafileFrameUnit frameUnit,
|
|
GDIPCONST WCHAR * description,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipRecordMetafileFileNameI);
|
|
CheckParameter(referenceHdc && frameRect);
|
|
CheckParameter(EmfTypeIsValid(type));
|
|
CheckParameter(MetafileFrameUnitIsValid(frameUnit));
|
|
|
|
GpRectF frameRectF(TOREAL(frameRect->X),
|
|
TOREAL(frameRect->Y),
|
|
TOREAL(frameRect->Width),
|
|
TOREAL(frameRect->Height));
|
|
|
|
return GdipRecordMetafileFileName(fileName,
|
|
referenceHdc,
|
|
type,
|
|
&frameRectF,
|
|
frameUnit,
|
|
description,
|
|
metafile);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRecordMetafileStream(
|
|
IStream * stream,
|
|
HDC referenceHdc,
|
|
EmfType type,
|
|
GDIPCONST GpRectF * frameRect,
|
|
MetafileFrameUnit frameUnit,
|
|
GDIPCONST WCHAR * description,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipRecordMetafileStream);
|
|
CheckParameter(stream && referenceHdc && metafile);
|
|
CheckParameter(EmfTypeIsValid(type));
|
|
CheckParameter(MetafileFrameUnitIsValid(frameUnit));
|
|
|
|
|
|
*metafile = new GpMetafile(stream, referenceHdc, type, frameRect, frameUnit, description);
|
|
|
|
if (*metafile)
|
|
{
|
|
if ((*metafile)->IsValid())
|
|
{
|
|
return Ok;
|
|
}
|
|
(*metafile)->Dispose();
|
|
*metafile = NULL;
|
|
}
|
|
return GenericError;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipRecordMetafileStreamI(
|
|
IStream * stream,
|
|
HDC referenceHdc,
|
|
EmfType type,
|
|
GDIPCONST GpRect * frameRect,
|
|
MetafileFrameUnit frameUnit,
|
|
GDIPCONST WCHAR * description,
|
|
GpMetafile ** metafile
|
|
)
|
|
{
|
|
API_ENTRY(GdipRecordMetafileStreamI);
|
|
CheckParameter(referenceHdc && frameRect);
|
|
CheckParameter(EmfTypeIsValid(type));
|
|
CheckParameter(MetafileFrameUnitIsValid(frameUnit));
|
|
|
|
GpRectF frameRectF(TOREAL(frameRect->X),
|
|
TOREAL(frameRect->Y),
|
|
TOREAL(frameRect->Width),
|
|
TOREAL(frameRect->Height));
|
|
|
|
return GdipRecordMetafileStream(stream,
|
|
referenceHdc,
|
|
type,
|
|
&frameRectF,
|
|
frameUnit,
|
|
description,
|
|
metafile);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetMetafileDownLevelRasterizationLimit(
|
|
GpMetafile * metafile,
|
|
UINT metafileRasterizationLimitDpi
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetMetafileDownLevelRasterizationLimit);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
|
|
// Since the rasterization limit is actually set in the graphics,
|
|
// we check if the graphics is busy too.
|
|
GpGraphics * g = metafile->PrivateAPIForGettingMetafileGraphicsContext();
|
|
CheckOptionalObjectBusy(g);
|
|
|
|
return metafile->SetDownLevelRasterizationLimit(metafileRasterizationLimitDpi);
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipGetMetafileDownLevelRasterizationLimit(
|
|
GDIPCONST GpMetafile * metafile,
|
|
UINT * metafileRasterizationLimitDpi
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetMetafileDownLevelRasterizationLimit);
|
|
CheckParameterValid(metafile);
|
|
CheckObjectBusy(metafile);
|
|
CheckParameter(metafileRasterizationLimitDpi);
|
|
|
|
// Since the rasterization limit is actually set in the graphics,
|
|
// we check if the graphics is busy too.
|
|
GpGraphics * g = metafile->PrivateAPIForGettingMetafileGraphicsContext();
|
|
CheckOptionalObjectBusy(g);
|
|
|
|
|
|
return metafile->GetDownLevelRasterizationLimit(metafileRasterizationLimitDpi);
|
|
}
|
|
|
|
// Codec management APIs
|
|
|
|
#define COPYCODECINFOSTR(_f) \
|
|
dst->_f = (GDIPCONST WCHAR*) buf; \
|
|
size = SizeofWSTR(cur->_f); \
|
|
memcpy(buf, cur->_f, size); \
|
|
buf += size
|
|
|
|
/**************************************************************************\
|
|
*
|
|
* Function Description:
|
|
*
|
|
* Returns, via the OUT arguments, the number of installed decoders
|
|
* and how much memory is needed to store the ImageCodecInfo for all the
|
|
* decoders. size tells how much memory the caller should allocate for
|
|
* the call to GdipGetImageDecoders.
|
|
*
|
|
* Arguments:
|
|
* numDecoders -- number of installed decoders
|
|
* size -- size (in bytes) of the ImageCodecInfo's of the decoders
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status code
|
|
*
|
|
\**************************************************************************/
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageDecodersSize(OUT UINT *numDecoders, OUT UINT *size)
|
|
{
|
|
API_ENTRY(GdipGetImageDecodersSize);
|
|
// Acquire global critical section
|
|
|
|
ImagingCritSec critsec;
|
|
|
|
ReloadCachedCodecInfo();
|
|
|
|
CachedCodecInfo* cur;
|
|
|
|
// Count the number of selected codecs
|
|
// and figure the amount of memory we need to allocate
|
|
|
|
*numDecoders = 0;
|
|
*size = 0;
|
|
|
|
for (cur = CachedCodecs; cur; cur = cur->next)
|
|
{
|
|
if (cur->Flags & IMGCODEC_DECODER)
|
|
{
|
|
(*numDecoders)++;
|
|
*size += cur->structSize;
|
|
}
|
|
}
|
|
// Global critical section is released in critsec destructor
|
|
return Ok;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
*
|
|
* Function Description:
|
|
*
|
|
* Given the number of decoders (numDecoders), the size of
|
|
* the incoming buffer (size), and a pointer to the buffer (decoders),
|
|
* fill the buffer with the decoder information.
|
|
*
|
|
* Arguments:
|
|
* numDecoders -- number of installed decoders
|
|
* size -- size (in bytes) of the ImageCodecInfo's of the decoders
|
|
* decoders -- pointer to a buffer to fill in the ImageCodecInfo
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status code
|
|
*
|
|
\**************************************************************************/
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageDecoders(UINT numDecoders,
|
|
UINT size,
|
|
ImageCodecInfo *decoders)
|
|
{
|
|
API_ENTRY(GdipGetImageDecoders);
|
|
GpStatus rv;
|
|
HRESULT hResult;
|
|
BYTE *buf;
|
|
ImageCodecInfo* dst;
|
|
CachedCodecInfo* cur;
|
|
UINT numDecodersCheck = 0;
|
|
UINT sizeCheck = 0;
|
|
|
|
// Acquire global critical section
|
|
|
|
ImagingCritSec critsec;
|
|
|
|
if (decoders == NULL)
|
|
{
|
|
rv = GenericError;
|
|
goto done;
|
|
}
|
|
|
|
GdipGetImageDecodersSize(&numDecodersCheck, &sizeCheck);
|
|
// Check that the number of codecs (and size) now equals the number
|
|
// that the user thinks there is.
|
|
if ((numDecoders != numDecodersCheck) || (size != sizeCheck))
|
|
{
|
|
rv = GenericError;
|
|
goto done;
|
|
}
|
|
// ASSERT: The result placed in sizeCheck is not used throughout
|
|
// the rest of this function.
|
|
|
|
buf = (BYTE *) decoders;
|
|
|
|
// Copy codec information to the output buffer
|
|
|
|
dst = decoders;
|
|
buf += numDecoders * sizeof(ImageCodecInfo);
|
|
|
|
for (cur = CachedCodecs; cur; cur = cur->next)
|
|
{
|
|
if ((cur->Flags & IMGCODEC_DECODER) == 0)
|
|
continue;
|
|
|
|
// First do a simple memory copy
|
|
|
|
*dst = *static_cast<ImageCodecInfo *>(cur);
|
|
|
|
// Then modify the pointer fields
|
|
|
|
COPYCODECINFOSTR(CodecName);
|
|
COPYCODECINFOSTR(FormatDescription);
|
|
COPYCODECINFOSTR(FilenameExtension);
|
|
COPYCODECINFOSTR(MimeType);
|
|
|
|
if (size = cur->SigCount*cur->SigSize)
|
|
{
|
|
dst->SigPattern = buf;
|
|
memcpy(buf, cur->SigPattern, size);
|
|
buf += size;
|
|
|
|
dst->SigMask = buf;
|
|
memcpy(buf, cur->SigMask, size);
|
|
buf += size;
|
|
}
|
|
|
|
dst++;
|
|
}
|
|
|
|
rv = Ok;
|
|
|
|
// Global critical section is released in critsec destructor
|
|
|
|
done:
|
|
return rv;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
*
|
|
* Function Description:
|
|
*
|
|
* Returns, via the OUT arguments, the number of installed encoders
|
|
* and how much memory is needed to store the ImageCodecInfo for all the
|
|
* encoders. size tells how much memory the caller should allocate for
|
|
* the call to GdipGetImageEncoders.
|
|
*
|
|
* Arguments:
|
|
* numDecoders -- number of installed encoders
|
|
* size -- size (in bytes) of the ImageCodecInfo's of the encoders
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status code
|
|
*
|
|
\**************************************************************************/
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageEncodersSize(OUT UINT *numEncoders, OUT UINT *size)
|
|
{
|
|
API_ENTRY(GdipGetImageEncodersSize);
|
|
// Acquire global critical section
|
|
|
|
ImagingCritSec critsec;
|
|
|
|
ReloadCachedCodecInfo();
|
|
|
|
CachedCodecInfo* cur;
|
|
|
|
// Count the number of selected codecs
|
|
// and figure the amount of memory we need to allocate
|
|
|
|
*numEncoders = 0;
|
|
*size = 0;
|
|
|
|
for (cur = CachedCodecs; cur; cur = cur->next)
|
|
{
|
|
if (cur->Flags & IMGCODEC_ENCODER)
|
|
{
|
|
(*numEncoders)++;
|
|
*size += cur->structSize;
|
|
}
|
|
}
|
|
// Global critical section is released in critsec destructor
|
|
return Ok;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
*
|
|
* Function Description:
|
|
*
|
|
* Given the number of encoders (numEncoders), the size of
|
|
* the incoming buffer (size), and a pointer to the buffer (encoders),
|
|
* fill the buffer with the encoder information.
|
|
*
|
|
* Arguments:
|
|
* numEncoders -- number of installed encoders
|
|
* size -- size (in bytes) of the ImageCodecInfo's of the encoders
|
|
* encoders -- pointer to a buffer to fill in the ImageCodecInfo
|
|
*
|
|
* Return Value:
|
|
*
|
|
* Status code
|
|
*
|
|
\**************************************************************************/
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetImageEncoders(UINT numEncoders,
|
|
UINT size,
|
|
ImageCodecInfo *encoders)
|
|
{
|
|
API_ENTRY(GdipGetImageEncoders);
|
|
GpStatus rv;
|
|
HRESULT hResult;
|
|
BYTE *buf;
|
|
ImageCodecInfo* dst;
|
|
CachedCodecInfo* cur;
|
|
UINT numEncodersCheck = 0;
|
|
UINT sizeCheck = 0;
|
|
|
|
// Acquire global critical section
|
|
|
|
ImagingCritSec critsec;
|
|
|
|
if (encoders == NULL)
|
|
{
|
|
rv = GenericError;
|
|
goto done;
|
|
}
|
|
|
|
GdipGetImageEncodersSize(&numEncodersCheck, &sizeCheck);
|
|
|
|
// Check that the number of codecs (and size) now equals the number
|
|
// that the user thinks there is.
|
|
if ((numEncoders != numEncodersCheck) || (size != sizeCheck))
|
|
{
|
|
rv = GenericError;
|
|
goto done;
|
|
}
|
|
// ASSERT: The result placed in sizeCheck is not used throughout
|
|
// the rest of this function.
|
|
|
|
buf = (BYTE *) encoders;
|
|
|
|
// Copy codec information to the output buffer
|
|
|
|
dst = encoders;
|
|
buf += numEncoders * sizeof(ImageCodecInfo);
|
|
|
|
for (cur = CachedCodecs; cur; cur = cur->next)
|
|
{
|
|
if ((cur->Flags & IMGCODEC_ENCODER) == 0)
|
|
continue;
|
|
|
|
// First do a simple memory copy
|
|
|
|
*dst = *static_cast<ImageCodecInfo*>(cur);
|
|
|
|
// Then modify the pointer fields
|
|
|
|
COPYCODECINFOSTR(CodecName);
|
|
COPYCODECINFOSTR(FormatDescription);
|
|
COPYCODECINFOSTR(FilenameExtension);
|
|
COPYCODECINFOSTR(MimeType);
|
|
|
|
if (size = cur->SigCount*cur->SigSize)
|
|
{
|
|
dst->SigPattern = buf;
|
|
memcpy(buf, cur->SigPattern, size);
|
|
buf += size;
|
|
|
|
dst->SigMask = buf;
|
|
memcpy(buf, cur->SigMask, size);
|
|
buf += size;
|
|
}
|
|
|
|
dst++;
|
|
}
|
|
|
|
rv = Ok;
|
|
|
|
// Global critical section is released in critsec destructor
|
|
|
|
done:
|
|
return rv;
|
|
}
|
|
|
|
void*
|
|
WINGDIPAPI
|
|
GdipAlloc(
|
|
size_t size
|
|
)
|
|
{
|
|
API_ENTRY(GdipAlloc);
|
|
CheckGdiplusInitialized_ReturnNULL;
|
|
|
|
#if DBG
|
|
return GpMallocAPI(size);
|
|
#else
|
|
return GpMalloc(size);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
WINGDIPAPI
|
|
GdipFree(
|
|
void* ptr
|
|
)
|
|
{
|
|
API_ENTRY(GdipFree);
|
|
GpFree(ptr);
|
|
}
|
|
|
|
/// Out of place font/text stuff
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
|
GpFontCollection *fontCollection,
|
|
GpFontFamily **fontFamily)
|
|
{
|
|
API_ENTRY(GdipCreateFontFamilyFromName);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(name && fontFamily);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckOptionalParameterValid(fontCollection);
|
|
|
|
return GpFontFamily::CreateFontFamilyFromName(
|
|
name,
|
|
fontCollection,
|
|
fontFamily);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily)
|
|
{
|
|
API_ENTRY(GdipGetGenericFontFamilySansSerif);
|
|
CheckParameter(nativeFamily);
|
|
return GpFontFamily::GetGenericFontFamilySansSerif(nativeFamily);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily)
|
|
{
|
|
API_ENTRY(GdipGetGenericFontFamilySerif);
|
|
CheckParameter(nativeFamily);
|
|
return GpFontFamily::GetGenericFontFamilySerif(nativeFamily);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily)
|
|
{
|
|
API_ENTRY(GdipGetGenericFontFamilyMonospace);
|
|
CheckParameter(nativeFamily);
|
|
return GpFontFamily::GetGenericFontFamilyMonospace(nativeFamily);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFont(
|
|
GDIPCONST GpFontFamily *fontFamily,
|
|
REAL size,
|
|
INT style,
|
|
Unit unit,
|
|
GpFont **font
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFont);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
GpStatus status = Ok;
|
|
// check parameters
|
|
CheckParameter(font);
|
|
|
|
// UnitDisplay is NOT valid; its only use is for Page Transforms
|
|
if (size <= 0 ||
|
|
// (style < StyleRegular || style > StyleStrikeout) ||
|
|
(unit < UnitWorld || unit > UnitMillimeter || unit == UnitDisplay))
|
|
{
|
|
return InvalidParameter;
|
|
}
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(fontFamily);
|
|
|
|
if (*font = new GpFont(size, fontFamily, style, unit)) {
|
|
if (!(*font)->GetFace()) {
|
|
delete *font;
|
|
*font = NULL;
|
|
status = FontStyleNotFound;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = OutOfMemory;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteFontFamily(GpFontFamily *gpFontFamily)
|
|
{
|
|
API_ENTRY(GdipDeleteFontFamily);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(gpFontFamily);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
gpFontFamily->DecFontFamilyRef();
|
|
|
|
if (gpFontFamily->IsFileLoaded(FALSE))
|
|
{
|
|
// Try to delete the font file (RemoveFontFile) for each Face[].
|
|
// This also will have the side effect of attempting to delete
|
|
// any deletable GpFontFamily objects.
|
|
UINT iFace = 0;
|
|
UINT iLastFace = 0;
|
|
GpFontFace *face = NULL;
|
|
|
|
// Compute the index of the last non-NULL Face[] pointer.
|
|
for (iFace = 0; iFace < NumFontFaces; iFace++)
|
|
{
|
|
face = gpFontFamily->GetFaceAbsolute(iFace);
|
|
if (face != NULL)
|
|
{
|
|
iLastFace = iFace;
|
|
}
|
|
}
|
|
|
|
for (iFace = 0; iFace <= iLastFace; iFace++)
|
|
{
|
|
face = gpFontFamily->GetFaceAbsolute(iFace);
|
|
// Try to remove the font file if RemoveFontFile has
|
|
// already been called on it.
|
|
// Note that if iFace == iLastFace, then the call to
|
|
// RemoveFontFile below might delete this gpFontFamily object,
|
|
// which means the Face[] pointers would be garbage. This is
|
|
// why the for loop index goes up to iLastFace.
|
|
if (face && face->pff->bRemoved)
|
|
{
|
|
GpFontCollection* actualFontCollection;
|
|
actualFontCollection = gpFontFamily->GetFontCollection();
|
|
actualFontCollection = actualFontCollection ?
|
|
actualFontCollection :
|
|
GpInstalledFontCollection::GetGpInstalledFontCollection();
|
|
|
|
actualFontCollection->GetFontTable()->RemoveFontFile(face->pff->pwszPathname_);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneFontFamily(GpFontFamily *gpFontFamily, GpFontFamily **gpClonedFontFamily)
|
|
{
|
|
API_ENTRY(GdipCloneFontFamily);
|
|
CheckParameter(gpClonedFontFamily);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(gpFontFamily);
|
|
|
|
gpFontFamily->IncFontFamilyRef();
|
|
*gpClonedFontFamily = gpFontFamily;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFamily(GpFont *font, GpFontFamily **family)
|
|
{
|
|
API_ENTRY(GdipGetFamily);
|
|
CheckParameter(family);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
|
|
*family = const_cast<GpFontFamily *>(font->GetFamily());
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontStyle(GpFont *font, INT *style)
|
|
{
|
|
API_ENTRY(GdipGetFontStyle);
|
|
CheckParameter(style);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
*style = font->GetStyle();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLogFontA(GpFont * font, GpGraphics *graphics, LOGFONTA * logfontA)
|
|
{
|
|
API_ENTRY(GdipGetLogFontA);
|
|
CheckParameter(logfontA);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
font->GetLogFontA(graphics, logfontA);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLogFontW(GpFont * font, GpGraphics *graphics, LOGFONTW * logfontW)
|
|
{
|
|
API_ENTRY(GdipGetLogFontW);
|
|
CheckParameter(logfontW);
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
font->GetLogFontW(graphics, logfontW);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontSize(GpFont *font, REAL *size)
|
|
{
|
|
API_ENTRY(GdipGetFontSize);
|
|
CheckParameter(size);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
*size = font->GetEmSize();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontUnit(GpFont *font, Unit *unit)
|
|
{
|
|
API_ENTRY(GdipGetFontUnit);
|
|
CheckParameter(unit);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
*unit = font->GetUnit();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontHeight(GDIPCONST GpFont *font, GDIPCONST GpGraphics *graphics, REAL *height)
|
|
{
|
|
API_ENTRY(GdipGetFontHeight);
|
|
CheckParameter(height);
|
|
CheckOptionalParameterValid(graphics);
|
|
CheckOptionalObjectBusy(graphics);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
return font->GetHeight(graphics, height);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height)
|
|
{
|
|
API_ENTRY(GdipGetFontHeight);
|
|
CheckParameter(height);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
return font->GetHeight(dpi, height);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneFont(
|
|
GpFont* font,
|
|
GpFont** cloneFont
|
|
)
|
|
{
|
|
API_ENTRY(GdipCloneFont);
|
|
CheckParameter(cloneFont);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
*cloneFont = font->Clone();
|
|
|
|
if (*cloneFont)
|
|
return Ok;
|
|
else
|
|
return OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteFont(
|
|
GpFont* font
|
|
)
|
|
{
|
|
API_ENTRY(GdipDeleteFont);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(font);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
delete font;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
/// End out of place font/text stuff
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetDC(
|
|
GpGraphics* graphics,
|
|
HDC * hdc
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetDC);
|
|
CheckParameter(hdc);
|
|
CheckParameterValid(graphics);
|
|
|
|
// NOTE: We have to leave the graphics locked until the GdipReleaseDC call
|
|
|
|
LONG * lockCount = (graphics->GetObjectLock())->GetLockCount();
|
|
LONG result = InterlockedIncrement(lockCount);
|
|
|
|
if (result != 0)
|
|
{
|
|
InterlockedDecrement(lockCount);
|
|
return ObjectBusy;
|
|
}
|
|
|
|
if ((*hdc = graphics->GetHdc()) == NULL)
|
|
{
|
|
InterlockedDecrement(lockCount);
|
|
return InvalidParameter;
|
|
}
|
|
|
|
graphics->LockedByGetDC = -1; // set graphics GetDC lock
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipReleaseDC(
|
|
GpGraphics* graphics,
|
|
HDC hdc
|
|
)
|
|
{
|
|
API_ENTRY(GdipReleaseDC);
|
|
CheckParameter(hdc);
|
|
CheckParameterValid(graphics);
|
|
|
|
// NOTE: The graphics should already be locked from the GdipGetDC call
|
|
|
|
LONG result;
|
|
|
|
if ((InterlockedIncrement(&(graphics->LockedByGetDC)) != 0) ||
|
|
(!(graphics->GetObjectLock())->IsLocked()))
|
|
{
|
|
InterlockedDecrement(&(graphics->LockedByGetDC));
|
|
return InvalidParameter;
|
|
}
|
|
|
|
graphics->ReleaseHdc(hdc);
|
|
|
|
InterlockedDecrement((graphics->GetObjectLock())->GetLockCount());
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipComment(
|
|
GpGraphics* graphics,
|
|
UINT sizeData,
|
|
GDIPCONST BYTE * data
|
|
)
|
|
{
|
|
API_ENTRY(GdipComment);
|
|
CheckParameter(data && (sizeData > 0));
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
|
|
return graphics->Comment(sizeData, data);
|
|
}
|
|
|
|
|
|
// FontFamily
|
|
|
|
/// GdipCreateFontFamilyFromName should be moved here
|
|
|
|
/// GdipEnumerableFonts should be moved here
|
|
|
|
/// GdipEnumerateFonts should be moved here
|
|
|
|
/// GdipGetFamilyName should be moved here
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipIsStyleAvailable(GDIPCONST GpFontFamily *family, INT style, BOOL * IsAvailable)
|
|
{
|
|
API_ENTRY(GdipIsStyleAvailable);
|
|
CheckParameter(IsAvailable);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
*IsAvailable = family->IsStyleAvailable(style);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, UINT16 * EmHeight)
|
|
{
|
|
API_ENTRY(GdipGetEmHeight);
|
|
CheckParameter(EmHeight);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
*EmHeight = family->GetDesignEmHeight(style);
|
|
|
|
return Ok;
|
|
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCellAscent(GDIPCONST GpFontFamily *family, INT style, UINT16 * CellAscent)
|
|
{
|
|
API_ENTRY(GdipGetCellAscent);
|
|
CheckParameter(CellAscent);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
*CellAscent = family->GetDesignCellAscent(style);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetCellDescent(GDIPCONST GpFontFamily *family, INT style, UINT16 * CellDescent)
|
|
{
|
|
API_ENTRY(GdipGetCellDescent);
|
|
CheckParameter(CellDescent);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
*CellDescent = family->GetDesignCellDescent(style);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetLineSpacing(GDIPCONST GpFontFamily *family, INT style, UINT16 * LineSpacing)
|
|
{
|
|
API_ENTRY(GdipGetLineSpacing);
|
|
CheckParameter(LineSpacing);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(family);
|
|
*LineSpacing = family->GetDesignLineSpacing(style);
|
|
|
|
return Ok;
|
|
}
|
|
|
|
// Font
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFontFromDC(
|
|
HDC hdc,
|
|
GpFont **font
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFontFromDC);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
GpStatus status = GenericError;
|
|
CheckParameter(hdc);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
if (*font = new GpFont(hdc))
|
|
{
|
|
// we should fail in case we don't have valid font family. (non-true type font selected in the hdc)
|
|
if (!(*font)->IsValid())
|
|
{
|
|
delete *font;
|
|
*font = NULL;
|
|
status = NotTrueTypeFont;
|
|
}
|
|
else
|
|
status = Ok;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFontFromLogfontA(
|
|
HDC hdc,
|
|
GDIPCONST LOGFONTA *logfont,
|
|
GpFont **font
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFontFromLogfontA);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
GpStatus status = GenericError;
|
|
CheckParameter(hdc && logfont);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
if (*font = new GpFont(hdc, const_cast<LOGFONTA*>(logfont)))
|
|
{
|
|
// we should fail in case we don't have valid font family. (non-true type font selected in the hdc)
|
|
if (!(*font)->IsValid())
|
|
{
|
|
delete *font;
|
|
*font = NULL;
|
|
status = NotTrueTypeFont;
|
|
}
|
|
else
|
|
status = Ok;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateFontFromLogfontW(
|
|
HDC hdc,
|
|
GDIPCONST LOGFONTW *logfont,
|
|
GpFont **font
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateFontFromLogfontW);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
GpStatus status = GenericError;
|
|
CheckParameter(hdc && logfont);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
if (*font = new GpFont(hdc, const_cast<LOGFONTW*>(logfont)))
|
|
{
|
|
// we should fail in case we don't have valid font family. (non-true type font selected in the hdc)
|
|
if (!(*font)->IsValid())
|
|
{
|
|
delete *font;
|
|
*font = NULL;
|
|
status = NotTrueTypeFont;
|
|
}
|
|
else
|
|
status = Ok;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/// GdipCreateFont should be moved here
|
|
|
|
/// GdipCloneFont should be moved here
|
|
|
|
/// GdipDeleteFont should be moved here
|
|
|
|
/// GdipGetFamily should be moved here
|
|
|
|
/// GdipGetFontStyle should be moved here
|
|
|
|
/// GdipGetFontSize should be moved here
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipNewInstalledFontCollection(GpFontCollection** fontCollection)
|
|
{
|
|
API_ENTRY(GdipNewInstalledFontCollection);
|
|
CheckParameter (fontCollection);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
*fontCollection = GpInstalledFontCollection::GetGpInstalledFontCollection();
|
|
|
|
return (*fontCollection ? Ok : FileNotFound);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipNewPrivateFontCollection(GpFontCollection** fontCollection)
|
|
{
|
|
API_ENTRY(GdipNewPrivateFontCollection);
|
|
CheckParameter (fontCollection);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
*fontCollection = new GpPrivateFontCollection;
|
|
|
|
return (*fontCollection ? Ok : GenericError);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeletePrivateFontCollection(GpFontCollection** fontCollection)
|
|
{
|
|
API_ENTRY(GdipDeletePrivateFontCollection);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter (fontCollection);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
delete static_cast<GpPrivateFontCollection *>(*fontCollection);
|
|
|
|
*fontCollection = NULL;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontCollectionFamilyCount(
|
|
GpFontCollection* fontCollection,
|
|
INT * numFound
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetFontCollectionFamilyCount);
|
|
CheckParameter (numFound);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(fontCollection);
|
|
*numFound = fontCollection->GetFamilyCount();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetFontCollectionFamilyList(
|
|
GpFontCollection* fontCollection,
|
|
INT numSought,
|
|
GpFontFamily* gpfamilies[],
|
|
INT* numFound
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetFontCollectionFamilyList);
|
|
GpStatus status;
|
|
CheckParameter(gpfamilies);
|
|
CheckParameter (numFound);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(fontCollection);
|
|
return fontCollection->GetFamilies(
|
|
numSought,
|
|
gpfamilies,
|
|
numFound);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipPrivateAddFontFile(
|
|
GpFontCollection* fontCollection,
|
|
GDIPCONST WCHAR* filename
|
|
)
|
|
{
|
|
API_ENTRY(GdipPrivateAddFontFile);
|
|
CheckParameter (filename);
|
|
|
|
// We can cast the fontCollection because we know that this
|
|
// function is called only from PrivateFontCollection::AddFontFile,
|
|
// and so we know that fontCollection really was constructed as
|
|
// a PrivateFontCollection.
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(fontCollection);
|
|
return static_cast<GpPrivateFontCollection *>
|
|
(fontCollection)->AddFontFile(filename);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipPrivateAddMemoryFont(
|
|
GpFontCollection* fontCollection,
|
|
GDIPCONST void* memory,
|
|
INT length
|
|
)
|
|
{
|
|
API_ENTRY(GdipPrivateAddMemoryFont);
|
|
CheckParameter (memory);
|
|
|
|
// We can cast the fontCollection because we know that this
|
|
// function is called only from PrivateFontCollection::AddMemoryFontFile,
|
|
// and so we know that fontCollection really was constructed as
|
|
// an PrivateFontCollection.
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(fontCollection);
|
|
return static_cast<GpPrivateFontCollection *>
|
|
(fontCollection)->AddMemoryFont(memory, length);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetFontSize(GpFont *font, REAL size, Unit unit)
|
|
{
|
|
API_ENTRY(GdipSetFontSize);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
CheckParameterValid(font);
|
|
|
|
// UnitDisplay is NOT valid; its only use is for Page Transforms
|
|
if ((unit >= UnitWorld) && (unit <= UnitMillimeter) && (unit != UnitDisplay))
|
|
{
|
|
font->SetEmSize(size);
|
|
font->SetUnit(unit);
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
return GenericError;
|
|
}
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateStringFormat(
|
|
INT formatAttributes,
|
|
LANGID language,
|
|
GpStringFormat **format
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateStringFormat);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(format);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
*format = new GpStringFormat(formatAttributes, language);
|
|
|
|
return format ? Ok : OutOfMemory;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipStringFormatGetGenericDefault(GpStringFormat **format)
|
|
{
|
|
API_ENTRY(GdipStringFormatGetGenericDefault);
|
|
CheckParameter(format);
|
|
|
|
GlobalTextLock lock;
|
|
*format = GpStringFormat::GenericDefault();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipStringFormatGetGenericTypographic(GpStringFormat **format)
|
|
{
|
|
API_ENTRY(GdipStringFormatGetGenericTypographic);
|
|
CheckParameter(format);
|
|
GlobalTextLock lock;
|
|
*format = GpStringFormat::GenericTypographic();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCloneStringFormat(
|
|
GDIPCONST GpStringFormat *format,
|
|
GpStringFormat **newFormat)
|
|
{
|
|
API_ENTRY(GdipCloneStringFormat);
|
|
CheckParameter(newFormat);
|
|
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
*newFormat = format->Clone();
|
|
|
|
return newFormat == NULL ? OutOfMemory : Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipDeleteStringFormat(GpStringFormat *format)
|
|
{
|
|
API_ENTRY(GdipDeleteStringFormat);
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(format);
|
|
|
|
GlobalTextLock lock;
|
|
|
|
if (!format->IsPermanent())
|
|
{
|
|
delete format;
|
|
}
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatFlags(GpStringFormat *format, INT flags)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatFlags);
|
|
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
format->SetFormatFlags(flags);
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatFlags(GDIPCONST GpStringFormat *format, INT *flags)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatFlags);
|
|
CheckParameter(flags);
|
|
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
*flags = format->GetFormatFlags();
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatAlign(
|
|
GpStringFormat *format,
|
|
StringAlignment align)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatAlign);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
CheckParameter( align >= StringAlignmentNear
|
|
&& align <= StringAlignmentFar);
|
|
|
|
return format->SetAlign(align);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatAlign(
|
|
GDIPCONST GpStringFormat *format,
|
|
StringAlignment *align)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatAlign);
|
|
CheckParameter(align);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetAlign(align);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatLineAlign(
|
|
GpStringFormat *format,
|
|
StringAlignment align)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatLineAlign);
|
|
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
CheckParameter( align >= StringAlignmentNear
|
|
&& align <= StringAlignmentFar);
|
|
|
|
return format->SetLineAlign(align);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatLineAlign(
|
|
GDIPCONST GpStringFormat *format,
|
|
StringAlignment *align)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatLineAlign);
|
|
CheckParameter(align);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetLineAlign(align);
|
|
}
|
|
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatHotkeyPrefix(
|
|
GpStringFormat *format,
|
|
INT hotkeyPrefix)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatHotkeyPrefix);
|
|
CheckParameter( hotkeyPrefix >= HotkeyPrefixNone
|
|
&& hotkeyPrefix <= HotkeyPrefixHide);
|
|
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->SetHotkeyPrefix(hotkeyPrefix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatHotkeyPrefix(
|
|
GDIPCONST GpStringFormat *format,
|
|
INT *hotkeyPrefix)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatHotkeyPrefix);
|
|
CheckParameter(hotkeyPrefix);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetHotkeyPrefix(hotkeyPrefix);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatTabStops(
|
|
GpStringFormat *format,
|
|
REAL firstTabOffset,
|
|
INT count,
|
|
GDIPCONST REAL *tabStops
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatTabStops);
|
|
CheckParameter(tabStops);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->SetTabStops (
|
|
firstTabOffset,
|
|
count,
|
|
tabStops
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatTabStopCount(
|
|
GDIPCONST GpStringFormat *format,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatTabStopCount);
|
|
CheckParameter(count);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetTabStopCount (count);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatTabStops(
|
|
GDIPCONST GpStringFormat *format,
|
|
INT count,
|
|
REAL *firstTabOffset,
|
|
REAL *tabStops
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatTabStops);
|
|
CheckParameter(firstTabOffset && tabStops);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetTabStops (
|
|
firstTabOffset,
|
|
count,
|
|
tabStops
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatMeasurableCharacterRangeCount(
|
|
GDIPCONST GpStringFormat *format,
|
|
INT *count
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatMeasurableCharacterRangeCount);
|
|
CheckParameter(count);
|
|
CheckParameterValid(format);
|
|
|
|
*count = format->GetMeasurableCharacterRanges();
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatMeasurableCharacterRanges(
|
|
GpStringFormat *format,
|
|
INT rangeCount,
|
|
GDIPCONST CharacterRange *ranges
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatMeasurableCharacterRanges);
|
|
CheckParameter(ranges);
|
|
CheckParameterValid(format);
|
|
|
|
if (rangeCount > 32)
|
|
{
|
|
return ValueOverflow;
|
|
}
|
|
|
|
return format->SetMeasurableCharacterRanges(
|
|
rangeCount,
|
|
ranges
|
|
);
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatDigitSubstitution(
|
|
GpStringFormat *format,
|
|
LANGID language,
|
|
StringDigitSubstitute substitute
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatDigitSubstitution);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->SetDigitSubstitution (
|
|
language,
|
|
substitute
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatDigitSubstitution(
|
|
GDIPCONST GpStringFormat *format,
|
|
LANGID *language,
|
|
StringDigitSubstitute *substitute
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatDigitSubstitution);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetDigitSubstitution (
|
|
language,
|
|
substitute
|
|
);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipSetStringFormatTrimming(
|
|
GpStringFormat *format,
|
|
StringTrimming trimming
|
|
)
|
|
{
|
|
API_ENTRY(GdipSetStringFormatTrimming);
|
|
CheckParameter( trimming >= StringTrimmingNone
|
|
&& trimming <= StringTrimmingEllipsisPath);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->SetTrimming(trimming);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipGetStringFormatTrimming(
|
|
GDIPCONST GpStringFormat *format,
|
|
StringTrimming *trimming
|
|
)
|
|
{
|
|
API_ENTRY(GdipGetStringFormatTrimming);
|
|
CheckParameter(trimming);
|
|
GlobalTextLock lock;
|
|
CheckParameterValid(format);
|
|
|
|
return format->GetTrimming(trimming);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipCreateCachedBitmap(
|
|
GpBitmap *bitmap,
|
|
GpGraphics *graphics,
|
|
GpCachedBitmap **nativeCachedBitmap
|
|
)
|
|
{
|
|
API_ENTRY(GdipCreateCachedBitmap);
|
|
CheckGdiplusInitialized; // We do this in all our object creation API's
|
|
|
|
CheckParameter(nativeCachedBitmap);
|
|
|
|
// must have a bitmap and a graphics to create a CachedBitmap.
|
|
// Also we must lock both objects for the duration of this call
|
|
// because we can't have any other APIs modifying them.
|
|
|
|
CheckParameterValid(graphics);
|
|
CheckObjectBusy(graphics);
|
|
CheckParameterValid(bitmap);
|
|
CheckObjectBusy(bitmap);
|
|
|
|
*nativeCachedBitmap = new GpCachedBitmap(bitmap, graphics);
|
|
if(nativeCachedBitmap)
|
|
{
|
|
return Ok;
|
|
}
|
|
else
|
|
{
|
|
return OutOfMemory;
|
|
}
|
|
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipDeleteCachedBitmap(GpCachedBitmap *nativeCachedBitmap)
|
|
{
|
|
API_ENTRY(GdipDeleteCachedBitmap);
|
|
|
|
// NOTE: Do NOT call CheckParameterValid(), because we need to free
|
|
// the object, even if it's not in a valid state.
|
|
CheckParameter(nativeCachedBitmap);
|
|
|
|
// Grab the lock for the duration of the delete so that we bounce if
|
|
// someone is busy rendering on it.
|
|
|
|
// !!! [asecchia] note this will bounce if the object is locked and then
|
|
// the deletion will fail. This will cause the app to leak memory because
|
|
// there is no way to check the return status from delete.
|
|
// This problem is common to all our deletion APIs
|
|
|
|
CheckObjectBusyForDelete(nativeCachedBitmap);
|
|
|
|
delete nativeCachedBitmap;
|
|
|
|
return Ok;
|
|
}
|
|
|
|
GpStatus WINGDIPAPI
|
|
GdipDrawCachedBitmap(
|
|
GpGraphics *nativeGraphics,
|
|
GpCachedBitmap *cb,
|
|
INT x,
|
|
INT y
|
|
)
|
|
{
|
|
API_ENTRY(GdipDrawCachedBitmap);
|
|
// Check the input parameters for NULL
|
|
|
|
CheckParameterValid(nativeGraphics);
|
|
CheckParameterValid(cb);
|
|
|
|
// Grab the lock to make sure nobody is currently trying to delete the
|
|
// object under us.
|
|
|
|
CheckObjectBusy(cb);
|
|
|
|
// Grab the lock on the GpGraphics
|
|
|
|
CheckObjectBusy(nativeGraphics);
|
|
|
|
return (nativeGraphics->DrawCachedBitmap(cb, x, y));
|
|
}
|
|
|
|
// The palette must be freed and recreated whenever the Desktop colors change
|
|
HPALETTE
|
|
WINGDIPAPI
|
|
GdipCreateHalftonePalette()
|
|
{
|
|
API_ENTRY(GdipCreateHalftonePalette);
|
|
|
|
// !!! [agodfrey]: I bet we haven't documented the fact that the user
|
|
// has to call this any time the desktop colors change.
|
|
// Also, I don't know why we read 12 colors instead of 4 (I thought
|
|
// there were only 4 magic colors.)
|
|
|
|
HPALETTE hpalette;
|
|
HDC hdc = ::GetDC(NULL); // Get a screen DC
|
|
|
|
if (hdc != NULL)
|
|
{
|
|
// See if we need to get the desktop colors
|
|
if ((::GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) &&
|
|
(::GetSystemPaletteUse(hdc) == SYSPAL_STATIC) &&
|
|
(::GetDeviceCaps(hdc, SIZEPALETTE) == 256))
|
|
{
|
|
// We have to get the desktop colors to guarantee
|
|
// a XO_TRIVIAL translate in GDI.
|
|
|
|
// First Entry is always Black
|
|
::GetSystemPaletteEntries(hdc, 1, 9,
|
|
Win9xHalftonePalette.palPalEntry + 1);
|
|
|
|
// We only can handle changes to the first 3 of the last 10
|
|
::GetSystemPaletteEntries(hdc, 246, 3,
|
|
Win9xHalftonePalette.palPalEntry + 246);
|
|
}
|
|
::ReleaseDC(NULL, hdc);
|
|
}
|
|
hpalette = ::CreatePalette((LOGPALETTE *)(&Win9xHalftonePalette));
|
|
return hpalette;
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipMonitorControl(GpMonitorControlEnum control, void * param)
|
|
{
|
|
API_ENTRY(GdipMonitorControl);
|
|
|
|
if(Globals::Monitors == NULL)
|
|
{
|
|
Globals::Monitors = new GpMonitors;
|
|
|
|
if(Globals::Monitors == NULL)
|
|
return OutOfMemory;
|
|
}
|
|
|
|
return Globals::Monitors->Control(control, param);
|
|
}
|
|
|
|
GpStatus
|
|
WINGDIPAPI
|
|
GdipTestControl(GpTestControlEnum control, void * param)
|
|
{
|
|
API_ENTRY(GdipTestControl);
|
|
|
|
GpStatus result = Ok;
|
|
|
|
switch(control)
|
|
{
|
|
case TestControlForceBilinear:
|
|
Globals::ForceBilinear = *((BOOL *) param);
|
|
break;
|
|
|
|
case TestControlNoICM:
|
|
Globals::NoICM = *((BOOL *) param);
|
|
break;
|
|
|
|
case TestControlGetBuildNumber:
|
|
*((INT32 *) param) = VER_PRODUCTBUILD;
|
|
break;
|
|
|
|
default:
|
|
result = InvalidParameter;
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
UINT
|
|
WINGDIPAPI
|
|
GdipEmfToWmfBits(HENHMETAFILE hemf,
|
|
UINT cbData16,
|
|
LPBYTE pData16,
|
|
INT iMapMode,
|
|
INT eFlags)
|
|
{
|
|
API_ENTRY(GdipEmfToWmfBits);
|
|
return ConvertEmfToPlaceableWmf(
|
|
hemf,
|
|
cbData16,
|
|
pData16,
|
|
iMapMode,
|
|
eFlags);
|
|
}
|
|
|
|
// Version information for debugging purposes
|
|
UINT32 GpBuildNumber = VER_PRODUCTBUILD;
|
|
|
|
} // end of extern "C"
|