799 lines
24 KiB
C
799 lines
24 KiB
C
/************************************************************/
|
||
|
||
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
||
/************************************************************/
|
||
|
||
/* picture.c -- MW format and display routines for pictures */
|
||
|
||
//#define NOGDICAPMASKS
|
||
#define NOWINMESSAGES
|
||
#define NOVIRTUALKEYCODES
|
||
#define NOWINSTYLES
|
||
#define NOCLIPBOARD
|
||
#define NOCTLMGR
|
||
#define NOSYSMETRICS
|
||
#define NOMENUS
|
||
#define NOICON
|
||
#define NOKEYSTATE
|
||
//#define NOATOM
|
||
#define NOCREATESTRUCT
|
||
#define NODRAWTEXT
|
||
#define NOFONT
|
||
#define NOMB
|
||
#define NOMENUS
|
||
#define NOOPENFILE
|
||
#define NOREGION
|
||
#define NOSCROLL
|
||
#define NOSOUND
|
||
#define NOWH
|
||
#define NOWINOFFSETS
|
||
#define NOWNDCLASS
|
||
#define NOCOMM
|
||
#include <windows.h>
|
||
|
||
#include "mw.h"
|
||
#define NOKCCODES
|
||
#include "ch.h"
|
||
#include "docdefs.h"
|
||
#include "fmtdefs.h"
|
||
#include "dispdefs.h"
|
||
#include "cmddefs.h"
|
||
#include "propdefs.h"
|
||
#include "stcdefs.h"
|
||
#include "wwdefs.h"
|
||
#include "filedefs.h"
|
||
#include "editdefs.h"
|
||
/* #include "str.h" */
|
||
#include "prmdefs.h"
|
||
/* #include "fkpdefs.h" */
|
||
/* #include "macro.h" */
|
||
#include "winddefs.h"
|
||
#if defined(OLE)
|
||
#include "obj.h"
|
||
#endif
|
||
|
||
extern typeCP cpMacCur;
|
||
extern int docCur;
|
||
extern int vfSelHidden;
|
||
extern struct WWD rgwwd[];
|
||
extern int wwCur;
|
||
extern int wwMac;
|
||
extern struct FLI vfli;
|
||
extern struct SEL selCur;
|
||
extern struct WWD *pwwdCur;
|
||
extern struct PAP vpapCache;
|
||
extern typeCP vcpFirstParaCache;
|
||
extern typeCP vcpLimParaCache;
|
||
extern int vfPictSel;
|
||
extern struct PAP vpapAbs;
|
||
extern struct SEP vsepAbs;
|
||
extern struct SEP vsepPage;
|
||
extern struct DOD (**hpdocdod)[];
|
||
extern unsigned cwHeapFree;
|
||
extern int vfInsertOn;
|
||
extern int vfPMS;
|
||
extern int dxpLogInch;
|
||
extern int dypLogInch;
|
||
extern int dxaPrPage;
|
||
extern int dyaPrPage;
|
||
extern int dxpPrPage;
|
||
extern int dypPrPage;
|
||
extern HBRUSH hbrBkgrnd;
|
||
extern long ropErase;
|
||
extern int vdocBitmapCache;
|
||
extern typeCP vcpBitmapCache;
|
||
extern HBITMAP vhbmBitmapCache;
|
||
extern BOOL vfBMBitmapCache;
|
||
extern HCURSOR vhcIBeam;
|
||
extern BOOL vfMonochrome;
|
||
|
||
|
||
/* Used in this module only */
|
||
#ifdef DEBUG
|
||
#define STATIC static
|
||
#else
|
||
#define STATIC
|
||
#endif
|
||
|
||
STATIC RECT rcPictInvalid; /* Rectangle (in window coords) that needs refresh */
|
||
int vfWholePictInvalid = TRUE;
|
||
|
||
|
||
FreeBitmapCache()
|
||
{
|
||
vdocBitmapCache = docNil;
|
||
if (vhbmBitmapCache != NULL)
|
||
{
|
||
DeleteObject( vhbmBitmapCache );
|
||
vhbmBitmapCache = NULL;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
MarkInvalidDlPict( ww, dlPict )
|
||
int ww;
|
||
int dlPict;
|
||
{ /* Mark the passed dl (presumed to be part of a picture) as requiring
|
||
eventual update, when DisplayGraphics is called */
|
||
|
||
register struct WWD *pwwd = &rgwwd [ww];
|
||
struct EDL (**hdndl)[] = pwwd->hdndl;
|
||
struct EDL *pedl = &(**hdndl)[ dlPict ];
|
||
RECT rcDl;
|
||
|
||
SetRect( (LPRECT) &rcDl, 0, pedl->yp - pedl->dyp,
|
||
pwwd->xpMac, pedl->yp );
|
||
|
||
if (vfWholePictInvalid)
|
||
{
|
||
CopyRect( (LPRECT) &rcPictInvalid, (LPRECT) &rcDl );
|
||
vfWholePictInvalid = FALSE;
|
||
}
|
||
else
|
||
{
|
||
RECT rcT;
|
||
|
||
rcT = rcPictInvalid; /* Necessary? i.e. can UnionRect handle
|
||
source == destination */
|
||
UnionRect( (LPRECT) &rcPictInvalid, (LPRECT) &rcT, (LPRECT) &rcDl );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
DisplayGraphics( ww, dl, fDontDisplay )
|
||
int ww;
|
||
int dl;
|
||
int fDontDisplay;
|
||
{ /* Display a line of graphics info */
|
||
struct WWD *pwwd = &rgwwd[ww];
|
||
struct EDL *pedl;
|
||
typeCP cpPictStart;
|
||
typeCP cp;
|
||
typeCP cpMac = (**hpdocdod)[vfli.doc].cpMac;
|
||
struct PICINFOX picInfo;
|
||
RECT rcEnclose;
|
||
RECT rcPict;
|
||
HANDLE hBits=NULL;
|
||
HDC hMDC=NULL;
|
||
HDC hMDCCache=NULL;
|
||
HANDLE hbm=NULL;
|
||
HDC hDC=pwwd->hDC;
|
||
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;
|
||
int fBitmap;
|
||
int ilevel=0;
|
||
|
||
/* THIS ROUTINE COULD USE SOME GDI-CALL ERROR CHECKING! ..pault */
|
||
|
||
int fDrew=false;
|
||
|
||
/* In the case of monochrome devices, this raster op will map white in
|
||
the bitmap to the background color and black to the foreground color. */
|
||
#define ropMonoBm 0x00990066
|
||
|
||
Assert( dl >= 0 && dl < pwwd->dlMax );
|
||
|
||
MarkInvalidDlPict( ww, dl );
|
||
|
||
if (fDontDisplay)
|
||
{
|
||
return;
|
||
}
|
||
|
||
Diag(CommSz("DisplayGraphics: \n\r"));
|
||
|
||
FreezeHp();
|
||
pedl = &(**(pwwd->hdndl))[dl];
|
||
cpPictStart=pedl->cpMin;
|
||
|
||
GetPicInfo( cpPictStart, cpMac, vfli.doc, &picInfo );
|
||
|
||
/* Compute desired display size of picture (in device pixels) */
|
||
|
||
ComputePictRect( &rcPict, &picInfo, pedl, ww );
|
||
dxpDisplay = rcPict.right - rcPict.left;
|
||
dypDisplay = rcPict.bottom - rcPict.top;
|
||
|
||
/* Compute original size of picture (in device pixels) */
|
||
/* MM_ANISOTROPIC and MM_ISOTROPIC pictures have no original size */
|
||
|
||
switch ( picInfo.mfp.mm ) {
|
||
case MM_ISOTROPIC:
|
||
case MM_ANISOTROPIC:
|
||
break;
|
||
case MM_BITMAP:
|
||
dxpOrig = picInfo.bm.bmWidth;
|
||
dypOrig = picInfo.bm.bmHeight;
|
||
break;
|
||
#if defined(OLE)
|
||
case MM_OLE:
|
||
{
|
||
extern BOOL vfObjDisplaying;
|
||
|
||
if (lpOBJ_QUERY_INFO(&picInfo) == NULL)
|
||
goto DontDraw;
|
||
|
||
/* just to be safe */
|
||
if (!CheckPointer(lpOBJ_QUERY_INFO(&picInfo),1))
|
||
goto DontDraw;
|
||
|
||
if (lpOBJ_QUERY_OBJECT(&picInfo) == NULL)
|
||
{
|
||
typeCP cpRet;
|
||
|
||
/* this can require memory, so unlock heap */
|
||
MeltHp();
|
||
vfObjDisplaying = TRUE;
|
||
|
||
cpRet = ObjLoadObjectInDoc(&picInfo,vfli.doc,cpPictStart);
|
||
|
||
vfObjDisplaying = FALSE;
|
||
FreezeHp();
|
||
pedl = &(**(pwwd->hdndl))[dl];
|
||
|
||
if (cpRet == cp0)
|
||
goto DontDraw;
|
||
}
|
||
}
|
||
break;
|
||
#endif
|
||
default:
|
||
dxpOrig = PxlConvert( picInfo.mfp.mm, picInfo.mfp.xExt,
|
||
GetDeviceCaps( hDC, HORZRES ),
|
||
GetDeviceCaps( hDC, HORZSIZE ) );
|
||
dypOrig = PxlConvert( picInfo.mfp.mm, picInfo.mfp.yExt,
|
||
GetDeviceCaps( hDC, VERTRES ),
|
||
GetDeviceCaps( hDC, VERTSIZE ) );
|
||
if (! (dxpOrig && dypOrig) )
|
||
{
|
||
goto DontDraw;
|
||
}
|
||
break;
|
||
}
|
||
|
||
/* Save DC as a guard against DC attribute alteration by a metafile */
|
||
#ifdef WINDOWS_BUG_FIXED /* Currently 0 is a valid level for Own DC's */
|
||
if ((ilevel=SaveDC( hDC )) == 0)
|
||
goto DontDraw;
|
||
#endif
|
||
ilevel = SaveDC( hDC );
|
||
SetStretchBltMode( hDC, BLACKONWHITE );
|
||
|
||
/* Clip out top bar, selection bar */
|
||
|
||
IntersectClipRect( hDC, ((wwCur == wwClipboard) ? 0 : xpSelBar),
|
||
pwwdCur->ypMin, pwwdCur->xpMac, pwwdCur->ypMac );
|
||
|
||
if (!vfWholePictInvalid)
|
||
/* Repainting less than the whole picture; clip out
|
||
what we're not drawing */
|
||
IntersectClipRect( hDC, rcPictInvalid.left, rcPictInvalid.top,
|
||
rcPictInvalid.right, rcPictInvalid.bottom );
|
||
|
||
/* Build rcEnclose, a rect enclosing the picture that
|
||
includes the "space before" and "space after" fields */
|
||
|
||
rcEnclose.left = xpSelBar;
|
||
if ((rcEnclose.top = rcPict.top -
|
||
DypFromDya( vpapAbs.dyaBefore, FALSE )) < pwwd->ypMin)
|
||
rcEnclose.top = pwwd->ypMin;
|
||
rcEnclose.right = pwwd->xpMac;
|
||
if ((rcEnclose.bottom = rcPict.bottom +
|
||
DypFromDya( vpapAbs.dyaAfter, FALSE )) > pwwd->ypMac)
|
||
rcEnclose.bottom = pwwd->ypMac;
|
||
|
||
/* White out enclosing rect */
|
||
|
||
PatBlt( hDC, rcEnclose.left, rcEnclose.top,
|
||
rcEnclose.right - rcEnclose.left,
|
||
rcEnclose.bottom - rcEnclose.top, ropErase );
|
||
|
||
/* If we have it cached, do display the easy way */
|
||
|
||
if (pwwd->doc == vdocBitmapCache && cpPictStart == vcpBitmapCache)
|
||
{
|
||
Assert( pwwd->doc != docNil && vhbmBitmapCache != NULL);
|
||
|
||
if ( ((hMDC = CreateCompatibleDC( hDC )) != NULL) &&
|
||
SelectObject( hMDC, vhbmBitmapCache ))
|
||
{
|
||
Diag(CommSz("DisplayGraphics: BitBlt\n\r"));
|
||
BitBlt( hDC, rcPict.left, rcPict.top, dxpDisplay, dypDisplay,
|
||
hMDC, 0, 0, vfMonochrome && vfBMBitmapCache ?
|
||
ropMonoBm : SRCCOPY );
|
||
fDrew = TRUE;
|
||
goto DontDraw;
|
||
}
|
||
else
|
||
{ /* Using the cache failed -- empty it
|
||
(SelectObject will fail if bitmap was discarded) */
|
||
FreeBitmapCache();
|
||
}
|
||
}
|
||
|
||
StartLongOp(); /* Put up an hourglass */
|
||
|
||
/* Build up all bytes associated with the picture (except the header)
|
||
into the global Windows handle hBits */
|
||
|
||
if ( picInfo.mfp.mm != MM_OLE)
|
||
{
|
||
if ((hBits=GlobalAlloc( GMEM_MOVEABLE, (long)picInfo.cbSize )) == NULL)
|
||
{ /* Not enough global heap space to load bitmap/metafile */
|
||
goto DontDraw;
|
||
}
|
||
|
||
#ifdef DCLIP
|
||
{
|
||
char rgch[200];
|
||
wsprintf(rgch,"DisplayGraphics: picinfo.cbSize %lu \n\r", picInfo.cbSize);
|
||
CommSz(rgch);
|
||
}
|
||
#endif
|
||
|
||
for ( cbPict = 0, cp = cpPictStart + picInfo.cbHeader;
|
||
cbPict < picInfo.cbSize;
|
||
cbPict += cchRun, cp += (typeCP) cchRun )
|
||
{
|
||
CHAR rgch[ 256 ];
|
||
#if WINVER >= 0x300
|
||
HPCH lpch;
|
||
#else
|
||
LPCH lpch;
|
||
#endif
|
||
|
||
#define ulmin(a,b) ((unsigned long)(a) < (unsigned long)(b) ? \
|
||
(unsigned long)(a) : (unsigned long)(b))
|
||
|
||
FetchRgch( &cchRun, rgch, vfli.doc, cp, cpMac,
|
||
(int) ulmin( picInfo.cbSize - cbPict, 256 ) );
|
||
if ((lpch=GlobalLock( hBits )) != NULL)
|
||
{
|
||
#ifdef DCLIP
|
||
{
|
||
char rgch[200];
|
||
wsprintf(rgch," copying %d bytes from %lX to %lX \n\r",cchRun,(LPSTR)rgch,lpch+cbPict);
|
||
CommSz(rgch);
|
||
}
|
||
|
||
{
|
||
char rgchT[200];
|
||
int i;
|
||
for (i = 0; i< min(20,cchRun); i++,i++)
|
||
{
|
||
wsprintf(rgchT,"%X ",* (int *) &(rgch[i]));
|
||
CommSz(rgchT);
|
||
}
|
||
CommSz("\n\r");
|
||
}
|
||
#endif
|
||
#if WINVER >= 0x300
|
||
bltbh( (LPSTR)rgch, lpch+cbPict, cchRun );
|
||
#else
|
||
bltbx( (LPSTR)rgch, lpch+cbPict, cchRun );
|
||
#endif
|
||
GlobalUnlock( hBits );
|
||
}
|
||
else
|
||
{
|
||
goto DontDraw;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* Display the picture */
|
||
|
||
MeltHp();
|
||
|
||
#if defined(OLE)
|
||
/* CASE 0: OLE */
|
||
if (picInfo.mfp.mm == MM_OLE)
|
||
{
|
||
Diag(CommSz("Case 0:\n\r"));
|
||
if (ObjDisplayObjectInDoc(&picInfo, vfli.doc, cpPictStart,
|
||
hDC, &rcPict) == FALSE)
|
||
goto DontDraw;
|
||
fDrew = true;
|
||
}
|
||
else
|
||
#endif
|
||
/* CASE 1: Bitmap */
|
||
if (fBitmap = (picInfo.mfp.mm == MM_BITMAP))
|
||
{
|
||
Diag(CommSz("Case 1: \n\r"));
|
||
if ( ((hMDC = CreateCompatibleDC( hDC )) != NULL) &&
|
||
((picInfo.bm.bmBits = GlobalLock( hBits )) != NULL) &&
|
||
((hbm=CreateBitmapIndirect((LPBITMAP)&picInfo.bm))!=NULL))
|
||
{
|
||
picInfo.bm.bmBits = NULL;
|
||
GlobalUnlock( hBits );
|
||
GlobalFree( hBits ); /* Free handle to bits to allow max room */
|
||
hBits = NULL;
|
||
SelectObject( hMDC, hbm );
|
||
|
||
goto CacheIt;
|
||
}
|
||
}
|
||
|
||
/* Case 2: non-scalable metafile pictures which we are, for
|
||
user interface consistency, scaling by force using StretchBlt */
|
||
|
||
else if ( ((dxpDisplay != dxpOrig) || (dypDisplay != dypOrig)) &&
|
||
(picInfo.mfp.mm != MM_ISOTROPIC) &&
|
||
(picInfo.mfp.mm != MM_ANISOTROPIC) )
|
||
{
|
||
|
||
Diag(CommSz("Case 2: \n\r"));
|
||
if (((hMDC=CreateCompatibleDC( hDC)) != NULL) &&
|
||
((hbm=CreateCompatibleBitmap( hDC, dxpOrig, dypOrig ))!=NULL) &&
|
||
SelectObject( hMDC, hbm ) && SelectObject( hMDC, hbrBkgrnd ))
|
||
{
|
||
extern int vfOutOfMemory;
|
||
|
||
PatBlt( hMDC, 0, 0, dxpOrig, dypOrig, ropErase );
|
||
SetMapMode( hMDC, picInfo.mfp.mm );
|
||
/* To cover StretchBlt calls within the metafile */
|
||
SetStretchBltMode( hMDC, BLACKONWHITE );
|
||
PlayMetaFile( hMDC, hBits );
|
||
/* Because we pass pixels to StretchBlt */
|
||
SetMapMode( hMDC, MM_TEXT );
|
||
|
||
CacheIt: Assert( hbm != NULL && hMDC != NULL );
|
||
|
||
if (vfOutOfMemory)
|
||
goto NoCache;
|
||
#ifndef NOCACHE
|
||
FreeBitmapCache();
|
||
/* Among other things, this code caches the current picture.
|
||
Notice that there are two assumptions: (1) all bitmaps are
|
||
monochrome, and (2) a newly created memory DC has a monochrome
|
||
bitmap selected in. */
|
||
if ( ((hMDCCache = CreateCompatibleDC( hDC )) != NULL) &&
|
||
((vhbmBitmapCache = CreateDiscardableBitmap(
|
||
fBitmap ? hMDCCache : hDC, dxpDisplay, dypDisplay )) !=
|
||
NULL) &&
|
||
SelectObject( hMDCCache, vhbmBitmapCache ))
|
||
{
|
||
if (!StretchBlt( hMDCCache, 0, 0, dxpDisplay,
|
||
dypDisplay, hMDC, 0, 0, dxpOrig, dypOrig, SRCCOPY ))
|
||
{ /* may get here if memory is low */
|
||
DeleteDC( hMDCCache );
|
||
hMDCCache = NULL;
|
||
DeleteObject( vhbmBitmapCache );
|
||
vhbmBitmapCache = NULL;
|
||
goto NoCache;
|
||
}
|
||
|
||
#ifdef DCLIP
|
||
if (vfMonochrome && fBitmap)
|
||
CommSzNum("BitBlt using ropMonoBm == ",ropMonoBm);
|
||
#endif
|
||
|
||
BitBlt( hDC, rcPict.left, rcPict.top, dxpDisplay,
|
||
dypDisplay, hMDCCache, 0, 0, vfMonochrome && fBitmap ?
|
||
ropMonoBm : SRCCOPY );
|
||
|
||
/* Cached bitmap OK, make cache valid */
|
||
vdocBitmapCache = pwwd->doc;
|
||
vcpBitmapCache = cpPictStart;
|
||
vfBMBitmapCache = fBitmap;
|
||
}
|
||
else
|
||
#endif /* ndef NOCACHE */
|
||
{
|
||
NoCache:
|
||
StretchBlt( hDC, rcPict.left, rcPict.top,
|
||
dxpDisplay, dypDisplay,
|
||
hMDC, 0, 0, dxpOrig, dypOrig, vfMonochrome &&
|
||
fBitmap ? ropMonoBm : SRCCOPY );
|
||
}
|
||
fDrew = TRUE;
|
||
}
|
||
}
|
||
|
||
/* Case 3: A metafile picture which can be directly scaled
|
||
or does not need to be because its size has not changed */
|
||
else
|
||
{
|
||
fDrew = true;
|
||
Diag(CommSz("Case 3:\n\r"));
|
||
SetMapMode( hDC, picInfo.mfp.mm );
|
||
|
||
SetViewportOrg( hDC, rcPict.left, rcPict.top );
|
||
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( hDC, 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( hDC, dxpDisplay, dypDisplay );
|
||
|
||
SetViewportExt( hDC, dxpDisplay, dypDisplay );
|
||
break;
|
||
}
|
||
|
||
PlayMetaFile( hDC, hBits );
|
||
}
|
||
DontDraw:
|
||
|
||
/* Clean up */
|
||
if ( *(pLocalHeap+1) )
|
||
MeltHp();
|
||
|
||
if (ilevel > 0)
|
||
RestoreDC( hDC, ilevel );
|
||
if (hMDCCache != NULL)
|
||
DeleteDC( hMDCCache );
|
||
if (hMDC != NULL)
|
||
DeleteDC( hMDC );
|
||
if (hbm != NULL)
|
||
DeleteObject( hbm );
|
||
if (hBits != NULL)
|
||
{
|
||
if (fBitmap && picInfo.bm.bmBits != NULL)
|
||
GlobalUnlock( hBits );
|
||
GlobalFree( hBits );
|
||
}
|
||
|
||
if (!fDrew)
|
||
{
|
||
void DrawBlank(HDC hDC, RECT FAR *rc);
|
||
DrawBlank(hDC,&rcPict);
|
||
}
|
||
|
||
/* Invert the selection */
|
||
if (ww == wwDocument && !vfSelHidden && !vfPMS)
|
||
{
|
||
extern int vypCursLine;
|
||
|
||
ilevel = SaveDC( hDC ); /* Because of clip calls below */
|
||
|
||
if (!vfWholePictInvalid)
|
||
/* Repainting less than the whole picture; clip out
|
||
what we're not drawing */
|
||
IntersectClipRect( hDC, rcPictInvalid.left, rcPictInvalid.top,
|
||
rcPictInvalid.right, rcPictInvalid.bottom );
|
||
|
||
/* Clip out top bar, selection bar */
|
||
|
||
IntersectClipRect( hDC, xpSelBar,
|
||
pwwdCur->ypMin, pwwdCur->xpMac, pwwdCur->ypMac );
|
||
|
||
if (selCur.cpLim > cpPictStart && selCur.cpFirst <= cpPictStart)
|
||
{ /* Take into account 'space before' field */
|
||
rcEnclose.left = rcPict.left;
|
||
rcEnclose.right = rcPict.right;
|
||
InvertRect( hDC, (LPRECT) &rcEnclose );
|
||
}
|
||
else if ((selCur.cpLim == selCur.cpFirst) &&
|
||
(selCur.cpFirst == cpPictStart) &&
|
||
(vfWholePictInvalid || rcPictInvalid.top < vypCursLine))
|
||
{ /* We erased the insert point */
|
||
vfInsertOn = fFalse;
|
||
}
|
||
RestoreDC( hDC, ilevel );
|
||
}
|
||
|
||
vfWholePictInvalid = TRUE; /* Next picture, start invalidation anew */
|
||
{
|
||
extern int vfPMS;
|
||
extern HCURSOR vhcPMS;
|
||
|
||
|
||
EndLongOp( vfPMS ? vhcPMS : vhcIBeam );
|
||
}
|
||
}
|
||
|
||
|
||
#ifdef ENABLE /* Don't use this anymore */
|
||
int
|
||
FPointInPict(pt)
|
||
POINT pt;
|
||
{ /* Return true if point is within the picture frame */
|
||
struct EDL *pedl;
|
||
struct PICINFOX picInfo;
|
||
RECT rcPict;
|
||
|
||
GetPicInfo(selCur.cpFirst, cpMacCur, docCur, &picInfo);
|
||
|
||
if (!FGetPictPedl(&pedl))
|
||
return false;
|
||
|
||
ComputePictRect( &rcPict, &picInfo, pedl, wwCur );
|
||
|
||
return PtInRect( (LPRECT)&rcPict, pt );
|
||
}
|
||
#endif /* ENABLE */
|
||
|
||
|
||
/* C O M P U T E P I C T R E C T */
|
||
ComputePictRect( prc, ppicInfo, pedl, ww )
|
||
RECT *prc;
|
||
register struct PICINFOX *ppicInfo;
|
||
struct EDL *pedl;
|
||
int ww;
|
||
{ /* Compute rect containing picture indicated by passed ppicInfo,
|
||
pedl, in the indicated ww. Return the computed rect through
|
||
prc. picInfo structure is not altered. */
|
||
|
||
int dypTop, xaLeft;
|
||
struct WWD *pwwd = &rgwwd[ww];
|
||
int xaStart;
|
||
int dxaText, dxa;
|
||
int dxpSize, dypSize;
|
||
int dxaSize, dyaSize;
|
||
|
||
CacheSectPic(pwwd->doc, pedl->cpMin);
|
||
|
||
if (ppicInfo->mfp.mm == MM_BITMAP && ((ppicInfo->dxaSize == 0) ||
|
||
(ppicInfo->dyaSize == 0)))
|
||
{
|
||
GetBitmapSize( &dxpSize, &dypSize, ppicInfo, FALSE );
|
||
dxaSize = DxaFromDxp( dxpSize, FALSE );
|
||
dyaSize = DyaFromDyp( dypSize, FALSE );
|
||
}
|
||
#if defined(OLE)
|
||
else if (ppicInfo->mfp.mm == MM_OLE)
|
||
{
|
||
dxpSize = DxpFromDxa(ppicInfo->dxaSize, FALSE );
|
||
dypSize = DypFromDya(ppicInfo->dyaSize, FALSE );
|
||
dxpSize = MultDiv( dxpSize, ppicInfo->mx, mxMultByOne );
|
||
dypSize = MultDiv( dypSize, ppicInfo->my, myMultByOne );
|
||
dxaSize = DxaFromDxp( dxpSize, FALSE );
|
||
dyaSize = DyaFromDyp( dypSize, FALSE );
|
||
}
|
||
#endif
|
||
else
|
||
{
|
||
|
||
dxpSize = DxpFromDxa( dxaSize = ppicInfo->dxaSize, FALSE );
|
||
dypSize = DypFromDya( dyaSize = ppicInfo->dyaSize, FALSE );
|
||
}
|
||
|
||
dypTop = pedl->dcpMac != 0 ?
|
||
/* Last line of picture */
|
||
DypFromDya( dyaSize + vpapAbs.dyaAfter, FALSE ) :
|
||
(pedl->ichCpMin + 1) * dypPicSizeMin;
|
||
dypTop = pedl->yp - dypTop;
|
||
|
||
xaStart = DxaFromDxp( xpSelBar - (int) pwwd->xpMin, FALSE );
|
||
dxaText = vsepAbs.dxaText;
|
||
switch (vpapAbs.jc)
|
||
{
|
||
case jcBoth:
|
||
case jcLeft:
|
||
dxa = ppicInfo->dxaOffset;
|
||
break;
|
||
case jcCenter:
|
||
dxa = (dxaText - (int)vpapAbs.dxaRight + (int)vpapAbs.dxaLeft -
|
||
dxaSize) / 2;
|
||
break;
|
||
case jcRight:
|
||
dxa = dxaText - (int)vpapAbs.dxaRight - dxaSize;
|
||
break;
|
||
}
|
||
|
||
xaLeft = xaStart + max( (int)vpapAbs.dxaLeft, dxa );
|
||
|
||
prc->right = (prc->left = DxpFromDxa( xaLeft, FALSE )) + dxpSize;
|
||
prc->bottom = (prc->top = dypTop) + dypSize;
|
||
}
|
||
|
||
FGetPictPedl(ppedl)
|
||
struct EDL **ppedl;
|
||
{
|
||
int dlLim = pwwdCur->dlMac;
|
||
int dl;
|
||
typeCP cpFirst = selCur.cpFirst;
|
||
struct EDL *pedl;
|
||
|
||
//Assert(vfPictSel);
|
||
|
||
if (!vfPictSel)
|
||
return FALSE;
|
||
|
||
pedl = &(**(pwwdCur->hdndl)[0]);
|
||
|
||
for (dl = 0; dl < dlLim; ++dl, ++pedl)
|
||
{
|
||
//if (!pedl->fValid)
|
||
//return false;
|
||
|
||
if (pedl->cpMin == cpFirst)
|
||
break;
|
||
}
|
||
if (dl >= dlLim)
|
||
return false; /* No part of picture is on screen */
|
||
|
||
*ppedl = pedl;
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* C P W I N G R A P H I C */
|
||
typeCP CpWinGraphic(pwwd)
|
||
struct WWD *pwwd;
|
||
{
|
||
int cdlPict, dl;
|
||
struct EDL *dndl = &(**(pwwd->hdndl))[0];
|
||
|
||
Assert( !pwwd->fDirty ); /* So we can rely on dl info */
|
||
CachePara(pwwd->doc, dndl->cpMin);
|
||
for (dl = 0; (dl < pwwd->dlMac - 1 && dndl[dl].fIchCpIncr); ++dl)
|
||
;
|
||
Assert(dndl[dl].fGraphics);
|
||
cdlPict = dndl[dl].ichCpMin + 1;
|
||
return (dndl[0].cpMin +
|
||
(vcpLimParaCache - vcpFirstParaCache) * dndl[0].ichCpMin / cdlPict);
|
||
}
|
||
|
||
|
||
|
||
|
||
CacheSectPic(doc, cp)
|
||
int doc;
|
||
typeCP cp;
|
||
{ /* Cache section and para props, taking into account that footnotes take props
|
||
from the reference point */
|
||
#ifdef FOOTNOTES
|
||
struct DOD *pdod = &(**hpdocdod)[doc];
|
||
struct FNTB (**hfntb) = pdod->hfntb;
|
||
#endif
|
||
|
||
CachePara(doc, cp);
|
||
|
||
#ifdef FOOTNOTES
|
||
if ( (hfntb != 0) && (cp >= (**hfntb).rgfnd[0].cpFtn) )
|
||
CacheSect( doc, CpRefFromFtn( doc, cp ) )
|
||
else
|
||
#endif
|
||
CacheSect(doc, cp); /* Normal text */
|
||
}
|
||
|
||
|
||
void DrawBlank(HDC hDC, RECT FAR *rc)
|
||
{ /* To tell us when the draw tried but failed */
|
||
int xpMid=rc->left + (rc->right-rc->left)/2;
|
||
int ypMid=rc->top + (rc->bottom - rc->top)/2;
|
||
int dxpQ=(rc->right-rc->left)/4;
|
||
int dypQ=(rc->bottom-rc->top)/4;
|
||
HPEN hOldPen;
|
||
HBRUSH hOldBrush;
|
||
|
||
hOldPen = SelectObject( hDC, GetStockObject( BLACK_PEN ) );
|
||
hOldBrush = SelectObject( hDC, GetStockObject( WHITE_BRUSH ) );
|
||
Rectangle(hDC,rc->left,rc->top,rc->right,rc->bottom);
|
||
MoveTo( hDC, rc->left, rc->top );
|
||
LineTo( hDC, rc->right, rc->bottom );
|
||
MoveTo( hDC, rc->left, rc->bottom );
|
||
LineTo( hDC, rc->right, rc->top );
|
||
MoveTo( hDC, xpMid, rc->top );
|
||
LineTo( hDC, xpMid, rc->bottom );
|
||
MoveTo( hDC, rc->left, ypMid );
|
||
LineTo( hDC, rc->right, ypMid );
|
||
Ellipse( hDC,
|
||
xpMid-dxpQ, ypMid-dypQ,
|
||
xpMid+dxpQ, ypMid+dypQ );
|
||
SelectObject( hDC, hOldPen );
|
||
SelectObject( hDC, hOldBrush );
|
||
}
|
||
|
||
|