294 lines
7.3 KiB
C
294 lines
7.3 KiB
C
/************************************************************/
|
||
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
/* These routines are the guts of the graphics print code. */
|
||
|
||
#define NOGDICAPMASKS
|
||
#define NOVIRTUALKEYCODES
|
||
#define NOWINMESSAGES
|
||
#define NOWINSTYLES
|
||
#define NOSYSMETRICS
|
||
#define NOICON
|
||
#define NOKEYSTATE
|
||
#define NOSYSCOMMANDS
|
||
#define NOSHOWWINDOW
|
||
//#define NOATOM
|
||
#define NOFONT
|
||
#define NOBRUSH
|
||
#define NOCLIPBOARD
|
||
#define NOCOLOR
|
||
#define NOCREATESTRUCT
|
||
#define NOCTLMGR
|
||
#define NODRAWTEXT
|
||
#define NOMB
|
||
#define NOOPENFILE
|
||
#define NOPEN
|
||
#define NOREGION
|
||
#define NOSCROLL
|
||
#define NOSOUND
|
||
#define NOWH
|
||
#define NOWINOFFSETS
|
||
#define NOWNDCLASS
|
||
#define NOCOMM
|
||
#include <windows.h>
|
||
#include "mw.h"
|
||
#include "printdef.h"
|
||
#include "fmtdefs.h"
|
||
#include "docdefs.h"
|
||
#define NOKCCODES
|
||
#include "winddefs.h"
|
||
#include "debug.h"
|
||
#include "str.h"
|
||
#if defined(OLE)
|
||
#include "obj.h"
|
||
#endif
|
||
|
||
PrintGraphics(xpPrint, ypPrint)
|
||
int xpPrint;
|
||
int ypPrint;
|
||
{
|
||
/* This routine prints the picture in the vfli structure at position
|
||
(xpPrint, ypPrint). */
|
||
|
||
extern HDC vhDCPrinter;
|
||
extern struct FLI vfli;
|
||
extern struct DOD (**hpdocdod)[];
|
||
extern int dxpPrPage;
|
||
extern int dypPrPage;
|
||
extern FARPROC lpFPrContinue;
|
||
|
||
typeCP cp;
|
||
typeCP cpMac = (**hpdocdod)[vfli.doc].cpMac;
|
||
struct PICINFOX picInfo;
|
||
HANDLE hBits = NULL;
|
||
HDC hMDC = NULL;
|
||
HBITMAP hbm = NULL;
|
||
LPCH lpBits;
|
||
int cchRun;
|
||
unsigned long cbPict = 0;
|
||
int dxpOrig; /* Size of picture in the original */
|
||
int dypOrig;
|
||
int dxpDisplay; /* Size of picture as we want to show it */
|
||
int dypDisplay;
|
||
BOOL fRescale;
|
||
BOOL fBitmap;
|
||
BOOL fPrint = FALSE;
|
||
int iLevel = 0;
|
||
RECT bounds;
|
||
|
||
Assert(vhDCPrinter);
|
||
GetPicInfo(vfli.cpMin, cpMac, vfli.doc, &picInfo);
|
||
|
||
/* Compute desired display size of picture (in device pixels) */
|
||
dxpDisplay = vfli.xpReal - vfli.xpLeft;
|
||
dypDisplay = vfli.dypLine;
|
||
|
||
/* Compute original size of picture (in device pixels) */
|
||
/* MM_ANISOTROPIC and MM_ISOTROPIC pictures have no original size */
|
||
|
||
fRescale = FALSE;
|
||
switch (picInfo.mfp.mm)
|
||
{
|
||
case MM_ISOTROPIC:
|
||
case MM_ANISOTROPIC:
|
||
break;
|
||
|
||
#if defined(OLE)
|
||
case MM_OLE:
|
||
if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
|
||
goto DontDraw;
|
||
|
||
if (lpOBJ_QUERY_OBJECT(&picInfo) == NULL)
|
||
goto DontDraw;
|
||
break;
|
||
#endif
|
||
|
||
case MM_BITMAP:
|
||
dxpOrig = picInfo.bm.bmWidth;
|
||
dypOrig = picInfo.bm.bmHeight;
|
||
break;
|
||
|
||
default:
|
||
dxpOrig = PxlConvert(picInfo.mfp.mm, picInfo.mfp.xExt, dxpPrPage,
|
||
GetDeviceCaps(vhDCPrinter, HORZSIZE));
|
||
dypOrig = PxlConvert(picInfo.mfp.mm, picInfo.mfp.yExt, dypPrPage,
|
||
GetDeviceCaps(vhDCPrinter, VERTSIZE));
|
||
if (dxpOrig == 0 || dypOrig == 0)
|
||
{
|
||
#ifdef DPRINT
|
||
CommSz("PrintGraphics: nodraw because dxpOrig==0 | dypOrig==0\r\n");
|
||
#endif
|
||
goto DontDraw;
|
||
}
|
||
fRescale = (dxpOrig != dxpDisplay) || (dypOrig != dypDisplay);
|
||
break;
|
||
}
|
||
|
||
/* Get a handle to a global object large enough to hold the picture. */
|
||
if (picInfo.mfp.mm != MM_OLE)
|
||
{
|
||
if ((hBits = GlobalAlloc(GMEM_MOVEABLE, (long)picInfo.cbSize)) == NULL)
|
||
{
|
||
/* Not enough global heap space to load bitmap/metafile */
|
||
#ifdef DPRINT
|
||
CommSz("PrintGraphics: nodraw because not enough mem to alloc\r\n");
|
||
#endif
|
||
goto DontDraw;
|
||
}
|
||
|
||
/* Build up all bytes associated with the picture (except the header) into
|
||
the global handle hBits */
|
||
for (cbPict = 0, cp = vfli.cpMin + picInfo.cbHeader; cbPict <
|
||
picInfo.cbSize; cbPict += cchRun, cp += cchRun)
|
||
{
|
||
CHAR rgch[256];
|
||
LPCH lpch;
|
||
|
||
#define ulmin(a,b) ((a) < (b) ? (a) : (b))
|
||
|
||
FetchRgch(&cchRun, rgch, vfli.doc, cp, cpMac, (int)ulmin(picInfo.cbSize
|
||
- cbPict, 256));
|
||
|
||
if ((lpch = GlobalLock(hBits)) == NULL)
|
||
{
|
||
#ifdef DPRINT
|
||
CommSz("PrintGraphics: nodraw because couldn't lock\r\n");
|
||
#endif
|
||
goto DontDraw;
|
||
}
|
||
|
||
bltbx((LPSTR)rgch, lpch + cbPict, cchRun);
|
||
GlobalUnlock(hBits);
|
||
}
|
||
}
|
||
|
||
/* Save the printer DC as a guard against DC attribute alteration by a
|
||
metafile */
|
||
iLevel = SaveDC(vhDCPrinter);
|
||
|
||
fBitmap = picInfo.mfp.mm == MM_BITMAP;
|
||
|
||
#if defined(OLE)
|
||
/* CASE 0: OLE */
|
||
if (picInfo.mfp.mm == MM_OLE)
|
||
{
|
||
RECT rcPict;
|
||
|
||
rcPict.left = xpPrint;
|
||
rcPict.top = ypPrint;
|
||
rcPict.right = rcPict.left + dxpDisplay;
|
||
rcPict.bottom = rcPict.top + dypDisplay;
|
||
SetMapMode(vhDCPrinter, MM_TEXT);
|
||
//SetViewportOrg( vhDCPrinter, xpPrint, ypPrint);
|
||
fPrint = ObjDisplayObjectInDoc(&picInfo, vfli.doc, vfli.cpMin, vhDCPrinter, &rcPict);
|
||
}
|
||
else
|
||
#endif
|
||
if (fBitmap)
|
||
{
|
||
if (((hMDC = CreateCompatibleDC(vhDCPrinter)) != NULL) &&
|
||
((picInfo.bm.bmBits = GlobalLock(hBits)) != NULL) && ((hbm =
|
||
CreateBitmapIndirect((LPBITMAP)&picInfo.bm)) != NULL))
|
||
{
|
||
picInfo.bm.bmBits = NULL;
|
||
GlobalUnlock(hBits);
|
||
if (SelectObject(hMDC, hbm) != NULL)
|
||
{
|
||
fPrint = StretchBlt(vhDCPrinter, xpPrint, ypPrint, dxpDisplay,
|
||
dypDisplay, hMDC, 0, 0, dxpOrig, dypOrig, SRCCOPY);
|
||
#ifdef DPRINT
|
||
CommSzNum("PrintGraphics: after StretchBlt1, fPrint==", fPrint);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Case 2: a non-scalable picture which we are nevertheless scaling by force
|
||
using StretchBlt */
|
||
else if (fRescale)
|
||
{
|
||
if (((hMDC = CreateCompatibleDC(vhDCPrinter)) != NULL) && ((hbm =
|
||
CreateCompatibleBitmap(vhDCPrinter, dxpOrig, dypOrig)) != NULL))
|
||
{
|
||
if (SelectObject(hMDC, hbm) && PatBlt(hMDC, 0, 0, dxpOrig, dypOrig,
|
||
WHITENESS) && SetMapMode(hMDC, picInfo.mfp.mm) &&
|
||
PlayMetaFile(hMDC, hBits))
|
||
{
|
||
/* Successfully played metafile */
|
||
SetMapMode(hMDC, MM_TEXT);
|
||
fPrint = StretchBlt(vhDCPrinter, xpPrint, ypPrint, dxpDisplay,
|
||
dypDisplay, hMDC, 0, 0, dxpOrig, dypOrig, SRCCOPY);
|
||
#ifdef DPRINT
|
||
CommSzNum("PrintGraphics: after StretchBlt2, fPrint==", fPrint);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Case 3: A metafile picture which can be directly scaled or does not
|
||
need to be because its size has not changed */
|
||
else
|
||
{
|
||
SetMapMode(vhDCPrinter, picInfo.mfp.mm);
|
||
|
||
SetViewportOrg(vhDCPrinter, xpPrint, ypPrint);
|
||
switch (picInfo.mfp.mm)
|
||
{
|
||
case MM_ISOTROPIC:
|
||
if (picInfo.mfp.xExt && picInfo.mfp.yExt)
|
||
{
|
||
/* So we get the correct shape rectangle when SetViewportExt
|
||
gets called */
|
||
SetWindowExt(vhDCPrinter, picInfo.mfp.xExt, picInfo.mfp.yExt);
|
||
}
|
||
|
||
/* FALL THROUGH */
|
||
case MM_ANISOTROPIC:
|
||
/** (9.17.91) v-dougk
|
||
Set the window extent in case the metafile is bad
|
||
and doesn't call it itself. This will prevent
|
||
possible gpfaults in GDI
|
||
**/
|
||
SetWindowExt( vhDCPrinter, dxpDisplay, dypDisplay );
|
||
|
||
SetViewportExt(vhDCPrinter, dxpDisplay, dypDisplay);
|
||
break;
|
||
}
|
||
|
||
fPrint = PlayMetaFile(vhDCPrinter, hBits);
|
||
#ifdef DPRINT
|
||
CommSzNum("PrintGraphics: after PlayMetaFile, fPrint==", fPrint);
|
||
#endif
|
||
}
|
||
|
||
DontDraw:
|
||
/* We've drawn all we are going to draw; now its time to clean up. */
|
||
if (iLevel > 0)
|
||
{
|
||
RestoreDC(vhDCPrinter, iLevel);
|
||
}
|
||
if (hMDC != NULL)
|
||
{
|
||
DeleteDC(hMDC);
|
||
}
|
||
if (hbm != NULL)
|
||
{
|
||
DeleteObject(hbm);
|
||
}
|
||
if (hBits != NULL)
|
||
{
|
||
if (fBitmap && picInfo.bm.bmBits != NULL)
|
||
{
|
||
GlobalUnlock(hBits);
|
||
}
|
||
GlobalFree(hBits);
|
||
}
|
||
|
||
/* If we couldn't print the picture, warn the user. */
|
||
if (!fPrint)
|
||
{
|
||
Error(IDPMTPrPictErr);
|
||
}
|
||
}
|
||
|