Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

401 lines
11 KiB

/*****************************************************************************
*
* frfc.c
* Copyright (C) Microsoft Corporation 1990.
* All Rights reserved.
*
******************************************************************************
*
* This file contains code for handling FCs in the layout manager.
*
* FCs (Full Context Points) are one of the key concepts of the layout
* manager. An FC is a piece of layout material which contains all of the
* information needed to display it. A display topic is nothing more than a
* series of FCs. FCs are never side by side- they are always stacked.
*
* FCs are laid out in a logical coordinate space where 0,0 corresponds to
* the upper-left-hand corner of the layout area. 0,0 in FC coordinates,
* therefore, corresponds to de.rct.left,de.rct.top in display device
* coordinates. All coordinates passed into frfc.c are in FC coordinates.
*
* FCs are stored in an MRD.
* The data structures in the FCM are as follows:
* HANDLE hfr; handle to array of FRs. Always exists, even when
* there are no frames (the size is padded by 1).
* INT fExport; used for text export?
* HFC hfc; HFC containing raw layout data for this FC
* FCID fcid; FCID of this FC
* INT xPos; position of the FC in FC space
* INT yPos;
* INT dxSize; size of the FC
* INT dySize;
* INT cfr; total number of frames in the FC. This may be 0.
* INT wStyle; current text style for this FC. Only for layout.
* INT imhiFirst; hotspot manager info
* INT imhiLast;
*
******************************************************************************
*
* Testing Notes
*
******************************************************************************
*
* Current Owner:
*
******************************************************************************
*
* Released by Development:
*
******************************************************************************
*
* Revision History:
* 15-Aug-1989 MattB Created
* 24-Oct-1990 LeoN JumpButton takes a pointer to its arg. Minor clenaup
* 04-Nov-1990 Tomsn Use new VA address type (enabling zeck compression).
* 30-Jul-1991 LeoN HELP31 #1244: remove fHiliteMatches from DE. Add
* FSet/GetMatchState
*
*****************************************************************************/
#include "help.h"
#include "inc\frstuff.h"
/*-------------------------------------------------------------------------
| IfcmLayout(qde, hfc, yPos, fFirst, fExport) |
| |
| Purpose: This lays out a new FC corresponding to the passed HFC, and |
| returns its IFCM. |
| Params: qde qde to use |
| hfc hfc containing raw layout data |
| yPos vertical position of this FCM |
| fFirst TRUE if FCM is first in layout chain |
| fExport TRUE if FCM is being used for text export. |
| Method: Each FC contains a single layout object, so all we do is call |
| LayoutObject() to lay it out. During layout, all frames are |
| placed in temporary storage provided by de.mrfr. After |
| layout, we increase the size of hfcm, and append the frames |
| after the fcm structure. |
-------------------------------------------------------------------------*/
IFCM STDCALL IfcmLayout(QDE qde, HFC hfc, int yPos, BOOL fFirst, BOOL fExport)
{
IFCM ifcm;
QFCM qfcm;
QB qbObj, qb;
MOBJ mobj;
LPSTR qchText;
int cfr;
OLR olr;
if (fFirst)
ifcm = IFooInsertFooMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), FOO_NIL);
else
ifcm = IFooInsertFooMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), IFooLastMRD(((QMRD)&qde->mrdFCM)));
qfcm = (QFCM)QFooInMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), ifcm);
qfcm->fExport = fExport;
qfcm->hfc = hfc;
qfcm->va = VaFromHfc(hfc);
qfcm->xPos = xLeftFCMargin;
qfcm->yPos = yPos;
qfcm->cfr = 0;
qfcm->wStyle = wStyleNil;
ClearMR((QMR)&qde->mrFr);
qbObj = (QB) QobjLockHfc(hfc);
#ifdef _X86_
qchText = qbObj + CbUnpackMOBJ((QMOBJ)&mobj, qbObj);
#else
qchText = qbObj + CbUnpackMOBJ((QMOBJ)&mobj, qbObj, QDE_ISDFFTOPIC(qde));
#endif
qchText += mobj.lcbSize;
qfcm->cobjrg = (COBJRG)mobj.wObjInfo;
#ifdef RAWHIDE
qfcm->cobjrgP = CobjrgFromHfc(hfc);
#endif
olr.xPos = olr.yPos = 0;
olr.ifrFirst = 0;
olr.objrgFirst = 0;
olr.objrgFront = objrgNil;
AccessMR((QMR)&qde->mrFr);
LayoutObject(qde, qfcm, qbObj, qchText, qde->rct.right - qde->rct.left
- xLeftFCMargin, &olr);
cfr = qfcm->cfr = olr.ifrMax;
/*
* REVIEW: This is pretty gross. cfr can be 0, but we always want to
* allocate an hfr, so that we don't have to check for it everywhere.
*/
qfcm->hfr = GhForceAlloc(0, cfr * sizeof(FR) + 1);
qb = PtrFromGh(qfcm->hfr);
MoveMemory((QB)qb, (QB)QFooInMR((QMR)&qde->mrFr, sizeof(FR), 0),
cfr * sizeof(FR));
DeAccessMR((QMR)&qde->mrFr);
qfcm->dxSize = olr.dxSize;
qfcm->dySize = olr.dySize;
if (!fExport) {
RegisterHotspots(qde, ifcm, fFirst);
#ifdef RAWHIDE
RegisterSearchHits(qde, ifcm, qchText);
#endif
}
return ifcm;
}
/*-------------------------------------------------------------------------
| DrawIfcm(qde, ifcm, pt, qrct, ifrFirst, ifrMax) |
| |
| Purpose: Draws a specified set of frames in an FCM. |
| Params: qde qde to use |
| pt offset between FC space and display space |
| qrct rectangle containing the area we want to draw. |
| This is for efficiency only- we don't handle |
| clipping. If qrct == NULL, it's ignored. |
| ifrFirst First frame to draw |
| ifrMax Max of frames to draw (ie, ifrMax isn't drawn) |
-------------------------------------------------------------------------*/
void STDCALL DrawIfcm(QDE qde, IFCM ifcm, POINT pt, LPRECT qrct, int ifrFirst,
int ifrMax, BOOL fErase)
{
QFCM qfcm;
QB qbObj;
MOBJ mobj;
LPSTR qchText;
QFR qfr;
QFR qfrStart;
int ifr;
qfcm = (QFCM)QFooInMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), ifcm);
ASSERT(!qfcm->fExport);
pt.x += qfcm->xPos;
pt.y += qfcm->yPos;
if (qrct != NULL && (pt.y > qrct->bottom || pt.y + qfcm->dySize <= qrct->top))
return;
qbObj = (QB) QobjLockHfc(qfcm->hfc);
#ifdef _X86_
qchText = qbObj + CbUnpackMOBJ((QMOBJ)&mobj, qbObj);
#else
qchText = qbObj + CbUnpackMOBJ((QMOBJ)&mobj, qbObj, QDE_ISDFFTOPIC(qde));
#endif
qchText += mobj.lcbSize;
qfrStart = qfr = (QFR)PtrFromGh(qfcm->hfr);
for (ifr = ifrFirst, qfr += ifr; ifr < ifrMax; ifr++, qfr++)
{
if (qrct != NULL && (qfr->yPos + pt.y > qrct->bottom
|| qfr->yPos + qfr->dySize + pt.y <= qrct->top))
continue;
switch(qfr->bType) {
case bFrTypeText:
DrawTextFrame(qde, qchText, qfr, pt, fErase);
break;
case bFrTypeAnno:
DrawAnnoFrame(qde, qfr, pt);
break;
case bFrTypeBitmap:
DrawBitmapFrame(qde, qfr, pt, fErase);
break;
case bFrTypeHotspot:
DrawHotspotFrame(qde, qfr, pt, fErase);
break;
case bFrTypeBox:
DrawBoxFrame(qde, qfr, pt);
break;
case bFrTypeWindow:
DrawWindowFrame(qde, qfr, pt);
break;
case bFrTypeColdspot:
/* Currently never drawn */
/* DrawColdspot(qde, qfr, pt); */
break;
}
#ifdef _DEBUG
#define coYELLOW RGB(255, 255, 0)
if (fDebugState & fDEBUGFRAME)
{
HSGC hsgc;
hsgc = (HSGC) HsgcFromQde(qde);
FSetPen(hsgc, 1, coDEFAULT, coYELLOW, wTRANSPARENT, roXOR, wPenSolid);
Rectangle(hsgc, pt.x + qfr->xPos, pt.y + qfr->yPos,
pt.x + qfr->xPos + qfr->dxSize, pt.y + qfr->yPos + qfr->dySize);
FreeHsgc(hsgc);
}
#endif
}
#ifdef _DEBUG
#define coMAGENTA RGB(255, 0, 255)
if (fDebugState & fDEBUGFRAME)
{
HSGC hsgc;
hsgc = (HSGC) HsgcFromQde(qde);
FSetPen(hsgc, 1, coDEFAULT, coMAGENTA, wTRANSPARENT, roCOPY, wPenSolid);
Rectangle(hsgc, pt.x, pt.y, pt.x + qfcm->dxSize, pt.y + qfcm->dySize);
FreeHsgc(hsgc);
}
#endif /* DEBUG */
#ifdef RAWHIDE
if (FGetMatchState()) {
/*
* If printing, don't show search hilites. On HP printers, prints
* out black squares instead of text where the search matches are.
*/
if (qde->deType != dePrint)
DrawMatchesIfcm(qde, ifcm, pt, qrct, ifrFirst, ifrMax, fErase);
}
#endif
}
/***************************************************************************
FUNCTION: ClickFC
PURPOSE: Handles a mouse click in an FC
PARAMETERS:
qde
ifcm
pt Offset between FC space and display space
RETURNS: TRUE if point is in a hotspot
COMMENTS:
MODIFICATION DATES:
13-Mar-1995 [ralphw]
***************************************************************************/
BOOL STDCALL ClickFC(QDE qde, IFCM ifcm, POINT pt)
{
QFCM qfcm;
QFR qfr;
int xNew, yNew, ifr;
qfcm = (QFCM)QFooInMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), ifcm);
ASSERT(!qfcm->fExport);
qfr = (QFR) PtrFromGh(qfcm->hfr);
xNew = pt.x - qfcm->xPos;
yNew = pt.y - qfcm->yPos;
for (ifr = 0; ifr < qfcm->cfr; ifr++, qfr++) {
if (qfr->rgf.fHot
&& xNew >= qfr->xPos && xNew <= qfr->xPos + qfr->dxSize
&& yNew >= qfr->yPos && yNew <= qfr->yPos + qfr->dySize) {
FSelectHotspot(qde, FOO_NIL);
ClickFrame(qde, ifcm, ifr);
return TRUE;
}
}
return FALSE;
}
/*-------------------------------------------------------------------------
| DiscardIfcm(qde, ifcm) |
| |
| Purpose: Discards all memory associated with an FC |
-------------------------------------------------------------------------*/
static int count;
void STDCALL DiscardIfcm(QDE qde, int ifcm)
{
QFCM qfcm;
QFR qfr;
qfcm = (QFCM)QFooInMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), ifcm);
qfr = (QFR)PtrFromGh(qfcm->hfr);
if (!qfcm->fExport) {
ReleaseHotspots(qde, ifcm);
#ifdef RAWHIDE
ReleaseSearchHits(qde, ifcm);
#endif
}
count++;
DiscardFrames(qde, qfr, qfr + qfcm->cfr);
if (qfcm->hfc != NULL)
lcClearFree(&qfcm->hfc);
if (qfcm->hfr)
lcClearFree(&qfcm->hfr);
DeleteFooMRD(((QMRD)&qde->mrdFCM), sizeof(FCM), ifcm);
}
/*-------------------------------------------------------------------------
| DiscardFrames(qde, qfrFirst, qfrMax) |
| |
| Purpose: Discards all memory associated with a given set of frames. |
| Currently, only bitmap, window and possibly hotspot frames |
| allocate memory. |
-------------------------------------------------------------------------*/
void STDCALL DiscardFrames(QDE qde, QFR qfrFirst, QFR qfrMax)
{
QFR qfr;
for (qfr = qfrFirst; qfr < qfrMax; qfr++) {
switch (qfr->bType) {
case bFrTypeText:
case bFrTypeAnno:
break;
case bFrTypeBitmap:
DiscardBitmapFrame(qfr);
break;
case bFrTypeHotspot:
DiscardHotspotFrame(qfr);
break;
case bFrTypeWindow:
DiscardWindowFrame(qde, qfr);
break;
}
}
}
/***************
**
** GH GhForceAlloc(WORD wFlags, DWORD lcb)
**
** purpose
** Create a handle to relocatable block
** Identical to GhAlloc, but dies in the event of an error
**
** arguments
** wFlags Memory allocation flags |'ed together
** lcb Number of bytes to allocate
**
** return value
** Handle to allocated block of memory, or NULL otherwise
**
***************/
GH STDCALL GhForceAlloc(UINT wFlags, DWORD lcb)
{
GH gh;
if ((gh = GhAlloc(wFlags, lcb)) == NULL)
OOM();
return gh;
}