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);
|
|||
|
}
|
|||
|
}
|
|||
|
|