2603 lines
76 KiB
C++
2603 lines
76 KiB
C++
#include "precomp.h"
|
||
|
||
|
||
//
|
||
// OD.CPP
|
||
// Order Decoding
|
||
//
|
||
// Copyright(c) Microsoft 1997-
|
||
//
|
||
|
||
#define MLZ_FILE_ZONE ZONE_ORDER
|
||
|
||
|
||
|
||
|
||
//
|
||
// OD_ViewStarting()
|
||
//
|
||
// Sets up the odLast... vars
|
||
//
|
||
BOOL ASShare::OD_ViewStarting(ASPerson * pasPerson)
|
||
{
|
||
BOOL rc = FALSE;
|
||
TSHR_COLOR colorWhite = {0xFF,0xFF,0xFF};
|
||
BYTE brushExtra[7] = {0,0,0,0,0,0,0};
|
||
|
||
DebugEntry(ASShare::OD_ViewStarting);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
//
|
||
// Invalidate OD results
|
||
//
|
||
pasPerson->m_pView->m_odInvalRgnTotal = CreateRectRgn(0, 0, 0, 0);
|
||
if (pasPerson->m_pView->m_odInvalRgnTotal == NULL)
|
||
{
|
||
ERROR_OUT(("OD_PartyStartingHosting: Couldn't create total invalid OD region"));
|
||
DC_QUIT;
|
||
}
|
||
|
||
pasPerson->m_pView->m_odInvalRgnOrder = CreateRectRgn(0, 0, 0, 0);
|
||
if (pasPerson->m_pView->m_odInvalRgnOrder == NULL)
|
||
{
|
||
ERROR_OUT(("OD_PartyStartingHosting: Couldn't create order invalid OD region"));
|
||
DC_QUIT;
|
||
}
|
||
|
||
//
|
||
// Back color.
|
||
//
|
||
pasPerson->m_pView->m_odLastBkColor = 0;
|
||
ODUseBkColor(pasPerson, TRUE, colorWhite);
|
||
|
||
//
|
||
// Text color.
|
||
//
|
||
pasPerson->m_pView->m_odLastTextColor = 0;
|
||
ODUseTextColor(pasPerson, TRUE, colorWhite);
|
||
|
||
//
|
||
// Background mode.
|
||
//
|
||
pasPerson->m_pView->m_odLastBkMode = TRANSPARENT;
|
||
ODUseBkMode(pasPerson, OPAQUE);
|
||
|
||
//
|
||
// ROP2.
|
||
//
|
||
pasPerson->m_pView->m_odLastROP2 = R2_BLACK;
|
||
ODUseROP2(pasPerson, R2_COPYPEN);
|
||
|
||
//
|
||
// Fill Mode. It's zero, we don't need to do anything since 0 isn't
|
||
// a valid mode, so we'll change it the first order we get that uses
|
||
// one.
|
||
//
|
||
ASSERT(pasPerson->m_pView->m_odLastFillMode == 0);
|
||
|
||
//
|
||
// Arc Direction. It's zero, we don't need to do anything since 0
|
||
// isn't a valid dir, so we'll change it the first order we get that
|
||
// uses one.
|
||
//
|
||
ASSERT(pasPerson->m_pView->m_odLastArcDirection == 0);
|
||
|
||
//
|
||
// Pen.
|
||
//
|
||
pasPerson->m_pView->m_odLastPenStyle = PS_DASH;
|
||
pasPerson->m_pView->m_odLastPenWidth = 2;
|
||
pasPerson->m_pView->m_odLastPenColor = 0;
|
||
ODUsePen(pasPerson, TRUE, PS_SOLID, 1, colorWhite);
|
||
|
||
//
|
||
// Brush.
|
||
//
|
||
pasPerson->m_pView->m_odLastBrushOrgX = 1;
|
||
pasPerson->m_pView->m_odLastBrushOrgY = 1;
|
||
pasPerson->m_pView->m_odLastBrushBkColor = 0;
|
||
pasPerson->m_pView->m_odLastBrushTextColor = 0;
|
||
pasPerson->m_pView->m_odLastLogBrushStyle = BS_NULL;
|
||
pasPerson->m_pView->m_odLastLogBrushHatch = HS_VERTICAL;
|
||
pasPerson->m_pView->m_odLastLogBrushColor.red = 0;
|
||
pasPerson->m_pView->m_odLastLogBrushColor.green = 0;
|
||
pasPerson->m_pView->m_odLastLogBrushColor.blue = 0;
|
||
ODUseBrush(pasPerson, TRUE, 0, 0, BS_SOLID, HS_HORIZONTAL,
|
||
colorWhite, brushExtra);
|
||
|
||
//
|
||
// Char extra.
|
||
//
|
||
pasPerson->m_pView->m_odLastCharExtra = 1;
|
||
ODUseTextCharacterExtra(pasPerson, 0);
|
||
|
||
//
|
||
// Text justification.
|
||
//
|
||
pasPerson->m_pView->m_odLastJustExtra = 1;
|
||
pasPerson->m_pView->m_odLastJustCount = 1;
|
||
ODUseTextJustification(pasPerson, 0, 0);
|
||
|
||
// odLastBaselineOffset. This is zero, which is the default in the DC
|
||
// right now so need to change anything.
|
||
|
||
//
|
||
// Font.
|
||
//
|
||
// We don't call ODUseFont because we know that the following values
|
||
// are invalid. The first valid font to arrive will be selected.
|
||
//
|
||
ASSERT(pasPerson->m_pView->m_odLastFontID == NULL);
|
||
pasPerson->m_pView->m_odLastFontCodePage = 0;
|
||
pasPerson->m_pView->m_odLastFontWidth = 0;
|
||
pasPerson->m_pView->m_odLastFontHeight = 0;
|
||
pasPerson->m_pView->m_odLastFontWeight = 0;
|
||
pasPerson->m_pView->m_odLastFontFlags = 0;
|
||
pasPerson->m_pView->m_odLastFontFaceLen = 0;
|
||
ZeroMemory(pasPerson->m_pView->m_odLastFaceName, sizeof(pasPerson->m_pView->m_odLastFaceName));
|
||
|
||
//
|
||
// These next 4 variables which describe the current clip rectangle are
|
||
// only valid if fRectReset is FALSE. If fRectReset is true then no
|
||
// clipping is in force.
|
||
//
|
||
pasPerson->m_pView->m_odRectReset = TRUE;
|
||
pasPerson->m_pView->m_odLastLeft = 0x12345678;
|
||
pasPerson->m_pView->m_odLastTop = 0x12345678;
|
||
pasPerson->m_pView->m_odLastRight = 0x12345678;
|
||
pasPerson->m_pView->m_odLastBottom = 0x12345678;
|
||
|
||
// odLastVGAColor?
|
||
// odLastVGAResult?
|
||
|
||
rc = TRUE;
|
||
|
||
DC_EXIT_POINT:
|
||
DebugExitBOOL(ASShare::OD_ViewStarting, rc);
|
||
return(rc);
|
||
}
|
||
|
||
|
||
//
|
||
// OD_ViewEnded()
|
||
// Cleans up any created objects
|
||
//
|
||
void ASShare::OD_ViewEnded(ASPerson * pasPerson)
|
||
{
|
||
DebugEntry(ASShare::OD_ViewEnded);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
//
|
||
// We may create and select in a font and a pen for our drawing decode.
|
||
// Select them out and delete them. Since we can't delete stock objects,
|
||
// if we didn't actually create one, there's no harm in it.
|
||
//
|
||
if (pasPerson->m_pView->m_usrDC != NULL)
|
||
{
|
||
DeleteBrush(SelectBrush(pasPerson->m_pView->m_usrDC, (HBRUSH)GetStockObject(BLACK_BRUSH)));
|
||
DeletePen(SelectPen(pasPerson->m_pView->m_usrDC, (HPEN)GetStockObject(BLACK_PEN)));
|
||
}
|
||
|
||
//
|
||
// Destroy the brush patern
|
||
//
|
||
if (pasPerson->m_pView->m_odLastBrushPattern != NULL)
|
||
{
|
||
DeleteBitmap(pasPerson->m_pView->m_odLastBrushPattern);
|
||
pasPerson->m_pView->m_odLastBrushPattern = NULL;
|
||
}
|
||
|
||
//
|
||
// Destroy the font -- but in this case we don't know that our font is
|
||
// actually the one in the DC. od2 also selects in fonts.
|
||
//
|
||
if (pasPerson->m_pView->m_odLastFontID != NULL)
|
||
{
|
||
// Make sure this isn't selected in to usrDC
|
||
SelectFont(pasPerson->m_pView->m_usrDC, (HFONT)GetStockObject(SYSTEM_FONT));
|
||
DeleteFont(pasPerson->m_pView->m_odLastFontID);
|
||
pasPerson->m_pView->m_odLastFontID = NULL;
|
||
}
|
||
|
||
if (pasPerson->m_pView->m_odInvalRgnTotal != NULL)
|
||
{
|
||
DeleteRgn(pasPerson->m_pView->m_odInvalRgnTotal);
|
||
pasPerson->m_pView->m_odInvalRgnTotal = NULL;
|
||
}
|
||
|
||
if (pasPerson->m_pView->m_odInvalRgnOrder != NULL)
|
||
{
|
||
DeleteRgn(pasPerson->m_pView->m_odInvalRgnOrder);
|
||
pasPerson->m_pView->m_odInvalRgnOrder = NULL;
|
||
}
|
||
|
||
DebugExitVOID(ASShare::OD_ViewEnded);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// OD_ReceivedPacket()
|
||
//
|
||
// Handles incoming orders packet from a host. Replays the drawing orders
|
||
// into the screen bitmap for the host, then repaints the view with the
|
||
// results.
|
||
//
|
||
void ASShare::OD_ReceivedPacket
|
||
(
|
||
ASPerson * pasPerson,
|
||
PS20DATAPACKET pPacket
|
||
)
|
||
{
|
||
PORDPACKET pOrders;
|
||
HPALETTE hOldPalette;
|
||
HPALETTE hOldSavePalette;
|
||
UINT cOrders;
|
||
UINT cUpdates;
|
||
UINT i;
|
||
LPCOM_ORDER_UA pOrder;
|
||
UINT decodedLength;
|
||
LPBYTE pEncodedOrder;
|
||
TSHR_INT32 xOrigin;
|
||
TSHR_INT32 yOrigin;
|
||
BOOL fPalRGB;
|
||
|
||
DebugEntry(ASShare::OD_ReceivedPacket);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
pOrders = (PORDPACKET)pPacket;
|
||
|
||
//
|
||
// The color type is RGB if we or they are < 256 colors
|
||
// Else it's PALETTE if they are old, or new and not sending 24bpp
|
||
//
|
||
fPalRGB = TRUE;
|
||
|
||
if ((g_usrScreenBPP < 8) || (pasPerson->cpcCaps.screen.capsBPP < 8))
|
||
{
|
||
TRACE_OUT(("OD_ReceivedPacket: no PALRGB"));
|
||
fPalRGB = FALSE;
|
||
}
|
||
else if (pasPerson->cpcCaps.general.version >= CAPS_VERSION_30)
|
||
{
|
||
// At 24bpp, no palette matching for RGB values unless we're <= 8
|
||
if ((g_usrScreenBPP > 8) && (pOrders->sendBPP > 8))
|
||
{
|
||
TRACE_OUT(("OD_ReceivedPacket: no PALRGB"));
|
||
fPalRGB = FALSE;
|
||
}
|
||
}
|
||
|
||
|
||
if (g_usrPalettized)
|
||
{
|
||
//
|
||
// Select and realize the current remote palette into the device
|
||
// context.
|
||
//
|
||
hOldPalette = SelectPalette(pasPerson->m_pView->m_usrDC, pasPerson->pmPalette, FALSE);
|
||
RealizePalette(pasPerson->m_pView->m_usrDC);
|
||
|
||
//
|
||
// We must select the same palette into the Save Bitmap DC so that
|
||
// no color conversion occurs during save and restore operations.
|
||
//
|
||
if (pasPerson->m_pView->m_ssiDC != NULL)
|
||
{
|
||
hOldSavePalette = SelectPalette(pasPerson->m_pView->m_ssiDC,
|
||
pasPerson->pmPalette, FALSE);
|
||
RealizePalette(pasPerson->m_pView->m_ssiDC);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Extract the number of orders supplied.
|
||
//
|
||
cOrders = pOrders->cOrders;
|
||
|
||
if (m_oefOE2EncodingOn)
|
||
{
|
||
pEncodedOrder = (LPBYTE)(&pOrders->data);
|
||
pOrder = NULL;
|
||
}
|
||
else
|
||
{
|
||
pOrder = (LPCOM_ORDER_UA)(&pOrders->data);
|
||
pEncodedOrder = NULL;
|
||
}
|
||
|
||
//
|
||
// Get the desktop origin for this person.
|
||
//
|
||
TRACE_OUT(( "Begin replaying %u orders ((", cOrders));
|
||
|
||
//
|
||
// This should be empty, we should have reset it when we invalidated
|
||
// the view of the host the last time we got a packet.
|
||
//
|
||
#ifdef _DEBUG
|
||
{
|
||
RECT rcBounds;
|
||
|
||
ASSERT(pasPerson->m_pView->m_odInvalTotal == 0);
|
||
GetRgnBox(pasPerson->m_pView->m_odInvalRgnTotal, &rcBounds);
|
||
ASSERT(IsRectEmpty(&rcBounds));
|
||
}
|
||
#endif // _DEBUG
|
||
|
||
//
|
||
// Repeat for each of the received orders.
|
||
//
|
||
for (i = 0; i < cOrders; i++)
|
||
{
|
||
if (m_oefOE2EncodingOn)
|
||
{
|
||
//
|
||
// Decode the first order. The pOrder returned by
|
||
// OD2_DecodeOrder should have all fields in local byte order
|
||
//
|
||
pOrder = OD2_DecodeOrder( (PDCEO2ORDER)pEncodedOrder,
|
||
&decodedLength,
|
||
pasPerson );
|
||
|
||
if (pOrder == NULL)
|
||
{
|
||
ERROR_OUT(( "Failed to decode order from pasPerson %u", pasPerson));
|
||
DC_QUIT;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Convert any font ids to be local ids.
|
||
//
|
||
|
||
//
|
||
// BOGUS LAURABU
|
||
// pOrder is unaligned, FH_Convert... takes an aligned order
|
||
//
|
||
FH_ConvertAnyFontIDToLocal((LPCOM_ORDER)pOrder, pasPerson);
|
||
decodedLength = pOrder->OrderHeader.cbOrderDataLength +
|
||
sizeof(COM_ORDER_HEADER);
|
||
}
|
||
|
||
//
|
||
// If the order is a Private Order then it is dealt with by
|
||
// the Bitmap Cache Controller.
|
||
//
|
||
if (EXTRACT_TSHR_UINT16_UA(&(pOrder->OrderHeader.fOrderFlags)) &
|
||
OF_PRIVATE)
|
||
{
|
||
RBC_ProcessCacheOrder(pasPerson, pOrder);
|
||
}
|
||
else if ( EXTRACT_TSHR_UINT16_UA(
|
||
&(((LPPATBLT_ORDER)pOrder->abOrderData)->type)) ==
|
||
LOWORD(ORD_DESKSCROLL))
|
||
{
|
||
TRACE_OUT(("Got DESKSCROLL order from remote"));
|
||
|
||
//
|
||
// There is no desktop scrolling order in 3.0
|
||
//
|
||
if (pasPerson->cpcCaps.general.version < CAPS_VERSION_30)
|
||
{
|
||
//
|
||
// Handle the desktop scroll order.
|
||
//
|
||
xOrigin = EXTRACT_TSHR_INT32_UA(
|
||
&(((LPDESKSCROLL_ORDER)pOrder->abOrderData)->xOrigin));
|
||
yOrigin = EXTRACT_TSHR_INT32_UA(
|
||
&(((LPDESKSCROLL_ORDER)pOrder->abOrderData)->yOrigin));
|
||
|
||
TRACE_OUT(( "ORDER: Desktop scroll %u,%u", xOrigin, yOrigin));
|
||
|
||
//
|
||
// Apply any previous drawing before we update the contents
|
||
// of the client
|
||
//
|
||
OD_UpdateView(pasPerson);
|
||
|
||
USR_ScrollDesktop(pasPerson, xOrigin, yOrigin);
|
||
}
|
||
else
|
||
{
|
||
ERROR_OUT(("Received DESKSCROLL order, obsolete, from 3.0 node [%d]",
|
||
pasPerson->mcsID));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Replay the received order. This will also add the
|
||
// bounds to the invalidate region.
|
||
//
|
||
//
|
||
OD_ReplayOrder(pasPerson, (LPCOM_ORDER)pOrder, fPalRGB);
|
||
}
|
||
|
||
if (m_oefOE2EncodingOn)
|
||
{
|
||
pEncodedOrder += decodedLength;
|
||
}
|
||
else
|
||
{
|
||
pOrder = (LPCOM_ORDER_UA)((LPBYTE)pOrder + decodedLength);
|
||
}
|
||
}
|
||
TRACE_OUT(( "End replaying orders ))"));
|
||
|
||
//
|
||
// Pass the Update Region to the Shadow Window Presenter.
|
||
//
|
||
OD_UpdateView(pasPerson);
|
||
|
||
DC_EXIT_POINT:
|
||
if (g_usrPalettized)
|
||
{
|
||
//
|
||
// Reinstate the old palette(s).
|
||
//
|
||
SelectPalette(pasPerson->m_pView->m_usrDC, hOldPalette, FALSE);
|
||
if (pasPerson->m_pView->m_ssiDC != NULL)
|
||
{
|
||
SelectPalette(pasPerson->m_pView->m_ssiDC, hOldSavePalette, FALSE);
|
||
}
|
||
}
|
||
|
||
DebugExitVOID(ASShare::OD_ReceivedPacket);
|
||
}
|
||
|
||
//
|
||
// OD_UpdateView()
|
||
//
|
||
// This is called after we've processed an order packet and replayed the
|
||
// drawing into our bitmap for the host.
|
||
//
|
||
// Replaying the drawing keeps a running tally of the area changed. This
|
||
// function invalidates the changed area in the view of the host, so it
|
||
// will repaint and show the updates.
|
||
//
|
||
void ASShare::OD_UpdateView(ASPerson * pasHost)
|
||
{
|
||
RECT rcBounds;
|
||
|
||
DebugEntry(ASShare::OD_UpdateView);
|
||
|
||
ValidateView(pasHost);
|
||
|
||
//
|
||
// Do nothing if there are no updates.
|
||
//
|
||
if (pasHost->m_pView->m_odInvalTotal == 0)
|
||
{
|
||
// Nothing got played back, nothing to repaint
|
||
}
|
||
else if (pasHost->m_pView->m_odInvalTotal <= MAX_UPDATE_REGION_ORDERS)
|
||
{
|
||
VIEW_InvalidateRgn(pasHost, pasHost->m_pView->m_odInvalRgnTotal);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Rather than invalidating a very complex region, which will
|
||
// chew up a lot of memory, just invalidate the bounding box.
|
||
//
|
||
GetRgnBox(pasHost->m_pView->m_odInvalRgnTotal, &rcBounds);
|
||
TRACE_OUT(("OD_UpdateView: Update region too complex; use bounds {%04d, %04d, %04d, %04d}",
|
||
rcBounds.left, rcBounds.top, rcBounds.right, rcBounds.bottom));
|
||
|
||
//
|
||
// BOGUS LAURABU!
|
||
// This code used to add one to the right & bottom, which was
|
||
// bogus EXCLUSIVE coordinate confusion. I fixed this--the bound
|
||
// box is the right area.
|
||
//
|
||
SetRectRgn(pasHost->m_pView->m_odInvalRgnTotal, rcBounds.left, rcBounds.top,
|
||
rcBounds.right, rcBounds.bottom);
|
||
VIEW_InvalidateRgn(pasHost, pasHost->m_pView->m_odInvalRgnTotal);
|
||
}
|
||
|
||
// Now reset the update region to empty
|
||
SetRectRgn(pasHost->m_pView->m_odInvalRgnTotal, 0, 0, 0, 0);
|
||
pasHost->m_pView->m_odInvalTotal = 0;
|
||
|
||
DebugExitVOID(ASShare::OD_UpdateView);
|
||
}
|
||
|
||
|
||
//
|
||
// OD_ReplayOrder()
|
||
//
|
||
// Replays one drawing operation, the next one, in the packet of orders
|
||
// we received from a host.
|
||
//
|
||
void ASShare::OD_ReplayOrder
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPCOM_ORDER pOrder,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
LPPATBLT_ORDER pDrawing;
|
||
LPSTR faceName;
|
||
UINT faceNameLength;
|
||
UINT trueFontWidth;
|
||
UINT maxFontHeight;
|
||
TSHR_UINT16 nFontFlags;
|
||
TSHR_UINT16 nCodePage;
|
||
UINT i;
|
||
RECT rcDst;
|
||
|
||
DebugEntry(ASShare::OD_ReplayOrder);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
pDrawing = (LPPATBLT_ORDER)pOrder->abOrderData;
|
||
|
||
//
|
||
// These are VD coords.
|
||
// WHEN 2.X INTEROP IS GONE, GET RID OF m_pView->m_dsScreenOrigin
|
||
//
|
||
RECT_FROM_TSHR_RECT16(&rcDst, pOrder->OrderHeader.rcsDst);
|
||
|
||
//
|
||
// The host bitmap is in screen, not VD, coords
|
||
//
|
||
if (pOrder->OrderHeader.fOrderFlags & OF_NOTCLIPPED)
|
||
{
|
||
//
|
||
// The rectangle associated with this order is the bounding
|
||
// rectangle of the order and does not clip it. We optimise this
|
||
// case by passing in a large rectangle that will not result in
|
||
// clipping to ODUseRectRegion. ODUseRectRegion will spot if this
|
||
// is the same as the last clip region we set and take a fast exit
|
||
// path. This improves performance substantially.
|
||
//
|
||
ODUseRectRegion(pasPerson, 0, 0, 10000, 10000);
|
||
}
|
||
else
|
||
{
|
||
ODUseRectRegion(pasPerson, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom);
|
||
}
|
||
|
||
switch (pDrawing->type)
|
||
{
|
||
case ORD_DSTBLT_TYPE:
|
||
ODReplayDSTBLT(pasPerson, (LPDSTBLT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_PATBLT_TYPE:
|
||
ODReplayPATBLT(pasPerson, (LPPATBLT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_SCRBLT_TYPE:
|
||
ODReplaySCRBLT(pasPerson, (LPSCRBLT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_MEMBLT_TYPE:
|
||
case ORD_MEMBLT_R2_TYPE:
|
||
ODReplayMEMBLT(pasPerson, (LPMEMBLT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_MEM3BLT_TYPE:
|
||
case ORD_MEM3BLT_R2_TYPE:
|
||
ODReplayMEM3BLT(pasPerson, (LPMEM3BLT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_RECTANGLE_TYPE:
|
||
ODReplayRECTANGLE(pasPerson, (LPRECTANGLE_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_POLYGON_TYPE:
|
||
ODReplayPOLYGON(pasPerson, (LPPOLYGON_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_PIE_TYPE:
|
||
ODReplayPIE(pasPerson, (LPPIE_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_ELLIPSE_TYPE:
|
||
ODReplayELLIPSE(pasPerson, (LPELLIPSE_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_ARC_TYPE:
|
||
ODReplayARC(pasPerson, (LPARC_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_CHORD_TYPE:
|
||
ODReplayCHORD(pasPerson, (LPCHORD_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_POLYBEZIER_TYPE:
|
||
ODReplayPOLYBEZIER(pasPerson, (LPPOLYBEZIER_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_ROUNDRECT_TYPE:
|
||
ODReplayROUNDRECT(pasPerson, (LPROUNDRECT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_LINETO_TYPE:
|
||
ODReplayLINETO(pasPerson, (LPLINETO_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_EXTTEXTOUT_TYPE:
|
||
ODReplayEXTTEXTOUT(pasPerson, (LPEXTTEXTOUT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_TEXTOUT_TYPE:
|
||
ODReplayTEXTOUT(pasPerson, (LPTEXTOUT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_OPAQUERECT_TYPE:
|
||
ODReplayOPAQUERECT(pasPerson, (LPOPAQUERECT_ORDER)pDrawing, fPalRGB);
|
||
break;
|
||
|
||
case ORD_SAVEBITMAP_TYPE:
|
||
SSI_SaveBitmap(pasPerson, (LPSAVEBITMAP_ORDER)pDrawing);
|
||
break;
|
||
|
||
default:
|
||
ERROR_OUT(( "ORDER: Unrecognised order %d from [%d]",
|
||
(int)pDrawing->type, pasPerson->mcsID));
|
||
break;
|
||
}
|
||
|
||
//
|
||
// rcDst is INCLUSIVE coords still
|
||
//
|
||
if ((rcDst.left <= rcDst.right) && (rcDst.top <= rcDst.bottom))
|
||
{
|
||
SetRectRgn(pasPerson->m_pView->m_odInvalRgnOrder, rcDst.left, rcDst.top,
|
||
rcDst.right+1, rcDst.bottom+1);
|
||
|
||
//
|
||
// Combine the rectangle region with the update region.
|
||
//
|
||
if (UnionRgn(pasPerson->m_pView->m_odInvalRgnTotal, pasPerson->m_pView->m_odInvalRgnTotal, pasPerson->m_pView->m_odInvalRgnOrder) <= ERROR)
|
||
{
|
||
RECT rcCur;
|
||
|
||
//
|
||
// Union failed; so simplyify the current region
|
||
//
|
||
WARNING_OUT(("OD_ReplayOrder: UnionRgn failed"));
|
||
|
||
//
|
||
// BOGUS LAURABU!
|
||
// This code used to add one to the right & bottom, which is
|
||
// bogus exclusive coord confusion. The bound box is the right
|
||
// area.
|
||
//
|
||
GetRgnBox(pasPerson->m_pView->m_odInvalRgnTotal, &rcCur);
|
||
SetRectRgn(pasPerson->m_pView->m_odInvalRgnTotal, rcCur.left, rcCur.top, rcCur.right,
|
||
rcCur.bottom);
|
||
|
||
//
|
||
// Reset odInvalTotal count -- this is really a # of bounds rects
|
||
// count, and now we have just one.
|
||
//
|
||
pasPerson->m_pView->m_odInvalTotal = 1;
|
||
|
||
if (UnionRgn(pasPerson->m_pView->m_odInvalRgnTotal, pasPerson->m_pView->m_odInvalRgnTotal, pasPerson->m_pView->m_odInvalRgnOrder) <= ERROR)
|
||
{
|
||
ERROR_OUT(("OD_ReplayOrder: UnionRgn failed after simplification"));
|
||
}
|
||
}
|
||
|
||
pasPerson->m_pView->m_odInvalTotal++;
|
||
}
|
||
|
||
DebugExitVOID(ASShare::OD_ReplayOrder);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ODReplayDSTBLT()
|
||
// Replays a DSTBLT order
|
||
//
|
||
void ASShare::ODReplayDSTBLT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPDSTBLT_ORDER pDstBlt,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
DebugEntry(ASShare::ODReplayDSTBLT);
|
||
|
||
TRACE_OUT(("ORDER: DstBlt X %hd Y %hd w %hd h %hd rop %08lX",
|
||
pDstBlt->nLeftRect,
|
||
pDstBlt->nTopRect,
|
||
pDstBlt->nWidth,
|
||
pDstBlt->nHeight,
|
||
(UINT)ODConvertToWindowsROP(pDstBlt->bRop)));
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
PatBlt(pasPerson->m_pView->m_usrDC,
|
||
pDstBlt->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pDstBlt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pDstBlt->nWidth,
|
||
pDstBlt->nHeight,
|
||
ODConvertToWindowsROP(pDstBlt->bRop));
|
||
|
||
DebugExitVOID(ASShare::ODReplayDSTBLT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayPATBLT()
|
||
// Replays a PATBLT order
|
||
//
|
||
void ASShare::ODReplayPATBLT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPPATBLT_ORDER pPatblt,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
|
||
DebugEntry(ASShare::ODReplayPATBLT);
|
||
|
||
TRACE_OUT(("ORDER: PatBlt BC %08lX FC %08lX Brush %02X %02X X %d Y %d w %d h %d rop %08lX",
|
||
pPatblt->BackColor,
|
||
pPatblt->ForeColor,
|
||
pPatblt->BrushStyle,
|
||
pPatblt->BrushHatch,
|
||
pPatblt->nLeftRect,
|
||
pPatblt->nTopRect,
|
||
pPatblt->nWidth,
|
||
pPatblt->nHeight,
|
||
ODConvertToWindowsROP(pPatblt->bRop) ));
|
||
|
||
ODAdjustColor(pasPerson, &(pPatblt->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPatblt->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pPatblt->BrushOrgX, pPatblt->BrushOrgY,
|
||
pPatblt->BrushStyle, pPatblt->BrushHatch, ForeColor, pPatblt->BrushExtra);
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
PatBlt(pasPerson->m_pView->m_usrDC,
|
||
pPatblt->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pPatblt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pPatblt->nWidth,
|
||
pPatblt->nHeight,
|
||
ODConvertToWindowsROP(pPatblt->bRop));
|
||
|
||
DebugExitVOID(ASShare::ODReplayPATBLT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplaySCRBLT()
|
||
// Replays SCRBLT order
|
||
//
|
||
void ASShare::ODReplaySCRBLT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPSCRBLT_ORDER pScrBlt,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
DebugEntry(ASShare::ODReplaySCRBLT);
|
||
|
||
TRACE_OUT(("ORDER: ScrBlt dx %d dy %d w %d h %d sx %d sy %d rop %08lX",
|
||
pScrBlt->nLeftRect,
|
||
pScrBlt->nTopRect,
|
||
pScrBlt->nWidth,
|
||
pScrBlt->nHeight,
|
||
pScrBlt->nXSrc,
|
||
pScrBlt->nYSrc,
|
||
ODConvertToWindowsROP(pScrBlt->bRop)));
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
BitBlt(pasPerson->m_pView->m_usrDC,
|
||
pScrBlt->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pScrBlt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pScrBlt->nWidth,
|
||
pScrBlt->nHeight,
|
||
pasPerson->m_pView->m_usrDC,
|
||
pScrBlt->nXSrc - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pScrBlt->nYSrc - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
ODConvertToWindowsROP(pScrBlt->bRop));
|
||
|
||
DebugExitVOID(ASShare::ODReplaySCRBLT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayMEMBLT()
|
||
// Replays MEMBLT and MEMBLT_R2 orders
|
||
//
|
||
void ASShare::ODReplayMEMBLT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPMEMBLT_ORDER pMemBlt,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
HPALETTE hpalOld;
|
||
HPALETTE hpalOld2;
|
||
TSHR_UINT16 cacheIndex;
|
||
UINT nXSrc;
|
||
HBITMAP cacheBitmap;
|
||
HBITMAP hOldBitmap;
|
||
COLORREF clrBk;
|
||
COLORREF clrText;
|
||
|
||
DebugEntry(ASShare::ODReplayMEMBLT);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
TRACE_OUT(("MEMBLT nXSrc %d",pMemBlt->nXSrc));
|
||
|
||
hpalOld = SelectPalette(pasPerson->m_pView->m_usrWorkDC, pasPerson->pmPalette, FALSE);
|
||
RealizePalette(pasPerson->m_pView->m_usrWorkDC);
|
||
|
||
hpalOld2 = SelectPalette( pasPerson->m_pView->m_usrDC, pasPerson->pmPalette, FALSE );
|
||
RealizePalette(pasPerson->m_pView->m_usrDC);
|
||
|
||
//
|
||
// Now get the source bitmap. The cache is defined by
|
||
// hBitmap. For R1 protocols the cache index is indicated
|
||
// by the source offset on the order. For R2 it is
|
||
// indicated by a separate field in the order.
|
||
// The color table index is in the high order of hBitmap
|
||
//
|
||
cacheIndex = ((LPMEMBLT_R2_ORDER)pMemBlt)->cacheIndex;
|
||
nXSrc = pMemBlt->nXSrc;
|
||
|
||
TRACE_OUT(( "MEMBLT color %d cache %d:%d",
|
||
MEMBLT_COLORINDEX(pMemBlt),
|
||
MEMBLT_CACHETABLE(pMemBlt),
|
||
cacheIndex));
|
||
|
||
cacheBitmap = RBC_MapCacheIDToBitmapHandle(pasPerson,
|
||
MEMBLT_CACHETABLE(pMemBlt), cacheIndex, MEMBLT_COLORINDEX(pMemBlt));
|
||
|
||
hOldBitmap = SelectBitmap(pasPerson->m_pView->m_usrWorkDC, cacheBitmap);
|
||
|
||
TRACE_OUT(("ORDER: MemBlt dx %d dy %d w %d h %d sx %d sy %d rop %08lX",
|
||
pMemBlt->nLeftRect,
|
||
pMemBlt->nTopRect,
|
||
pMemBlt->nWidth,
|
||
pMemBlt->nHeight,
|
||
nXSrc,
|
||
pMemBlt->nYSrc,
|
||
ODConvertToWindowsROP(pMemBlt->bRop)));
|
||
|
||
//
|
||
// ALWAYS set back/fore color to white/black in case of rops like
|
||
// SRCAND or SRCINVERT which will use their values.
|
||
//
|
||
clrBk = SetBkColor(pasPerson->m_pView->m_usrDC, RGB(255, 255, 255));
|
||
clrText = SetTextColor(pasPerson->m_pView->m_usrDC, RGB(0, 0, 0));
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
BitBlt(pasPerson->m_pView->m_usrDC,
|
||
pMemBlt->nLeftRect- pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pMemBlt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pMemBlt->nWidth,
|
||
pMemBlt->nHeight,
|
||
pasPerson->m_pView->m_usrWorkDC,
|
||
nXSrc,
|
||
pMemBlt->nYSrc,
|
||
ODConvertToWindowsROP(pMemBlt->bRop));
|
||
|
||
//
|
||
// If the relevant property is set hatch the area in blue.
|
||
//
|
||
if (m_usrHatchBitmaps)
|
||
{
|
||
SDP_DrawHatchedRect(pasPerson->m_pView->m_usrDC,
|
||
pMemBlt->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pMemBlt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pMemBlt->nWidth,
|
||
pMemBlt->nHeight,
|
||
USR_HATCH_COLOR_BLUE);
|
||
}
|
||
|
||
//
|
||
// Restore back, text colors
|
||
//
|
||
SetTextColor(pasPerson->m_pView->m_usrDC, clrText);
|
||
SetBkColor(pasPerson->m_pView->m_usrDC, clrBk);
|
||
|
||
//
|
||
// Deselect the bitmap from the DC.
|
||
//
|
||
SelectBitmap(pasPerson->m_pView->m_usrWorkDC, hOldBitmap);
|
||
|
||
SelectPalette(pasPerson->m_pView->m_usrWorkDC, hpalOld, FALSE);
|
||
SelectPalette(pasPerson->m_pView->m_usrDC, hpalOld2, FALSE);
|
||
|
||
DebugExitVOID(ASShare::ODReplayMEMBLT);
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayMEM3BLT()
|
||
// Replays MEM3BLT and MEM3BLT_R2 orders
|
||
//
|
||
void ASShare::ODReplayMEM3BLT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPMEM3BLT_ORDER pMem3Blt,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
HPALETTE hpalOld;
|
||
HPALETTE hpalOld2;
|
||
TSHR_UINT16 cacheIndex;
|
||
int nXSrc;
|
||
HBITMAP cacheBitmap;
|
||
HBITMAP hOldBitmap;
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
|
||
DebugEntry(ASShare::ODReplayMEM3BLT);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
TRACE_OUT(("MEM3BLT nXSrc %d",pMem3Blt->nXSrc));
|
||
TRACE_OUT(("ORDER: Mem3Blt brush %04lX %04lX dx %d dy %d "\
|
||
"w %d h %d sx %d sy %d rop %08lX",
|
||
pMem3Blt->BrushStyle,
|
||
pMem3Blt->BrushHatch,
|
||
pMem3Blt->nLeftRect,
|
||
pMem3Blt->nTopRect,
|
||
pMem3Blt->nWidth,
|
||
pMem3Blt->nHeight,
|
||
pMem3Blt->nXSrc,
|
||
pMem3Blt->nYSrc,
|
||
(UINT)ODConvertToWindowsROP(pMem3Blt->bRop)));
|
||
|
||
|
||
hpalOld = SelectPalette(pasPerson->m_pView->m_usrWorkDC, pasPerson->pmPalette, FALSE);
|
||
RealizePalette(pasPerson->m_pView->m_usrWorkDC);
|
||
|
||
hpalOld2 = SelectPalette( pasPerson->m_pView->m_usrDC, pasPerson->pmPalette, FALSE);
|
||
RealizePalette(pasPerson->m_pView->m_usrDC);
|
||
|
||
//
|
||
// Now get the source bitmap. The cache is defined by
|
||
// hBitmap. For R1 protocols the cache index is indicated
|
||
// by the source offset on the order. For R2 it is
|
||
// indicated by a separate field in the order.
|
||
// The color table index is in the high order of hBitmap
|
||
//
|
||
cacheIndex = ((LPMEM3BLT_R2_ORDER)pMem3Blt)->cacheIndex;
|
||
nXSrc = pMem3Blt->nXSrc;
|
||
|
||
TRACE_OUT(("MEM3BLT color %d cache %d:%d",
|
||
MEMBLT_COLORINDEX(pMem3Blt),
|
||
MEMBLT_CACHETABLE(pMem3Blt),
|
||
cacheIndex));
|
||
|
||
cacheBitmap = RBC_MapCacheIDToBitmapHandle(pasPerson,
|
||
MEMBLT_CACHETABLE(pMem3Blt), cacheIndex, MEMBLT_COLORINDEX(pMem3Blt));
|
||
|
||
hOldBitmap = SelectBitmap(pasPerson->m_pView->m_usrWorkDC, cacheBitmap);
|
||
|
||
ODAdjustColor(pasPerson, &(pMem3Blt->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pMem3Blt->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pMem3Blt->BrushOrgX, pMem3Blt->BrushOrgY,
|
||
pMem3Blt->BrushStyle, pMem3Blt->BrushHatch, ForeColor,
|
||
pMem3Blt->BrushExtra);
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
BitBlt(pasPerson->m_pView->m_usrDC,
|
||
pMem3Blt->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pMem3Blt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pMem3Blt->nWidth,
|
||
pMem3Blt->nHeight,
|
||
pasPerson->m_pView->m_usrWorkDC,
|
||
nXSrc,
|
||
pMem3Blt->nYSrc,
|
||
ODConvertToWindowsROP(pMem3Blt->bRop));
|
||
|
||
//
|
||
// If the relevant property is set hatch the area in blue.
|
||
//
|
||
if (m_usrHatchBitmaps)
|
||
{
|
||
SDP_DrawHatchedRect(pasPerson->m_pView->m_usrDC,
|
||
pMem3Blt->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pMem3Blt->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pMem3Blt->nWidth,
|
||
pMem3Blt->nHeight,
|
||
USR_HATCH_COLOR_BLUE);
|
||
}
|
||
|
||
//
|
||
// Deselect the bitmap from the DC.
|
||
//
|
||
SelectBitmap(pasPerson->m_pView->m_usrWorkDC, hOldBitmap);
|
||
|
||
SelectPalette(pasPerson->m_pView->m_usrWorkDC, hpalOld, FALSE);
|
||
SelectPalette(pasPerson->m_pView->m_usrDC, hpalOld2, FALSE);
|
||
|
||
DebugExitVOID(ASShare::ODReplayMEM3BLT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayRECTANGLE()
|
||
// Replays RECTANGLE order
|
||
//
|
||
void ASShare::ODReplayRECTANGLE
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPRECTANGLE_ORDER pRectangle,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayRECTANGLE);
|
||
|
||
TRACE_OUT(("ORDER: Rectangle BC %08lX FC %08lX BM %04hX brush %02hX " \
|
||
"%02hX rop2 %04hX pen %04hX %04hX %08lX rect %d %d %d %d",
|
||
pRectangle->BackColor,
|
||
pRectangle->ForeColor,
|
||
(TSHR_UINT16)pRectangle->BackMode,
|
||
(TSHR_UINT16)pRectangle->BrushStyle,
|
||
(TSHR_UINT16)pRectangle->BrushHatch,
|
||
(TSHR_UINT16)pRectangle->ROP2,
|
||
(TSHR_UINT16)pRectangle->PenStyle,
|
||
(TSHR_UINT16)pRectangle->PenWidth,
|
||
pRectangle->PenColor,
|
||
(int)pRectangle->nLeftRect,
|
||
(int)pRectangle->nTopRect,
|
||
(int)pRectangle->nRightRect + 1,
|
||
(int)pRectangle->nBottomRect + 1));
|
||
|
||
ODAdjustColor(pasPerson, &(pRectangle->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pRectangle->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pRectangle->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pRectangle->BackMode);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pRectangle->BrushOrgX, pRectangle->BrushOrgY,
|
||
pRectangle->BrushStyle, pRectangle->BrushHatch, ForeColor,
|
||
pRectangle->BrushExtra);
|
||
|
||
ODUseROP2(pasPerson, pRectangle->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pRectangle->PenStyle, pRectangle->PenWidth,
|
||
PenColor);
|
||
|
||
//
|
||
// The rectangle in the order is inclusive but Windows works
|
||
// with exclusive rectangles.
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
Rectangle(pasPerson->m_pView->m_usrDC,
|
||
pRectangle->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pRectangle->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pRectangle->nRightRect - pasPerson->m_pView->m_dsScreenOrigin.x + 1,
|
||
pRectangle->nBottomRect- pasPerson->m_pView->m_dsScreenOrigin.y + 1);
|
||
|
||
DebugExitVOID(ASShare::ODReplayRECTANGLE);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayPOLYGON()
|
||
// Replays POLYGON order
|
||
//
|
||
void ASShare::ODReplayPOLYGON
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPPOLYGON_ORDER pPolygon,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
POINT aP[ORD_MAX_POLYGON_POINTS];
|
||
UINT i;
|
||
UINT cPoints;
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayPOLYGON);
|
||
|
||
cPoints = pPolygon->variablePoints.len /
|
||
sizeof(pPolygon->variablePoints.aPoints[0]);
|
||
|
||
TRACE_OUT(("ORDER: Polygon BC %08lX FC %08lX BM %04hX brush %02hX %02hX "
|
||
"%02hX %02hX rop2 %04hX pen %04hX %04hX %08lX points %d",
|
||
pPolygon->BackColor,
|
||
pPolygon->ForeColor,
|
||
(TSHR_UINT16)pPolygon->BackMode,
|
||
(TSHR_UINT16)pPolygon->BrushStyle,
|
||
(TSHR_UINT16)pPolygon->BrushHatch,
|
||
(TSHR_UINT16)pPolygon->ROP2,
|
||
(TSHR_UINT16)pPolygon->PenStyle,
|
||
(TSHR_UINT16)pPolygon->PenWidth,
|
||
pPolygon->PenColor,
|
||
cPoints));
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
// while copying to native size point array.
|
||
//
|
||
for (i = 0; i < cPoints; i++)
|
||
{
|
||
TRACE_OUT(( "aPoints[%u]: %d,%d", i,
|
||
(int)(pPolygon->variablePoints.aPoints[i].x),
|
||
(int)(pPolygon->variablePoints.aPoints[i].y)));
|
||
|
||
aP[i].x = pPolygon->variablePoints.aPoints[i].x -
|
||
pasPerson->m_pView->m_dsScreenOrigin.x;
|
||
aP[i].y = pPolygon->variablePoints.aPoints[i].y -
|
||
pasPerson->m_pView->m_dsScreenOrigin.y;
|
||
}
|
||
|
||
ODAdjustColor(pasPerson, &(pPolygon->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPolygon->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPolygon->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pPolygon->BackMode);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pPolygon->BrushOrgX, pPolygon->BrushOrgY,
|
||
pPolygon->BrushStyle, pPolygon->BrushHatch, ForeColor,
|
||
pPolygon->BrushExtra);
|
||
|
||
ODUseROP2(pasPerson, pPolygon->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pPolygon->PenStyle, pPolygon->PenWidth,
|
||
PenColor);
|
||
|
||
ODUseFillMode(pasPerson, pPolygon->FillMode);
|
||
|
||
|
||
Polygon(pasPerson->m_pView->m_usrDC, aP, cPoints);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayPOLYGON);
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayPIE()
|
||
// Replays PIE order
|
||
//
|
||
void ASShare::ODReplayPIE
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPPIE_ORDER pPie,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayPIE);
|
||
|
||
TRACE_OUT(("ORDER: Pie BC %08lX FC %08lX BM %04hX brush %02hX "
|
||
" %02hX rop2 %04hX pen %04hX %04hX %08lX rect %d %d %d %d",
|
||
pPie->BackColor,
|
||
pPie->ForeColor,
|
||
(TSHR_UINT16)pPie->BackMode,
|
||
(TSHR_UINT16)pPie->BrushStyle,
|
||
(TSHR_UINT16)pPie->BrushHatch,
|
||
(TSHR_UINT16)pPie->ROP2,
|
||
(TSHR_UINT16)pPie->PenStyle,
|
||
(TSHR_UINT16)pPie->PenWidth,
|
||
pPie->PenColor,
|
||
(int)pPie->nLeftRect,
|
||
(int)pPie->nTopRect,
|
||
(int)pPie->nRightRect + 1,
|
||
(int)pPie->nBottomRect + 1));
|
||
|
||
ODAdjustColor(pasPerson, &(pPie->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPie->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPie->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pPie->BackMode);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pPie->BrushOrgX, pPie->BrushOrgY,
|
||
pPie->BrushStyle, pPie->BrushHatch, ForeColor, pPie->BrushExtra);
|
||
|
||
ODUseROP2(pasPerson, pPie->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pPie->PenStyle, pPie->PenWidth,
|
||
PenColor);
|
||
|
||
ODUseArcDirection(pasPerson, (int)pPie->ArcDirection);
|
||
|
||
|
||
Pie(pasPerson->m_pView->m_usrDC,
|
||
pPie->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pPie->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pPie->nRightRect - pasPerson->m_pView->m_dsScreenOrigin.x + 1,
|
||
pPie->nBottomRect - pasPerson->m_pView->m_dsScreenOrigin.y + 1,
|
||
pPie->nXStart - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pPie->nYStart - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pPie->nXEnd - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pPie->nYEnd - pasPerson->m_pView->m_dsScreenOrigin.y);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayPIE);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayELLIPSE()
|
||
// Replays ELLIPSE order
|
||
//
|
||
void ASShare::ODReplayELLIPSE
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPELLIPSE_ORDER pEllipse,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayELLIPSE);
|
||
|
||
TRACE_OUT(("ORDER: Ellipse BC %08lX FC %08lX BM %04hX brush %02hX %02hX "
|
||
"rop2 %04hX pen %04hX %04hX %08lX rect %d %d %d %d",
|
||
pEllipse->BackColor,
|
||
pEllipse->ForeColor,
|
||
(TSHR_UINT16)pEllipse->BackMode,
|
||
(TSHR_UINT16)pEllipse->BrushStyle,
|
||
(TSHR_UINT16)pEllipse->BrushHatch,
|
||
(TSHR_UINT16)pEllipse->ROP2,
|
||
(TSHR_UINT16)pEllipse->PenStyle,
|
||
(TSHR_UINT16)pEllipse->PenWidth,
|
||
pEllipse->PenColor,
|
||
(int)pEllipse->nLeftRect,
|
||
(int)pEllipse->nTopRect,
|
||
(int)pEllipse->nRightRect + 1,
|
||
(int)pEllipse->nBottomRect + 1));
|
||
|
||
ODAdjustColor(pasPerson, &(pEllipse->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pEllipse->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pEllipse->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pEllipse->BackMode);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pEllipse->BrushOrgX, pEllipse->BrushOrgY,
|
||
pEllipse->BrushStyle, pEllipse->BrushHatch, ForeColor,
|
||
pEllipse->BrushExtra);
|
||
|
||
ODUseROP2(pasPerson, pEllipse->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pEllipse->PenStyle, pEllipse->PenWidth,
|
||
PenColor);
|
||
|
||
|
||
Ellipse(pasPerson->m_pView->m_usrDC,
|
||
pEllipse->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pEllipse->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pEllipse->nRightRect - pasPerson->m_pView->m_dsScreenOrigin.x + 1,
|
||
pEllipse->nBottomRect - pasPerson->m_pView->m_dsScreenOrigin.y + 1);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayELLIPSE);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayARC()
|
||
// Replays ARC order
|
||
//
|
||
void ASShare::ODReplayARC
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPARC_ORDER pArc,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayARC);
|
||
|
||
TRACE_OUT(("ORDER: Arc BC %08lX BM %04hX rop2 %04hX pen %04hX "
|
||
"%04hX %08lX rect %d %d %d %d",
|
||
pArc->BackColor,
|
||
(TSHR_UINT16)pArc->BackMode,
|
||
(TSHR_UINT16)pArc->ROP2,
|
||
(TSHR_UINT16)pArc->PenStyle,
|
||
(TSHR_UINT16)pArc->PenWidth,
|
||
pArc->PenColor,
|
||
(int)pArc->nLeftRect,
|
||
(int)pArc->nTopRect,
|
||
(int)pArc->nRightRect + 1,
|
||
(int)pArc->nBottomRect + 1));
|
||
|
||
ODAdjustColor(pasPerson, &(pArc->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pArc->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseBkMode(pasPerson, pArc->BackMode);
|
||
|
||
ODUseROP2(pasPerson, pArc->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pArc->PenStyle, pArc->PenWidth,
|
||
PenColor);
|
||
|
||
ODUseArcDirection(pasPerson, pArc->ArcDirection);
|
||
|
||
|
||
Arc(pasPerson->m_pView->m_usrDC,
|
||
pArc->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pArc->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pArc->nRightRect - pasPerson->m_pView->m_dsScreenOrigin.x + 1,
|
||
pArc->nBottomRect - pasPerson->m_pView->m_dsScreenOrigin.y + 1,
|
||
pArc->nXStart - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pArc->nYStart - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pArc->nXEnd - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pArc->nYEnd - pasPerson->m_pView->m_dsScreenOrigin.y);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayARC);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayCHORD()
|
||
// Replays CHORD order
|
||
//
|
||
void ASShare::ODReplayCHORD
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPCHORD_ORDER pChord,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayCHORD);
|
||
|
||
TRACE_OUT(("ORDER: Chord BC %08lX FC %08lX BM %04hX brush "
|
||
"%02hX %02hX rop2 %04hX pen %04hX %04hX %08lX rect "
|
||
"%d %d %d %d",
|
||
pChord->BackColor,
|
||
pChord->ForeColor,
|
||
(TSHR_UINT16)pChord->BackMode,
|
||
(TSHR_UINT16)pChord->BrushStyle,
|
||
(TSHR_UINT16)pChord->BrushHatch,
|
||
(TSHR_UINT16)pChord->ROP2,
|
||
(TSHR_UINT16)pChord->PenStyle,
|
||
(TSHR_UINT16)pChord->PenWidth,
|
||
pChord->PenColor,
|
||
(int)pChord->nLeftRect,
|
||
(int)pChord->nTopRect,
|
||
(int)pChord->nRightRect + 1,
|
||
(int)pChord->nBottomRect + 1));
|
||
|
||
|
||
ODAdjustColor(pasPerson, &(pChord->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pChord->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pChord->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pChord->BackMode);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pChord->BrushOrgX, pChord->BrushOrgY,
|
||
pChord->BrushStyle, pChord->BrushHatch, ForeColor,
|
||
pChord->BrushExtra);
|
||
|
||
ODUseROP2(pasPerson, pChord->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pChord->PenStyle, pChord->PenWidth,
|
||
PenColor);
|
||
|
||
ODUseArcDirection(pasPerson, pChord->ArcDirection);
|
||
|
||
|
||
Chord(pasPerson->m_pView->m_usrDC,
|
||
pChord->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pChord->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pChord->nRightRect - pasPerson->m_pView->m_dsScreenOrigin.x + 1,
|
||
pChord->nBottomRect - pasPerson->m_pView->m_dsScreenOrigin.y + 1,
|
||
pChord->nXStart - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pChord->nYStart - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pChord->nXEnd - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pChord->nYEnd - pasPerson->m_pView->m_dsScreenOrigin.y);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayCHORD);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayPOLYBEZIER()
|
||
// Replays POLYBEZIER order
|
||
//
|
||
void ASShare::ODReplayPOLYBEZIER
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPPOLYBEZIER_ORDER pPolyBezier,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
POINT aP[ORD_MAX_POLYBEZIER_POINTS];
|
||
UINT i;
|
||
UINT cPoints;
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayPOLYBEZIER);
|
||
|
||
cPoints = pPolyBezier->variablePoints.len /
|
||
sizeof(pPolyBezier->variablePoints.aPoints[0]);
|
||
|
||
TRACE_OUT(("ORDER: PolyBezier BC %08lX FC %08lX BM %04hX rop2 "
|
||
"%04hX pen %04hX %04hX %08lX points %d",
|
||
pPolyBezier->BackColor,
|
||
pPolyBezier->ForeColor,
|
||
(TSHR_UINT16)pPolyBezier->BackMode,
|
||
(TSHR_UINT16)pPolyBezier->ROP2,
|
||
(TSHR_UINT16)pPolyBezier->PenStyle,
|
||
(TSHR_UINT16)pPolyBezier->PenWidth,
|
||
pPolyBezier->PenColor,
|
||
(int)cPoints));
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
// while copying to native size point array.
|
||
//
|
||
for (i = 0; i < cPoints; i++)
|
||
{
|
||
TRACE_OUT(("aPoints[%u]: %d,%d",(UINT)i,
|
||
(int)(pPolyBezier->variablePoints.aPoints[i].x),
|
||
(int)(pPolyBezier->variablePoints.aPoints[i].y)));
|
||
|
||
aP[i].x = pPolyBezier->variablePoints.aPoints[i].x -
|
||
pasPerson->m_pView->m_dsScreenOrigin.x;
|
||
aP[i].y = pPolyBezier->variablePoints.aPoints[i].y -
|
||
pasPerson->m_pView->m_dsScreenOrigin.y;
|
||
}
|
||
|
||
ODAdjustColor(pasPerson, &(pPolyBezier->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPolyBezier->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pPolyBezier->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pPolyBezier->BackMode);
|
||
|
||
ODUseROP2(pasPerson, pPolyBezier->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pPolyBezier->PenStyle, pPolyBezier->PenWidth,
|
||
PenColor);
|
||
|
||
|
||
PolyBezier(pasPerson->m_pView->m_usrDC, aP, cPoints);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayPOLYBEZIER);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayROUNDRECT()
|
||
//
|
||
void ASShare::ODReplayROUNDRECT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPROUNDRECT_ORDER pRoundRect,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayROUNDRECT);
|
||
|
||
TRACE_OUT(("ORDER: RoundRect BC %08lX FC %08lX BM %04hX " \
|
||
"brush %02hX %02hX rop2 %04hX pen %04hX %04hX " \
|
||
"%08lX rect %d %d %d %d ellipse %d %d",
|
||
pRoundRect->BackColor,
|
||
pRoundRect->ForeColor,
|
||
(TSHR_UINT16)pRoundRect->BackMode,
|
||
(TSHR_UINT16)pRoundRect->BrushStyle,
|
||
(TSHR_UINT16)pRoundRect->BrushHatch,
|
||
(TSHR_UINT16)pRoundRect->ROP2,
|
||
(TSHR_UINT16)pRoundRect->PenStyle,
|
||
(TSHR_UINT16)pRoundRect->PenWidth,
|
||
pRoundRect->PenColor,
|
||
(int)pRoundRect->nLeftRect,
|
||
(int)pRoundRect->nTopRect,
|
||
(int)pRoundRect->nRightRect,
|
||
(int)pRoundRect->nBottomRect,
|
||
(int)pRoundRect->nEllipseWidth,
|
||
(int)pRoundRect->nEllipseHeight));
|
||
|
||
ODAdjustColor(pasPerson, &(pRoundRect->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pRoundRect->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
ODAdjustColor(pasPerson, &(pRoundRect->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pRoundRect->BackMode);
|
||
|
||
ODUseBrush(pasPerson, fPalRGB, pRoundRect->BrushOrgX, pRoundRect->BrushOrgY,
|
||
pRoundRect->BrushStyle, pRoundRect->BrushHatch, ForeColor,
|
||
pRoundRect->BrushExtra);
|
||
|
||
ODUseROP2(pasPerson, pRoundRect->ROP2);
|
||
|
||
ODUsePen(pasPerson, fPalRGB, pRoundRect->PenStyle, pRoundRect->PenWidth,
|
||
PenColor);
|
||
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform).
|
||
//
|
||
RoundRect(pasPerson->m_pView->m_usrDC,
|
||
pRoundRect->nLeftRect - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pRoundRect->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pRoundRect->nRightRect - pasPerson->m_pView->m_dsScreenOrigin.x + 1,
|
||
pRoundRect->nBottomRect- pasPerson->m_pView->m_dsScreenOrigin.y + 1,
|
||
pRoundRect->nEllipseWidth,
|
||
pRoundRect->nEllipseHeight);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayROUNDRECT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayLINETO()
|
||
// Replays LINETO order
|
||
//
|
||
void ASShare::ODReplayLINETO
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPLINETO_ORDER pLineTo,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR PenColor;
|
||
|
||
DebugEntry(ASShare::ODReplayLINETO);
|
||
|
||
TRACE_OUT(("ORDER: LineTo BC %08lX BM %04X rop2 %04X pen " \
|
||
"%04X %04X %08lX x1 %d y1 %d x2 %d y2 %d",
|
||
pLineTo->BackColor,
|
||
pLineTo->BackMode,
|
||
pLineTo->ROP2,
|
||
pLineTo->PenStyle,
|
||
pLineTo->PenWidth,
|
||
pLineTo->PenColor,
|
||
pLineTo->nXStart,
|
||
pLineTo->nYStart,
|
||
pLineTo->nXEnd,
|
||
pLineTo->nYEnd));
|
||
|
||
ODAdjustColor(pasPerson, &(pLineTo->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pLineTo->PenColor), &PenColor, OD_PEN_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseBkMode(pasPerson, pLineTo->BackMode);
|
||
|
||
ODUseROP2(pasPerson, pLineTo->ROP2);
|
||
ODUsePen(pasPerson, fPalRGB, pLineTo->PenStyle, pLineTo->PenWidth,
|
||
PenColor);
|
||
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
MoveToEx(pasPerson->m_pView->m_usrDC,
|
||
pLineTo->nXStart - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pLineTo->nYStart - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
NULL);
|
||
LineTo(pasPerson->m_pView->m_usrDC,
|
||
pLineTo->nXEnd - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pLineTo->nYEnd - pasPerson->m_pView->m_dsScreenOrigin.y);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayLINETO);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayEXTTEXTOUT()
|
||
// Replays EXTTEXTOUT order
|
||
//
|
||
void ASShare::ODReplayEXTTEXTOUT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPEXTTEXTOUT_ORDER pExtTextOut,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
LPINT lpDx;
|
||
RECT rect;
|
||
|
||
DebugEntry(ASShare::ODReplayEXTTEXTOUT);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
//
|
||
// Convert from TSHR_RECT32 to RECT we can manipulate
|
||
// And convert to screen coords
|
||
//
|
||
rect.left = pExtTextOut->rectangle.left;
|
||
rect.top = pExtTextOut->rectangle.top;
|
||
rect.right = pExtTextOut->rectangle.right;
|
||
rect.bottom = pExtTextOut->rectangle.bottom;
|
||
OffsetRect(&rect, -pasPerson->m_pView->m_dsScreenOrigin.x, -pasPerson->m_pView->m_dsScreenOrigin.y);
|
||
|
||
//
|
||
// Get pointers to the optional/variable parameters.
|
||
//
|
||
if (pExtTextOut->fuOptions & ETO_WINDOWS)
|
||
{
|
||
//
|
||
// Make the rectangle exclusive for Windows to use.
|
||
//
|
||
rect.right++;
|
||
rect.bottom++;
|
||
}
|
||
|
||
if (pExtTextOut->fuOptions & ETO_LPDX)
|
||
{
|
||
//
|
||
// if OE2 encoding is in use, the 'variable' string is
|
||
// in fact fixed at its maximum possible value, hence
|
||
// deltaX is always in the same place.
|
||
//
|
||
if (m_oefOE2EncodingOn)
|
||
{
|
||
lpDx = (LPINT)(pExtTextOut->variableDeltaX.deltaX);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// If OE2 encoding is not in use, the variable string is
|
||
// truly variable, hence the position of deltaX depends
|
||
// on the length of the string.
|
||
//
|
||
lpDx = (LPINT)( ((LPBYTE)pExtTextOut) +
|
||
FIELD_OFFSET(EXTTEXTOUT_ORDER, variableString.string) +
|
||
pExtTextOut->variableString.len +
|
||
sizeof(pExtTextOut->variableDeltaX.len) );
|
||
}
|
||
|
||
//
|
||
// Note that deltaLen contains the number of bytes used
|
||
// for the deltas, NOT the number of deltas.
|
||
//
|
||
|
||
//
|
||
// THERE IS A BUG IN THE ORDER ENCODING - THE DELTA
|
||
// LENGTH FIELD IS NOT ALWAYS SET UP CORRECTLY. USE
|
||
// THE STRING LENGTH INSTEAD.
|
||
//
|
||
}
|
||
else
|
||
{
|
||
lpDx = NULL;
|
||
}
|
||
|
||
TRACE_OUT(( "ORDER: ExtTextOut %u %s",
|
||
pExtTextOut->variableString.len,
|
||
pExtTextOut->variableString.string));
|
||
|
||
//
|
||
// Call our internal routine to draw the text
|
||
//
|
||
ODDrawTextOrder(pasPerson,
|
||
TRUE, // ExtTextOut
|
||
fPalRGB,
|
||
&pExtTextOut->common,
|
||
pExtTextOut->variableString.string,
|
||
pExtTextOut->variableString.len,
|
||
&rect,
|
||
pExtTextOut->fuOptions,
|
||
lpDx);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayEXTTEXTOUT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayTEXTOUT()
|
||
// Replays TEXTOUT order
|
||
//
|
||
void ASShare::ODReplayTEXTOUT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPTEXTOUT_ORDER pTextOut,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
DebugEntry(ASShare::ODReplayTEXTOUT);
|
||
|
||
TRACE_OUT(("ORDER: TextOut len %hu '%s' flags %04hx bc %08lX " \
|
||
"fc %08lX bm %04hx",
|
||
(TSHR_UINT16)(pTextOut->variableString.len),
|
||
pTextOut->variableString.string,
|
||
pTextOut->common.FontFlags,
|
||
pTextOut->common.BackColor,
|
||
pTextOut->common.ForeColor,
|
||
pTextOut->common.BackMode));
|
||
|
||
//
|
||
// Call our internal routine to draw the text
|
||
//
|
||
ODDrawTextOrder(pasPerson,
|
||
FALSE, // Not ExtTextOut
|
||
fPalRGB,
|
||
&pTextOut->common,
|
||
pTextOut->variableString.string,
|
||
pTextOut->variableString.len,
|
||
NULL, // ExtTextOut specific
|
||
0, // ExtTextOut specific
|
||
NULL); // ExtTextOut specific
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayTEXTOUT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODReplayOPAQUERECT()
|
||
// Replays OPAQUERECT order
|
||
//
|
||
void ASShare::ODReplayOPAQUERECT
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPOPAQUERECT_ORDER pOpaqueRect,
|
||
BOOL fPalRGB
|
||
)
|
||
{
|
||
RECT rect;
|
||
TSHR_COLOR ForeColor;
|
||
|
||
DebugEntry(ASShare::ODReplayOPAQUERECT);
|
||
|
||
TRACE_OUT(( "ORDER: OpaqueRect BC %08lX x %d y %d w %x h %d",
|
||
pOpaqueRect->Color,
|
||
(int)pOpaqueRect->nLeftRect,
|
||
(int)pOpaqueRect->nTopRect,
|
||
(int)pOpaqueRect->nWidth,
|
||
(int)pOpaqueRect->nHeight));
|
||
|
||
ODAdjustColor(pasPerson, &(pOpaqueRect->Color), &ForeColor, OD_FORE_COLOR);
|
||
|
||
ODUseBkColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
rect.left = pOpaqueRect->nLeftRect- pasPerson->m_pView->m_dsScreenOrigin.x;
|
||
rect.top = pOpaqueRect->nTopRect - pasPerson->m_pView->m_dsScreenOrigin.y;
|
||
rect.right = rect.left + pOpaqueRect->nWidth;
|
||
rect.bottom = rect.top + pOpaqueRect->nHeight;
|
||
|
||
|
||
ExtTextOut(pasPerson->m_pView->m_usrDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
|
||
|
||
|
||
DebugExitVOID(ASShare::ODReplayOPAQUERECT);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// OD_ResetRectRegion()
|
||
//
|
||
void ASShare::OD_ResetRectRegion(ASPerson * pasPerson)
|
||
{
|
||
DebugEntry(ASShare::OD_ResetRectRegion);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
if (!pasPerson->m_pView->m_odRectReset)
|
||
{
|
||
SelectClipRgn(pasPerson->m_pView->m_usrDC, NULL);
|
||
|
||
//
|
||
// Indicate that the region is currently reset.
|
||
//
|
||
pasPerson->m_pView->m_odRectReset = TRUE;
|
||
}
|
||
|
||
DebugExitVOID(ASShare::OD_ResetRectRegion);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ODUseFont()
|
||
//
|
||
void ASShare::ODUseFont
|
||
(
|
||
ASPerson * pasPerson,
|
||
LPSTR pName,
|
||
UINT facelength,
|
||
UINT CodePage,
|
||
UINT MaxHeight,
|
||
UINT Height,
|
||
UINT Width,
|
||
UINT Weight,
|
||
UINT flags
|
||
)
|
||
{
|
||
BOOL rc = TRUE;
|
||
TEXTMETRIC* pfm = NULL;
|
||
UINT textAlign;
|
||
|
||
DebugEntry(ASShare::ODUseFont);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
//
|
||
// If the baseline alignment flag has been set or cleared, change the
|
||
// alignment in our surface (do this now before we reset the
|
||
// odLastFontFlags variable).
|
||
//
|
||
if ((flags & NF_BASELINE) != (pasPerson->m_pView->m_odLastFontFlags & NF_BASELINE))
|
||
{
|
||
textAlign = GetTextAlign(pasPerson->m_pView->m_usrDC);
|
||
if ((flags & NF_BASELINE) != 0)
|
||
{
|
||
//
|
||
// We are setting the baseline alignment flag. We have to
|
||
// clear the top alignment flag and set the baseline flag (they
|
||
// are mutually exclusive).
|
||
//
|
||
textAlign &= ~TA_TOP;
|
||
textAlign |= TA_BASELINE;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// We are clearing the baseline alignment flag. We have to set
|
||
// the top alignment flag and clear the baseline flag (they are
|
||
// mutually exclusive).
|
||
//
|
||
textAlign |= TA_TOP;
|
||
textAlign &= ~TA_BASELINE;
|
||
}
|
||
SetTextAlign(pasPerson->m_pView->m_usrDC, textAlign);
|
||
}
|
||
|
||
//
|
||
// The font face string is NOT null terminated in the order data so we
|
||
// must use strncmp.
|
||
//
|
||
if ((pasPerson->m_pView->m_odLastFontFaceLen != facelength ) ||
|
||
(memcmp((LPSTR)pasPerson->m_pView->m_odLastFaceName,pName,facelength) != 0 ) ||
|
||
(pasPerson->m_pView->m_odLastFontCodePage != CodePage ) ||
|
||
(pasPerson->m_pView->m_odLastFontHeight != Height ) ||
|
||
(pasPerson->m_pView->m_odLastFontWidth != Width ) ||
|
||
(pasPerson->m_pView->m_odLastFontWeight != Weight ) ||
|
||
(pasPerson->m_pView->m_odLastFontFlags != flags ))
|
||
{
|
||
TRACE_OUT((
|
||
"Change font from %s (CodePage %d height %d width %d " \
|
||
"weight %d flags %04X) to %s (CodePage %d height %d " \
|
||
"width %d weight %u flags %04X)",
|
||
pasPerson->m_pView->m_odLastFaceName,
|
||
pasPerson->m_pView->m_odLastFontCodePage,
|
||
pasPerson->m_pView->m_odLastFontHeight,
|
||
pasPerson->m_pView->m_odLastFontWidth,
|
||
pasPerson->m_pView->m_odLastFontWeight,
|
||
pasPerson->m_pView->m_odLastFontFlags,
|
||
pName,
|
||
CodePage,
|
||
Height,
|
||
Width,
|
||
Weight,
|
||
flags));
|
||
|
||
memcpy(pasPerson->m_pView->m_odLastFaceName, pName, facelength);
|
||
pasPerson->m_pView->m_odLastFontFaceLen = facelength;
|
||
pasPerson->m_pView->m_odLastFaceName[facelength] = '\0';
|
||
pasPerson->m_pView->m_odLastFontCodePage = CodePage;
|
||
pasPerson->m_pView->m_odLastFontHeight = Height;
|
||
pasPerson->m_pView->m_odLastFontWidth = Width;
|
||
pasPerson->m_pView->m_odLastFontWeight = Weight;
|
||
pasPerson->m_pView->m_odLastFontFlags = flags;
|
||
|
||
rc = USR_UseFont(pasPerson->m_pView->m_usrDC, &pasPerson->m_pView->m_odLastFontID,
|
||
pfm, (LPSTR)pasPerson->m_pView->m_odLastFaceName, CodePage, MaxHeight,
|
||
Height, Width, Weight, flags);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// The font hasn't changed. But we must still select it in since
|
||
// both OD2 and OD code select in fonts.
|
||
//
|
||
ASSERT(pasPerson->m_pView->m_odLastFontID != NULL);
|
||
SelectFont(pasPerson->m_pView->m_usrDC, pasPerson->m_pView->m_odLastFontID);
|
||
}
|
||
|
||
DebugExitVOID(ASShare::ODUseFont);
|
||
}
|
||
|
||
//
|
||
// FUNCTION: ASShare::ODUseRectRegion
|
||
//
|
||
// DESCRIPTION:
|
||
//
|
||
// Set the clipping rectangle in the ScreenBitmap to the given rectangle.
|
||
// The values passed are inclusive.
|
||
//
|
||
// PARAMETERS:
|
||
//
|
||
void ASShare::ODUseRectRegion
|
||
(
|
||
ASPerson * pasPerson,
|
||
int left,
|
||
int top,
|
||
int right,
|
||
int bottom
|
||
)
|
||
{
|
||
POINT aPoints[2];
|
||
HRGN hrgnRect;
|
||
|
||
DebugEntry(ASShare::ODUseRectRegion);
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
// Adjust for 2.x desktop scrolling
|
||
left -= pasPerson->m_pView->m_dsScreenOrigin.x;
|
||
top -= pasPerson->m_pView->m_dsScreenOrigin.y;
|
||
right -= pasPerson->m_pView->m_dsScreenOrigin.x;
|
||
bottom -= pasPerson->m_pView->m_dsScreenOrigin.y;
|
||
|
||
if ((pasPerson->m_pView->m_odRectReset) ||
|
||
(left != pasPerson->m_pView->m_odLastLeft) ||
|
||
(top != pasPerson->m_pView->m_odLastTop) ||
|
||
(right != pasPerson->m_pView->m_odLastRight) ||
|
||
(bottom != pasPerson->m_pView->m_odLastBottom))
|
||
{
|
||
//
|
||
// The region clip rectangle has changed, so we change the region
|
||
// in the screen bitmap DC.
|
||
//
|
||
aPoints[0].x = left;
|
||
aPoints[0].y = top;
|
||
aPoints[1].x = right;
|
||
aPoints[1].y = bottom;
|
||
|
||
//
|
||
// Windows requires that the coordinates are in DEVICE values for
|
||
// its SelectClipRgn call.
|
||
//
|
||
LPtoDP(pasPerson->m_pView->m_usrDC, aPoints, 2);
|
||
|
||
if ((left > right) || (top > bottom))
|
||
{
|
||
//
|
||
// We get this for SaveScreenBitmap orders. SFR5292
|
||
//
|
||
TRACE_OUT(( "Null bounds of region rect"));
|
||
hrgnRect = CreateRectRgn(0, 0, 0, 0);
|
||
}
|
||
else
|
||
{
|
||
// We must add one to right & bottom since coords were inclusive
|
||
hrgnRect = CreateRectRgn( aPoints[0].x,
|
||
aPoints[0].y,
|
||
aPoints[1].x+1,
|
||
aPoints[1].y+1);
|
||
|
||
}
|
||
SelectClipRgn(pasPerson->m_pView->m_usrDC, hrgnRect);
|
||
|
||
pasPerson->m_pView->m_odLastLeft = left;
|
||
pasPerson->m_pView->m_odLastTop = top;
|
||
pasPerson->m_pView->m_odLastRight = right;
|
||
pasPerson->m_pView->m_odLastBottom = bottom;
|
||
pasPerson->m_pView->m_odRectReset = FALSE;
|
||
|
||
if (hrgnRect != NULL)
|
||
{
|
||
DeleteRgn(hrgnRect);
|
||
}
|
||
}
|
||
|
||
DebugExitVOID(ASShare::ODUseRectRegion);
|
||
}
|
||
|
||
|
||
//
|
||
// ODUseBrush creates the correct brush to use. NB. We rely on
|
||
// UseTextColor and UseBKColor being called before this routine to set up
|
||
// pasPerson->m_pView->m_odLastTextColor and pasPerson->m_pView->m_odLastBkColor correctly.
|
||
//
|
||
void ASShare::ODUseBrush
|
||
(
|
||
ASPerson * pasPerson,
|
||
BOOL fPalRGB,
|
||
int x,
|
||
int y,
|
||
UINT Style,
|
||
UINT Hatch,
|
||
TSHR_COLOR Color,
|
||
BYTE Extra[7]
|
||
)
|
||
{
|
||
HBRUSH hBrushNew = NULL;
|
||
|
||
DebugEntry(ASShare::ODUseBrush);
|
||
|
||
// Reset the origin
|
||
if ((x != pasPerson->m_pView->m_odLastBrushOrgX) ||
|
||
(y != pasPerson->m_pView->m_odLastBrushOrgY))
|
||
{
|
||
SetBrushOrgEx(pasPerson->m_pView->m_usrDC, x, y, NULL);
|
||
|
||
// Update saved brush org
|
||
pasPerson->m_pView->m_odLastBrushOrgX = x;
|
||
pasPerson->m_pView->m_odLastBrushOrgY = y;
|
||
}
|
||
|
||
if ((Style != pasPerson->m_pView->m_odLastLogBrushStyle) ||
|
||
(Hatch != pasPerson->m_pView->m_odLastLogBrushHatch) ||
|
||
(memcmp(&Color, &pasPerson->m_pView->m_odLastLogBrushColor, sizeof(Color))) ||
|
||
(memcmp(Extra,pasPerson->m_pView->m_odLastLogBrushExtra,sizeof(pasPerson->m_pView->m_odLastLogBrushExtra))) ||
|
||
((pasPerson->m_pView->m_odLastLogBrushStyle == BS_PATTERN) &&
|
||
((pasPerson->m_pView->m_odLastTextColor != pasPerson->m_pView->m_odLastBrushTextColor) ||
|
||
(pasPerson->m_pView->m_odLastBkColor != pasPerson->m_pView->m_odLastBrushBkColor))))
|
||
{
|
||
pasPerson->m_pView->m_odLastLogBrushStyle = Style;
|
||
pasPerson->m_pView->m_odLastLogBrushHatch = Hatch;
|
||
pasPerson->m_pView->m_odLastLogBrushColor = Color;
|
||
memcpy(pasPerson->m_pView->m_odLastLogBrushExtra, Extra, sizeof(pasPerson->m_pView->m_odLastLogBrushExtra));
|
||
|
||
if (pasPerson->m_pView->m_odLastLogBrushStyle == BS_PATTERN)
|
||
{
|
||
//
|
||
// A pattern from a bitmap is required.
|
||
//
|
||
if (pasPerson->m_pView->m_odLastBrushPattern == NULL)
|
||
{
|
||
TRACE_OUT(( "Creating bitmap to use for brush setup"));
|
||
|
||
pasPerson->m_pView->m_odLastBrushPattern = CreateBitmap(8,8,1,1,NULL);
|
||
}
|
||
|
||
if (pasPerson->m_pView->m_odLastBrushPattern != NULL)
|
||
{
|
||
char lpBits[16];
|
||
|
||
//
|
||
// Place the bitmap bits into an array of bytes in the
|
||
// correct form for SetBitmapBits which uses 16 bits per
|
||
// scanline.
|
||
//
|
||
lpBits[14] = (char)Hatch;
|
||
lpBits[12] = Extra[0];
|
||
lpBits[10] = Extra[1];
|
||
lpBits[8] = Extra[2];
|
||
lpBits[6] = Extra[3];
|
||
lpBits[4] = Extra[4];
|
||
lpBits[2] = Extra[5];
|
||
lpBits[0] = Extra[6];
|
||
|
||
SetBitmapBits(pasPerson->m_pView->m_odLastBrushPattern,8*2,lpBits);
|
||
|
||
hBrushNew = CreatePatternBrush(pasPerson->m_pView->m_odLastBrushPattern);
|
||
if (hBrushNew == NULL)
|
||
{
|
||
ERROR_OUT(( "Failed to create pattern brush"));
|
||
}
|
||
else
|
||
{
|
||
pasPerson->m_pView->m_odLastBrushTextColor = pasPerson->m_pView->m_odLastTextColor;
|
||
pasPerson->m_pView->m_odLastBrushBkColor = pasPerson->m_pView->m_odLastBkColor;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
LOGBRUSH logBrush;
|
||
|
||
logBrush.lbStyle = pasPerson->m_pView->m_odLastLogBrushStyle;
|
||
logBrush.lbHatch = pasPerson->m_pView->m_odLastLogBrushHatch;
|
||
logBrush.lbColor = ODCustomRGB(pasPerson->m_pView->m_odLastLogBrushColor.red,
|
||
pasPerson->m_pView->m_odLastLogBrushColor.green,
|
||
pasPerson->m_pView->m_odLastLogBrushColor.blue,
|
||
fPalRGB);
|
||
hBrushNew = CreateBrushIndirect(&logBrush);
|
||
}
|
||
|
||
if (hBrushNew == NULL)
|
||
{
|
||
ERROR_OUT(( "Failed to create brush"));
|
||
}
|
||
else
|
||
{
|
||
TRACE_OUT(( "Selecting new brush 0x%08x", hBrushNew));
|
||
DeleteBrush(SelectBrush(pasPerson->m_pView->m_usrDC, hBrushNew));
|
||
}
|
||
}
|
||
|
||
DebugExitVOID(ASShare::ODUseBrush);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ODDrawTextOrder()
|
||
// Common text order playback code for EXTTEXTOUT and TEXTOUT
|
||
//
|
||
void ASShare::ODDrawTextOrder
|
||
(
|
||
ASPerson * pasPerson,
|
||
BOOL isExtTextOut,
|
||
BOOL fPalRGB,
|
||
LPCOMMON_TEXTORDER pCommon,
|
||
LPSTR pText,
|
||
UINT textLength,
|
||
LPRECT pExtRect,
|
||
UINT extOptions,
|
||
LPINT pExtDx
|
||
)
|
||
{
|
||
LPSTR faceName;
|
||
UINT faceNameLength;
|
||
UINT maxFontHeight;
|
||
TSHR_UINT16 nFontFlags;
|
||
TSHR_UINT16 nCodePage;
|
||
TSHR_COLOR BackColor;
|
||
TSHR_COLOR ForeColor;
|
||
|
||
DebugEntry(ASShare::ODDrawTextOrder);
|
||
|
||
ODAdjustColor(pasPerson, &(pCommon->BackColor), &BackColor, OD_BACK_COLOR);
|
||
ODAdjustColor(pasPerson, &(pCommon->ForeColor), &ForeColor, OD_FORE_COLOR);
|
||
|
||
ODUseTextBkColor(pasPerson, fPalRGB, BackColor);
|
||
ODUseTextColor(pasPerson, fPalRGB, ForeColor);
|
||
|
||
ODUseBkMode(pasPerson, pCommon->BackMode);
|
||
|
||
ODUseTextCharacterExtra(pasPerson, pCommon->CharExtra);
|
||
ODUseTextJustification(pasPerson, pCommon->BreakExtra, pCommon->BreakCount);
|
||
|
||
faceName = FH_GetFaceNameFromLocalHandle(pCommon->FontIndex,
|
||
&faceNameLength);
|
||
|
||
maxFontHeight = FH_GetMaxHeightFromLocalHandle(pCommon->FontIndex);
|
||
|
||
//
|
||
// Get the local font flags for the font, so that we can merge in any
|
||
// specific local flag information when setting up the font. The prime
|
||
// example of this is whether the local font we matched is TrueType or
|
||
// not, which information is not sent over the wire, but does need to
|
||
// be used when setting up the font - or else we may draw using a local
|
||
// fixed font of the same facename.
|
||
//
|
||
nFontFlags = (TSHR_UINT16)FH_GetFontFlagsFromLocalHandle(pCommon->FontIndex);
|
||
|
||
//
|
||
// Get the local CodePage for the font.
|
||
//
|
||
nCodePage = (TSHR_UINT16)FH_GetCodePageFromLocalHandle(pCommon->FontIndex);
|
||
|
||
ODUseFont(pasPerson, faceName, faceNameLength, nCodePage,
|
||
maxFontHeight, pCommon->FontHeight, pCommon->FontWidth,
|
||
pCommon->FontWeight, pCommon->FontFlags | (nFontFlags & NF_LOCAL));
|
||
|
||
//
|
||
// Make the call.
|
||
//
|
||
if (isExtTextOut)
|
||
{
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
ExtTextOut(pasPerson->m_pView->m_usrDC,
|
||
pCommon->nXStart - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pCommon->nYStart - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
extOptions & ETO_WINDOWS,
|
||
pExtRect,
|
||
pText,
|
||
textLength,
|
||
pExtDx);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Apply DS origin offset ourselves (do not use transform)
|
||
//
|
||
TextOut(pasPerson->m_pView->m_usrDC,
|
||
pCommon->nXStart - pasPerson->m_pView->m_dsScreenOrigin.x,
|
||
pCommon->nYStart - pasPerson->m_pView->m_dsScreenOrigin.y,
|
||
pText,
|
||
textLength);
|
||
}
|
||
|
||
|
||
DebugExitVOID(ASShare::ODDrawTextOrder);
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ODAdjustColor()
|
||
//
|
||
// Used for playback on 4bpp devices. We convert colors that are 'close'
|
||
// to VGA to their VGA equivalents.
|
||
//
|
||
// This function tries to find a close match in the VGA color set for a
|
||
// given input color. Close is defined as follows: each color element
|
||
// (red, green, blue) must be within 7 of the corresponding element in a
|
||
// VGA color, without wrapping. For example
|
||
//
|
||
// - 0xc7b8c6 is 'close' to 0xc0c0c0
|
||
//
|
||
// - 0xf8f8f8 is 'close' to 0xffffff
|
||
//
|
||
// - 0xff0102 is not 'close' to 0x000000, but is 'close' to 0xff0000
|
||
//
|
||
// Closeness is determined as follows:
|
||
//
|
||
// - for each entry in the table s_odVGAColors
|
||
// - ADD the addMask to the color
|
||
// - AND the result with the andMask
|
||
// - if the result equals the testMask, this VGA color is close match
|
||
//
|
||
// Think about it. It works.
|
||
//
|
||
//
|
||
void ASShare::ODAdjustColor
|
||
(
|
||
ASPerson * pasPerson,
|
||
const TSHR_COLOR * pColorIn,
|
||
LPTSHR_COLOR pColorOut,
|
||
int type
|
||
)
|
||
{
|
||
int i;
|
||
COLORREF color;
|
||
COLORREF work;
|
||
|
||
DebugEntry(ASShare::ODAdjustColor);
|
||
|
||
*pColorOut = *pColorIn;
|
||
|
||
if (g_usrScreenBPP > 4)
|
||
{
|
||
// Nothing to convert; bail out
|
||
DC_QUIT;
|
||
}
|
||
|
||
//
|
||
// Convert the color to a single integer
|
||
//
|
||
color = (pColorOut->red << 16) + (pColorOut->green << 8) + pColorOut->blue;
|
||
|
||
//
|
||
// See if this is the same as the last call of this type
|
||
//
|
||
if (color == pasPerson->m_pView->m_odLastVGAColor[type])
|
||
{
|
||
*pColorOut = pasPerson->m_pView->m_odLastVGAResult[type];
|
||
TRACE_OUT(("Same as last %s color",
|
||
(type == OD_BACK_COLOR ? "background" :
|
||
type == OD_FORE_COLOR ? "foreground" : "pen")));
|
||
DC_QUIT;
|
||
}
|
||
|
||
|
||
//
|
||
// Scan the table for a close match.
|
||
//
|
||
for (i = 0; i < 16; i++)
|
||
{
|
||
//
|
||
// Check for a close match. Don't bother to look for an exact
|
||
// match, as that is caught by this code. The trade off is between
|
||
// - an additional test and jump in non-exact cases
|
||
// - an 'add' and an 'and' in the exact case.
|
||
//
|
||
work = color;
|
||
work += s_odVGAColors[i].addMask;
|
||
work &= s_odVGAColors[i].andMask;
|
||
if (work == s_odVGAColors[i].testMask)
|
||
{
|
||
TRACE_OUT(( "%#6.6lx is close match for %#6.6lx (%s)",
|
||
s_odVGAColors[i].color, color,
|
||
type == OD_BACK_COLOR ? "background" :
|
||
type == OD_FORE_COLOR ? "foreground" : "pen"));
|
||
*pColorOut = s_odVGAColors[i].result;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (i == 16)
|
||
{
|
||
TRACE_OUT(( "No close VGA match found for %#6.6lx (%s)",
|
||
color,
|
||
type == OD_BACK_COLOR ? "background" :
|
||
type == OD_FORE_COLOR ? "foreground" : "pen"));
|
||
}
|
||
|
||
//
|
||
// Save the result for next time.
|
||
//
|
||
pasPerson->m_pView->m_odLastVGAColor[type] = color;
|
||
pasPerson->m_pView->m_odLastVGAResult[type] = *pColorOut;
|
||
|
||
DC_EXIT_POINT:
|
||
DebugExitVOID(ASShare::ODAdjustColor);
|
||
}
|
||
|
||
|
||
//
|
||
// LITTLE ASShare::ODUse() functions
|
||
//
|
||
|
||
//
|
||
// ASShare::ODUseTextBkColor()
|
||
//
|
||
void ASShare::ODUseTextBkColor
|
||
(
|
||
ASPerson * pasPerson,
|
||
BOOL fPalRGB,
|
||
TSHR_COLOR color
|
||
)
|
||
{
|
||
COLORREF rgb;
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
rgb = ODCustomRGB(color.red, color.green, color.blue, fPalRGB);
|
||
SetBkColor(pasPerson->m_pView->m_usrDC, rgb);
|
||
|
||
// Update BK COLOR cache
|
||
pasPerson->m_pView->m_odLastBkColor = rgb;
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseBkColor()
|
||
//
|
||
void ASShare::ODUseBkColor
|
||
(
|
||
ASPerson * pasPerson,
|
||
BOOL fPalRGB,
|
||
TSHR_COLOR color
|
||
)
|
||
{
|
||
COLORREF rgb;
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
rgb = ODCustomRGB(color.red, color.green, color.blue, fPalRGB);
|
||
if (rgb != pasPerson->m_pView->m_odLastBkColor)
|
||
{
|
||
SetBkColor(pasPerson->m_pView->m_usrDC, rgb);
|
||
|
||
// Update BK COLOR cache
|
||
pasPerson->m_pView->m_odLastBkColor = rgb;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseTextColor()
|
||
//
|
||
void ASShare::ODUseTextColor
|
||
(
|
||
ASPerson * pasPerson,
|
||
BOOL fPalRGB,
|
||
TSHR_COLOR color
|
||
)
|
||
{
|
||
COLORREF rgb;
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
rgb = ODCustomRGB(color.red, color.green, color.blue, fPalRGB);
|
||
if (rgb != pasPerson->m_pView->m_odLastTextColor)
|
||
{
|
||
SetTextColor(pasPerson->m_pView->m_usrDC, rgb);
|
||
|
||
// Update TEXT COLOR cache
|
||
pasPerson->m_pView->m_odLastTextColor = rgb;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseBkMode()
|
||
//
|
||
void ASShare::ODUseBkMode(ASPerson * pasPerson, int mode)
|
||
{
|
||
if (mode != pasPerson->m_pView->m_odLastBkMode)
|
||
{
|
||
SetBkMode(pasPerson->m_pView->m_usrDC, mode);
|
||
|
||
// Update BK MODE cache
|
||
pasPerson->m_pView->m_odLastBkMode = mode;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODUsePen()
|
||
//
|
||
void ASShare::ODUsePen
|
||
(
|
||
ASPerson * pasPerson,
|
||
BOOL fPalRGB,
|
||
UINT style,
|
||
UINT width,
|
||
TSHR_COLOR color
|
||
)
|
||
{
|
||
HPEN hPenNew;
|
||
COLORREF rgb;
|
||
|
||
ValidateView(pasPerson);
|
||
|
||
rgb = ODCustomRGB(color.red, color.green, color.blue, fPalRGB);
|
||
|
||
if ((style != pasPerson->m_pView->m_odLastPenStyle) ||
|
||
(rgb != pasPerson->m_pView->m_odLastPenColor) ||
|
||
(width != pasPerson->m_pView->m_odLastPenWidth))
|
||
{
|
||
hPenNew = CreatePen(style, width, rgb);
|
||
|
||
DeletePen(SelectPen(pasPerson->m_pView->m_usrDC, hPenNew));
|
||
|
||
// Update PEN cache
|
||
pasPerson->m_pView->m_odLastPenStyle = style;
|
||
pasPerson->m_pView->m_odLastPenColor = rgb;
|
||
pasPerson->m_pView->m_odLastPenWidth = width;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseROP2()
|
||
//
|
||
void ASShare::ODUseROP2(ASPerson * pasPerson, int rop2)
|
||
{
|
||
if (rop2 != pasPerson->m_pView->m_odLastROP2)
|
||
{
|
||
SetROP2(pasPerson->m_pView->m_usrDC, rop2);
|
||
|
||
// Update ROP2 cache
|
||
pasPerson->m_pView->m_odLastROP2 = rop2;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseTextCharacterExtra()
|
||
//
|
||
void ASShare::ODUseTextCharacterExtra(ASPerson * pasPerson, int extra)
|
||
{
|
||
if (extra != pasPerson->m_pView->m_odLastCharExtra)
|
||
{
|
||
SetTextCharacterExtra(pasPerson->m_pView->m_usrDC, extra);
|
||
|
||
// Update TEXT EXTRA cache
|
||
pasPerson->m_pView->m_odLastCharExtra = extra;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ASShare::ODUseTextJustification()
|
||
//
|
||
void ASShare::ODUseTextJustification(ASPerson * pasPerson, int extra, int count)
|
||
{
|
||
if ((extra != pasPerson->m_pView->m_odLastJustExtra) ||
|
||
(count != pasPerson->m_pView->m_odLastJustCount))
|
||
{
|
||
SetTextJustification(pasPerson->m_pView->m_usrDC, extra, count);
|
||
|
||
// Update TEXT JUST cache
|
||
pasPerson->m_pView->m_odLastJustExtra = extra;
|
||
pasPerson->m_pView->m_odLastJustCount = count;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseFillMode()
|
||
//
|
||
void ASShare::ODUseFillMode(ASPerson * pasPerson, UINT mode)
|
||
{
|
||
if (mode != pasPerson->m_pView->m_odLastFillMode)
|
||
{
|
||
SetPolyFillMode(pasPerson->m_pView->m_usrDC, (mode == ORD_FILLMODE_WINDING) ?
|
||
WINDING : ALTERNATE);
|
||
|
||
// Update FILL MODE cache
|
||
pasPerson->m_pView->m_odLastFillMode = mode;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// ASShare::ODUseArcDirection()
|
||
//
|
||
void ASShare::ODUseArcDirection(ASPerson * pasPerson, UINT dir)
|
||
{
|
||
if (dir != pasPerson->m_pView->m_odLastArcDirection)
|
||
{
|
||
SetArcDirection(pasPerson->m_pView->m_usrDC, (dir == ORD_ARC_CLOCKWISE) ?
|
||
AD_CLOCKWISE : AD_COUNTERCLOCKWISE);
|
||
|
||
// Update ARC DIR cache
|
||
pasPerson->m_pView->m_odLastArcDirection = dir;
|
||
}
|
||
}
|
||
|