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