Skip to content
Permalink
Browse files

Merge pull request #41 from shoo/add_EnhancedMetaFile

Add enhanced meta file
  • Loading branch information...
Rayerd committed Jan 13, 2015
2 parents 704496b + 6434ed0 commit 409009ed04a81cb895cd9b5dc2a8aceb69778da5
Showing with 290 additions and 3 deletions.
  1. +219 −0 win32/dfl/drawing.d
  2. +71 −3 win32/dfl/internal/winapi.d
@@ -1172,6 +1172,125 @@ class Bitmap: Image // docmain
}


///
final class EnhancedMetaFile: Image
{
private:
HENHMETAFILE hemf;
ENHMETAHEADER emfh;
HDC hdcref;
bool owned;
public:
// Used internally.
this(HENHMETAFILE hemf, HDC hdcref = null, bool owned = true)
{
this.hemf = hemf;
GetEnhMetaFileHeader(hemf, ENHMETAHEADER.sizeof, &emfh);
assert(hdcref || owned);
if (!hdcref)
{
this.hdcref = GetDC(null);
this.owned = true;
}
}

/// Load from a emf file.
this(string fileName, HDC hdcref = null)
{
import std.utf;
auto tmp = GetEnhMetaFileW(fileName.toUTF16z());
if(!tmp)
throw new DflException("Unable to load EnhanceMetaFile from file '" ~ fileName ~ "'");
this(tmp, hdcref);
}

///
void dispose()
{
DeleteEnhMetaFile(hemf);
hemf = null;
if (owned)
ReleaseDC(null, hdcref);
}


~this()
{
dispose();
}


///
final HENHMETAFILE handle() @property // getter
{
return hemf;
}

///
Rect bounds() const nothrow @property
{
with (emfh)
{
auto rc = RECT(
MulDiv(rclBounds.left * 1000, szlDevice.cx * GetDeviceCaps(cast(HDC)hdcref, HORZSIZE), szlMicrometers.cx * GetDeviceCaps(cast(HDC)hdcref, HORZRES)),
MulDiv(rclBounds.top * 1000, szlDevice.cy * GetDeviceCaps(cast(HDC)hdcref, VERTSIZE), szlMicrometers.cy * GetDeviceCaps(cast(HDC)hdcref, VERTRES)),
MulDiv(rclBounds.right * 1000, szlDevice.cx * GetDeviceCaps(cast(HDC)hdcref, HORZSIZE), szlMicrometers.cx * GetDeviceCaps(cast(HDC)hdcref, HORZRES)),
MulDiv(rclBounds.bottom * 1000, szlDevice.cy * GetDeviceCaps(cast(HDC)hdcref, VERTSIZE), szlMicrometers.cy * GetDeviceCaps(cast(HDC)hdcref, VERTRES)));
return Rect(&rc);
}
}

///
override int width() const pure nothrow @property // getter
{
with (emfh)
return MulDiv(rclFrame.right - rclFrame.left, szlDevice.cx * 10, szlMicrometers.cx);
}

///
override int height() const pure nothrow @property // getter
{
with (emfh)
return MulDiv(rclFrame.bottom - rclFrame.top, szlDevice.cy * 10, szlMicrometers.cy);
}

///
override Size size() const pure nothrow @property // getter
{
return Size(width, height);
}

///
Rect frameRectangle() const pure nothrow @property
{
with (emfh)
{
return Rect(
MulDiv(rclFrame.left, szlDevice.cx * 10, szlMicrometers.cx),
MulDiv(rclFrame.top, szlDevice.cy * 10, szlMicrometers.cy),
width, height);
}
}

///
override void draw(Graphics g, Point pt)
{
auto sz = size;
RECT rc;
Rect(pt.x, pt.y, sz.width, sz.height).getRect(&rc);
PlayEnhMetaFile(g.handle, hemf, &rc);
}

///
override void drawStretched(Graphics g, Rect r)
{
RECT rc;
r.getRect(&rc);
PlayEnhMetaFile(g.handle, hemf, &rc);
}
}


///
class Picture: Image // docmain
{
@@ -3124,6 +3243,106 @@ class MemoryGraphics: Graphics // docmain
int _w, _h;
}

