/* AbiSource Application Framework * Copyright (C) 1998 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include #include #include #include #include "ut_assert.h" #include "ut_string.h" #include "ut_path.h" #include "ut_debugmsg.h" #include "xap_Dialog_Id.h" #include "xap_Win32Dlg_PrintPreview.h" #include "xap_Frame.h" #include "xap_App.h" #include "xap_DialogFactory.h" #include "gr_Win32Graphics.h" #include "ut_rand.h" #include "ut_Win32OS.h" #include "fp_PageSize.h" #include "fv_View.h" #define INITGUID #include #define GDIPCONST const #define WINGDIPAPI __stdcall typedef int GpStatus; typedef int PixelFormat; typedef void GpImage; typedef void GpBitmap; typedef void GpMetafile; typedef void GpGraphics; struct _GdiplusStartupInput { guint32 GdiplusVersion; gpointer DebugEventCallback; gboolean SuppressBackgroundThread; gboolean SuppressExternalCodecs; }; typedef struct _GdiplusStartupInput GdiplusStartupInput; struct EncoderParameter { GUID Guid; ULONG NumberOfValues; ULONG Type; VOID* Value; }; struct EncoderParameters { UINT Count; /* Number of parameters in this structure */ EncoderParameter Parameter[1]; /* Parameter values */ }; typedef enum { EncoderParameterValueTypeByte = 1, EncoderParameterValueTypeASCII = 2, EncoderParameterValueTypeShort = 3, EncoderParameterValueTypeLong = 4, EncoderParameterValueTypeRational = 5, EncoderParameterValueTypeLongRange = 6, EncoderParameterValueTypeUndefined = 7, EncoderParameterValueTypeRationalRange = 8, EncoderParameterValueTypePointer = 9 } EncoderParameterValueType; enum EncoderValue { EncoderValueColorTypeCMYK, EncoderValueColorTypeYCCK, EncoderValueCompressionLZW, EncoderValueCompressionCCITT3, EncoderValueCompressionCCITT4, EncoderValueCompressionRle, EncoderValueCompressionNone, EncoderValueScanMethodInterlaced, EncoderValueScanMethodNonInterlaced, EncoderValueVersionGif87, EncoderValueVersionGif89, EncoderValueRenderProgressive, EncoderValueRenderNonProgressive, EncoderValueTransformRotate90, EncoderValueTransformRotate180, EncoderValueTransformRotate270, EncoderValueTransformFlipHorizontal, EncoderValueTransformFlipVertical, EncoderValueMultiFrame, EncoderValueLastFrame, EncoderValueFlush, EncoderValueFrameDimensionTime, EncoderValueFrameDimensionResolution, EncoderValueFrameDimensionPage }; #define PixelFormatIndexed 0x00010000 // Indexes into a palette #define PixelFormatGDI 0x00020000 // Is a GDI-supported format #define PixelFormatAlpha 0x00040000 // Has an alpha component #define PixelFormatPAlpha 0x00080000 // Pre-multiplied alpha #define PixelFormatExtended 0x00100000 // Extended color 16 bits/channel #define PixelFormatCanonical 0x00200000 #define PixelFormatUndefined 0 #define PixelFormatDontCare 0 #define PixelFormat1bppIndexed (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI) #define PixelFormat4bppIndexed (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI) #define PixelFormat8bppIndexed (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI) #define PixelFormat16bppGrayScale (4 | (16 << 8) | PixelFormatExtended) #define PixelFormat16bppRGB555 (5 | (16 << 8) | PixelFormatGDI) #define PixelFormat16bppRGB565 (6 | (16 << 8) | PixelFormatGDI) #define PixelFormat16bppARGB1555 (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI) #define PixelFormat24bppRGB (8 | (24 << 8) | PixelFormatGDI) #define PixelFormat32bppRGB (9 | (32 << 8) | PixelFormatGDI) #define PixelFormat32bppARGB (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical) #define PixelFormat32bppPARGB (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI) #define PixelFormat48bppRGB (12 | (48 << 8) | PixelFormatExtended) #define PixelFormat64bppARGB (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended) #define PixelFormat64bppPARGB (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended) typedef DWORD ARGB; typedef GpStatus (WINGDIPAPI* GdiplusStartupFunc) (gpointer, const gpointer, gpointer); typedef GpStatus (WINGDIPAPI* GdipDisposeImageFunc) (GpImage*); typedef GpStatus (WINGDIPAPI* GdipSaveImageToFileFunc) (GpImage *image, GDIPCONST WCHAR* filename, GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams); typedef GpStatus (WINGDIPAPI* GdipLoadImageFromFileFunc) (GDIPCONST WCHAR* filename, GpImage **image); typedef GpStatus (WINGDIPAPI* GdipSaveAddFunc) (GpImage *image, GDIPCONST EncoderParameters* encoderParams); typedef GpStatus (WINGDIPAPI* GdipSaveAddImageFunc) (GpImage *orig, GpImage *image, GDIPCONST EncoderParameters* encoderParams); typedef GpStatus (WINGDIPAPI* GdipCreateMetafileFromEmfFunc) (HENHMETAFILE hEmf, BOOL deleteEmf, GpMetafile **image); typedef GpStatus (WINGDIPAPI* GdipCreateMetafileFromFileFunc) (GDIPCONST WCHAR* file, GpMetafile **metafile); typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromFileFunc) (GDIPCONST WCHAR* filename, GpBitmap **bitmap); typedef GpStatus (WINGDIPAPI* GdipDeleteGraphicsFunc) (GpGraphics *graphics); typedef GpStatus (WINGDIPAPI* GdipCreateBitmapFromScan0Func) (INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap); typedef GpStatus (WINGDIPAPI* GdipGetImageWidthFunc) (GpImage*, guint*); typedef GpStatus (WINGDIPAPI* GdipGetImageHeightFunc) (GpImage*, guint*); typedef GpStatus (WINGDIPAPI* GdipDrawImageIFunc) (GpGraphics *graphics, GpImage *image, INT x, INT y); typedef GpStatus (WINGDIPAPI* GdipGetImageGraphicsContextFunc) (GpImage *image, GpGraphics **graphics); typedef GpStatus (WINGDIPAPI* GdipFlushFunc) (GpGraphics *graphics, INT intention); typedef GpStatus (WINGDIPAPI* GdipGraphicsClearFunc) (GpGraphics *graphics, ARGB color); typedef GpStatus (WINGDIPAPI* GdipBitmapSetResolutionFunc) (GpBitmap* bitmap, float xdpi, float ydpi); typedef GpStatus (WINGDIPAPI* GdipGetImageHorizontalResolutionFunc) (GpImage *image, float *resolution); typedef GpStatus (WINGDIPAPI* GdipGetImageVerticalResolutionFunc) (GpImage *image, float *resolution); static GdiplusStartupFunc GdiplusStartup = 0; static GdipDisposeImageFunc GdipDisposeImage = 0; static GdipSaveImageToFileFunc GdipSaveImageToFile = 0; static GdipLoadImageFromFileFunc GdipLoadImageFromFile = 0; static GdipSaveAddImageFunc GdipSaveAddImage = 0; static GdipSaveAddFunc GdipSaveAdd = 0; static GdipCreateMetafileFromEmfFunc GdipCreateMetafileFromEmf = 0; static GdipCreateMetafileFromFileFunc GdipCreateMetafileFromFile = 0; static GdipCreateBitmapFromFileFunc GdipCreateBitmapFromFile = 0; static GdipDeleteGraphicsFunc GdipDeleteGraphics = 0; static GdipCreateBitmapFromScan0Func GdipCreateBitmapFromScan0 = 0; static GdipGetImageWidthFunc GdipGetImageWidth = 0; static GdipGetImageHeightFunc GdipGetImageHeight = 0; static GdipDrawImageIFunc GdipDrawImageI = 0; static GdipGetImageGraphicsContextFunc GdipGetImageGraphicsContext = 0; static GdipFlushFunc GdipFlush = 0; static GdipGraphicsClearFunc GdipGraphicsClear = 0; static GdipBitmapSetResolutionFunc GdipBitmapSetResolution = 0; static GdipGetImageHorizontalResolutionFunc GdipGetImageHorizontalResolution = 0; static GdipGetImageVerticalResolutionFunc GdipGetImageVerticalResolution = 0; static GDIPCONST CLSID tiff_clsid = { 0x557cf405, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } }; static GDIPCONST GUID EncoderSaveFlag = { 0x292266FC, 0xac40, 0x47bf, { 0x8c, 0xfc, 0xa8, 0x5b, 0x89, 0xa6,0x55, 0xde } }; #if 0 #define d(x) G_STMT_START { (x); } G_STMT_END #else #define d(x) G_STMT_START { } G_STMT_END #endif static GpStatus gdip_init (void) { GdiplusStartupInput input; ULONG_PTR gdiplusToken = 0; static HINSTANCE gdipluslib = NULL; if (!gdipluslib) gdipluslib = LoadLibrary ("gdiplus.dll"); else return 0; /* gdip_init() is idempotent */ if (!gdipluslib) return 18; // GdiplusNotInitialized #define LOOKUP(func) \ G_STMT_START { \ func = (func##Func) GetProcAddress (gdipluslib, #func); \ if (!func) {\ g_warning ("Couldn't load function: %s\n", #func); \ return 18; \ } \ } G_STMT_END LOOKUP (GdiplusStartup); LOOKUP (GdipDisposeImage); LOOKUP (GdipSaveImageToFile); LOOKUP (GdipLoadImageFromFile); LOOKUP (GdipSaveAddImage); LOOKUP (GdipSaveAdd); LOOKUP (GdipCreateMetafileFromEmf); LOOKUP (GdipCreateMetafileFromFile); LOOKUP (GdipCreateBitmapFromFile); LOOKUP (GdipCreateBitmapFromScan0); LOOKUP (GdipDeleteGraphics); LOOKUP (GdipGetImageWidth); LOOKUP (GdipGetImageHeight); LOOKUP (GdipDrawImageI); LOOKUP (GdipGetImageGraphicsContext); LOOKUP (GdipFlush); LOOKUP (GdipGraphicsClear); LOOKUP (GdipBitmapSetResolution); LOOKUP (GdipGetImageHorizontalResolution); LOOKUP (GdipGetImageVerticalResolution); #undef LOOKUP input.GdiplusVersion = 1; input.DebugEventCallback = NULL; input.SuppressBackgroundThread = input.SuppressExternalCodecs = FALSE; return GdiplusStartup (&gdiplusToken, &input, NULL); } #define ASSERT_GDIP_SUCCESS(status, func) \ G_STMT_START { \ GpStatus _gdip_status = (status); \ if (_gdip_status != 0) { \ g_warning ("%s failed with reason %d\n", #func, _gdip_status); \ } \ } G_STMT_END class ABI_EXPORT GR_Win32PrintPreviewGraphics : public GR_Win32Graphics { public: GR_Win32PrintPreviewGraphics(const RECT &rect) : GR_Win32Graphics(createbestmetafilehdc(), getDocInfo()), m_pGraphics(0), page_rect(rect), metafile_dc(0), m_multiPageTiff(0), m_tiffFilename(0) { GpStatus status = gdip_init (); ASSERT_GDIP_SUCCESS (status, gdip_init); if (status != 0) throw "GDI+ initialization failed"; d (g_print ("gdip_init() was successful. preview graphics created\n")); metafile_xres = GetDeviceCaps(getPrimaryDC(), LOGPIXELSX); metafile_yres = GetDeviceCaps(getPrimaryDC(), LOGPIXELSY); d (g_print ("xres: %d | yres: %d\n", metafile_xres, metafile_yres)); } virtual ~GR_Win32PrintPreviewGraphics() { d (g_print ("~GR_Win32PrintPreviewGraphics()\n")); if (m_multiPageTiff) GdipDisposeImage (m_multiPageTiff); g_free(m_tiffFilename); // todo: delete DC and docInfo } virtual UT_uint32 getClassId() {return s_getClassId();} virtual GR_Capability getCapability() {return GRCAP_PRINTER_ONLY;} static const char * graphicsDescriptor(){return "Win32 Print Preview";} virtual void drawGlyph(UT_uint32 glyph_idx, UT_sint32 xoff, UT_sint32 yoff) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("drawGlyph()\n")); m_pGraphics->drawGlyph(glyph_idx, xoff, yoff); } virtual void drawChar(UT_UCSChar Char, UT_sint32 xoff, UT_sint32 yoff) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("drawChar()\n")); m_pGraphics->drawChar(Char, xoff, yoff); } virtual void drawChars(const UT_UCSChar* pChars, int iCharOffset, int iLength, UT_sint32 xoff, UT_sint32 yoff, int * pCharWidth) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("drawChars()\n")); m_pGraphics->drawChars(pChars, iCharOffset, iLength, xoff, yoff, pCharWidth); } virtual void setFont(const GR_Font* pFont) { if (m_pGraphics) { m_pGraphics->setFont(pFont); d (g_print ("setFont()\n")); } else GR_Win32Graphics::setFont(pFont); } virtual void clearFont(void) { if (m_pGraphics) { m_pGraphics->clearFont(); d (g_print ("clearFont()\n")); } else GR_Win32Graphics::clearFont(); } virtual void setColor(const UT_RGBColor& clr) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("setColor()\n")); m_pGraphics->setColor(clr); } virtual void getColor(UT_RGBColor& clr) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("getColor()\n")); m_pGraphics->getColor(clr); } virtual void drawLine(UT_sint32 a, UT_sint32 b, UT_sint32 c, UT_sint32 d) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("drawLine()\n")); m_pGraphics->drawLine(a, b, c, d); } virtual void xorLine(UT_sint32 a, UT_sint32 b, UT_sint32 c, UT_sint32 d) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("xorLine()\n")); m_pGraphics->xorLine(a, b, c, d); } virtual void setLineWidth(UT_sint32 w) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("setLineWidth()\n")); m_pGraphics->setLineWidth(w); } virtual void setLineProperties ( double inWidthPixels, JoinStyle inJoinStyle = JOIN_MITER, CapStyle inCapStyle = CAP_BUTT, LineStyle inLineStyle = LINE_SOLID ) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("setLineProperties()\n")); m_pGraphics->setLineProperties(inWidthPixels, inJoinStyle, inCapStyle, inLineStyle); } virtual void polyLine(UT_Point * pts, UT_uint32 nPoints) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("polyLine()\n")); m_pGraphics->polyLine(pts, nPoints); } virtual void fillRect(const UT_RGBColor& c, UT_sint32 x, UT_sint32 y, UT_sint32 w, UT_sint32 h) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("fillRect()\n")); m_pGraphics->fillRect(c, x, y, w, h); } virtual void invertRect(const UT_Rect* pRect) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("invertRect()\n")); m_pGraphics->invertRect(pRect); } virtual void setClipRect(const UT_Rect* pRect) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("setClipRect()\n")); m_pGraphics->setClipRect(pRect); } virtual void clearArea(UT_sint32 a, UT_sint32 b, UT_sint32 c, UT_sint32 d) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("clearArea()\n")); m_pGraphics->clearArea(a, b, c, d); } virtual GR_Image* createNewImage(const char* pszName, const UT_ByteBuf* pBB, const std::string& mimetype, UT_sint32 iDisplayWidth, UT_sint32 iDisplayHeight, GR_Image::GRType iType) { d (g_print ("createNewImage()\n")); if (m_pGraphics) return m_pGraphics->createNewImage(pszName, pBB, mimetype, iDisplayWidth, iDisplayHeight, iType); else return GR_Win32Graphics::createNewImage(pszName, pBB, mimetype, iDisplayWidth, iDisplayHeight, iType); } virtual void drawImage(GR_Image* pImg, UT_sint32 xDest, UT_sint32 yDest) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("drawImage()\n")); m_pGraphics->drawImage(pImg, xDest, yDest); } virtual bool queryProperties(GR_Graphics::Properties gp) const { d (g_print ("queryProperties()\n")); return (gp == DGP_PAPER); } virtual void polygon(UT_RGBColor& c,UT_Point *pts,UT_uint32 nPoints) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("polygon()\n")); m_pGraphics->polygon(c, pts, nPoints); } virtual GR_Image * genImageFromRectangle(const UT_Rect & r) { UT_return_val_if_fail(m_pGraphics != 0, 0); d (g_print ("genImageFromRectangle()\n")); return m_pGraphics->genImageFromRectangle(r); } virtual void saveRectangle(UT_Rect & r, UT_uint32 iIndx) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("saveRectangle()\n")); m_pGraphics->saveRectangle(r, iIndx); } virtual void restoreRectangle(UT_uint32 iIndx) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("restoreRectangle()\n")); m_pGraphics->restoreRectangle(iIndx); } virtual void flush(void) { UT_return_if_fail(m_pGraphics != 0); d (g_print ("flush()\n")); m_pGraphics->flush(); } virtual bool startPrint(void) { std::string sName = UT_createTmpFile("pr", ".tif"); d (g_print ("saving to %s\n", sName.c_str())); m_tiffFilename = g_utf8_to_utf16 (sName.c_str(), -1, NULL, NULL, NULL); return true; } virtual bool startPage(const char * /*szPageLabel*/, UT_uint32 /*pageNumber*/, bool /*bPortrait*/, UT_uint32 /*iWidth*/, UT_uint32 /*iHeight*/) { endPage(); // prints any previous pages and clears the font cache d (g_print ("startPage(%d)\n", pageNumber)); metafile_dc = CreateEnhMetaFileW (getPrimaryDC(), NULL, &page_rect, L"AbiWord\0Print Preview\0\0"); GR_Win32AllocInfo ai(metafile_dc, m_pDocInfo, NULL); m_pGraphics = (GR_Win32Graphics *)XAP_App::getApp()->newGraphics(ai); return true; } virtual bool endPrint(void) { endPage(); EncoderParameters encoder_params; ULONG parameterValue = EncoderValueFlush; encoder_params.Count = 1; encoder_params.Parameter[0].Guid = EncoderSaveFlag; encoder_params.Parameter[0].Type = EncoderParameterValueTypeLong; encoder_params.Parameter[0].NumberOfValues = 1; encoder_params.Parameter[0].Value = ¶meterValue; GpStatus status = GdipSaveAdd (m_multiPageTiff, &encoder_params); ASSERT_GDIP_SUCCESS (status, GdipSaveAdd); status = GdipDisposeImage (m_multiPageTiff); m_multiPageTiff = 0; ASSERT_GDIP_SUCCESS (status, GdipDisposeImage); d (g_print("endPrint()\n")); ShellExecuteW (NULL, L"open", (WCHAR *)m_tiffFilename, NULL, NULL, SW_SHOW); return true; } void endPage() { invalidateCache(); // clear the font cache d (g_print ("endPage()\n")); if (metafile_dc) { GpStatus status; HENHMETAFILE metafile; metafile = CloseEnhMetaFile (metafile_dc); d (g_print ("metafile = %p\n", metafile)); // must be a Bitmap for the multi-page stuff to work GpImage *meta; // jump through hoops to convert a metafile to a bitmap // saveaddimage() won't work if the base image or the // new image is a metafile. GpImage *m; status = GdipCreateMetafileFromEmf(metafile, TRUE, &m); ASSERT_GDIP_SUCCESS (status, GdipCreateMetafileFromEmf); guint width, height; GdipGetImageWidth(m, &width); GdipGetImageHeight(m, &height); d (g_print ("w: %d | h: %d\n", width, height)); status = GdipCreateBitmapFromScan0 (width, height, 0, PixelFormat32bppARGB, NULL, &meta); ASSERT_GDIP_SUCCESS (status, GdipCreateBitmapFromScan0); status = GdipBitmapSetResolution (meta, metafile_xres, metafile_yres); ASSERT_GDIP_SUCCESS (status, GdipBitmapSetResolution); GpGraphics *g; status = GdipGetImageGraphicsContext (meta, &g); ASSERT_GDIP_SUCCESS (status, GdipGetImageGraphicsContext); // gotta clear the bitmap status = GdipGraphicsClear(g, 0xffffffff); ASSERT_GDIP_SUCCESS (status, GdipGraphicsClear); status = GdipDrawImageI(g, m, 0, 0); ASSERT_GDIP_SUCCESS (status, GdipDrawImage); status = GdipFlush(g, 1); ASSERT_GDIP_SUCCESS (status, GdipFlush); GdipDeleteGraphics(g); GdipDisposeImage(m); if (!m_multiPageTiff) { EncoderParameters encoder_params; ULONG parameterValue = EncoderValueMultiFrame; encoder_params.Count = 1; encoder_params.Parameter[0].Guid = EncoderSaveFlag; encoder_params.Parameter[0].Type = EncoderParameterValueTypeLong; encoder_params.Parameter[0].NumberOfValues = 1; encoder_params.Parameter[0].Value = ¶meterValue; status = GdipSaveImageToFile (meta, (WCHAR *)m_tiffFilename, &tiff_clsid, &encoder_params); ASSERT_GDIP_SUCCESS (status, GdipSaveImageToFile); d (g_print ("Saved EMF to file\n")); m_multiPageTiff = meta; } else { EncoderParameters encoder_params; ULONG parameterValue = EncoderValueFrameDimensionPage; encoder_params.Count = 1; encoder_params.Parameter[0].Guid = EncoderSaveFlag; encoder_params.Parameter[0].Type = EncoderParameterValueTypeLong; encoder_params.Parameter[0].NumberOfValues = 1; encoder_params.Parameter[0].Value = ¶meterValue; status = GdipSaveAddImage (m_multiPageTiff, meta, &encoder_params); ASSERT_GDIP_SUCCESS (status, GdipSaveAddImage); d (g_print ("SaveAddImage\n")); GdipDisposeImage (meta); } metafile_dc = 0; DELETEP(m_pGraphics); } } protected: virtual GR_Font* _findFont(const char* pszFontFamily, const char* pszFontStyle, const char* pszFontVariant, const char* pszFontWeight, const char* pszFontStretch, const char* pszFontSize, const char* pszLang) { if (!m_pGraphics) return GR_Win32Graphics::_findFont(pszFontFamily, pszFontStyle, pszFontVariant, pszFontWeight, pszFontStretch, pszFontSize, pszLang); else return m_pGraphics->findFont(pszFontFamily, pszFontStyle, pszFontVariant, pszFontWeight, pszFontStretch, pszFontSize, pszLang); } GR_Win32Graphics *m_pGraphics; RECT page_rect; HDC metafile_dc; GpBitmap *m_multiPageTiff; gunichar2 * m_tiffFilename; int metafile_xres; int metafile_yres; }; XAP_Win32Dialog_PrintPreview::XAP_Win32Dialog_PrintPreview(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id) : XAP_Dialog_PrintPreview(pDlgFactory,id), m_pPrintGraphics(0), m_emfFilename(0) { } XAP_Win32Dialog_PrintPreview::~XAP_Win32Dialog_PrintPreview(void) { DELETEP(m_pPrintGraphics); g_free(m_emfFilename); } XAP_Dialog * XAP_Win32Dialog_PrintPreview::static_constructor(XAP_DialogFactory * pFactory, XAP_Dialog_Id id) { return new XAP_Win32Dialog_PrintPreview (pFactory,id); } GR_Graphics * XAP_Win32Dialog_PrintPreview::getPrinterGraphicsContext(void) { return m_pPrintGraphics; } void XAP_Win32Dialog_PrintPreview::releasePrinterGraphicsContext(GR_Graphics * /*pGraphics*/) { DELETEP(m_pPrintGraphics); } void XAP_Win32Dialog_PrintPreview::runModal(XAP_Frame * pFrame) { RECT rect; FV_View * pView = static_cast(pFrame->getCurrentView()); rect.left = 0; rect.right = (LONG)(pView->getPageSize().Width (DIM_MM) * 100); rect.top = 0; rect.bottom = (LONG)(pView->getPageSize().Height (DIM_MM) * 100); try { m_pPrintGraphics = new GR_Win32PrintPreviewGraphics(rect); } catch (...) { m_pPrintGraphics = 0; } }