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.
2603 lines
78 KiB
2603 lines
78 KiB
#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;
|
|
}
|
|
}
|
|
|