2810 lines
77 KiB
C++
2810 lines
77 KiB
C++
|
/******************************Module*Header*******************************\
|
||
|
* Module Name: test.c
|
||
|
*
|
||
|
* Created: 09-Dec-1992 10:51:46
|
||
|
* Author: Kirk Olynyk [kirko]
|
||
|
*
|
||
|
* Copyright (c) 1991 Microsoft Corporation
|
||
|
*
|
||
|
* Contains the test
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <objbase.h>
|
||
|
#include <math.h> // sin & cos
|
||
|
#include "wndstuff.h"
|
||
|
#include "debug.h"
|
||
|
|
||
|
//
|
||
|
// Where is IStream included from?
|
||
|
//
|
||
|
|
||
|
#define IStream int
|
||
|
|
||
|
#include <gdiplus.h>
|
||
|
|
||
|
using namespace Gdiplus;
|
||
|
|
||
|
#ifndef ASSERT
|
||
|
#define ASSERT(cond) if (!(cond)) { DebugBreak(); }
|
||
|
#endif
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* vTest
|
||
|
*
|
||
|
* This is the workhorse routine that does the test. The test is
|
||
|
* started by chosing it from the window menu.
|
||
|
*
|
||
|
* History:
|
||
|
* Tue 08-Dec-1992 17:31:22 by Kirk Olynyk [kirko]
|
||
|
* Wrote it.
|
||
|
\**************************************************************************/
|
||
|
|
||
|
class RectI
|
||
|
{
|
||
|
public:
|
||
|
INT X;
|
||
|
INT Y;
|
||
|
INT Width;
|
||
|
INT Height;
|
||
|
};
|
||
|
|
||
|
VOID TestRotatedLine(Graphics *g);
|
||
|
VOID TestLineWithTexture(Graphics *g);
|
||
|
VOID TestRegionExcludeClip(Graphics *g);
|
||
|
VOID TestRegionXorClip(Graphics *g);
|
||
|
VOID TestContainerClip(Graphics *g);
|
||
|
VOID TestContainer(Graphics *g);
|
||
|
VOID TestPolygons(Graphics *g);
|
||
|
VOID TestPaths(Graphics *g);
|
||
|
VOID TestPathIterators(Graphics *g);
|
||
|
VOID TestDashes(Graphics *g);
|
||
|
VOID TestWideningAndWarping(Graphics *g);
|
||
|
VOID TestRegions(Graphics *g);
|
||
|
VOID TestGradients(Graphics* g);
|
||
|
VOID TestHatches(Graphics* g);
|
||
|
VOID TestBitmaps(Graphics* g);
|
||
|
VOID TestPrimitives(Graphics *g);
|
||
|
VOID TestMixedObjects(Graphics *g);
|
||
|
VOID TestTexts(Graphics* g);
|
||
|
VOID TestTextAlongPath(Graphics *g);
|
||
|
VOID TestDerive(HWND hwnd);
|
||
|
VOID TestImaging(Graphics* g);
|
||
|
VOID TestBitmapGraphics(Graphics* g);
|
||
|
VOID TestDibsection(Graphics* g);
|
||
|
VOID TestCompoundLines(Graphics *g);
|
||
|
VOID TestImageSampling(Graphics *g);
|
||
|
VOID TestIcon(Graphics *g);
|
||
|
|
||
|
VOID TestWmfs(Graphics *g);
|
||
|
VOID TestMetaGetDC(Graphics *g, HWND hwnd);
|
||
|
VOID TestMetafileEnumeration(Graphics *g);
|
||
|
VOID TestMetafileTextureBrush(Graphics *g);
|
||
|
VOID TestGetHemf(HDC hdc);
|
||
|
VOID TestLargeMetafileObject(Graphics* g, HDC hdc);
|
||
|
VOID TestTextToMetafile(Graphics *g, HDC hdc);
|
||
|
VOID TestCmykSeparation(Graphics *g);
|
||
|
VOID TestDownLevelBitmapTransparency(Graphics *g, HDC hdc);
|
||
|
VOID DrawHatches(Graphics * g);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
Test(
|
||
|
HWND hwnd
|
||
|
)
|
||
|
{
|
||
|
HDC hdc = GetDC(hwnd);
|
||
|
|
||
|
// Select in the halftone palette for 256-color display mode testing
|
||
|
HPALETTE hpal = Graphics::GetHalftonePalette();
|
||
|
SelectPalette(hdc, hpal, FALSE);
|
||
|
RealizePalette(hdc);
|
||
|
|
||
|
Graphics *g = new Graphics(hdc);
|
||
|
|
||
|
TestMetaGetDC(g, hwnd); // this has to be the first test!
|
||
|
|
||
|
// Test GetNearestColor
|
||
|
Color c(0x32, 0x67, 0x98);
|
||
|
g->GetNearestColor(&c);
|
||
|
|
||
|
TestDownLevelBitmapTransparency(g, hdc);
|
||
|
TestTextToMetafile(g, hdc);
|
||
|
TestLargeMetafileObject(g, hdc);
|
||
|
TestGetHemf(hdc);
|
||
|
TestMetafileEnumeration(g);
|
||
|
TestMetafileTextureBrush(g);
|
||
|
TestRotatedLine(g);
|
||
|
TestWmfs(g);
|
||
|
|
||
|
g->SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
|
||
|
// Scale everything up by scale
|
||
|
REAL scale = (REAL) 1.2;
|
||
|
g->SetPageUnit(UnitDisplay);
|
||
|
g->SetPageScale(scale);
|
||
|
g->RotateTransform(10);
|
||
|
|
||
|
{
|
||
|
HDC hdc = GetDC(hwnd);
|
||
|
{
|
||
|
Metafile recording(L"TestEmfP.Emf", hdc);
|
||
|
Graphics gMeta(&recording);
|
||
|
|
||
|
gMeta.SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
TestRegionExcludeClip(&gMeta);
|
||
|
TestRegionXorClip(&gMeta);
|
||
|
TestBitmaps(&gMeta);
|
||
|
gMeta.RotateTransform(30);
|
||
|
gMeta.SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
TestContainer(&gMeta);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
Metafile playback(L"TestEmfP.Emf");
|
||
|
g->DrawImage(&playback, 0, 0);
|
||
|
}
|
||
|
ReleaseDC(hwnd, hdc);
|
||
|
}
|
||
|
|
||
|
TestContainerClip(g);
|
||
|
TestPolygons(g);
|
||
|
// TestPaths(g);
|
||
|
TestPathIterators(g); // Identical to TestPaths except for using iterators.
|
||
|
TestRegions(g);
|
||
|
TestBitmaps(g);
|
||
|
TestPrimitives(g);
|
||
|
TestMixedObjects(g);
|
||
|
TestGradients(g);
|
||
|
TestHatches(g);
|
||
|
TestTexts(g);
|
||
|
TestDerive(hwnd);
|
||
|
TestDashes(g);
|
||
|
TestWideningAndWarping(g);
|
||
|
TestImaging(g);
|
||
|
TestBitmapGraphics(g);
|
||
|
TestLineWithTexture(g);
|
||
|
TestDibsection(g);
|
||
|
TestCompoundLines(g);
|
||
|
TestImageSampling(g);
|
||
|
TestIcon(g);
|
||
|
TestCmykSeparation(g);
|
||
|
DrawHatches(g);
|
||
|
|
||
|
{
|
||
|
Metafile recordDown(L"Hatches.emf", hdc, EmfTypeEmfOnly);
|
||
|
{
|
||
|
Graphics gMeta(&recordDown);
|
||
|
|
||
|
DrawHatches(&gMeta);
|
||
|
}
|
||
|
g->DrawImage(&recordDown, 330, 0);
|
||
|
}
|
||
|
|
||
|
delete g;
|
||
|
ReleaseDC(hwnd, hdc);
|
||
|
DeleteObject(hpal);
|
||
|
}
|
||
|
|
||
|
VOID DrawHatches(Graphics * g)
|
||
|
{
|
||
|
HatchBrush h1 (HatchStyleHorizontal, Color(255, 0, 0), Color(0, 255, 255));
|
||
|
HatchBrush h2 (HatchStyleVertical, Color(255, 0, 0), Color(0, 255, 255));
|
||
|
HatchBrush h3 (HatchStyleForwardDiagonal, Color(255, 0, 0), Color(0, 255, 255));
|
||
|
HatchBrush h4 (HatchStyleBackwardDiagonal, Color(255, 0, 0), Color(0, 255, 255));
|
||
|
HatchBrush h5 (HatchStyleCross, Color(255, 0, 0), Color(0, 255, 255));
|
||
|
HatchBrush h6 (HatchStyleDiagonalCross, Color(255, 0, 0), Color(0, 255, 255));
|
||
|
|
||
|
g->FillEllipse(&h1, 0, 0, 100, 100);
|
||
|
g->FillEllipse(&h2, 110, 0, 100, 100);
|
||
|
g->FillEllipse(&h3, 220, 0, 100, 100);
|
||
|
g->FillEllipse(&h4, 0, 110, 100, 100);
|
||
|
g->FillEllipse(&h5, 110, 110, 100, 100);
|
||
|
g->FillEllipse(&h6, 220, 110, 100, 100);
|
||
|
}
|
||
|
|
||
|
VOID TestDownLevelBitmapTransparency(Graphics *g, HDC hdc)
|
||
|
{
|
||
|
Metafile recordDown(L"DownLevelBm.emf", hdc, EmfTypeEmfOnly);
|
||
|
{
|
||
|
Graphics gMeta(&recordDown);
|
||
|
Bitmap bm(50, 50, PixelFormat32bppARGB);
|
||
|
{
|
||
|
Graphics gBitmap(&bm);
|
||
|
gBitmap.Clear(Color(128, 255, 0, 0));
|
||
|
}
|
||
|
|
||
|
GraphicsPath path;
|
||
|
|
||
|
Rect r(0,0,50,50);
|
||
|
path.AddRectangle(r);
|
||
|
SolidBrush sb(Color(0, 0xFF, 0));
|
||
|
|
||
|
gMeta.FillPath(&sb, &path);
|
||
|
gMeta.DrawImage(&bm, 25, 25);
|
||
|
}
|
||
|
g->DrawImage(&recordDown, 200, 200);
|
||
|
}
|
||
|
|
||
|
VOID TestLargeMetafileObject(Graphics* g, HDC hdc)
|
||
|
{
|
||
|
Metafile recording(L"Large.emf", hdc);
|
||
|
{
|
||
|
Image image(L"..\\data\\real3.jpg");
|
||
|
TextureBrush textureBrush(&image, WrapModeTile);
|
||
|
Matrix matrix;
|
||
|
matrix.Scale(.2f, .2f);
|
||
|
textureBrush.SetTransform(&matrix);
|
||
|
Graphics gMeta(&recording);
|
||
|
gMeta.FillRectangle(&textureBrush, 0, 0, 800, 600);
|
||
|
Pen pen(&textureBrush, 40.0);
|
||
|
pen.SetLineJoin(LineJoinMiter);
|
||
|
PointF spiralPoints[12] = {
|
||
|
PointF(540.0f, 550.0f),
|
||
|
PointF(540.0f, 75.0f),
|
||
|
PointF( 60.0f, 75.0f),
|
||
|
PointF( 60.0f, 460.0f),
|
||
|
PointF(460.0f, 460.0f),
|
||
|
PointF(460.0f, 140.0f),
|
||
|
PointF(140.0f, 140.0f),
|
||
|
PointF(140.0f, 400.0f),
|
||
|
PointF(380.0f, 400.0f),
|
||
|
PointF(380.0f, 190.0f),
|
||
|
PointF(260.0f, 190.0f),
|
||
|
PointF(260.0f, 350.0f),
|
||
|
};
|
||
|
|
||
|
gMeta.DrawLines(&pen, spiralPoints, 12);
|
||
|
}
|
||
|
g->DrawImage(&recording, 20, 300, 600, 400);
|
||
|
}
|
||
|
|
||
|
VOID TestGetHemf(HDC hdc)
|
||
|
{
|
||
|
Metafile recording(L"Abcdefg.Emf", hdc);
|
||
|
{
|
||
|
Graphics gMeta(&recording);
|
||
|
SolidBrush sb(Color(0xFF, 0, 0));
|
||
|
gMeta.FillRectangle(&sb, 0, 0, 20, 20);
|
||
|
}
|
||
|
HENHMETAFILE hemf;
|
||
|
hemf = recording.GetHENHMETAFILE();
|
||
|
DeleteEnhMetaFile(hemf);
|
||
|
}
|
||
|
|
||
|
VOID TestMetafileTextureBrush(Graphics *g)
|
||
|
{
|
||
|
Metafile m1(L"..\\data\\agree.emf");
|
||
|
Rect r(0, 0, 50, 50);
|
||
|
TextureBrush textureBrush(&m1, WrapModeTile, r);
|
||
|
g->FillRectangle(&textureBrush, 0, 0, 800, 800);
|
||
|
}
|
||
|
|
||
|
extern "C"
|
||
|
BOOL CALLBACK
|
||
|
MyPlayMetafileRecordCallback(
|
||
|
EmfPlusRecordType recordType,
|
||
|
UINT recordFlags,
|
||
|
UINT recordDataSize,
|
||
|
const BYTE * recordData,
|
||
|
VOID * callbackData
|
||
|
)
|
||
|
{
|
||
|
((Metafile *)callbackData)->PlayRecord(recordType, recordFlags, recordDataSize, recordData);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
VOID TestMetafileEnumeration(Graphics *g)
|
||
|
{
|
||
|
Metafile m1(L"..\\data\\agree.emf");
|
||
|
g->EnumerateMetafile(&m1, Rect(50, 10, 800, 500), MyPlayMetafileRecordCallback, &m1);
|
||
|
|
||
|
Metafile m2(L"..\\data\\tiger.wmf");
|
||
|
g->EnumerateMetafile(&m2, Rect(50, 10, 800, 500), MyPlayMetafileRecordCallback, &m2);
|
||
|
}
|
||
|
|
||
|
VOID DrawContainer(Graphics * g, ARGB * argb, INT count)
|
||
|
{
|
||
|
Matrix mymatrix;
|
||
|
g->SetPageUnit(UnitInch);
|
||
|
|
||
|
RectF clipRect(0,0,5,5);
|
||
|
g->SetClip(clipRect);
|
||
|
|
||
|
mymatrix.Translate(2.5, 2.5);
|
||
|
mymatrix.Rotate(15);
|
||
|
mymatrix.Translate(-2.5, -2.5);
|
||
|
g->SetTransform(&mymatrix);
|
||
|
|
||
|
Color color(*argb++);
|
||
|
SolidBrush contBrush(color);
|
||
|
g->FillRectangle(&contBrush, 0, 0, 5, 5);
|
||
|
if (--count == 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
RectF destRect(.5, .5, 4, 4);
|
||
|
RectF srcRect(0, 0, 5, 5);
|
||
|
INT id = g->BeginContainer(destRect, srcRect, UnitInch);
|
||
|
g->ResetClip();
|
||
|
DrawContainer (g, argb, count);
|
||
|
g->EndContainer(id);
|
||
|
}
|
||
|
|
||
|
VOID TestContainerClip(Graphics *g)
|
||
|
{
|
||
|
ARGB colors[5];
|
||
|
|
||
|
colors[0] = Color::MakeARGB(255, 255, 0, 0);
|
||
|
colors[1] = Color::MakeARGB(255, 0, 255, 0);
|
||
|
colors[2] = Color::MakeARGB(255, 0, 0, 255);
|
||
|
colors[3] = Color::MakeARGB(255, 255, 255, 0);
|
||
|
colors[4] = Color::MakeARGB(255, 0, 255, 255);
|
||
|
|
||
|
GraphicsState s = g->Save();
|
||
|
DrawContainer(g, colors, 5);
|
||
|
g->Restore(s);
|
||
|
}
|
||
|
|
||
|
GraphicsPath circlePath;
|
||
|
RectF circleRect(0,0,4,4);
|
||
|
BOOL circleInitialized = FALSE;
|
||
|
|
||
|
#define ROOT 0
|
||
|
#define LEFT 1
|
||
|
#define RIGHT 2
|
||
|
#define TOP 3
|
||
|
#define BOTTOM 4
|
||
|
|
||
|
|
||
|
|
||
|
VOID DrawFractal(Graphics * g, BYTE gray, INT side, INT count)
|
||
|
{
|
||
|
ARGB argb;
|
||
|
|
||
|
switch (count % 3)
|
||
|
{
|
||
|
case 0:
|
||
|
argb = Color::MakeARGB(255, 0, 0, gray);
|
||
|
break;
|
||
|
case 1:
|
||
|
argb = Color::MakeARGB(255, 0, gray, 0);
|
||
|
break;
|
||
|
case 2:
|
||
|
argb = Color::MakeARGB(255, gray, 0, 0);
|
||
|
gray -= 60;
|
||
|
break;
|
||
|
}
|
||
|
Color color(argb);
|
||
|
SolidBrush contBrush(color);
|
||
|
g->SetPageUnit(UnitInch);
|
||
|
g->FillPath(&contBrush, &circlePath);
|
||
|
|
||
|
if (--count == 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RectF destRect;
|
||
|
GraphicsContainer cstate;
|
||
|
|
||
|
if (side != LEFT)
|
||
|
{
|
||
|
destRect = RectF(4, 1, 2, 2);
|
||
|
cstate = g->BeginContainer(destRect, circleRect, UnitInch);
|
||
|
g->SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
DrawFractal(g, gray, RIGHT, count);
|
||
|
g->EndContainer(cstate);
|
||
|
}
|
||
|
if (side != TOP)
|
||
|
{
|
||
|
destRect = RectF(1, 4, 2, 2);
|
||
|
cstate = g->BeginContainer(destRect, circleRect, UnitInch);
|
||
|
g->SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
DrawFractal(g, gray, BOTTOM, count);
|
||
|
g->EndContainer(cstate);
|
||
|
}
|
||
|
if (side != RIGHT)
|
||
|
{
|
||
|
destRect = RectF(-2, 1, 2, 2);
|
||
|
cstate = g->BeginContainer(destRect, circleRect, UnitInch);
|
||
|
g->SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
DrawFractal(g, gray, LEFT, count);
|
||
|
g->EndContainer(cstate);
|
||
|
}
|
||
|
if (side != BOTTOM)
|
||
|
{
|
||
|
destRect = RectF(1, -2, 2, 2);
|
||
|
cstate = g->BeginContainer(destRect, circleRect, UnitInch);
|
||
|
g->SetSmoothingMode(SmoothingModeAntiAlias);
|
||
|
DrawFractal(g, gray, TOP, count);
|
||
|
g->EndContainer(cstate);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
VOID TestContainer(Graphics * g)
|
||
|
{
|
||
|
if(!circleInitialized)
|
||
|
{
|
||
|
circlePath.AddEllipse(circleRect);
|
||
|
circleInitialized = TRUE;
|
||
|
}
|
||
|
|
||
|
INT id = g->Save();
|
||
|
g->TranslateTransform(5, 4);
|
||
|
DrawFractal(g, 245, ROOT, 8);
|
||
|
g->Restore(id);
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestPolygons
|
||
|
*
|
||
|
* A test for drawing and filling of rectangles and polygons.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestPolygons(Graphics *g)
|
||
|
{
|
||
|
REAL width = 4; // Pen width
|
||
|
|
||
|
Color redColor(255, 0, 0);
|
||
|
|
||
|
SolidBrush redBrush(redColor);
|
||
|
g->FillRectangle(&redBrush, 20, 20, 50, 50);
|
||
|
|
||
|
Color alphaColor(128, 0, 255, 0);
|
||
|
|
||
|
SolidBrush alphaBrush(alphaColor);
|
||
|
g->FillRectangle(&alphaBrush, 10, 10, 40, 40);
|
||
|
|
||
|
PointF points[4];
|
||
|
points[0].X = 50;
|
||
|
points[0].Y = 50;
|
||
|
points[1].X = 100;
|
||
|
points[1].Y = 50;
|
||
|
points[2].X = 120;
|
||
|
points[2].Y = 120;
|
||
|
points[3].X = 50;
|
||
|
points[3].Y = 100;
|
||
|
|
||
|
Color blueColor(128, 0, 0, 255);
|
||
|
|
||
|
SolidBrush blueBrush(blueColor);
|
||
|
g->FillPolygon(&blueBrush, points, 4);
|
||
|
|
||
|
// Currently only Geometric pen works for lines. - ikkof 1/6/99.
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
blackPen.SetLineJoin(LineJoinRound);
|
||
|
g->DrawPolygon(&blackPen, points, 4);
|
||
|
// g->DrawLines(&blackPen, points, 4, FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestPaths
|
||
|
*
|
||
|
* A test for general paths.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestPaths(Graphics *g)
|
||
|
{
|
||
|
REAL width = 4; // Pen width
|
||
|
PointF points[4];
|
||
|
|
||
|
points[0].X = 100;
|
||
|
points[0].Y = 10;
|
||
|
points[1].X = -50;
|
||
|
points[1].Y = 50;
|
||
|
points[2].X = 150;
|
||
|
points[2].Y = 200;
|
||
|
points[3].X = 200;
|
||
|
points[3].Y = 70;
|
||
|
|
||
|
Color yellowColor(128, 255, 255, 0);
|
||
|
SolidBrush yellowBrush(yellowColor);
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddBeziers(points, 4);
|
||
|
Matrix matrix;
|
||
|
matrix.Scale(1.5, 1.5);
|
||
|
|
||
|
// If you wanto to flatten the path before rendering,
|
||
|
// Flatten() can be called.
|
||
|
|
||
|
BOOL flattenFirst = FALSE;
|
||
|
|
||
|
if(!flattenFirst)
|
||
|
{
|
||
|
// Don't flatten and keep the original path.
|
||
|
// FillPath or DrawPath will flatten the path automatically
|
||
|
// without modifying the original path.
|
||
|
|
||
|
path->Transform(&matrix);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Flatten this path. The resultant path is made of line
|
||
|
// segments. The original path information is lost.
|
||
|
|
||
|
path->Flatten(&matrix);
|
||
|
}
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
// Set the pen width in inch.
|
||
|
width = 15;
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
blackPen.SetStartCap(LineCapRound);
|
||
|
// blackPen.SetEndCap(LineCapSquare);
|
||
|
blackPen.SetEndCap(LineCapArrowAnchor);
|
||
|
Region * region = new Region(path);
|
||
|
g->FillPath(&yellowBrush, path);
|
||
|
g->DrawPath(&blackPen, path);
|
||
|
delete path;
|
||
|
delete region;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestPaths
|
||
|
*
|
||
|
* A test for general paths.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestPathIterators(Graphics *g)
|
||
|
{
|
||
|
REAL width = 4; // Pen width
|
||
|
PointF points[4];
|
||
|
|
||
|
points[0].X = 100;
|
||
|
points[0].Y = 10;
|
||
|
points[1].X = -50;
|
||
|
points[1].Y = 50;
|
||
|
points[2].X = 150;
|
||
|
points[2].Y = 200;
|
||
|
points[3].X = 200;
|
||
|
points[3].Y = 70;
|
||
|
|
||
|
Color yellowColor(128, 255, 255, 0);
|
||
|
SolidBrush yellowBrush(yellowColor);
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddBeziers(points, 4);
|
||
|
Matrix matrix;
|
||
|
matrix.Scale(1.5, 1.5);
|
||
|
|
||
|
// If you wanto to flatten the path before rendering,
|
||
|
// Flatten() can be called.
|
||
|
|
||
|
BOOL flattenFirst = FALSE;
|
||
|
|
||
|
if(!flattenFirst)
|
||
|
{
|
||
|
// Don't flatten and keep the original path.
|
||
|
// FillPath or DrawPath will flatten the path automatically
|
||
|
// without modifying the original path.
|
||
|
|
||
|
path->Transform(&matrix);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Flatten this path. The resultant path is made of line
|
||
|
// segments. The original path information is lost.
|
||
|
|
||
|
path->Flatten(&matrix);
|
||
|
}
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
// Set the pen width in inch.
|
||
|
width = 15;
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
blackPen.SetStartCap(LineCapRound);
|
||
|
// blackPen.SetEndCap(LineCapSquare);
|
||
|
blackPen.SetEndCap(LineCapArrowAnchor);
|
||
|
|
||
|
|
||
|
// Test for Path data getter and setter.
|
||
|
|
||
|
INT count = path->GetPointCount();
|
||
|
if(count > 0)
|
||
|
{
|
||
|
// Allocate points and types buffers.
|
||
|
|
||
|
PathData pathData1;
|
||
|
pathData1.Points = new PointF[count];
|
||
|
pathData1.Types = new BYTE[count];
|
||
|
|
||
|
if(pathData1.Points && pathData1.Types)
|
||
|
{
|
||
|
pathData1.Count = count;
|
||
|
|
||
|
// Get the path data.
|
||
|
|
||
|
if(path->GetPathData(&pathData1) == Ok)
|
||
|
{
|
||
|
GraphicsPath* path1 = new GraphicsPath(pathData1.Points,
|
||
|
pathData1.Types,
|
||
|
pathData1.Count,
|
||
|
FillModeAlternate);
|
||
|
if(path1)
|
||
|
{
|
||
|
g->FillPath(&yellowBrush, path1);
|
||
|
}
|
||
|
|
||
|
delete path1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test for Path Iterator.
|
||
|
|
||
|
GraphicsPathIterator iter(path);
|
||
|
|
||
|
if(iter.GetLastStatus() == Ok)
|
||
|
{
|
||
|
count = iter.GetCount();
|
||
|
|
||
|
PointF* newPts = new PointF[count];
|
||
|
BYTE* newTypes = new BYTE[count];
|
||
|
|
||
|
if(newPts && newTypes && count > 0)
|
||
|
{
|
||
|
// Get the path's points and types data by using
|
||
|
// an enumeration method.
|
||
|
|
||
|
INT resultCount = iter.Enumerate(newPts, newTypes, count);
|
||
|
if (resultCount > 0)
|
||
|
{
|
||
|
GraphicsPath* path2 = new GraphicsPath(newPts,
|
||
|
newTypes,
|
||
|
resultCount,
|
||
|
FillModeAlternate);
|
||
|
|
||
|
if(path2 && resultCount > 0)
|
||
|
{
|
||
|
g->DrawPath(&blackPen, path2);
|
||
|
|
||
|
delete path2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete[] newPts;
|
||
|
delete[] newTypes;
|
||
|
}
|
||
|
|
||
|
delete path;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestDashes
|
||
|
*
|
||
|
* A test for drawing dashed lines.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestDashes(Graphics *g)
|
||
|
{
|
||
|
REAL width = 4; // Pen width
|
||
|
PointF points[4];
|
||
|
|
||
|
points[0].X = 100;
|
||
|
points[0].Y = 10;
|
||
|
points[1].X = -50;
|
||
|
points[1].Y = 50;
|
||
|
points[2].X = 150;
|
||
|
points[2].Y = 200;
|
||
|
points[3].X = 200;
|
||
|
points[3].Y = 70;
|
||
|
|
||
|
Color yellowColor(128, 255, 255, 0);
|
||
|
SolidBrush yellowBrush(yellowColor);
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddBeziers(points, 4);
|
||
|
Matrix matrix;
|
||
|
matrix.Scale(1.5, 1.5);
|
||
|
|
||
|
path->Transform(&matrix);
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
// Set the pen width in inch.
|
||
|
width = 15;
|
||
|
Pen pen1(&blackBrush, width);
|
||
|
pen1.SetDashStyle(DashStyleDashDotDot);
|
||
|
pen1.SetDashCap(DashCapRound);
|
||
|
g->DrawPath(&pen1, path);
|
||
|
|
||
|
// Create a multiple segment with a closed segment.
|
||
|
|
||
|
points[0].X = 50;
|
||
|
points[0].Y = 50;
|
||
|
points[1].X = 100;
|
||
|
points[1].Y = 50;
|
||
|
points[2].X = 120;
|
||
|
points[2].Y = 120;
|
||
|
points[3].X = 50;
|
||
|
points[3].Y = 100;
|
||
|
|
||
|
path->Reset();
|
||
|
path->AddLines(points, 4);
|
||
|
path->CloseFigure();
|
||
|
|
||
|
points[0].X = 150;
|
||
|
points[0].Y = 60;
|
||
|
points[1].X = 200;
|
||
|
points[1].Y = 150;
|
||
|
path->AddLines(points, 2);
|
||
|
path->Transform(&matrix);
|
||
|
|
||
|
Color blueColor(128, 0, 0, 255);
|
||
|
|
||
|
SolidBrush blueBrush(blueColor);
|
||
|
|
||
|
width = 5;
|
||
|
Pen pen2(&blueBrush, width);
|
||
|
pen2.SetDashStyle(DashStyleDashDotDot);
|
||
|
g->DrawPath(&pen2, path);
|
||
|
|
||
|
delete path;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestWideningAndWarping
|
||
|
*
|
||
|
* A test for widening and warping paths.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestWideningAndWarping(Graphics *g)
|
||
|
{
|
||
|
REAL width; // Pen width
|
||
|
RectF rect;
|
||
|
|
||
|
rect.X = 250;
|
||
|
rect.Y = -30;
|
||
|
rect.Width = 150;
|
||
|
rect.Height = 150;
|
||
|
|
||
|
Color yellowColor(128, 255, 255, 0);
|
||
|
SolidBrush yellowBrush(yellowColor);
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddRectangle(rect);
|
||
|
|
||
|
rect.Y = 70;
|
||
|
path->AddEllipse(rect);
|
||
|
|
||
|
Matrix matrix;
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
|
||
|
// Set the pen width in inch.
|
||
|
width = 15;
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
blackPen.SetStartCap(LineCapRound);
|
||
|
blackPen.SetEndCap(LineCapSquare);
|
||
|
|
||
|
path->Widen(&blackPen, &matrix);
|
||
|
|
||
|
RectF bounds;
|
||
|
|
||
|
path->GetBounds(&bounds);
|
||
|
|
||
|
PointF destPoints[4];
|
||
|
|
||
|
destPoints[0].X = bounds.X + bounds.Width/4;
|
||
|
destPoints[0].Y = bounds.Y;
|
||
|
destPoints[1].X = bounds.X + 3*bounds.Width/4;
|
||
|
destPoints[1].Y = bounds.Y;
|
||
|
destPoints[2].X = bounds.X;
|
||
|
destPoints[2].Y = bounds.Y + bounds.Height;
|
||
|
destPoints[3].X = bounds.X + bounds.Width;
|
||
|
destPoints[3].Y = bounds.Y + bounds.Height;
|
||
|
|
||
|
path->Warp(&destPoints[0], 4, bounds);
|
||
|
|
||
|
g->FillPath(&yellowBrush, path);
|
||
|
|
||
|
width = 0.05f;
|
||
|
blackPen.SetWidth(width);
|
||
|
g->DrawPath(&blackPen, path);
|
||
|
delete path;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestRegions
|
||
|
*
|
||
|
* A test for region fill.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestRegions(Graphics *g)
|
||
|
{
|
||
|
REAL width = 2; // Pen width
|
||
|
PointF points[5];
|
||
|
|
||
|
REAL s, c, theta;
|
||
|
REAL pi = 3.1415926535897932f;
|
||
|
REAL scale = 30;
|
||
|
PointF orig(200, 140);
|
||
|
|
||
|
theta = -pi/2;
|
||
|
|
||
|
// Create a star shape.
|
||
|
for(INT i = 0; i < 5; i++)
|
||
|
{
|
||
|
s = sinf(theta);
|
||
|
c = cosf(theta);
|
||
|
points[i].X = scale*c + orig.X;
|
||
|
points[i].Y = scale*s + orig.Y;
|
||
|
theta += 0.8f*pi;
|
||
|
}
|
||
|
|
||
|
Color orangeColor(128, 255, 180, 0);
|
||
|
|
||
|
SolidBrush orangeBrush(orangeColor);
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
// Path* path = new GraphicsPath(Winding);
|
||
|
path->AddPolygon(points, 5);
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
Region * region = new Region(path);
|
||
|
|
||
|
Matrix m;
|
||
|
g->GetTransform(&m);
|
||
|
INT rectCount;
|
||
|
rectCount = region->GetRegionScansCount(&m);
|
||
|
Rect * rects = new Rect[rectCount];
|
||
|
region->GetRegionScans(&m, rects, &rectCount);
|
||
|
delete rects;
|
||
|
|
||
|
g->FillRegion(&orangeBrush, region); // There is a BUG!
|
||
|
// g->FillGraphicsPath(&orangeBrush, path); // Fill path works fine.
|
||
|
|
||
|
blackPen.SetLineJoin(LineJoinMiter);
|
||
|
g->DrawPath(&blackPen, path);
|
||
|
delete path;
|
||
|
delete region;
|
||
|
}
|
||
|
|
||
|
GraphicsPath* CreateHeartPath(const RectF& rect)
|
||
|
{
|
||
|
GpPointF points[7];
|
||
|
points[0].X = 0;
|
||
|
points[0].Y = 0;
|
||
|
points[1].X = 1.00;
|
||
|
points[1].Y = -1.00;
|
||
|
points[2].X = 2.00;
|
||
|
points[2].Y = 1.00;
|
||
|
points[3].X = 0;
|
||
|
points[3].Y = 2.00;
|
||
|
points[4].X = -2.00;
|
||
|
points[4].Y = 1.00;
|
||
|
points[5].X = -1.00;
|
||
|
points[5].Y = -1.00;
|
||
|
points[6].X = 0;
|
||
|
points[6].Y = 0;
|
||
|
|
||
|
Matrix matrix;
|
||
|
|
||
|
matrix.Scale(rect.Width/2, rect.Height/3, MatrixOrderAppend);
|
||
|
matrix.Translate(3*rect.Width/2, 4*rect.Height/3, MatrixOrderAppend);
|
||
|
matrix.TransformPoints(&points[0], 7);
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath();
|
||
|
|
||
|
if(path)
|
||
|
{
|
||
|
path->AddBeziers(&points[0], 7);
|
||
|
path->CloseFigure();
|
||
|
}
|
||
|
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestGradients
|
||
|
*
|
||
|
* A test for rectangle and radial gradients.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestGradients(Graphics* g)
|
||
|
{
|
||
|
REAL width = 4; // Pen width
|
||
|
|
||
|
// Create a rectangular gradient brush.
|
||
|
|
||
|
RectF brushRect(0, 0, 32, 32);
|
||
|
|
||
|
Color colors[5] = {
|
||
|
Color(255, 255, 255, 255),
|
||
|
Color(255, 255, 0, 0),
|
||
|
Color(255, 0, 255, 0),
|
||
|
Color(255, 0, 0, 255),
|
||
|
Color(255, 0, 0, 0)
|
||
|
};
|
||
|
|
||
|
// !! No longer used
|
||
|
// RectangleGradientBrush rectGrad(brushRect, (Color*) &colors, WrapModeTile);
|
||
|
|
||
|
// Rotate a brush.
|
||
|
GpMatrix xForm;
|
||
|
xForm.Rotate(30);
|
||
|
// rectGrad.SetTransform(&xForm);
|
||
|
|
||
|
// Change the wrapping mode and fill.
|
||
|
|
||
|
// rectGrad.SetWrapMode(WrapModeTileFlipXY);
|
||
|
// !! No longer used
|
||
|
// g->FillRectangle(&rectGrad, 350, 20, 100, 80);
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
|
||
|
g->DrawRectangle(&blackPen, brushRect);
|
||
|
|
||
|
// Create a radial gradient brush.
|
||
|
|
||
|
Color centerColor(255, 255, 255, 255);
|
||
|
Color boundaryColor(255, 0, 0, 0);
|
||
|
brushRect.X = 380;
|
||
|
brushRect.Y = 130;
|
||
|
brushRect.Width = 60;
|
||
|
brushRect.Height = 32;
|
||
|
PointF center;
|
||
|
center.X = brushRect.X + brushRect.Width/2;
|
||
|
center.Y = brushRect.Y + brushRect.Height/2;
|
||
|
xForm.Reset();
|
||
|
xForm.RotateAt(-30, center, MatrixOrderAppend);
|
||
|
// !! No longer used
|
||
|
// RadialGradientBrush radGrad(brushRect, centerColor,
|
||
|
// boundaryColor, WrapModeClamp);
|
||
|
// radGrad.SetTransform(&xForm);
|
||
|
// g->FillRectangle(&radGrad, 320, 120, 120, 100);
|
||
|
|
||
|
// Pen gradPen(&rectGrad, width);
|
||
|
// g->DrawRectangle(&gradPen, 320, 120, 120, 100);
|
||
|
|
||
|
// Triangle gradient.
|
||
|
|
||
|
PointF points[7];
|
||
|
points[0].X = 50;
|
||
|
points[0].Y = 10;
|
||
|
points[1].X = 200;
|
||
|
points[1].Y = 20;
|
||
|
points[2].X = 100;
|
||
|
points[2].Y = 100;
|
||
|
points[3].X = 30;
|
||
|
points[3].Y = 120;
|
||
|
|
||
|
Color colors1[5] = {
|
||
|
Color(255, 255, 255, 0),
|
||
|
Color(255, 255, 0, 0),
|
||
|
Color(255, 0, 255, 0),
|
||
|
Color(255, 0, 0, 255),
|
||
|
Color(255, 0, 0, 0)
|
||
|
};
|
||
|
|
||
|
// !! No longer used
|
||
|
// TriangleGradientBrush triGrad(points, (Color*) &colors);
|
||
|
// g->FillPolygon(&triGrad, points, 3);
|
||
|
RectF triRect;
|
||
|
// triGrad.GetRectangle(triRect);
|
||
|
// g->FillRectangle(&triGrad, triRect);
|
||
|
|
||
|
points[0].X = 200;
|
||
|
points[0].Y = 300;
|
||
|
points[1].X = 280;
|
||
|
points[1].Y = 350;
|
||
|
points[2].X = 220;
|
||
|
points[2].Y = 420;
|
||
|
points[3].X = 160;
|
||
|
points[3].Y = 440;
|
||
|
points[4].X = 120;
|
||
|
points[4].Y = 370;
|
||
|
|
||
|
PathGradientBrush polyGrad(points, 5);
|
||
|
|
||
|
REAL blend[10];
|
||
|
Color presetColors[10];
|
||
|
REAL positions[10];
|
||
|
INT count;
|
||
|
INT i;
|
||
|
|
||
|
count = 3;
|
||
|
blend[0] = (REAL) 0;
|
||
|
blend[1] = (REAL) 0;
|
||
|
blend[2] = (REAL) 1;
|
||
|
positions[0] = (REAL) 0;
|
||
|
positions[1] = (REAL) 0.4;
|
||
|
positions[2] = (REAL) 1;
|
||
|
|
||
|
// Test for blending factors.
|
||
|
|
||
|
polyGrad.SetBlend(&blend[0], &positions[0], count);
|
||
|
|
||
|
polyGrad.SetCenterColor(centerColor);
|
||
|
INT colorset = 5;
|
||
|
polyGrad.SetSurroundColors(&colors1[0], &colorset);
|
||
|
|
||
|
// g->FillPolygon(&polyGrad, points, 5);
|
||
|
RectF polyRect;
|
||
|
polyGrad.GetRectangle(&polyRect);
|
||
|
g->FillRectangle(&polyGrad, polyRect);
|
||
|
|
||
|
// Create a heart shaped path.
|
||
|
|
||
|
RectF rect;
|
||
|
rect.X = 300;
|
||
|
rect.Y = 300;
|
||
|
rect.Width = 150;
|
||
|
rect.Height = 150;
|
||
|
GraphicsPath *path = CreateHeartPath(rect);
|
||
|
|
||
|
// Create a gradient from a path.
|
||
|
|
||
|
PathGradientBrush pathGrad(path);
|
||
|
delete path;
|
||
|
pathGrad.SetCenterColor(centerColor);
|
||
|
INT colorsset = 5;
|
||
|
colors1[0] = Color(255, 255, 0, 0);
|
||
|
pathGrad.SetSurroundColors(&colors1[0], &colorsset);
|
||
|
pathGrad.GetRectangle(&polyRect);
|
||
|
|
||
|
// Set the rect focus.
|
||
|
|
||
|
PointF centerPt;
|
||
|
|
||
|
pathGrad.GetCenterPoint(¢erPt);
|
||
|
centerPt.X -= 15;
|
||
|
centerPt.Y += 30;
|
||
|
pathGrad.SetCenterPoint(centerPt);
|
||
|
REAL xScale, yScale;
|
||
|
pathGrad.GetFocusScales(&xScale, &yScale);
|
||
|
xScale = 0.4f;
|
||
|
yScale = 0.3f;
|
||
|
pathGrad.SetFocusScales(xScale, yScale);
|
||
|
|
||
|
g->FillRectangle(&pathGrad, polyRect);
|
||
|
|
||
|
// Test for LineGradientBrush.
|
||
|
|
||
|
RectF lineRect(120, -20, 200, 60);
|
||
|
Color color1(200, 255, 255, 0);
|
||
|
Color color2(200, 0, 0, 255);
|
||
|
|
||
|
LinearGradientBrush lineGrad(lineRect, color1, color1,
|
||
|
LinearGradientModeForwardDiagonal);
|
||
|
|
||
|
// Test for preset colors
|
||
|
|
||
|
presetColors[0] = Color(200, 0, 255, 255);
|
||
|
presetColors[1] = Color(200, 255, 255, 0);
|
||
|
presetColors[2] = Color(200, 0, 255, 0);
|
||
|
lineGrad.SetInterpolationColors(&presetColors[0], &positions[0], count);
|
||
|
|
||
|
g->FillRectangle(&lineGrad, lineRect);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestHatches
|
||
|
*
|
||
|
* A test for hatch brushes
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestHatches(Graphics* g)
|
||
|
{
|
||
|
Color foreColor(0, 0, 0);
|
||
|
Color backColor(255, 255, 255);
|
||
|
|
||
|
int x, y;
|
||
|
|
||
|
x = 0; y = 0;
|
||
|
|
||
|
for (int i = HatchStyleMin; i <= HatchStyleMax; i++)
|
||
|
{
|
||
|
if ((i > 0) && ((i & 7) == 0))
|
||
|
{
|
||
|
x = 0;
|
||
|
y += 100;
|
||
|
}
|
||
|
HatchBrush hatch((HatchStyle)i, foreColor, backColor);
|
||
|
g->FillRectangle(&hatch, x, y, 100, 100);
|
||
|
x += 100;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestBitmaps
|
||
|
*
|
||
|
* A test for texture filling and DrawImage.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestBitmaps(Graphics* g)
|
||
|
{
|
||
|
Point points[4];
|
||
|
REAL width = 4; // Pen width
|
||
|
|
||
|
|
||
|
WCHAR filename[256];
|
||
|
wcscpy(filename, L"../data/brick.jpg");
|
||
|
Bitmap *bitmap = new Bitmap(filename);
|
||
|
|
||
|
// Create a texture brush.
|
||
|
|
||
|
RectI copyRect;
|
||
|
copyRect.X = 0;
|
||
|
copyRect.Y = 0;
|
||
|
copyRect.Width = 40;
|
||
|
copyRect.Height = 30;
|
||
|
|
||
|
Bitmap *copiedBitmap = bitmap->Clone(copyRect.X, copyRect.Y,
|
||
|
copyRect.Width, copyRect.Height,
|
||
|
PixelFormat32bppARGB);
|
||
|
|
||
|
if(copiedBitmap)
|
||
|
{
|
||
|
// Create a texture brush.
|
||
|
|
||
|
TextureBrush textureBrush(copiedBitmap, WrapModeTile);
|
||
|
|
||
|
//copiedBitmap->Dispose();
|
||
|
|
||
|
// Create a radial gradient pen.
|
||
|
|
||
|
Color redColor(255, 0, 0);
|
||
|
|
||
|
SolidBrush redBrush(redColor);
|
||
|
Pen redPen(&redBrush, width);
|
||
|
|
||
|
GraphicsPath *path;
|
||
|
|
||
|
points[0].X = 100;
|
||
|
points[0].Y = 60;
|
||
|
points[1].X = -50;
|
||
|
points[1].Y = 60;
|
||
|
points[2].X = 150;
|
||
|
points[2].Y = 250;
|
||
|
points[3].X = 200;
|
||
|
points[3].Y = 120;
|
||
|
path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddBeziers(points, 4);
|
||
|
g->FillPath(&textureBrush, path);
|
||
|
g->DrawPath(&redPen, path);
|
||
|
|
||
|
delete path;
|
||
|
delete copiedBitmap;
|
||
|
}
|
||
|
|
||
|
delete bitmap;
|
||
|
|
||
|
PointF destPoints[3];
|
||
|
|
||
|
destPoints[0].X = 300;
|
||
|
destPoints[0].Y = 50;
|
||
|
destPoints[1].X = 450;
|
||
|
destPoints[1].Y = 50;
|
||
|
destPoints[2].X = 240;
|
||
|
destPoints[2].Y = 200;
|
||
|
|
||
|
Matrix mat;
|
||
|
mat.Translate(0, 100);
|
||
|
mat.TransformPoints(&destPoints[0], 3);
|
||
|
wcscpy(filename, L"../data/apple1.png");
|
||
|
bitmap = new Bitmap(filename);
|
||
|
g->DrawImage(bitmap, &destPoints[0], 3);
|
||
|
|
||
|
delete bitmap;
|
||
|
|
||
|
destPoints[0].X = 30;
|
||
|
destPoints[0].Y = 200;
|
||
|
destPoints[1].X = 200;
|
||
|
destPoints[1].Y = 200;
|
||
|
destPoints[2].X = 200;
|
||
|
destPoints[2].Y = 420;
|
||
|
|
||
|
wcscpy(filename, L"../data/dog2.png");
|
||
|
bitmap = new Bitmap(filename);
|
||
|
g->DrawImage(bitmap, &destPoints[0], 3);
|
||
|
|
||
|
delete bitmap;
|
||
|
|
||
|
Color color(100, 128, 255, 0);
|
||
|
|
||
|
SolidBrush brush(color);
|
||
|
|
||
|
Point pts[10];
|
||
|
INT count = 4;
|
||
|
|
||
|
pts[0].X = 150;
|
||
|
pts[0].Y = 60;
|
||
|
pts[1].X = 100;
|
||
|
pts[1].Y = 230;
|
||
|
pts[2].X = 250;
|
||
|
pts[2].Y = 260;
|
||
|
pts[3].X = 350;
|
||
|
pts[3].Y = 100;
|
||
|
|
||
|
g->FillClosedCurve(&brush, pts, count);
|
||
|
|
||
|
wcscpy(filename, L"../data/ballmer.jpg");
|
||
|
bitmap = new Bitmap(filename);
|
||
|
RectF destRect(220, 50, 180, 120);
|
||
|
RectF srcRect;
|
||
|
srcRect.X = 100;
|
||
|
srcRect.Y = 40;
|
||
|
srcRect.Width = 200;
|
||
|
srcRect.Height = 200;
|
||
|
g->DrawImage(bitmap, destRect, srcRect.X, srcRect.Y,
|
||
|
srcRect.Width, srcRect.Height, UnitPixel);
|
||
|
|
||
|
g->DrawImage(bitmap, pts, 3, (INT) srcRect.X, (INT) srcRect.Y,
|
||
|
(INT) srcRect.Width, (INT) srcRect.Height, UnitPixel);
|
||
|
|
||
|
delete bitmap;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestPrimitives
|
||
|
*
|
||
|
* A test for ellipse, arc, pie, curve, and closed curve.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID
|
||
|
TestPrimitives(
|
||
|
Graphics* g
|
||
|
)
|
||
|
{
|
||
|
RectF rect;
|
||
|
|
||
|
rect.X = 250;
|
||
|
rect.Y = 230;
|
||
|
rect.Width = 150;
|
||
|
rect.Height = 100;
|
||
|
|
||
|
Color color(128, 128, 255, 0);
|
||
|
|
||
|
SolidBrush brush(color);
|
||
|
|
||
|
REAL width = 1;
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
Pen pen(&blackBrush, width);
|
||
|
|
||
|
// g->FillEllipse(&brush, rect);
|
||
|
// g->DrawEllipse(&pen, rect);
|
||
|
REAL startAngle = 0;
|
||
|
REAL sweepAngle = 240;
|
||
|
g->FillPie(&brush, rect, startAngle, sweepAngle);
|
||
|
g->DrawPie(&pen, rect, startAngle, sweepAngle);
|
||
|
|
||
|
PointF pts[10];
|
||
|
INT count = 4;
|
||
|
|
||
|
pts[0].X = 200;
|
||
|
pts[0].Y = 160;
|
||
|
pts[1].X = 150;
|
||
|
pts[1].Y = 230;
|
||
|
pts[2].X = 200;
|
||
|
pts[2].Y = 260;
|
||
|
pts[3].X = 300;
|
||
|
pts[3].Y = 200;
|
||
|
|
||
|
g->FillClosedCurve(&brush, pts, count);
|
||
|
g->DrawClosedCurve(&pen, pts, count);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestMixedObjects
|
||
|
*
|
||
|
* A test for different brushes and pens.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestMixedObjects(Graphics* g)
|
||
|
{
|
||
|
PointF points[10];
|
||
|
REAL width = 4; // Pen width
|
||
|
|
||
|
// Load bmp files.
|
||
|
|
||
|
WCHAR *filename = L"winnt256.bmp";
|
||
|
Bitmap *bitmap = new Bitmap(filename);
|
||
|
|
||
|
// Create a texture brush.
|
||
|
|
||
|
RectI copyRect;
|
||
|
copyRect.X = 60;
|
||
|
copyRect.Y = 60;
|
||
|
copyRect.Width = 80;
|
||
|
copyRect.Height = 60;
|
||
|
Bitmap *copiedBitmap = bitmap->Clone(copyRect.X, copyRect.Y,
|
||
|
copyRect.Width, copyRect.Height,
|
||
|
PixelFormat32bppPARGB);
|
||
|
|
||
|
// Create a rectangular gradient brush.
|
||
|
|
||
|
RectF brushRect(0, 0, 32, 32);
|
||
|
Color colors[4] = {
|
||
|
Color(255, 255, 255, 255),
|
||
|
Color(255, 255, 0, 0),
|
||
|
Color(255, 0, 255, 0),
|
||
|
Color(255, 0, 0, 255)
|
||
|
};
|
||
|
// !! No longer supported
|
||
|
// RectangleGradientBrush rectGrad(brushRect, (Color*)&colors, WrapModeTile);
|
||
|
width = 8;
|
||
|
// Pen gradPen(&rectGrad, width);
|
||
|
|
||
|
if(copiedBitmap)
|
||
|
{
|
||
|
// Create a texture brush.
|
||
|
|
||
|
TextureBrush textureBrush(copiedBitmap, WrapModeTile);
|
||
|
|
||
|
delete copiedBitmap;
|
||
|
|
||
|
// Create a radial gradient pen.
|
||
|
|
||
|
points[3].X = 50;
|
||
|
points[3].Y = 300;
|
||
|
points[2].X = 100;
|
||
|
points[2].Y = 300;
|
||
|
points[1].X = 120;
|
||
|
points[1].Y = 370;
|
||
|
points[0].X = 50;
|
||
|
points[0].Y = 350;
|
||
|
|
||
|
// gradPen.SetLineJoin(LineJoinMiter);
|
||
|
g->FillPolygon(&textureBrush, points, 4);
|
||
|
// g->DrawPolygon(&gradPen, points, 4);
|
||
|
}
|
||
|
|
||
|
delete bitmap;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestTexts
|
||
|
*
|
||
|
* A test for drawing texts.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestTexts(Graphics *g)
|
||
|
{
|
||
|
//Font font(L"Arial", 60);
|
||
|
|
||
|
FontFamily ff(L"Arial");
|
||
|
RectF rectf(20, 0, 300, 200);
|
||
|
GraphicsPath path;
|
||
|
|
||
|
// Solid color text.
|
||
|
|
||
|
Color color(128, 100, 0, 200);
|
||
|
SolidBrush brush(color);
|
||
|
path.AddString(L"Color", 5, &ff, 0, 60, rectf, NULL);
|
||
|
g->FillPath(&brush, &path);
|
||
|
|
||
|
// Texture text.
|
||
|
|
||
|
WCHAR filename[256];
|
||
|
wcscpy(filename, L"../data/marble1.jpg");
|
||
|
Bitmap *bitmap = new Bitmap(filename);
|
||
|
TextureBrush textureBrush(bitmap, WrapModeTile);
|
||
|
path.Reset();
|
||
|
rectf.X = 200;
|
||
|
rectf.Y = 20;
|
||
|
path.AddString(L"Texture", 7, &ff, 0, 60, rectf, NULL);
|
||
|
g->FillPath(&textureBrush, &path);
|
||
|
delete bitmap;
|
||
|
|
||
|
// Gradient text.
|
||
|
|
||
|
rectf.X = 40;
|
||
|
rectf.Y = 80;
|
||
|
path.Reset();
|
||
|
path.AddString(L"Gradient", 8, &ff, 0, 60, rectf, NULL);
|
||
|
Color color1(255, 255, 0, 0);
|
||
|
Color color2(255, 0, 255, 0);
|
||
|
LinearGradientBrush lineGrad(rectf, color1, color2, 0.0f);
|
||
|
g->FillPath(&lineGrad, &path);
|
||
|
|
||
|
// Shadow test
|
||
|
|
||
|
REAL charHeight = 60;
|
||
|
REAL topMargin = - 5;
|
||
|
rectf.X = 0;
|
||
|
rectf.Y = - charHeight - topMargin; // Make y-coord of the base line
|
||
|
// of the characters to be 0.
|
||
|
|
||
|
path.Reset();
|
||
|
path.AddString(L"Shadow", 6, &ff, 0, charHeight, rectf, NULL);
|
||
|
GraphicsPath* clonePath = path.Clone();
|
||
|
|
||
|
Color redColor(255, 0, 0);
|
||
|
Color grayColor(128, 0, 0, 0);
|
||
|
SolidBrush redBrush(redColor);
|
||
|
SolidBrush grayBrush(grayColor);
|
||
|
|
||
|
// Shadow part.
|
||
|
|
||
|
REAL tx = 180, ty = 200;
|
||
|
Matrix skew;
|
||
|
skew.Scale(1.0, 0.5);
|
||
|
skew.Shear(-2.0, 0, MatrixOrderAppend);
|
||
|
skew.Translate(tx, ty, MatrixOrderAppend);
|
||
|
clonePath->Transform(&skew);
|
||
|
g->FillPath(&grayBrush, clonePath);
|
||
|
delete clonePath;
|
||
|
|
||
|
// Front part.
|
||
|
|
||
|
Matrix trans1;
|
||
|
trans1.Translate(tx, ty);
|
||
|
path.Transform(&trans1);
|
||
|
g->FillPath(&redBrush, &path);
|
||
|
|
||
|
|
||
|
return;
|
||
|
/*
|
||
|
REAL x = 200, y = 150;
|
||
|
|
||
|
RectF brushRect(x, y, 150, 32);
|
||
|
Color colors[4] = {
|
||
|
Color(180, 255, 0, 0),
|
||
|
Color(180, 0, 255, 0),
|
||
|
Color(180, 255, 0, 0),
|
||
|
Color(180, 0, 255, 0)
|
||
|
};
|
||
|
RectangleGradientBrush rectGrad(brushRect, (Color*)&colors, WrapModeTile);
|
||
|
|
||
|
g->DrawString(L"GDI+", &font, &rectGrad, x, y);
|
||
|
|
||
|
|
||
|
// And now with DrawText
|
||
|
|
||
|
RectF rect(400, 200, 400, 400);
|
||
|
|
||
|
g->DrawText(
|
||
|
DrawTextDisplay,
|
||
|
L"A few words powered by GDI+: \
|
||
|
\x3c3\x3bb\x3b1\x3b4 \
|
||
|
\x627\x644\x633\x644\x627\x645 \
|
||
|
\x5e9\x5dc\x5d5\x5dd \
|
||
|
\xe2d\xe4d\xe01\xe29\xe23\xe44\xe17\xe22 \
|
||
|
\x110\x068\x0ea\x300\x103",
|
||
|
&font, // Initial font
|
||
|
&rectGrad, // Initial brush (ignored for the time being)
|
||
|
LANG_NEUTRAL, // Initial language
|
||
|
&rect // Formatting rectangle
|
||
|
);
|
||
|
*/
|
||
|
|
||
|
}
|
||
|
|
||
|
#ifdef TEXTV2
|
||
|
// We don't support text along a path in v1
|
||
|
|
||
|
VOID TestTextAlongPath(Graphics *g)
|
||
|
{
|
||
|
Point points[4];
|
||
|
|
||
|
points[3].X = 100;
|
||
|
points[3].Y = 10;
|
||
|
points[2].X = -50;
|
||
|
points[2].Y = 50;
|
||
|
points[1].X = 150;
|
||
|
points[1].Y = 200;
|
||
|
points[0].X = 200;
|
||
|
points[0].Y = 70;
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddBeziers(points, 4);
|
||
|
Matrix matrix;
|
||
|
matrix.Scale(1.5, 1.5);
|
||
|
|
||
|
path->Transform(&matrix);
|
||
|
|
||
|
Color textColor(180, 200, 0, 200);
|
||
|
SolidBrush textBrush(textColor);
|
||
|
|
||
|
WCHAR text[] = L"Windows 2000";
|
||
|
|
||
|
REAL offset = 60;
|
||
|
|
||
|
g->DrawString(text, 12, NULL, path, NULL, textBrush, offset);
|
||
|
|
||
|
delete path;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestDerive
|
||
|
*
|
||
|
* Test
|
||
|
* A test for derivation support.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID
|
||
|
TestDerive(
|
||
|
HWND hwnd
|
||
|
)
|
||
|
{
|
||
|
HDC hdcScreen = GetDC(hwnd);
|
||
|
HRGN hrgn = CreateEllipticRgn(10, 10, 300, 300);
|
||
|
|
||
|
SetMapMode(hdcScreen, MM_TWIPS);
|
||
|
SelectClipRgn(hdcScreen, hrgn);
|
||
|
HBRUSH hbrushRed = CreateSolidBrush(RGB(255, 0, 0));
|
||
|
SelectObject(hdcScreen, hbrushRed);
|
||
|
Rectangle(hdcScreen, 0, 0, 3000, -3000);
|
||
|
|
||
|
{
|
||
|
Graphics g(hdcScreen);
|
||
|
SolidBrush solidBrush(Color(0, 255, 0));
|
||
|
g.FillRectangle(&solidBrush, 0, -3000, 3000, 3000);
|
||
|
}
|
||
|
|
||
|
HBITMAP hbmBitmap = CreateCompatibleBitmap(hdcScreen, 50, 50);
|
||
|
HDC hdcBitmap = CreateCompatibleDC(hdcScreen);
|
||
|
SelectObject(hdcBitmap, hbmBitmap);
|
||
|
SetWindowOrgEx(hdcBitmap, 40, 80, NULL);
|
||
|
|
||
|
SelectObject(hdcBitmap, hbrushRed);
|
||
|
Rectangle(hdcBitmap, 40, 80, 50, 50);
|
||
|
|
||
|
{
|
||
|
POINT point;
|
||
|
Graphics g(hdcBitmap);
|
||
|
SolidBrush solidBrush(Color(0, 0, 255));
|
||
|
g.FillRectangle(&solidBrush, 40, 80, 90, 130);
|
||
|
|
||
|
// The DC that we get back should have the same transform set
|
||
|
// as that which we originally passed in:
|
||
|
|
||
|
HDC hdcGet = g.GetHDC();
|
||
|
point.x = 0;
|
||
|
point.y = 0;
|
||
|
DPtoLP(hdcGet, &point, 1);
|
||
|
|
||
|
ASSERT((hdcGet != NULL) && (point.x == 40) && (point.y == 80));
|
||
|
|
||
|
g.ReleaseHDC(hdcGet);
|
||
|
}
|
||
|
|
||
|
// The DC should have beeen returned to the top save level:
|
||
|
|
||
|
INT saveLevel = SaveDC(hdcBitmap);
|
||
|
ASSERT(saveLevel == 1);
|
||
|
|
||
|
// The DC should have had its transform restored:
|
||
|
|
||
|
POINT oldPoint;
|
||
|
SetWindowOrgEx(hdcBitmap, 0, 0, &oldPoint);
|
||
|
|
||
|
ASSERT((oldPoint.x == 40) && (oldPoint.y == 80));
|
||
|
|
||
|
// Blt the (hopefully) blue square to the screen. But first,
|
||
|
// reset our transform on 'hdcScreen' the lazy way:
|
||
|
|
||
|
ReleaseDC(hwnd, hdcScreen);
|
||
|
hdcScreen = GetDC(hwnd);
|
||
|
BitBlt(hdcScreen, 0, 0, 50, 50, hdcBitmap, 0, 0, SRCCOPY);
|
||
|
ReleaseDC(hwnd, hdcScreen);
|
||
|
|
||
|
// Test two equivalent methods. This should result in two grey
|
||
|
// squares, one on top of the other, each inset by a red circle
|
||
|
// and the text "Ack!".
|
||
|
|
||
|
hdcScreen = GetDC(hwnd);
|
||
|
{
|
||
|
// First:
|
||
|
|
||
|
{
|
||
|
Graphics g(hdcScreen);
|
||
|
SolidBrush fillBrush(Color(128, 128, 128));
|
||
|
g.FillRectangle(&fillBrush, 200, 200, 80, 80);
|
||
|
}
|
||
|
TextOutA(hdcScreen, 220, 230, "Ack!", 4);
|
||
|
{
|
||
|
Graphics g(hdcScreen);
|
||
|
SolidBrush strokeBrush(Color(255, 0, 0));
|
||
|
Pen pen(&strokeBrush, 0);
|
||
|
g.DrawEllipse(&pen, 200, 200, 80, 80);
|
||
|
}
|
||
|
|
||
|
// Second:
|
||
|
|
||
|
{
|
||
|
Graphics g(hdcScreen);
|
||
|
SolidBrush fillBrush(Color(128, 128, 128));
|
||
|
g.FillRectangle(&fillBrush, 200, 300, 80, 80);
|
||
|
|
||
|
HDC hdcNew = g.GetHDC();
|
||
|
ASSERT(hdcNew != NULL);
|
||
|
SetViewportOrgEx(hdcScreen, 220, 230, NULL);
|
||
|
TextOutA(hdcNew, 0, 100, "Ack!", 4);
|
||
|
SetViewportOrgEx(hdcScreen, 0, 0, NULL);
|
||
|
g.ReleaseHDC(hdcNew);
|
||
|
|
||
|
SolidBrush strokeBrush(Color(255, 0, 0));
|
||
|
Pen pen(&strokeBrush, 0);
|
||
|
g.DrawEllipse(&pen, 200, 300, 80, 80);
|
||
|
}
|
||
|
}
|
||
|
ReleaseDC(hwnd, hdcScreen);
|
||
|
}
|
||
|
|
||
|
VOID TestRegionExcludeClip(Graphics *g)
|
||
|
{
|
||
|
Gdiplus::Status status;
|
||
|
RectF rect(100, 100, 500, 500);
|
||
|
Gdiplus::Region region(rect);
|
||
|
|
||
|
rect.X = 50; rect.Y = 25; rect.Width = 100; rect.Height = 100;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 250;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 550;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 50; rect.Y = 150; rect.Height = 75;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 550;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 300; rect.Y = 300; rect.Height = 125;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 550; rect.Y = 250; rect.Height = 75;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.Y = 375;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.Y = 550;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 350;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.X = 50;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.Y = 450;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
rect.Y = 315;
|
||
|
status = region.Exclude(rect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
// g->SetPageTransform(UnitDisplay, 0.5f);
|
||
|
status = g->SetClip(®ion);
|
||
|
ASSERT(status == Ok);
|
||
|
status = g->TranslateClip(-50.0f, -50.0f);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
Gdiplus::SolidBrush b(Gdiplus::Color::Purple);
|
||
|
status = g->FillRectangle(&b, 0, 0, 800, 800);
|
||
|
ASSERT(status == Ok);
|
||
|
g->ResetClip();
|
||
|
// g->SetPageTransform(UnitDisplay, 1.0f);
|
||
|
}
|
||
|
|
||
|
VOID TestRegionXorClip(Graphics *g)
|
||
|
{
|
||
|
Gdiplus::Status status;
|
||
|
PointF bez1[7];
|
||
|
GraphicsPath * pathBez1 = new GraphicsPath();
|
||
|
ASSERT(pathBez1 != NULL);
|
||
|
|
||
|
bez1[0].X = 200; bez1[0].Y = 275;
|
||
|
bez1[1].X = 200; bez1[1].Y = 225;
|
||
|
bez1[2].X = 300; bez1[2].Y = 225;
|
||
|
bez1[3].X = 300; bez1[3].Y = 275;
|
||
|
bez1[4].X = 300; bez1[4].Y = 325;
|
||
|
bez1[5].X = 200; bez1[5].Y = 325;
|
||
|
bez1[6].X = 200; bez1[6].Y = 275;
|
||
|
|
||
|
status = pathBez1->AddBeziers(bez1, 7);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
PointF bez2[7];
|
||
|
GraphicsPath * pathBez2 = new GraphicsPath();
|
||
|
ASSERT(pathBez2 != NULL);
|
||
|
|
||
|
bez2[0].X = 50; bez2[0].Y = 250;
|
||
|
bez2[1].X = 50; bez2[1].Y = 0;
|
||
|
bez2[2].X = 450; bez2[2].Y = 0;
|
||
|
bez2[3].X = 450; bez2[3].Y = 250;
|
||
|
bez2[4].X = 450; bez2[4].Y = 500;
|
||
|
bez2[5].X = 50; bez2[5].Y = 500;
|
||
|
bez2[6].X = 50; bez2[6].Y = 250;
|
||
|
|
||
|
status = pathBez2->AddBeziers(bez2, 7);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
PointF star[10];
|
||
|
GraphicsPath * pathStar = new GraphicsPath();
|
||
|
ASSERT(pathStar != NULL);
|
||
|
|
||
|
star[0].X = 12; star[0].Y = 192;
|
||
|
star[1].X = 193; star[1].Y = 192;
|
||
|
star[2].X = 250; star[2].Y = 20;
|
||
|
star[3].X = 306; star[3].Y = 192;
|
||
|
star[4].X = 487; star[4].Y = 192;
|
||
|
star[5].X = 340; star[5].Y = 299;
|
||
|
star[6].X = 396; star[6].Y = 472;
|
||
|
star[7].X = 250; star[7].Y = 365;
|
||
|
star[8].X = 103; star[8].Y = 472;
|
||
|
star[9].X = 159; star[9].Y = 299;
|
||
|
|
||
|
status = pathStar->AddPolygon(star, 10);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
RectF regionRect(100, 100, 300, 300);
|
||
|
Gdiplus::Region region(pathStar);
|
||
|
|
||
|
status = region.Xor(regionRect);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
status = region.Union(pathBez1);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
status = region.Xor(pathBez2);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
UINT regionDataSize = region.GetDataSize();
|
||
|
BYTE * regionData = new BYTE[regionDataSize];
|
||
|
ASSERT(regionData);
|
||
|
|
||
|
region.GetData(regionData, regionDataSize, ®ionDataSize);
|
||
|
|
||
|
Gdiplus::Region region2(regionData, regionDataSize);
|
||
|
|
||
|
delete [] regionData;
|
||
|
|
||
|
status = g->SetClip(®ion2);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
PointF pointsRect[4];
|
||
|
|
||
|
pointsRect[0].X = 0;
|
||
|
pointsRect[0].Y = 0;
|
||
|
pointsRect[1].X = 600;
|
||
|
pointsRect[1].Y = 0;
|
||
|
pointsRect[2].X = 600;
|
||
|
pointsRect[2].Y = 600;
|
||
|
pointsRect[3].X = 0;
|
||
|
pointsRect[3].Y = 600;
|
||
|
|
||
|
Gdiplus::SolidBrush alphaBrush(Color(128, 0, 255, 0));
|
||
|
status = g->FillPolygon(&alphaBrush, pointsRect, 4);
|
||
|
ASSERT(status == Ok);
|
||
|
|
||
|
g->ResetClip();
|
||
|
|
||
|
delete pathStar;
|
||
|
delete pathBez1;
|
||
|
delete pathBez2;
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestImaging
|
||
|
*
|
||
|
* A test for imaging and DrawImage.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID RemapBlackAndWhiteMatrix(ColorMatrix *matrix, Color replaceBlack, Color replaceWhite)
|
||
|
{
|
||
|
// Normalize the colors to 1.0.
|
||
|
|
||
|
REAL normBlackRed = ((REAL)replaceBlack.GetRed() )/(REAL)255.0;
|
||
|
REAL normBlackGreen = ((REAL)replaceBlack.GetGreen())/(REAL)255.0;
|
||
|
REAL normBlackBlue = ((REAL)replaceBlack.GetBlue() )/(REAL)255.0;
|
||
|
REAL normBlackAlpha = ((REAL)replaceBlack.GetAlpha())/(REAL)255.0;
|
||
|
|
||
|
REAL normWhiteRed = ((REAL)replaceWhite.GetRed() )/(REAL)255.0;
|
||
|
REAL normWhiteGreen = ((REAL)replaceWhite.GetGreen())/(REAL)255.0;
|
||
|
REAL normWhiteBlue = ((REAL)replaceWhite.GetBlue() )/(REAL)255.0;
|
||
|
REAL normWhiteAlpha = ((REAL)replaceWhite.GetAlpha())/(REAL)255.0;
|
||
|
|
||
|
// Setup a matrix that will map white to transparent black and
|
||
|
// black to the specified color.
|
||
|
//
|
||
|
// | -B -B -B -B 0 |
|
||
|
// | r g b a |
|
||
|
// | |
|
||
|
// | W W W W 0 |
|
||
|
// | r g b a |
|
||
|
// | |
|
||
|
// | 0 0 0 0 0 |
|
||
|
// | |
|
||
|
// | |
|
||
|
// | 0 0 0 0 0 |
|
||
|
// | |
|
||
|
// | |
|
||
|
// | B B B B 1 |
|
||
|
// | r g b a |
|
||
|
|
||
|
memset(matrix, 0, sizeof(ColorMatrix));
|
||
|
|
||
|
matrix->m[0][0] = -normBlackRed;
|
||
|
matrix->m[0][1] = -normBlackGreen;
|
||
|
matrix->m[0][2] = -normBlackBlue;
|
||
|
matrix->m[0][3] = -normBlackAlpha;
|
||
|
|
||
|
matrix->m[1][0] = normWhiteRed;
|
||
|
matrix->m[1][1] = normWhiteGreen;
|
||
|
matrix->m[1][2] = normWhiteBlue;
|
||
|
matrix->m[1][3] = normWhiteAlpha;
|
||
|
|
||
|
matrix->m[4][0] = normBlackRed;
|
||
|
matrix->m[4][1] = normBlackGreen;
|
||
|
matrix->m[4][2] = normBlackBlue;
|
||
|
matrix->m[4][3] = normBlackAlpha;
|
||
|
matrix->m[4][4] = 1.0;
|
||
|
}
|
||
|
|
||
|
VOID NextDestRect(INT xRef, INT yRef, Rect *rect)
|
||
|
{
|
||
|
rect->Y += rect->Height;
|
||
|
|
||
|
if (rect->Y >= (yRef + (4 * rect->Height)))
|
||
|
{
|
||
|
rect->X += rect->Width;
|
||
|
rect->Y = yRef;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BOOL CALLBACK MyDrawImageAbort(VOID* data)
|
||
|
{
|
||
|
UINT *count = (UINT*) data;
|
||
|
|
||
|
*count += 1;
|
||
|
|
||
|
//LBprintf("MyDrawImageAbort: %ld", *count);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
VOID TestImaging(Graphics* g)
|
||
|
{
|
||
|
// Load bmp files.
|
||
|
|
||
|
WCHAR *filename = L"winnt256.bmp";
|
||
|
|
||
|
Image *image = new Image(filename);
|
||
|
|
||
|
// Get information on the image.
|
||
|
|
||
|
UINT imageWidth = image->GetWidth();
|
||
|
UINT imageHeight = image->GetHeight();
|
||
|
|
||
|
// Source clip but preserve aspect ratio (destination is a square).
|
||
|
|
||
|
if (imageWidth < imageHeight)
|
||
|
{
|
||
|
imageWidth = (INT) ((REAL)imageWidth * (REAL).7);
|
||
|
imageHeight = imageWidth;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
imageHeight = (INT) ((REAL)imageHeight * (REAL).7);
|
||
|
imageWidth = imageHeight;
|
||
|
}
|
||
|
|
||
|
// Try to save thumbnail
|
||
|
|
||
|
WCHAR *thumbfile = L"thumb256.bmp";
|
||
|
|
||
|
CLSID _BmpCodecClsID_ =
|
||
|
{
|
||
|
0x557cf400,
|
||
|
0x1a04,
|
||
|
0x11d3,
|
||
|
{0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e}
|
||
|
};
|
||
|
|
||
|
UINT abortCount = 0;
|
||
|
|
||
|
ImageAttributes imgAttrib;
|
||
|
|
||
|
Rect destRect(50, 10, 100, 100);
|
||
|
|
||
|
// Make near-white to white transparent
|
||
|
|
||
|
#ifdef TESTOUTCROP
|
||
|
g->DrawImage(image, destRect, -20, -20, imageOutCrop.Width+20, imageOutCrop.Height+20,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
#else
|
||
|
Color c1(200, 200, 200);
|
||
|
Color c2(255, 255, 255);
|
||
|
imgAttrib.SetColorKey(c2, c2);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
#endif
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
ColorMatrix greyMatrix = {.25, .25, .25, 0, 0,
|
||
|
.25, .25, .25, 0, 0,
|
||
|
.25, .25, .25, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
(REAL).1, (REAL).1, (REAL).1, 0, 1};
|
||
|
|
||
|
imgAttrib.ClearColorKey();
|
||
|
imgAttrib.SetColorMatrix(&greyMatrix);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
ColorMatrix pinkMatrix = {(REAL).33, .25, .25, 0, 0,
|
||
|
(REAL).33, .25, .25, 0, 0,
|
||
|
(REAL).33, .25, .25, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1};
|
||
|
|
||
|
imgAttrib.SetColorMatrix(&pinkMatrix, ColorMatrixFlagsSkipGrays);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
ColorMatrix darkMatrix = {.75, 0, 0, 0, 0,
|
||
|
0, .75, 0, 0, 0,
|
||
|
0, 0, .75, 0, 0,
|
||
|
0, 0, 0, 1, 0,
|
||
|
0, 0, 0, 0, 1};
|
||
|
|
||
|
imgAttrib.SetColorMatrix(&darkMatrix);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
imgAttrib.ClearColorMatrix();
|
||
|
imgAttrib.SetGamma(3.0);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetThreshold(0.5);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
// red->blue, green->red, blue->green, alpha = 0.75
|
||
|
ColorMatrix swapMatrix = {0, 0, 1, 0, 0,
|
||
|
1, 0, 0, 0, 0,
|
||
|
0, 1, 0, 0, 0,
|
||
|
0, 0, 0, .75, 0,
|
||
|
0, 0, 0, 0, 1};
|
||
|
|
||
|
imgAttrib.SetColorMatrix(&swapMatrix);
|
||
|
imgAttrib.ClearGamma();
|
||
|
imgAttrib.ClearThreshold();
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
// red->blue, green->red, blue->green, alpha = 0.9
|
||
|
ColorMatrix swapMatrix2 = {0, 0, 1, 0, 0,
|
||
|
1, 0, 0, 0, 0,
|
||
|
0, 1, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0,
|
||
|
0, 0, 0, (REAL).9, 1};
|
||
|
|
||
|
imgAttrib.SetNoOp();
|
||
|
imgAttrib.SetColorMatrix(&swapMatrix2);
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
imgAttrib.ClearNoOp();
|
||
|
|
||
|
g->DrawImage(image, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
{
|
||
|
Bitmap* bitmap = new Bitmap(imageWidth, imageHeight, g);
|
||
|
if (bitmap)
|
||
|
{
|
||
|
Graphics *bitmapGraphics = Graphics::FromImage(bitmap);
|
||
|
if (bitmapGraphics)
|
||
|
{
|
||
|
imgAttrib.ClearNoOp();
|
||
|
imgAttrib.ClearColorMatrix();
|
||
|
imgAttrib.ClearColorKey();
|
||
|
imgAttrib.ClearGamma();
|
||
|
imgAttrib.SetThreshold(0.5);
|
||
|
|
||
|
Rect rect(0, 0, imageWidth, imageHeight);
|
||
|
bitmapGraphics->DrawImage(image, rect,
|
||
|
0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
|
||
|
delete bitmapGraphics;
|
||
|
}
|
||
|
else
|
||
|
LBprintf("TestImaging: graphics from image");
|
||
|
|
||
|
imgAttrib.ClearThreshold();
|
||
|
|
||
|
ColorMatrix remapBlackAndWhite;
|
||
|
|
||
|
RemapBlackAndWhiteMatrix(&remapBlackAndWhite, Gdiplus::Color::Maroon, 0);
|
||
|
imgAttrib.SetColorMatrix(&remapBlackAndWhite);
|
||
|
|
||
|
g->DrawImage(bitmap, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
RemapBlackAndWhiteMatrix(&remapBlackAndWhite, 0, Gdiplus::Color::Green);
|
||
|
imgAttrib.SetColorMatrix(&remapBlackAndWhite);
|
||
|
|
||
|
g->DrawImage(bitmap, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
Color blackRemap(128, 0xff, 0x00, 0x00);
|
||
|
Color whiteRemap(128, 0x00, 0xff, 0x00);
|
||
|
RemapBlackAndWhiteMatrix(&remapBlackAndWhite, blackRemap, whiteRemap);
|
||
|
imgAttrib.SetColorMatrix(&remapBlackAndWhite);
|
||
|
|
||
|
g->DrawImage(bitmap, destRect, 0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel, &imgAttrib,
|
||
|
MyDrawImageAbort, (VOID*)&abortCount);
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
|
||
|
delete bitmap;
|
||
|
}
|
||
|
else
|
||
|
LBprintf("TestImaging: bitmap creation failed");
|
||
|
}
|
||
|
|
||
|
g->Flush();
|
||
|
|
||
|
delete image;
|
||
|
}
|
||
|
|
||
|
VOID TestBitmapGraphics(Graphics* g)
|
||
|
{
|
||
|
INT bitmapSize = 500;
|
||
|
|
||
|
WCHAR *filename = L"../data/apple1.png";
|
||
|
Bitmap *bitmap = new Bitmap(filename);
|
||
|
|
||
|
UINT imageWidth = bitmap->GetWidth();
|
||
|
UINT imageHeight = bitmap->GetHeight();
|
||
|
|
||
|
Graphics *bitmapGraphics = Graphics::FromImage(bitmap);
|
||
|
|
||
|
if ((!bitmapGraphics) || (bitmapGraphics->GetLastStatus() != Ok))
|
||
|
LBprintf("Bitmap.GetGraphics() failed");
|
||
|
|
||
|
TestRegionExcludeClip(bitmapGraphics);
|
||
|
TestRegionXorClip(bitmapGraphics);
|
||
|
TestContainerClip(bitmapGraphics);
|
||
|
TestContainer(bitmapGraphics);
|
||
|
TestPolygons(bitmapGraphics);
|
||
|
TestPaths(bitmapGraphics);
|
||
|
TestRegions(bitmapGraphics);
|
||
|
TestGradients(bitmapGraphics);
|
||
|
TestHatches(bitmapGraphics);
|
||
|
TestBitmaps(bitmapGraphics);
|
||
|
TestPrimitives(bitmapGraphics);
|
||
|
TestMixedObjects(bitmapGraphics);
|
||
|
TestTexts(bitmapGraphics);
|
||
|
TestImaging(bitmapGraphics);
|
||
|
|
||
|
HDC hdc = bitmapGraphics->GetHDC();
|
||
|
|
||
|
if (!hdc)
|
||
|
LBprintf("Graphics.GetHdc() failed");
|
||
|
|
||
|
LPSTR testString = "Hello, Boo-Boo!";
|
||
|
TextOutA(hdc, 20, 20, testString, strlen(testString));
|
||
|
SetBkMode(hdc, TRANSPARENT);
|
||
|
TextOutA(hdc, 20, 200, testString, strlen(testString));
|
||
|
|
||
|
bitmapGraphics->ReleaseHDC(hdc);
|
||
|
|
||
|
delete bitmapGraphics;
|
||
|
|
||
|
Rect destRect(100, 100, imageWidth, imageHeight);
|
||
|
|
||
|
g->DrawImage(bitmap, destRect, 0, 0, imageWidth, imageHeight, UnitPixel);
|
||
|
|
||
|
delete bitmap;
|
||
|
}
|
||
|
|
||
|
VOID TestWmfs(Graphics *g)
|
||
|
{
|
||
|
GraphicsState s = g->Save();
|
||
|
Metafile * playback = new Metafile(L"Globe.wmf");
|
||
|
// Metafile * playback = new Metafile(L"..\\data\\Flower.wmf");
|
||
|
// Metafile * playback = new Metafile(L"..\\\\radt\\vbssdb\\VbTests\\shadow\\WFCClientRuntime\\Libs\\WFCTestLib\\Util\\Images\\Flower.wmf");
|
||
|
|
||
|
g->SetPageUnit(UnitInch);
|
||
|
g->SetPageScale(1.0f);
|
||
|
g->DrawImage(playback, 0.5f, 0.5f, 4.0f, 4.0f);
|
||
|
delete playback;
|
||
|
g->Restore(s);
|
||
|
}
|
||
|
|
||
|
Matrix * GetTransformFromHdc(HDC hdc);
|
||
|
|
||
|
VOID TestMetaGetDC(Graphics *g, HWND hwnd)
|
||
|
{
|
||
|
{
|
||
|
GpRectF frameRect(0, 0, 100, 100);
|
||
|
HDC hDC = GetDC ( hwnd );
|
||
|
Gdiplus::Metafile emf ( L"test1.emf", hDC, frameRect, Gdiplus::MetafileFrameUnitPixel );
|
||
|
ReleaseDC(hwnd, hDC);
|
||
|
{
|
||
|
Gdiplus::Graphics graphics ( &emf );
|
||
|
HDC gDC = graphics.GetHDC ();
|
||
|
SetWindowOrgEx(gDC, 100, 100, NULL);
|
||
|
Matrix * m = GetTransformFromHdc(gDC);
|
||
|
graphics.ReleaseHDC ( gDC );
|
||
|
graphics.SetTransform(m);
|
||
|
delete m;
|
||
|
|
||
|
Gdiplus::Pen p ( Gdiplus::Color::Black, 1);
|
||
|
graphics.DrawRectangle ( &p, 100, 100, 100, 100 );
|
||
|
|
||
|
graphics.SetRenderingOrigin(10,3);
|
||
|
gDC = graphics.GetHDC ();
|
||
|
HBRUSH brush = CreateSolidBrush ( 0x00FF00 );
|
||
|
HBRUSH prev = ( HBRUSH ) SelectObject ( gDC, brush );
|
||
|
ExtFloodFill(gDC, 170, 170, 0xffffff, FLOODFILLSURFACE);
|
||
|
SelectObject ( gDC, prev );
|
||
|
DeleteObject ( brush );
|
||
|
graphics.ReleaseHDC ( gDC );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Gdiplus::Metafile emf ( L"test1.emf" );
|
||
|
g->DrawImage ( &emf, 10, 10 );
|
||
|
}
|
||
|
|
||
|
#define LTOF(x) (static_cast<REAL>(x))
|
||
|
Matrix * GetTransformFromHdc(HDC hdc)
|
||
|
{
|
||
|
POINT points[3];
|
||
|
PointF destPoints[3];
|
||
|
RectF srcRect;
|
||
|
RectF destRect;
|
||
|
|
||
|
// It would take a lot of time to call all the Win32 APIs to query
|
||
|
// the transform: we would minimally have to call GetMapMode,
|
||
|
// GetWindowOrgEx, and GetViewportOrgEx; and maximally also have to
|
||
|
// call GetWorldTransform, GetViewportExtEx, and GetWindowExtEx.
|
||
|
//
|
||
|
// We cheat a little by making a single call to LPtoDP with a
|
||
|
// parallelogram, and then inferring the result. Note that we do
|
||
|
// run the risk of some error, and on Win9x of overflow, since Win9x
|
||
|
// only supports 16-bit coordinates. To counteract this, we try to
|
||
|
// choose large values that won't overflow.
|
||
|
|
||
|
points[0].x = 0;
|
||
|
points[0].y = 0;
|
||
|
points[1].x = 8192;
|
||
|
points[1].y = 0;
|
||
|
points[2].x = 0;
|
||
|
points[2].y = 8192;
|
||
|
|
||
|
if (!LPtoDP(hdc, points, 3))
|
||
|
{
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
srcRect.X = 0.0f;
|
||
|
srcRect.Y = 0.0f;
|
||
|
srcRect.Width = 8192.0f;
|
||
|
srcRect.Height = 8192.0f;
|
||
|
|
||
|
destPoints[0].X = LTOF(points[0].x);
|
||
|
destPoints[0].Y = LTOF(points[0].y);
|
||
|
destPoints[1].X = LTOF(points[1].x);
|
||
|
destPoints[1].Y = LTOF(points[1].y);
|
||
|
destPoints[2].X = LTOF(points[2].x);
|
||
|
destPoints[2].Y = LTOF(points[2].y);
|
||
|
|
||
|
return new Matrix(srcRect, destPoints);
|
||
|
}
|
||
|
|
||
|
VOID TestLineWithTexture(Graphics *g)
|
||
|
{
|
||
|
Bitmap andrew(L"Gio.jpg");
|
||
|
TextureBrush textureBrush(&andrew, WrapModeTile);
|
||
|
Pen pen(&textureBrush, 40.0);
|
||
|
|
||
|
pen.SetLineJoin(LineJoinMiter);
|
||
|
|
||
|
PointF spiralPoints[12] = {
|
||
|
PointF(540.0f, 550.0f),
|
||
|
PointF(540.0f, 75.0f),
|
||
|
PointF( 60.0f, 75.0f),
|
||
|
PointF( 60.0f, 460.0f),
|
||
|
PointF(460.0f, 460.0f),
|
||
|
PointF(460.0f, 140.0f),
|
||
|
PointF(140.0f, 140.0f),
|
||
|
PointF(140.0f, 400.0f),
|
||
|
PointF(380.0f, 400.0f),
|
||
|
PointF(380.0f, 190.0f),
|
||
|
PointF(260.0f, 190.0f),
|
||
|
PointF(260.0f, 350.0f),
|
||
|
};
|
||
|
|
||
|
g->DrawLines(&pen, spiralPoints, 12);
|
||
|
}
|
||
|
|
||
|
VOID TestRotatedLine(Graphics *g)
|
||
|
{
|
||
|
INT i;
|
||
|
SolidBrush blueBrush(Color(128, 0, 0, 255));
|
||
|
Pen pen(&blueBrush, 10.0);
|
||
|
GraphicsState gState = g->Save();
|
||
|
PointF points[3];
|
||
|
|
||
|
pen.SetDashStyle(DashStyleDot);
|
||
|
pen.SetEndCap(LineCapRound);
|
||
|
|
||
|
points[0].X = 200; points[0].Y = 200;
|
||
|
points[1].X = 340; points[1].Y = 200;
|
||
|
points[2].X = 340; points[2].Y = 345;
|
||
|
|
||
|
#define MYDEGREES 45
|
||
|
for (i = 0; i < 360; i += MYDEGREES)
|
||
|
{
|
||
|
g->TranslateTransform(200, 200);
|
||
|
g->RotateTransform(MYDEGREES);
|
||
|
g->TranslateTransform(-200, -200);
|
||
|
|
||
|
g->DrawLines(&pen, points, 3);
|
||
|
g->Flush();
|
||
|
}
|
||
|
g->Restore(gState);
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestDibsection
|
||
|
*
|
||
|
* This is a quick visual test for verifying that GDI+ properly draws
|
||
|
* to both top-down and bottom-up DIBSections. A red square should
|
||
|
* appear in the upper-left corner of both black squares.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestDibsection(Graphics *g)
|
||
|
{
|
||
|
BITMAPINFO bmi;
|
||
|
HBITMAP hbm;
|
||
|
HDC hdc;
|
||
|
HDC hdcScreen;
|
||
|
HBITMAP hbmOld;
|
||
|
|
||
|
hdcScreen = g->GetHDC();
|
||
|
hdc = CreateCompatibleDC(hdcScreen);
|
||
|
SolidBrush blackBrush(Color::Black);
|
||
|
SolidBrush redBrush(Color::Red);
|
||
|
|
||
|
//////////////////////////////////////////////////////
|
||
|
// First, create the DIB-section as bottom-up:
|
||
|
|
||
|
RtlZeroMemory(&bmi, sizeof(bmi));
|
||
|
|
||
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||
|
bmi.bmiHeader.biWidth = 31;
|
||
|
bmi.bmiHeader.biHeight = 31;
|
||
|
bmi.bmiHeader.biPlanes = 1;
|
||
|
bmi.bmiHeader.biBitCount = 32;
|
||
|
bmi.bmiHeader.biCompression = BI_RGB;
|
||
|
|
||
|
hbm = CreateDIBSection(hdcScreen, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
|
||
|
hbmOld = (HBITMAP) SelectObject(hdc, hbm);
|
||
|
|
||
|
{
|
||
|
Graphics bitmap(hdc);
|
||
|
|
||
|
bitmap.FillRectangle(&blackBrush, 0, 0, 31, 31);
|
||
|
bitmap.FillRectangle(&redBrush, 0, 0, 8, 8);
|
||
|
|
||
|
BitBlt(hdcScreen, 0, 0, 31, 31, hdc, 0, 0, SRCCOPY);
|
||
|
}
|
||
|
|
||
|
SelectObject(hdc, hbmOld);
|
||
|
DeleteObject(hbm);
|
||
|
|
||
|
//////////////////////////////////////////////////////
|
||
|
// Now, create the DIB-section as top-down:
|
||
|
|
||
|
bmi.bmiHeader.biHeight = -31;
|
||
|
|
||
|
hbm = CreateDIBSection(hdcScreen, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
|
||
|
hbmOld = (HBITMAP) SelectObject(hdc, hbm);
|
||
|
|
||
|
{
|
||
|
Graphics bitmap(hdc);
|
||
|
|
||
|
bitmap.FillRectangle(&blackBrush, 0, 0, 31, 31);
|
||
|
bitmap.FillRectangle(&redBrush, 0, 0, 8, 8);
|
||
|
|
||
|
BitBlt(hdcScreen, 40, 0, 31, 31, hdc, 0, 0, SRCCOPY);
|
||
|
}
|
||
|
|
||
|
SelectObject(hdc, hbmOld);
|
||
|
DeleteObject(hbm);
|
||
|
|
||
|
//////////////////////////////////////////////////////
|
||
|
|
||
|
g->ReleaseHDC(hdcScreen);
|
||
|
DeleteObject(hdc);
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* TestCompoundLines
|
||
|
*
|
||
|
* A test for compound lines.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID TestCompoundLines(Graphics *g)
|
||
|
{
|
||
|
REAL width = 4; // Pen width
|
||
|
PointF points[4];
|
||
|
|
||
|
points[0].X = 100;
|
||
|
points[0].Y = 10;
|
||
|
points[1].X = -50;
|
||
|
points[1].Y = 50;
|
||
|
points[2].X = 150;
|
||
|
points[2].Y = 200;
|
||
|
points[3].X = 200;
|
||
|
points[3].Y = 70;
|
||
|
|
||
|
Color yellowColor(128, 255, 255, 0);
|
||
|
SolidBrush yellowBrush(yellowColor);
|
||
|
|
||
|
GraphicsPath* path = new GraphicsPath(FillModeAlternate);
|
||
|
path->AddBeziers(points, 4);
|
||
|
|
||
|
points[0].X = 260;
|
||
|
points[0].Y = 20;
|
||
|
path->AddLines(points, 1);
|
||
|
Matrix matrix;
|
||
|
matrix.Scale(1.5, 1.5);
|
||
|
matrix.Translate(0, 30);
|
||
|
|
||
|
// If you wanto to flatten the path before rendering,
|
||
|
// Flatten() can be called.
|
||
|
|
||
|
BOOL flattenFirst = FALSE;
|
||
|
|
||
|
if(!flattenFirst)
|
||
|
{
|
||
|
// Don't flatten and keep the original path.
|
||
|
// FillPath or DrawPath will flatten the path automatically
|
||
|
// without modifying the original path.
|
||
|
|
||
|
path->Transform(&matrix);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Flatten this path. The resultant path is made of line
|
||
|
// segments. The original path information is lost.
|
||
|
|
||
|
path->Flatten(&matrix);
|
||
|
}
|
||
|
|
||
|
Color blackColor(0, 0, 0);
|
||
|
|
||
|
SolidBrush blackBrush(blackColor);
|
||
|
// Set the pen width in inch.
|
||
|
width = 15;
|
||
|
Pen blackPen(&blackBrush, width);
|
||
|
|
||
|
REAL* compoundArray = new REAL[6];
|
||
|
compoundArray[0] = 0.0f;
|
||
|
compoundArray[1] = 0.2f;
|
||
|
compoundArray[2] = 0.4f;
|
||
|
compoundArray[3] = 0.6f;
|
||
|
compoundArray[4] = 0.8f;
|
||
|
compoundArray[5] = 1.0f;
|
||
|
blackPen.SetCompoundArray(&compoundArray[0], 6);
|
||
|
blackPen.SetDashStyle(DashStyleDash);
|
||
|
|
||
|
blackPen.SetStartCap(LineCapDiamondAnchor);
|
||
|
blackPen.SetEndCap(LineCapArrowAnchor);
|
||
|
|
||
|
g->FillPath(&yellowBrush, path);
|
||
|
g->DrawPath(&blackPen, path);
|
||
|
delete path;
|
||
|
}
|
||
|
|
||
|
VOID TestImageSampling(Graphics* g)
|
||
|
{
|
||
|
// Load bmp files.
|
||
|
|
||
|
WCHAR *filename = L"..\\data\\3x3.bmp";
|
||
|
|
||
|
Image *image = new Image(filename);
|
||
|
|
||
|
// Get information on the image.
|
||
|
|
||
|
if (image && (image->GetLastStatus() == Ok))
|
||
|
{
|
||
|
UINT imageWidth = image->GetWidth();
|
||
|
UINT imageHeight = image->GetHeight();
|
||
|
|
||
|
if (image->GetLastStatus() == Ok)
|
||
|
{
|
||
|
if (imageHeight >= 2 && imageWidth >= 2)
|
||
|
{
|
||
|
// Draw the whole image
|
||
|
|
||
|
Rect destRect(50, 10, 100, 100);
|
||
|
g->DrawImage(image, destRect,
|
||
|
0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel);
|
||
|
|
||
|
// Stretch pixel (1, 1)
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
g->DrawImage(image, destRect,
|
||
|
1, 1, 1, 1,
|
||
|
UnitPixel);
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Image is %ldx%ld, 2x2 image or greater required",
|
||
|
imageWidth, imageHeight);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to load image file %ws", filename);
|
||
|
|
||
|
delete image;
|
||
|
}
|
||
|
|
||
|
VOID TestIcon(Graphics* g)
|
||
|
{
|
||
|
Rect destRect(50, 10, 8, 8);
|
||
|
|
||
|
// Load bmp files.
|
||
|
|
||
|
//WCHAR *filename = L"..\\data\\nyt.ico";
|
||
|
//WCHAR *filename = L"..\\data\\pos.ico";
|
||
|
//WCHAR *filename = L"..\\data\\signl.ico";
|
||
|
WCHAR *filename = L"..\\data\\wbros.ico";
|
||
|
|
||
|
Image *image = new Image(filename);
|
||
|
|
||
|
// Get information on the image.
|
||
|
|
||
|
if (image)
|
||
|
{
|
||
|
if (image->GetLastStatus() == Ok)
|
||
|
{
|
||
|
UINT imageWidth = image->GetWidth();
|
||
|
UINT imageHeight = image->GetHeight();
|
||
|
|
||
|
if (image->GetLastStatus() == Ok)
|
||
|
{
|
||
|
LBprintf("icon size: %ld x %ld", imageWidth, imageHeight);
|
||
|
|
||
|
g->DrawImage(image, destRect);
|
||
|
g->Flush();
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 12;
|
||
|
destRect.Height = 12;
|
||
|
|
||
|
g->DrawImage(image, destRect);
|
||
|
g->Flush();
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 16;
|
||
|
destRect.Height = 16;
|
||
|
|
||
|
g->DrawImage(image, destRect);
|
||
|
g->Flush();
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 24;
|
||
|
destRect.Height = 24;
|
||
|
|
||
|
g->DrawImage(image, destRect);
|
||
|
g->Flush();
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 32;
|
||
|
destRect.Height = 32;
|
||
|
|
||
|
g->DrawImage(image, destRect);
|
||
|
g->Flush();
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 48;
|
||
|
destRect.Height = 48;
|
||
|
|
||
|
g->DrawImage(image, destRect,
|
||
|
0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel
|
||
|
);
|
||
|
g->Flush();
|
||
|
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 64;
|
||
|
destRect.Height = 64;
|
||
|
|
||
|
g->DrawImage(image, destRect,
|
||
|
0, 0, imageWidth, imageHeight,
|
||
|
UnitPixel
|
||
|
);
|
||
|
g->Flush();
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to get image width/height");
|
||
|
}
|
||
|
|
||
|
delete image;
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to load image file %ws", filename);
|
||
|
|
||
|
HICON hicon = LoadIcon(NULL, IDI_ERROR);
|
||
|
|
||
|
if (hicon)
|
||
|
{
|
||
|
Bitmap *icon = new Bitmap(hicon);
|
||
|
|
||
|
if (icon)
|
||
|
{
|
||
|
NextDestRect(50, 10, &destRect);
|
||
|
destRect.Width = 32;
|
||
|
destRect.Height = 32;
|
||
|
|
||
|
g->DrawImage(icon, destRect);
|
||
|
|
||
|
delete icon;
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to create Bitmap from HICON");
|
||
|
|
||
|
WCHAR *iconfile = L"..\\data\\pos.ico";
|
||
|
|
||
|
Bitmap* bitmap = new Bitmap(iconfile);
|
||
|
|
||
|
if (bitmap)
|
||
|
{
|
||
|
HDC hdc = g->GetHDC();
|
||
|
if (hdc)
|
||
|
{
|
||
|
HICON hicon2;
|
||
|
|
||
|
if (bitmap->GetHICON(&hicon2) == Ok)
|
||
|
{
|
||
|
DrawIcon(hdc, 100, 100, hicon2);
|
||
|
|
||
|
DestroyIcon(hicon2);
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Bitmap::GetHICON failed");
|
||
|
|
||
|
g->ReleaseHDC(hdc);
|
||
|
}
|
||
|
|
||
|
delete bitmap;
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to load %ws", iconfile);
|
||
|
|
||
|
DestroyIcon(hicon);
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to load Win32 icon IDI_ERROR");
|
||
|
}
|
||
|
|
||
|
VOID TestTextToMetafile(Graphics *g, HDC hdc)
|
||
|
{
|
||
|
FontFamily ff(L"Arial");
|
||
|
RectF rectf(20, 0, 300, 200);
|
||
|
Font font(&ff, 20, FontStyleBold, UnitPixel);
|
||
|
SolidBrush brush(Color(128, 100, 0, 200));
|
||
|
|
||
|
g->DrawString(L"The quick brown fox jumped over the lazy dog", -1,
|
||
|
&font, rectf, NULL, &brush);
|
||
|
|
||
|
g->Flush();
|
||
|
|
||
|
Metafile metaFile(L"Text.emf", hdc);
|
||
|
{
|
||
|
Graphics gMeta(&metaFile);
|
||
|
gMeta.DrawString(L"ABCDEFG", 7,
|
||
|
&font, rectf, NULL, &brush);
|
||
|
}
|
||
|
g->DrawImage(&metaFile, 100, 100);
|
||
|
g->Flush();
|
||
|
}
|
||
|
|
||
|
VOID TestCmykSeparation(Graphics *g)
|
||
|
{
|
||
|
HINSTANCE hinst = GetModuleHandle(NULL);
|
||
|
|
||
|
if (hinst)
|
||
|
{
|
||
|
Bitmap *bitmap = new Bitmap(hinst, MAKEINTRESOURCE(IDB_BITMAPCMYKTEST));
|
||
|
|
||
|
// Get information on the bitmap.
|
||
|
|
||
|
if (bitmap)
|
||
|
{
|
||
|
if (bitmap->GetLastStatus() == Ok)
|
||
|
{
|
||
|
UINT width = bitmap->GetWidth();
|
||
|
UINT height = bitmap->GetHeight();
|
||
|
|
||
|
if (bitmap->GetLastStatus() == Ok)
|
||
|
{
|
||
|
Rect destRect(150, 10, 100, 100);
|
||
|
|
||
|
ImageAttributes imgAttrib;
|
||
|
|
||
|
imgAttrib.SetOutputChannelColorProfile(L"..\\data\\mswopallp8.icm");
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsC);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsM);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsY);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsK);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannelColorProfile(L"..\\data\\mswopintent.icm");
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsC);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsM);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsY);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsK);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.ClearOutputChannelColorProfile();
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsC);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsM);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsY);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
imgAttrib.SetOutputChannel(ColorChannelFlagsK);
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
|
||
|
|
||
|
imgAttrib.ClearOutputChannel();
|
||
|
g->DrawImage(bitmap, destRect,
|
||
|
0, 0, width, height,
|
||
|
UnitPixel, &imgAttrib);
|
||
|
NextDestRect(150, 10, &destRect);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
delete bitmap;
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to bitmap resource");
|
||
|
}
|
||
|
else
|
||
|
LBprintf("Failed to get module handle");
|
||
|
}
|