From 2432b970ddde25fe955122b8a8dbd3149d4f1325 Mon Sep 17 00:00:00 2001 From: ulferikson Date: Mon, 14 Jul 2008 14:14:43 +0000 Subject: [PATCH] Minor fixes for emf input/output on windows --- src/extension/internal/emf-win32-inout.cpp | 416 +++++++++++++++------ src/extension/internal/emf-win32-print.cpp | 84 ++++- 2 files changed, 361 insertions(+), 139 deletions(-) diff --git a/src/extension/internal/emf-win32-inout.cpp b/src/extension/internal/emf-win32-inout.cpp index 7c2aa9192..acae6d333 100644 --- a/src/extension/internal/emf-win32-inout.cpp +++ b/src/extension/internal/emf-win32-inout.cpp @@ -189,20 +189,22 @@ typedef struct emf_callback_data { SIZEL sizeWnd; SIZEL sizeView; - float PixelsX; - float PixelsY; + float PixelsInX, PixelsInY; + float PixelsOutX, PixelsOutY; float MMX; float MMY; float dwInchesX; float dwInchesY; POINTL winorg; POINTL vieworg; - double ScaleX, ScaleY; + double ScaleInX, ScaleInY; + double ScaleOutX, ScaleOutY; COLORREF textColor; bool textColorSet; DWORD textAlign; XFORM worldTransform; unsigned int id; + CHAR *pDesc; int n_obj; PEMF_OBJECT emf_obj; @@ -303,7 +305,7 @@ static double _pix_x_to_point(PEMF_CALLBACK_DATA d, double px) { double tmp = px - d->winorg.x; - tmp *= d->ScaleX ? (double) PX_PER_IN / d->ScaleX : 1.0; + tmp *= d->ScaleInX ? d->ScaleInX : 1.0; tmp += d->vieworg.x; return tmp; } @@ -312,7 +314,7 @@ static double _pix_y_to_point(PEMF_CALLBACK_DATA d, double px) { double tmp = px - d->winorg.y; - tmp *= d->ScaleY ? (double) PX_PER_IN / d->ScaleY : 1.0; + tmp *= d->ScaleInY ? d->ScaleInY : 1.0; tmp += d->vieworg.y; return tmp; } @@ -325,6 +327,7 @@ pix_to_x_point(PEMF_CALLBACK_DATA d, double px, double py) double ppy = _pix_y_to_point(d, py); double x = ppx * d->worldTransform.eM11 + ppy * d->worldTransform.eM21 + d->worldTransform.eDx; + x *= d->ScaleOutX ? d->ScaleOutX : DEVICESCALE; return x; } @@ -336,20 +339,11 @@ pix_to_y_point(PEMF_CALLBACK_DATA d, double px, double py) double ppy = _pix_y_to_point(d, py); double y = ppx * d->worldTransform.eM12 + ppy * d->worldTransform.eM22 + d->worldTransform.eDy; + y *= d->ScaleOutY ? d->ScaleOutY : DEVICESCALE; return y; } - -static double -_pix_size_to_point(PEMF_CALLBACK_DATA d, double px) -{ - double tmp = px; - tmp *= d->ScaleX ? (double) PX_PER_IN / d->ScaleX : 1.0; - return tmp; -} - - static double pix_to_size_point(PEMF_CALLBACK_DATA d, double px) { @@ -677,7 +671,7 @@ static void assert_empty_path(PEMF_CALLBACK_DATA d, const char *fun) { if (!d->path->empty()) { - g_debug("emf-win32-inout: assert_empty_path failed for %s\n", fun); + // g_debug("emf-win32-inout: assert_empty_path failed for %s\n", fun); *(d->outsvg) += "\n"; + + *(d->outsvg) += "\n"; + + if (d->pDesc) { + *(d->outsvg) += "\n"; + } + ENHMETAHEADER *pEmr = (ENHMETAHEADER *) lpEMFR; tmp_outsvg << "xDPI = 2540; d->yDPI = 2540; - d->PixelsX = pEmr->rclFrame.right - pEmr->rclFrame.left; - d->PixelsY = pEmr->rclFrame.bottom - pEmr->rclFrame.top; + d->PixelsInX = pEmr->rclFrame.right - pEmr->rclFrame.left; + d->PixelsInY = pEmr->rclFrame.bottom - pEmr->rclFrame.top; - d->MMX = d->PixelsX / 100.0; - d->MMY = d->PixelsY / 100.0; + d->MMX = d->PixelsInX / 100.0; + d->MMY = d->PixelsInY / 100.0; + d->PixelsOutX = d->MMX * PX_PER_MM; + d->PixelsOutY = d->MMY * PX_PER_MM; + tmp_outsvg << " width=\"" << d->MMX << "mm\"\n" << - " height=\"" << d->MMY << "mm\">\n"; - tmp_outsvg << "\n"; + " height=\"" << d->MMY << "mm\"\n"; + tmp_outsvg << + " id=\"" << (d->id++) << "\">\n"; + + tmp_outsvg << + "id++) << "\">\n"; if (pEmr->nHandles) { d->n_obj = pEmr->nHandles; @@ -763,6 +779,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYBEZIER: { + dbg_str << "\n"; + PEMRPOLYBEZIER pEmr = (PEMRPOLYBEZIER) lpEMFR; DWORD i,j; @@ -803,6 +821,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYGON: { + dbg_str << "\n"; + EMRPOLYGON *pEmr = (EMRPOLYGON *) lpEMFR; DWORD i; @@ -834,6 +854,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYLINE: { + dbg_str << "\n"; + EMRPOLYLINE *pEmr = (EMRPOLYLINE *) lpEMFR; DWORD i; @@ -872,6 +894,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYBEZIERTO: { + dbg_str << "\n"; + PEMRPOLYBEZIERTO pEmr = (PEMRPOLYBEZIERTO) lpEMFR; DWORD i,j; @@ -893,6 +917,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYLINETO: { + dbg_str << "\n"; + PEMRPOLYLINETO pEmr = (PEMRPOLYLINETO) lpEMFR; DWORD i; @@ -913,6 +939,11 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb case EMR_POLYPOLYLINE: case EMR_POLYPOLYGON: { + if (lpEMFR->iType == EMR_POLYPOLYLINE) + dbg_str << "\n"; + if (lpEMFR->iType == EMR_POLYPOLYGON) + dbg_str << "\n"; + PEMRPOLYPOLYGON pEmr = (PEMRPOLYPOLYGON) lpEMFR; unsigned int n, i, j; @@ -960,94 +991,134 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_SETWINDOWEXTEX: { - PEMRSETWINDOWEXTEX pEmr = (PEMRSETWINDOWEXTEX) lpEMFR; + dbg_str << "\n"; - *(d->outsvg) += "\n"; + PEMRSETWINDOWEXTEX pEmr = (PEMRSETWINDOWEXTEX) lpEMFR; d->sizeWnd = pEmr->szlExtent; - d->PixelsX = d->sizeWnd.cx; - d->PixelsY = d->sizeWnd.cy; - d->ScaleX = d->xDPI / (100*d->MMX / d->PixelsX); - d->ScaleY = d->yDPI / (100*d->MMY / d->PixelsY); + if (!d->sizeWnd.cx || !d->sizeWnd.cy) { + d->sizeWnd = d->sizeView; + if (!d->sizeWnd.cx || !d->sizeWnd.cy) { + d->sizeWnd.cx = d->PixelsOutX; + d->sizeWnd.cy = d->PixelsOutY; + } + } + + if (!d->sizeView.cx || !d->sizeView.cy) { + d->sizeView = d->sizeWnd; + } + + d->PixelsInX = d->sizeWnd.cx; + d->PixelsInY = d->sizeWnd.cy; + + if (d->PixelsInX && d->PixelsInY) { + d->ScaleInX = (double) d->sizeView.cx / (double) d->PixelsInX; + d->ScaleInY = (double) d->sizeView.cy / (double) d->PixelsInY; + } + else { + d->ScaleInX = 1; + d->ScaleInY = 1; + } + + if (d->sizeView.cx && d->sizeView.cy) { + d->ScaleOutX = (double) d->PixelsOutX / (double) d->sizeView.cx; + d->ScaleOutY = (double) d->PixelsOutY / (double) d->sizeView.cy; + } + else { + d->ScaleOutX = DEVICESCALE; + d->ScaleOutY = DEVICESCALE; + } break; } case EMR_SETWINDOWORGEX: { + dbg_str << "\n"; + PEMRSETWINDOWORGEX pEmr = (PEMRSETWINDOWORGEX) lpEMFR; d->winorg = pEmr->ptlOrigin; break; } case EMR_SETVIEWPORTEXTEX: { - PEMRSETVIEWPORTEXTEX pEmr = (PEMRSETVIEWPORTEXTEX) lpEMFR; + dbg_str << "\n"; - *(d->outsvg) += "\n"; + PEMRSETVIEWPORTEXTEX pEmr = (PEMRSETVIEWPORTEXTEX) lpEMFR; d->sizeView = pEmr->szlExtent; - if (d->sizeWnd.cx && d->sizeWnd.cy) { - /* - HDC hScreenDC = GetDC( NULL ); - - float scrPixelsX = (float)GetDeviceCaps( hScreenDC, HORZRES ); - float scrPixelsY = (float)GetDeviceCaps( hScreenDC, VERTRES ); - float scrMMX = (float)GetDeviceCaps( hScreenDC, HORZSIZE ); - float scrMMY = (float)GetDeviceCaps( hScreenDC, VERTSIZE ); - - ReleaseDC( NULL, hScreenDC ); - - d->dwInchesX = d->sizeView.cx / (25.4f*scrPixelsX/scrMMX); - d->dwInchesY = d->sizeView.cy / (25.4f*scrPixelsY/scrMMY); - d->xDPI = d->sizeWnd.cx / d->dwInchesX; - d->yDPI = d->sizeWnd.cy / d->dwInchesY; - */ - if (1) { - d->xDPI = 2540; - d->yDPI = 2540; - d->dwInchesX = d->PixelsX / d->xDPI; - d->dwInchesY = d->PixelsY / d->yDPI; - d->ScaleX = d->xDPI; - d->ScaleY = d->yDPI; + if (!d->sizeView.cx || !d->sizeView.cy) { + d->sizeView = d->sizeWnd; + if (!d->sizeView.cx || !d->sizeView.cy) { + d->sizeView.cx = d->PixelsOutX; + d->sizeView.cy = d->PixelsOutY; } + } + + if (!d->sizeWnd.cx || !d->sizeWnd.cy) { + d->sizeWnd = d->sizeView; + } + + d->PixelsInX = d->sizeWnd.cx; + d->PixelsInY = d->sizeWnd.cy; + + if (d->PixelsInX && d->PixelsInY) { + d->ScaleInX = (double) d->sizeView.cx / (double) d->PixelsInX; + d->ScaleInY = (double) d->sizeView.cy / (double) d->PixelsInY; + } + else { + d->ScaleInX = 1; + d->ScaleInY = 1; + } - d->MMX = d->dwInchesX * MM_PER_IN; - d->MMY = d->dwInchesY * MM_PER_IN; + if (d->sizeView.cx && d->sizeView.cy) { + d->ScaleOutX = (double) d->PixelsOutX / (double) d->sizeView.cx; + d->ScaleOutY = (double) d->PixelsOutY / (double) d->sizeView.cy; + } + else { + d->ScaleOutX = DEVICESCALE; + d->ScaleOutY = DEVICESCALE; } break; } case EMR_SETVIEWPORTORGEX: { + dbg_str << "\n"; + PEMRSETVIEWPORTORGEX pEmr = (PEMRSETVIEWPORTORGEX) lpEMFR; d->vieworg = pEmr->ptlOrigin; break; } case EMR_SETBRUSHORGEX: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_EOF: { + dbg_str << "\n"; + assert_empty_path(d, "EMR_EOF"); tmp_outsvg << "\n"; tmp_outsvg << "\n"; break; } case EMR_SETPIXELV: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETMAPPERFLAGS: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETMAPMODE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETBKMODE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETPOLYFILLMODE: { + dbg_str << "\n"; + PEMRSETPOLYFILLMODE pEmr = (PEMRSETPOLYFILLMODE) lpEMFR; d->style.fill_rule.value = (pEmr->iMode == ALTERNATE ? 0 : @@ -1055,35 +1126,41 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_SETROP2: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETSTRETCHBLTMODE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETTEXTALIGN: { + dbg_str << "\n"; + PEMRSETTEXTALIGN pEmr = (PEMRSETTEXTALIGN) lpEMFR; d->textAlign = pEmr->iMode; break; } case EMR_SETCOLORADJUSTMENT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETTEXTCOLOR: { + dbg_str << "\n"; + PEMRSETTEXTCOLOR pEmr = (PEMRSETTEXTCOLOR) lpEMFR; d->textColor = pEmr->crColor; d->textColorSet = true; break; } case EMR_SETBKCOLOR: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_OFFSETCLIPRGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_MOVETOEX: { + dbg_str << "\n"; + PEMRMOVETOEX pEmr = (PEMRMOVETOEX) lpEMFR; if (d->path->empty()) { @@ -1098,34 +1175,38 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_SETMETARGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_EXCLUDECLIPRECT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_INTERSECTCLIPRECT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SCALEVIEWPORTEXTEX: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SCALEWINDOWEXTEX: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SAVEDC: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_RESTOREDC: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETWORLDTRANSFORM: { + dbg_str << "\n"; + PEMRSETWORLDTRANSFORM pEmr = (PEMRSETWORLDTRANSFORM) lpEMFR; d->worldTransform = pEmr->xform; break; } case EMR_MODIFYWORLDTRANSFORM: { + dbg_str << "\n"; + PEMRMODIFYWORLDTRANSFORM pEmr = (PEMRMODIFYWORLDTRANSFORM) lpEMFR; switch (pEmr->iMode) { @@ -1232,6 +1313,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_SELECTOBJECT: { + dbg_str << "\n"; + PEMRSELECTOBJECT pEmr = (PEMRSELECTOBJECT) lpEMFR; unsigned int index = pEmr->ihObject; @@ -1309,6 +1392,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_CREATEPEN: { + dbg_str << "\n"; + PEMRCREATEPEN pEmr = (PEMRCREATEPEN) lpEMFR; int index = pEmr->ihPen; @@ -1321,6 +1406,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_CREATEBRUSHINDIRECT: { + dbg_str << "\n"; + PEMRCREATEBRUSHINDIRECT pEmr = (PEMRCREATEBRUSHINDIRECT) lpEMFR; int index = pEmr->ihBrush; @@ -1332,12 +1419,15 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_DELETEOBJECT: + dbg_str << "\n"; break; case EMR_ANGLEARC: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_ELLIPSE: { + dbg_str << "\n"; + PEMRELLIPSE pEmr = (PEMRELLIPSE) lpEMFR; RECTL rclBox = pEmr->rclBox; @@ -1369,6 +1459,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_RECTANGLE: { + dbg_str << "\n"; + PEMRRECTANGLE pEmr = (PEMRRECTANGLE) lpEMFR; RECTL rc = pEmr->rclBox; @@ -1396,37 +1488,39 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_ROUNDRECT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_ARC: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_CHORD: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_PIE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SELECTPALETTE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_CREATEPALETTE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETPALETTEENTRIES: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_RESIZEPALETTE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_REALIZEPALETTE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_EXTFLOODFILL: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_LINETO: { + dbg_str << "\n"; + PEMRLINETO pEmr = (PEMRLINETO) lpEMFR; if (d->path->empty()) { @@ -1441,16 +1535,18 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_ARCTO: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_POLYDRAW: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETARCDIRECTION: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETMITERLIMIT: { + dbg_str << "\n"; + PEMRSETMITERLIMIT pEmr = (PEMRSETMITERLIMIT) lpEMFR; d->style.stroke_miterlimit.value = pix_to_size_point( d, pEmr->eMiterLimit ); @@ -1461,6 +1557,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_BEGINPATH: { + dbg_str << "\n"; + tmp_path << "d=\""; *(d->path) = ""; d->inpath = true; @@ -1468,12 +1566,16 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_ENDPATH: { + dbg_str << "\n"; + tmp_path << "\""; d->inpath = false; break; } case EMR_CLOSEFIGURE: { + dbg_str << "\n"; + tmp_path << "\n\tz"; break; } @@ -1481,6 +1583,13 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb case EMR_STROKEANDFILLPATH: case EMR_STROKEPATH: { + if (lpEMFR->iType == EMR_FILLPATH) + dbg_str << "\n"; + if (lpEMFR->iType == EMR_STROKEANDFILLPATH) + dbg_str << "\n"; + if (lpEMFR->iType == EMR_STROKEPATH) + dbg_str << "\n"; + *(d->outsvg) += " iType); *(d->outsvg) += "\n\t"; @@ -1490,55 +1599,79 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_FLATTENPATH: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_WIDENPATH: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SELECTCLIPPATH: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_ABORTPATH: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_GDICOMMENT: - *(d->outsvg) += "\n"; + { + dbg_str << "\n"; + + PEMRGDICOMMENT pEmr = (PEMRGDICOMMENT) lpEMFR; + + CHAR *szTxt = (CHAR *) pEmr->Data; + + for (DWORD i = 0; i < pEmr->cbData; i++) { + if ( *szTxt) { + if ( *szTxt >= ' ' && *szTxt < 'z' && *szTxt != '<' && *szTxt != '>' ) { + tmp_str << *szTxt; + } + szTxt++; + } + } + + if (0 && strlen(tmp_str.str().c_str())) { + tmp_outsvg << " \n"; + } + break; + } case EMR_FILLRGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_FRAMERGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_INVERTRGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_PAINTRGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_EXTSELECTCLIPRGN: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_BITBLT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_STRETCHBLT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_MASKBLT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_PLGBLT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETDIBITSTODEVICE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_STRETCHDIBITS: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_EXTCREATEFONTINDIRECTW: { + dbg_str << "\n"; + PEMREXTCREATEFONTINDIRECTW pEmr = (PEMREXTCREATEFONTINDIRECTW) lpEMFR; int index = pEmr->ihFont; @@ -1551,11 +1684,13 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_EXTTEXTOUTA: { - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; } case EMR_EXTTEXTOUTW: { + dbg_str << "\n"; + PEMREXTTEXTOUTW pEmr = (PEMREXTTEXTOUTW) lpEMFR; double x1 = pEmr->emrtext.ptlReference.x; @@ -1639,6 +1774,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYBEZIER16: { + dbg_str << "\n"; + PEMRPOLYBEZIER16 pEmr = (PEMRPOLYBEZIER16) lpEMFR; POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ? DWORD i,j; @@ -1680,6 +1817,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYGON16: { + dbg_str << "\n"; + PEMRPOLYGON16 pEmr = (PEMRPOLYGON16) lpEMFR; POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ? SVGOStringStream tmp_poly; @@ -1710,6 +1849,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYLINE16: { + dbg_str << "\n"; + EMRPOLYLINE16 *pEmr = (EMRPOLYLINE16 *) lpEMFR; POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ? DWORD i; @@ -1749,6 +1890,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYBEZIERTO16: { + dbg_str << "\n"; + PEMRPOLYBEZIERTO16 pEmr = (PEMRPOLYBEZIERTO16) lpEMFR; POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ? DWORD i,j; @@ -1771,6 +1914,8 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb } case EMR_POLYLINETO16: { + dbg_str << "\n"; + PEMRPOLYLINETO16 pEmr = (PEMRPOLYLINETO16) lpEMFR; POINTS *apts = (POINTS *) pEmr->apts; // Bug in MinGW wingdi.h ? DWORD i; @@ -1792,6 +1937,11 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb case EMR_POLYPOLYLINE16: case EMR_POLYPOLYGON16: { + if (lpEMFR->iType == EMR_POLYPOLYLINE16) + dbg_str << "\n"; + if (lpEMFR->iType == EMR_POLYPOLYGON16) + dbg_str << "\n"; + PEMRPOLYPOLYGON16 pEmr = (PEMRPOLYPOLYGON16) lpEMFR; unsigned int n, i, j; @@ -1838,16 +1988,18 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_POLYDRAW16: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_CREATEMONOBRUSH: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_CREATEDIBPATTERNBRUSHPT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_EXTCREATEPEN: { + dbg_str << "\n"; + PEMREXTCREATEPEN pEmr = (PEMREXTCREATEPEN) lpEMFR; int index = pEmr->ihPen; @@ -1868,34 +2020,38 @@ myEnhMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, ENHMETARECORD *lpEMFR, int nOb break; } case EMR_POLYTEXTOUTA: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_POLYTEXTOUTW: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETICMMODE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_CREATECOLORSPACE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_SETCOLORSPACE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_DELETECOLORSPACE: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_GLSRECORD: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_GLSBOUNDEDRECORD: - *(d->outsvg) += "\n"; + dbg_str << "\n"; break; case EMR_PIXELFORMAT: - *(d->outsvg) += "\n"; + dbg_str << "\n"; + break; + default: + dbg_str << "\n"; break; } +// *(d->outsvg) += dbg_str.str().c_str(); *(d->outsvg) += tmp_outsvg.str().c_str(); *(d->path) += tmp_path.str().c_str(); @@ -1918,12 +2074,12 @@ myMetaFileProc(HDC hDC, HANDLETABLE *lpHTable, METARECORD *lpMFR, int nObj, LPAR #pragma pack( 2 ) typedef struct { - DWORD dwKey; - WORD hmf; - SMALL_RECT bbox; - WORD wInch; - DWORD dwReserved; - WORD wCheckSum; + DWORD dwKey; + WORD hmf; + SMALL_RECT bbox; + WORD wInch; + DWORD dwReserved; + WORD wCheckSum; } APMHEADER, *PAPMHEADER; #pragma pack( pop ) @@ -1990,8 +2146,8 @@ EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri ) else hmf = GetMetaFileA(ansi_uri); - METAFILEPICT mp; - HDC hDC; + METAFILEPICT mp; + HDC hDC; if (!hmf) { if (PrintWin32::is_os_wide()) { @@ -2106,7 +2262,18 @@ EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri ) return NULL; } + d.pDesc = NULL; + if (hemf) { + DWORD dwNeeded = GetEnhMetaFileDescriptionA( hemf, 0, NULL ); + if ( dwNeeded > 0 ) { + d.pDesc = (CHAR *) malloc( dwNeeded + 1 ); + if ( GetEnhMetaFileDescription( hemf, dwNeeded, d.pDesc ) == 0 ) + lstrcpy( d.pDesc, "" ); + if ( lstrlen( d.pDesc ) > 1 ) + d.pDesc[lstrlen(d.pDesc)] = '#'; + } + EnumEnhMetaFile(NULL, hemf, myEnhMetaFileProc, (LPVOID) &d, NULL); DeleteEnhMetaFile(hemf); } @@ -2114,6 +2281,9 @@ EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri ) EnumMetaFile(NULL, hmf, myMetaFileProc, (LPARAM) &d); DeleteMetaFile(hmf); } + + if (d.pDesc) + free( d.pDesc ); // std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl; diff --git a/src/extension/internal/emf-win32-print.cpp b/src/extension/internal/emf-win32-print.cpp index e696df06d..9bb4be722 100644 --- a/src/extension/internal/emf-win32-print.cpp +++ b/src/extension/internal/emf-win32-print.cpp @@ -35,7 +35,7 @@ #include "libnr/nr-point-matrix-ops.h" #include "libnr/nr-rect.h" #include "libnr/nr-matrix.h" -#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-matrix-ops.h" #include "libnr/nr-matrix-scale-ops.h" #include "libnr/nr-matrix-translate-ops.h" #include "libnr/nr-scale-translate-ops.h" @@ -113,7 +113,7 @@ PrintEmfWin32::~PrintEmfWin32 (void) #if !defined(_WIN32) && !defined(__WIN32__) (void) signal(SIGPIPE, SIG_DFL); #endif - return; + return; } @@ -173,11 +173,35 @@ PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc) // Get a Reference DC HDC hScreenDC = GetDC( NULL ); - // Create the Metafile - if (PrintWin32::is_os_wide()) - hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, NULL ); + // Get the physical characteristics of the reference DC + int PixelsX = GetDeviceCaps( hScreenDC, HORZRES ); + int PixelsY = GetDeviceCaps( hScreenDC, VERTRES ); + int MMX = GetDeviceCaps( hScreenDC, HORZSIZE ); + int MMY = GetDeviceCaps( hScreenDC, VERTSIZE ); + + CHAR buff[1024]; + ZeroMemory(buff, sizeof(buff)); + snprintf(buff, sizeof(buff)-1, "Inkscape %s (%s)", INKSCAPE_VERSION, __DATE__); + INT len = strlen(buff); + CHAR *p1 = strrchr(ansi_uri, '\\'); + CHAR *p2 = strrchr(ansi_uri, '/'); + CHAR *p = MAX(p1, p2); + if (p) + p++; else - hdc = CreateEnhMetaFileA( hScreenDC, ansi_uri, &rc, NULL ); + p = ansi_uri; + snprintf(buff+len+1, sizeof(buff)-len-2, "%s", p); + + // Create the Metafile + if (PrintWin32::is_os_wide()) { + WCHAR wbuff[1024]; + ZeroMemory(wbuff, sizeof(wbuff)); + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buff, sizeof(buff)/sizeof(buff[0]), wbuff, sizeof(wbuff)/sizeof(wbuff[0])); + hdc = CreateEnhMetaFileW( hScreenDC, unicode_uri, &rc, wbuff ); + } + else { + hdc = CreateEnhMetaFileA( hScreenDC, ansi_uri, &rc, buff ); + } // Release the reference DC ReleaseDC( NULL, hScreenDC ); @@ -194,14 +218,23 @@ PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc) SetMapMode( hdc, MM_ANISOTROPIC ); // Set the Windows extent - SetWindowExtEx( hdc, (int) (dwInchesX*dwDPI), (int) (dwInchesY*dwDPI), NULL ); + int windowextX = (int) ceil(dwInchesX*dwDPI); + int windowextY = (int) ceil(dwInchesY*dwDPI); + SetWindowExtEx( hdc, windowextX, windowextY, NULL ); // Set the viewport extent to reflect // dwInchesX" x dwInchesY" in device units - SetViewportExtEx( hdc, - (int) ((float) dwInchesX*25.4f*PX_PER_MM), - (int) ((float) dwInchesY*25.4f*PX_PER_MM), - NULL ); + int viewportextX = (int)((float)dwInchesX*25.4f*(float)PixelsX/(float)MMX); + int viewportextY = (int)((float)dwInchesY*25.4f*(float)PixelsY/(float)MMY); + SetViewportExtEx( hdc, viewportextX, viewportextY, NULL ); + + if (1) { + snprintf(buff, sizeof(buff)-1, "Screen=%dx%dpx, %dx%dmm", PixelsX, PixelsY, MMX, MMY); + GdiComment(hdc, strlen(buff), (BYTE*) buff); + + snprintf(buff, sizeof(buff)-1, "Drawing=%.1lfx%.1lfpx, %.1lfx%.1lfmm", _width, _height, dwInchesX * MM_PER_IN, dwInchesY * MM_PER_IN); + GdiComment(hdc, strlen(buff), (BYTE*) buff); + } SetRect( &rc, 0, 0, (int) ceil(dwInchesX*dwDPI), (int) ceil(dwInchesY*dwDPI) ); @@ -209,6 +242,7 @@ PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc) g_free(unicode_fn); m_tr_stack.push( NR::scale(1, -1) * NR::translate(0, sp_document_height(doc))); + return 0; } @@ -655,14 +689,26 @@ PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const NR::Matrix *tran } bool done = false; - bool circular = (lpPoints[0].x == lpPoints[i-1].x) && (lpPoints[0].y == lpPoints[i-1].y); + bool closed = (lpPoints[0].x == lpPoints[i-1].x) && (lpPoints[0].y == lpPoints[i-1].y); bool polygon = false; + bool polyline = false; + bool rectangle = false; bool ellipse = false; - if (moves == 1 && moves+lines == nodes && circular) { + if (moves == 1 && moves+lines == nodes && closed) { polygon = true; + if (nodes==5) { + if (lpPoints[0].x == lpPoints[3].x && lpPoints[1].x == lpPoints[2].x && + lpPoints[0].y == lpPoints[1].y && lpPoints[2].y == lpPoints[3].y) + { + rectangle = true; + } + } } - else if (moves == 1 && nodes == 5 && moves+curves == nodes && circular) { + else if (moves == 1 && moves+lines == nodes) { + polyline = true; + } + else if (moves == 1 && nodes == 5 && moves+curves == nodes && closed) { if (lpPoints[0].x == lpPoints[1].x && lpPoints[1].x == lpPoints[11].x && lpPoints[5].x == lpPoints[6].x && lpPoints[6].x == lpPoints[7].x && lpPoints[2].x == lpPoints[10].x && lpPoints[3].x == lpPoints[9].x && lpPoints[4].x == lpPoints[8].x && @@ -674,7 +720,7 @@ PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const NR::Matrix *tran } } - if (polygon || ellipse) { + if (polygon || polyline || ellipse) { HPEN hpenTmp = NULL; HPEN hpenOld = NULL; HBRUSH hbrushTmp = NULL; @@ -692,7 +738,13 @@ PrintEmfWin32::print_simple_shape(const NArtBpath *bpath, const NR::Matrix *tran } if (polygon) { - Polygon( hdc, lpPoints, nodes ); + if (rectangle) + Rectangle( hdc, lpPoints[0].x, lpPoints[0].y, lpPoints[2].x, lpPoints[2].y ); + else + Polygon( hdc, lpPoints, nodes ); + } + else if (polyline) { + Polyline( hdc, lpPoints, nodes ); } else if (ellipse) { Ellipse( hdc, lpPoints[6].x, lpPoints[3].y, lpPoints[0].x, lpPoints[9].y); -- 2.30.2