///
final class EmfGraphics: Graphics
{
private:
HDC _hdc;
Rect _area;
public:

///
this(Graphics refGraphics = null, Rect area = Rect.init, string filename = null, string description = null)
{
_area = area;
RECT rc;
RECT* pRc;
HDC hdcref;
if (refGraphics)
{
hdcref = refGraphics.handle;
}
else
{
hdcref = GetDC(null);
}
scope (exit)
{
if (!refGraphics)
ReleaseDC(null, hdcref);
}
if (area != Rect.init)
{
auto tmphdc = CreateEnhMetaFileW(hdcref, null, null, null);
auto tmpemf = CloseEnhMetaFile(tmphdc);
ENHMETAHEADER tmphdr;
GetEnhMetaFileHeader(tmpemf, ENHMETAHEADER.sizeof, &tmphdr);
DeleteEnhMetaFile(tmpemf);
rc.left = MulDiv(_area.x, GetDeviceCaps(hdcref, HORZSIZE) * 100, tmphdr.szlDevice.cx);
rc.top = MulDiv(_area.y, GetDeviceCaps(hdcref, VERTSIZE) * 100, tmphdr.szlDevice.cy);
rc.right = MulDiv(_area.right, GetDeviceCaps(hdcref, HORZSIZE) * 100, tmphdr.szlDevice.cx);
rc.bottom = MulDiv(_area.bottom, GetDeviceCaps(hdcref, VERTSIZE) * 100, tmphdr.szlDevice.cy);
pRc = &rc;
}
import std.utf;
_hdc = CreateEnhMetaFileW(
hdcref,
filename.length ? filename.toUTF16z(): null,
pRc,
description.length ? description.toUTF16z(): null);
super(_hdc, false);
}

///
this(Rect area, string filename = null, string description = null)
{
this(null, area, filename, description);
}

///
this(uint width, uint height, string filename = null, string description = null)
{
this(null, Rect(0, 0, width, height), filename, description);
}

override void dispose()
{
super.dispose();
if (_hdc)
DeleteEnhMetaFile(CloseEnhMetaFile(_hdc));
}

///
Size size() const pure nothrow @property
{
return _area.size;
}

///
uint width() const pure nothrow @property
{
return _area.width;
}

///
uint height() const pure nothrow @property
{
return _area.height;
}

///
Rect frameRectangle() const pure nothrow @property
{
return _area;
}

///
EnhancedMetaFile toEnhancedMetaFile()
{
return new EnhancedMetaFile(CloseEnhMetaFile(_hdc));
}
}


// Use with GetDC()/GetWindowDC()/GetDCEx() so that
// the HDC is properly released instead of deleted.
@@ -810,10 +810,46 @@ extern(Windows) nothrow:
}


enum
enum: int
{
LOGPIXELSX = 88,
LOGPIXELSY = 90,
DRIVERVERSION = 0,
TECHNOLOGY = 2,
HORZSIZE = 4,
VERTSIZE = 6,
HORZRES = 8,
VERTRES = 10,
BITSPIXEL = 12,
PLANES = 14,
NUMBRUSHES = 16,
NUMPENS = 18,
NUMMARKERS = 20,
NUMFONTS = 22,
NUMCOLORS = 24,
PDEVICESIZE = 26,
CURVECAPS = 28,
LINECAPS = 30,
POLYGONALCAPS = 32,
TEXTCAPS = 34,
CLIPCAPS = 36,
RASTERCAPS = 38,
ASPECTX = 40,
ASPECTY = 42,
ASPECTXY = 44,
LOGPIXELSX = 88,
LOGPIXELSY = 90,
SIZEPALETTE = 104,
NUMRESERVED = 106,
COLORRES = 108,
PHYSICALWIDTH = 110,
PHYSICALHEIGHT = 111,
PHYSICALOFFSETX = 112,
PHYSICALOFFSETY = 113,
SCALINGFACTORX = 114,
SCALINGFACTORY = 115,
VREFRESH = 116,
DESKTOPVERTRES = 117,
DESKTOPHORZRES = 118,
BLTALIGNMENT = 119
}


@@ -2749,6 +2785,32 @@ extern(Windows) nothrow:
}


struct ENHMETAHEADER
{
alias SIZE SIZEL;
alias RECT RECTL;
DWORD iType = 1;
DWORD nSize = ENHMETAHEADER.sizeof;
RECTL rclBounds;
RECTL rclFrame;
DWORD dSignature = 1179469088;
DWORD nVersion;
DWORD nBytes;
DWORD nRecords;
WORD nHandles;
WORD sReserved;
DWORD nDescription;
DWORD offDescription;
DWORD nPalEntries;
SIZEL szlDevice;
SIZEL szlMillimeters;
DWORD cbPixelFormat;
DWORD offPixelFormat;
DWORD bOpenGL;
SIZEL szlMicrometers;
}


BOOL DrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
BOOL DrawIcon(HDC hDC, int X, int Y, HICON hIcon);
BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
@@ -2965,6 +3027,12 @@ extern(Windows) nothrow:
BOOL IsMenu(HMENU hMenu);
HMENU GetSystemMenu(HWND hWnd, BOOL bRevert);
DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize);
HDC CreateEnhMetaFileW(HDC hdcRef, LPCWSTR lpFilename, in RECT* lpRect, LPCWSTR lpDescription );
BOOL PlayEnhMetaFile(HDC hdc, HENHMETAFILE hemf, in RECT* lpRect);
HENHMETAFILE CloseEnhMetaFile(HDC hdc);
BOOL DeleteEnhMetaFile(HENHMETAFILE hemf);
HENHMETAFILE GetEnhMetaFileW(LPCWSTR lpszMetaFile);
UINT GetEnhMetaFileHeader(HENHMETAFILE hemf, UINT cbBuffer, ENHMETAHEADER* cbBuffer);
HBITMAP CreateBitmap(int nWidth, int nHeight, UINT cPlanes, UINT cBitsPerPel, VOID *lpvBits);
BOOL SetBrushOrgEx(HDC hdc, int nXOrg, int nYOrg, LPPOINT lppt);
BOOL PatBlt(HDC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, DWORD dwRop);

0 comments on commit 409009e

Please sign in to comment.
You can’t perform that action at this time.