/****************************************************************************/ // odapi.cpp // // Order Decoder API functions. // // Copyright (c) 1997-2000 Microsoft Corp. // Portions copyright (c) 1992-2000 Microsoft /****************************************************************************/ #include extern "C" { #define TRC_GROUP TRC_GROUP_CORE #define TRC_FILE "aodapi" #include } #define TSC_HR_FILEID TSC_HR_ODAPI_CPP #include "od.h" /****************************************************************************/ /* Define macros used to build the Order Decoder decoding data tables. */ /* */ /* Entries can be of fixed size or variable size. Variable size entries */ /* must be the last in each order structure. OD decodes variable entries */ /* into the unpacked structures. */ /****************************************************************************/ /****************************************************************************/ /* Fields can either be signed (DCINT16 etc), or unsigned (DCUINT16 etc). */ /****************************************************************************/ #define SIGNED_FIELD OD_OFI_TYPE_SIGNED #define UNSIGNED_FIELD 0 /****************************************************************************/ /* DTABLE_FIXED_ENTRY */ /* */ /* Field is a fixed size */ /* type - The unencoded order structure type */ /* size - The size of the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure */ /****************************************************************************/ #define DTABLE_FIXED_ENTRY(type,size,signed,field) \ { (DCUINT8)FIELDOFFSET(type,field), \ (DCUINT8)FIELDSIZE(type,field), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_FIXED | signed) } /****************************************************************************/ /* DTABLE_FIXED_COORDS_ENTRY */ /* */ /* Field is coordinate of a fixed size */ /* type - The unencoded order structure type */ /* size - The size of the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure */ /****************************************************************************/ #define DTABLE_FIXED_COORDS_ENTRY(type,size,signed,field) \ { (DCUINT8)FIELDOFFSET(type,field), \ (DCUINT8)FIELDSIZE(type,field), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_FIXED | OD_OFI_TYPE_COORDINATES | signed) } /****************************************************************************/ /* DTABLE_DATA_ENTRY */ /* */ /* Field is a fixed number of bytes (array?) */ /* type - The unencoded order structure type */ /* size - The number of bytes in the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure */ /****************************************************************************/ #define DTABLE_DATA_ENTRY(type,size,signed,field) \ { (DCUINT8)FIELDOFFSET(type,field), \ (DCUINT8)FIELDSIZE(type,field), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_FIXED | OD_OFI_TYPE_DATA | signed) } /****************************************************************************/ /* DTABLE_VARIABLE_ENTRY */ /* */ /* Field is a variable structure of the form below, with the length field */ /* encoded as ONE byte */ /* typedef struct */ /* { */ /* DCUINT32 len; */ /* varType varEntry[len]; */ /* } varStruct */ /* */ /* type - The unencoded order structure type */ /* size - The size of the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure (varStruct) */ /* elem - The name of the variable element array (varEntry) */ /****************************************************************************/ #define DTABLE_VARIABLE_ENTRY(type,size,signed,field,elem) \ { (DCUINT8)FIELDOFFSET(type,field.len), \ (DCUINT8)FIELDSIZE(type,field.elem[0]), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_VARIABLE | signed) } /****************************************************************************/ /* DTABLE_LONG_VARIABLE_ENTRY */ /* */ /* Field is a variable structure of the form below, with the length field */ /* encoded as TWO bytes */ /* typedef struct */ /* { */ /* DCUINT32 len; */ /* varType varEntry[len]; */ /* } varStruct */ /* */ /* type - The unencoded order structure type */ /* size - The size of the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure (varStruct) */ /* elem - The name of the variable element array (varEntry) */ /****************************************************************************/ #define DTABLE_LONG_VARIABLE_ENTRY(type,size,signed,field,elem) \ { (DCUINT8)FIELDOFFSET(type,field.len), \ (DCUINT8)FIELDSIZE(type,field.elem[0]), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_LONG_VARIABLE | signed) } // Unused currently, so we also can ifdef some code. #ifdef USE_VARIABLE_COORDS /****************************************************************************/ /* DTABLE_VARIABLE_COORDS_ENTRY */ /* */ /* Field is a variable structure with its length encoded in ONE byte and */ /* containing coords of the form */ /* typedef struct */ /* { */ /* DCUINT32 len; */ /* varCoord varEntry[len]; */ /* } varStruct */ /* */ /* type - The unencoded order structure type */ /* size - The size of the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure (varStruct) */ /* elem - The name of the variable element array (varEntry) */ /****************************************************************************/ #define DTABLE_VARIABLE_COORDS_ENTRY(type,size,signed,field,elem) \ { (DCUINT8)FIELDOFFSET(type,field.len), \ (DCUINT8)FIELDSIZE(type,field.elem[0]), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_VARIABLE | OD_OFI_TYPE_COORDINATES | signed) } /****************************************************************************/ /* DTABLE_LONG_VARIABLE_COORDS_ENTRY */ /* */ /* Field is a variable structure with its length encoded in TWO bytes and */ /* containing coords of the form */ /* typedef struct */ /* { */ /* DCUINT32 len; */ /* varCoord varEntry[len]; */ /* } varStruct */ /* */ /* type - The unencoded order structure type */ /* size - The size of the encoded version of the field */ /* signed - TRUE if the field is signed, FALSE otherwise */ /* field - The name of the field in the order structure (varStruct) */ /* elem - The name of the variable element array (varEntry) */ /****************************************************************************/ #define DTABLE_LONG_VARIABLE_COORDS_ENTRY(type,size,signed,field,elem) \ { (DCUINT8)FIELDOFFSET(type,field.len), \ (DCUINT8)FIELDSIZE(type,field.elem[0]), \ (DCUINT8)size, \ (DCUINT8)(OD_OFI_TYPE_LONG_VARIABLE | OD_OFI_TYPE_COORDINATES | signed) } #endif // USE_VARIABLE_COORDS const OD_ORDER_FIELD_INFO odDstBltFields[] = { DTABLE_FIXED_COORDS_ENTRY(DSTBLT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(DSTBLT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(DSTBLT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(DSTBLT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_FIXED_ENTRY (DSTBLT_ORDER, 1, UNSIGNED_FIELD, bRop) }; // Fast-path decode function used. #if 0 const OD_ORDER_FIELD_INFO odPatBltFields[] = { DTABLE_FIXED_COORDS_ENTRY(PATBLT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(PATBLT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(PATBLT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(PATBLT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_FIXED_ENTRY (PATBLT_ORDER, 1, UNSIGNED_FIELD, bRop), DTABLE_DATA_ENTRY (PATBLT_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (PATBLT_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_ENTRY (PATBLT_ORDER, 1, SIGNED_FIELD, BrushOrgX), DTABLE_FIXED_ENTRY (PATBLT_ORDER, 1, SIGNED_FIELD, BrushOrgY), DTABLE_FIXED_ENTRY (PATBLT_ORDER, 1, UNSIGNED_FIELD, BrushStyle), DTABLE_FIXED_ENTRY (PATBLT_ORDER, 1, UNSIGNED_FIELD, BrushHatch), DTABLE_DATA_ENTRY (PATBLT_ORDER, 7, UNSIGNED_FIELD, BrushExtra) }; #endif const OD_ORDER_FIELD_INFO odScrBltFields[] = { DTABLE_FIXED_COORDS_ENTRY(SCRBLT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(SCRBLT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(SCRBLT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(SCRBLT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_FIXED_ENTRY (SCRBLT_ORDER, 1, UNSIGNED_FIELD, bRop), DTABLE_FIXED_COORDS_ENTRY(SCRBLT_ORDER, 2, SIGNED_FIELD, nXSrc), DTABLE_FIXED_COORDS_ENTRY(SCRBLT_ORDER, 2, SIGNED_FIELD, nYSrc) }; // Fast-path decode function used. #if 0 const OD_ORDER_FIELD_INFO odLineToFields[] = { DTABLE_FIXED_ENTRY (LINETO_ORDER, 2, SIGNED_FIELD, BackMode), DTABLE_FIXED_COORDS_ENTRY(LINETO_ORDER, 2, SIGNED_FIELD, nXStart), DTABLE_FIXED_COORDS_ENTRY(LINETO_ORDER, 2, SIGNED_FIELD, nYStart), DTABLE_FIXED_COORDS_ENTRY(LINETO_ORDER, 2, SIGNED_FIELD, nXEnd), DTABLE_FIXED_COORDS_ENTRY(LINETO_ORDER, 2, SIGNED_FIELD, nYEnd), DTABLE_DATA_ENTRY (LINETO_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_FIXED_ENTRY (LINETO_ORDER, 1, UNSIGNED_FIELD, ROP2), DTABLE_FIXED_ENTRY (LINETO_ORDER, 1, UNSIGNED_FIELD, PenStyle), DTABLE_FIXED_ENTRY (LINETO_ORDER, 1, UNSIGNED_FIELD, PenWidth), DTABLE_DATA_ENTRY (LINETO_ORDER, 3, UNSIGNED_FIELD, PenColor) }; #endif // Fast-path decode function used. #if 0 const OD_ORDER_FIELD_INFO odOpaqueRectFields[] = { DTABLE_FIXED_COORDS_ENTRY(OPAQUERECT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(OPAQUERECT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(OPAQUERECT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(OPAQUERECT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_DATA_ENTRY(OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, Color.u.rgb.red), DTABLE_DATA_ENTRY(OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, Color.u.rgb.green), DTABLE_DATA_ENTRY(OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, Color.u.rgb.blue) }; #endif const OD_ORDER_FIELD_INFO odSaveBitmapFields[] = { DTABLE_FIXED_ENTRY (SAVEBITMAP_ORDER, 4, UNSIGNED_FIELD, SavedBitmapPosition), DTABLE_FIXED_COORDS_ENTRY(SAVEBITMAP_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(SAVEBITMAP_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(SAVEBITMAP_ORDER, 2, SIGNED_FIELD, nRightRect), DTABLE_FIXED_COORDS_ENTRY(SAVEBITMAP_ORDER, 2, SIGNED_FIELD, nBottomRect), DTABLE_FIXED_ENTRY (SAVEBITMAP_ORDER, 1, UNSIGNED_FIELD, Operation) }; // Fast-path decode function used. #if 0 const OD_ORDER_FIELD_INFO odMemBltFields[] = { DTABLE_FIXED_ENTRY (MEMBLT_R2_ORDER, 2, UNSIGNED_FIELD, Common.cacheId), DTABLE_FIXED_COORDS_ENTRY(MEMBLT_R2_ORDER, 2, SIGNED_FIELD, Common.nLeftRect), DTABLE_FIXED_COORDS_ENTRY(MEMBLT_R2_ORDER, 2, SIGNED_FIELD, Common.nTopRect), DTABLE_FIXED_COORDS_ENTRY(MEMBLT_R2_ORDER, 2, SIGNED_FIELD, Common.nWidth), DTABLE_FIXED_COORDS_ENTRY(MEMBLT_R2_ORDER, 2, SIGNED_FIELD, Common.nHeight), DTABLE_FIXED_ENTRY (MEMBLT_R2_ORDER, 1, UNSIGNED_FIELD, Common.bRop), DTABLE_FIXED_COORDS_ENTRY(MEMBLT_R2_ORDER, 2, SIGNED_FIELD, Common.nXSrc), DTABLE_FIXED_COORDS_ENTRY(MEMBLT_R2_ORDER, 2, SIGNED_FIELD, Common.nYSrc), DTABLE_FIXED_ENTRY (MEMBLT_R2_ORDER, 2, UNSIGNED_FIELD, Common.cacheIndex) }; #endif const OD_ORDER_FIELD_INFO odMem3BltFields[] = { DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 2, UNSIGNED_FIELD,Common.cacheId), DTABLE_FIXED_COORDS_ENTRY(MEM3BLT_R2_ORDER, 2, SIGNED_FIELD, Common.nLeftRect), DTABLE_FIXED_COORDS_ENTRY(MEM3BLT_R2_ORDER, 2, SIGNED_FIELD, Common.nTopRect), DTABLE_FIXED_COORDS_ENTRY(MEM3BLT_R2_ORDER, 2, SIGNED_FIELD, Common.nWidth), DTABLE_FIXED_COORDS_ENTRY(MEM3BLT_R2_ORDER, 2, SIGNED_FIELD, Common.nHeight), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 1, UNSIGNED_FIELD,Common.bRop), DTABLE_FIXED_COORDS_ENTRY(MEM3BLT_R2_ORDER, 2, SIGNED_FIELD, Common.nXSrc), DTABLE_FIXED_COORDS_ENTRY(MEM3BLT_R2_ORDER, 2, SIGNED_FIELD, Common.nYSrc), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 3, UNSIGNED_FIELD,BackColor), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 3, UNSIGNED_FIELD,ForeColor), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 1, SIGNED_FIELD, BrushOrgX), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 1, SIGNED_FIELD, BrushOrgY), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 1, UNSIGNED_FIELD,BrushStyle), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 1, UNSIGNED_FIELD,BrushHatch), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 7, UNSIGNED_FIELD,BrushExtra), DTABLE_FIXED_ENTRY (MEM3BLT_R2_ORDER, 2, UNSIGNED_FIELD,Common.cacheIndex) }; const OD_ORDER_FIELD_INFO odMultiDstBltFields[] = { DTABLE_FIXED_COORDS_ENTRY(MULTI_DSTBLT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_DSTBLT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_DSTBLT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(MULTI_DSTBLT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_FIXED_ENTRY (MULTI_DSTBLT_ORDER, 1, UNSIGNED_FIELD, bRop), DTABLE_FIXED_ENTRY (MULTI_DSTBLT_ORDER, 1, UNSIGNED_FIELD, nDeltaEntries), DTABLE_LONG_VARIABLE_ENTRY(MULTI_DSTBLT_ORDER, 1, UNSIGNED_FIELD, codedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odMultiPatBltFields[] = { DTABLE_FIXED_COORDS_ENTRY(MULTI_PATBLT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_PATBLT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_PATBLT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(MULTI_PATBLT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_FIXED_ENTRY (MULTI_PATBLT_ORDER, 1, UNSIGNED_FIELD, bRop), DTABLE_DATA_ENTRY (MULTI_PATBLT_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (MULTI_PATBLT_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_ENTRY (MULTI_PATBLT_ORDER, 1, SIGNED_FIELD, BrushOrgX), DTABLE_FIXED_ENTRY (MULTI_PATBLT_ORDER, 1, SIGNED_FIELD, BrushOrgY), DTABLE_FIXED_ENTRY (MULTI_PATBLT_ORDER, 1, UNSIGNED_FIELD, BrushStyle), DTABLE_FIXED_ENTRY (MULTI_PATBLT_ORDER, 1, UNSIGNED_FIELD, BrushHatch), DTABLE_DATA_ENTRY (MULTI_PATBLT_ORDER, 7, UNSIGNED_FIELD, BrushExtra), DTABLE_FIXED_ENTRY (MULTI_PATBLT_ORDER, 1, UNSIGNED_FIELD, nDeltaEntries), DTABLE_LONG_VARIABLE_ENTRY(MULTI_PATBLT_ORDER, 1, UNSIGNED_FIELD, codedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odMultiScrBltFields[] = { DTABLE_FIXED_COORDS_ENTRY(MULTI_SCRBLT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_SCRBLT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_SCRBLT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(MULTI_SCRBLT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_FIXED_ENTRY (MULTI_SCRBLT_ORDER, 1, UNSIGNED_FIELD, bRop), DTABLE_FIXED_COORDS_ENTRY(MULTI_SCRBLT_ORDER, 2, SIGNED_FIELD, nXSrc), DTABLE_FIXED_COORDS_ENTRY(MULTI_SCRBLT_ORDER, 2, SIGNED_FIELD, nYSrc), DTABLE_FIXED_ENTRY (MULTI_SCRBLT_ORDER, 1, UNSIGNED_FIELD, nDeltaEntries), DTABLE_LONG_VARIABLE_ENTRY(MULTI_SCRBLT_ORDER, 1, UNSIGNED_FIELD, codedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odMultiOpaqueRectFields[] = { DTABLE_FIXED_COORDS_ENTRY(MULTI_OPAQUERECT_ORDER, 2, SIGNED_FIELD, nLeftRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_OPAQUERECT_ORDER, 2, SIGNED_FIELD, nTopRect), DTABLE_FIXED_COORDS_ENTRY(MULTI_OPAQUERECT_ORDER, 2, SIGNED_FIELD, nWidth), DTABLE_FIXED_COORDS_ENTRY(MULTI_OPAQUERECT_ORDER, 2, SIGNED_FIELD, nHeight), DTABLE_DATA_ENTRY (MULTI_OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, Color.u.rgb.red), DTABLE_DATA_ENTRY (MULTI_OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, Color.u.rgb.green), DTABLE_DATA_ENTRY (MULTI_OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, Color.u.rgb.blue), DTABLE_FIXED_ENTRY (MULTI_OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, nDeltaEntries), DTABLE_LONG_VARIABLE_ENTRY(MULTI_OPAQUERECT_ORDER, 1, UNSIGNED_FIELD, codedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odPolygonSCFields[] = { DTABLE_FIXED_COORDS_ENTRY(POLYGON_SC_ORDER, 2, SIGNED_FIELD, XStart), DTABLE_FIXED_COORDS_ENTRY(POLYGON_SC_ORDER, 2, SIGNED_FIELD, YStart), DTABLE_FIXED_ENTRY (POLYGON_SC_ORDER, 1, UNSIGNED_FIELD, ROP2), DTABLE_FIXED_ENTRY (POLYGON_SC_ORDER, 1, UNSIGNED_FIELD, FillMode), DTABLE_DATA_ENTRY (POLYGON_SC_ORDER, 3, UNSIGNED_FIELD, BrushColor), DTABLE_FIXED_ENTRY (POLYGON_SC_ORDER, 1, UNSIGNED_FIELD, NumDeltaEntries), DTABLE_VARIABLE_ENTRY (POLYGON_SC_ORDER, 1, UNSIGNED_FIELD, CodedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odPolygonCBFields[] = { DTABLE_FIXED_COORDS_ENTRY(POLYGON_CB_ORDER, 2, SIGNED_FIELD, XStart), DTABLE_FIXED_COORDS_ENTRY(POLYGON_CB_ORDER, 2, SIGNED_FIELD, YStart), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, UNSIGNED_FIELD, ROP2), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, UNSIGNED_FIELD, FillMode), DTABLE_DATA_ENTRY (POLYGON_CB_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (POLYGON_CB_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, SIGNED_FIELD, BrushOrgX), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, SIGNED_FIELD, BrushOrgY), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, UNSIGNED_FIELD, BrushStyle), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, UNSIGNED_FIELD, BrushHatch), DTABLE_DATA_ENTRY (POLYGON_CB_ORDER, 7, UNSIGNED_FIELD, BrushExtra), DTABLE_FIXED_ENTRY (POLYGON_CB_ORDER, 1, UNSIGNED_FIELD, NumDeltaEntries), DTABLE_VARIABLE_ENTRY (POLYGON_CB_ORDER, 1, UNSIGNED_FIELD, CodedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odPolyLineFields[] = { DTABLE_FIXED_COORDS_ENTRY(POLYLINE_ORDER, 2, SIGNED_FIELD, XStart), DTABLE_FIXED_COORDS_ENTRY(POLYLINE_ORDER, 2, SIGNED_FIELD, YStart), DTABLE_FIXED_ENTRY (POLYLINE_ORDER, 1, UNSIGNED_FIELD, ROP2), DTABLE_FIXED_ENTRY (POLYLINE_ORDER, 2, UNSIGNED_FIELD, BrushCacheEntry), DTABLE_DATA_ENTRY (POLYLINE_ORDER, 3, UNSIGNED_FIELD, PenColor), DTABLE_FIXED_ENTRY (POLYLINE_ORDER, 1, UNSIGNED_FIELD, NumDeltaEntries), DTABLE_VARIABLE_ENTRY (POLYLINE_ORDER, 1, UNSIGNED_FIELD, CodedDeltaList, Deltas) }; const OD_ORDER_FIELD_INFO odEllipseSCFields[] = { DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_SC_ORDER, 2, SIGNED_FIELD, LeftRect), DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_SC_ORDER, 2, SIGNED_FIELD, TopRect), DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_SC_ORDER, 2, SIGNED_FIELD, RightRect), DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_SC_ORDER, 2, SIGNED_FIELD, BottomRect), DTABLE_FIXED_ENTRY (ELLIPSE_SC_ORDER, 1, UNSIGNED_FIELD, ROP2), DTABLE_FIXED_ENTRY (ELLIPSE_SC_ORDER, 1, UNSIGNED_FIELD, FillMode), DTABLE_DATA_ENTRY (ELLIPSE_SC_ORDER, 3, UNSIGNED_FIELD, Color) }; const OD_ORDER_FIELD_INFO odEllipseCBFields[] = { DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_CB_ORDER, 2, SIGNED_FIELD, LeftRect), DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_CB_ORDER, 2, SIGNED_FIELD, TopRect), DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_CB_ORDER, 2, SIGNED_FIELD, RightRect), DTABLE_FIXED_COORDS_ENTRY(ELLIPSE_CB_ORDER, 2, SIGNED_FIELD, BottomRect), DTABLE_FIXED_ENTRY (ELLIPSE_CB_ORDER, 1, UNSIGNED_FIELD, ROP2), DTABLE_FIXED_ENTRY (ELLIPSE_CB_ORDER, 1, UNSIGNED_FIELD, FillMode), DTABLE_DATA_ENTRY (ELLIPSE_CB_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (ELLIPSE_CB_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_ENTRY (ELLIPSE_CB_ORDER, 1, SIGNED_FIELD, BrushOrgX), DTABLE_FIXED_ENTRY (ELLIPSE_CB_ORDER, 1, SIGNED_FIELD, BrushOrgY), DTABLE_FIXED_ENTRY (ELLIPSE_CB_ORDER, 1, UNSIGNED_FIELD, BrushStyle), DTABLE_FIXED_ENTRY (ELLIPSE_CB_ORDER, 1, UNSIGNED_FIELD, BrushHatch), DTABLE_DATA_ENTRY (ELLIPSE_CB_ORDER, 7, UNSIGNED_FIELD, BrushExtra) }; // Fast-path decode function used. #if 0 const OD_ORDER_FIELD_INFO odFastIndexFields[] = { DTABLE_DATA_ENTRY (FAST_INDEX_ORDER, 1, UNSIGNED_FIELD, cacheId), DTABLE_DATA_ENTRY (FAST_INDEX_ORDER, 2, UNSIGNED_FIELD, fDrawing), DTABLE_DATA_ENTRY (FAST_INDEX_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (FAST_INDEX_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, BkLeft), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, BkTop), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, BkRight), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, BkBottom), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, OpLeft), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, OpTop), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, OpRight), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, OpBottom), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, x), DTABLE_FIXED_COORDS_ENTRY(FAST_INDEX_ORDER, 2, SIGNED_FIELD, y), DTABLE_VARIABLE_ENTRY (FAST_INDEX_ORDER, 1, UNSIGNED_FIELD, variableBytes, arecs) }; #endif const OD_ORDER_FIELD_INFO odFastGlyphFields[] = { DTABLE_DATA_ENTRY (FAST_GLYPH_ORDER, 1, UNSIGNED_FIELD, cacheId), DTABLE_DATA_ENTRY (FAST_GLYPH_ORDER, 2, UNSIGNED_FIELD, fDrawing), DTABLE_DATA_ENTRY (FAST_GLYPH_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (FAST_GLYPH_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, BkLeft), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, BkTop), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, BkRight), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, BkBottom), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, OpLeft), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, OpTop), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, OpRight), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, OpBottom), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, x), DTABLE_FIXED_COORDS_ENTRY(FAST_GLYPH_ORDER, 2, SIGNED_FIELD, y), DTABLE_VARIABLE_ENTRY (FAST_GLYPH_ORDER, 1, UNSIGNED_FIELD, variableBytes, glyphData) }; const OD_ORDER_FIELD_INFO odGlyphIndexFields[] = { DTABLE_DATA_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, cacheId), DTABLE_DATA_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, flAccel), DTABLE_DATA_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, ulCharInc), DTABLE_DATA_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, fOpRedundant), DTABLE_DATA_ENTRY (INDEX_ORDER, 3, UNSIGNED_FIELD, BackColor), DTABLE_DATA_ENTRY (INDEX_ORDER, 3, UNSIGNED_FIELD, ForeColor), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, BkLeft), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, BkTop), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, BkRight), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, BkBottom), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, OpLeft), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, OpTop), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, OpRight), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, OpBottom), DTABLE_FIXED_ENTRY (INDEX_ORDER, 1, SIGNED_FIELD, BrushOrgX), DTABLE_FIXED_ENTRY (INDEX_ORDER, 1, SIGNED_FIELD, BrushOrgY), DTABLE_FIXED_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, BrushStyle), DTABLE_FIXED_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, BrushHatch), DTABLE_DATA_ENTRY (INDEX_ORDER, 7, UNSIGNED_FIELD, BrushExtra), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, x), DTABLE_FIXED_ENTRY (INDEX_ORDER, 2, SIGNED_FIELD, y), DTABLE_VARIABLE_ENTRY (INDEX_ORDER, 1, UNSIGNED_FIELD, variableBytes, arecs) }; #ifdef DRAW_NINEGRID const OD_ORDER_FIELD_INFO odDrawNineGridFields[] = { DTABLE_FIXED_COORDS_ENTRY(DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcLeft), DTABLE_FIXED_COORDS_ENTRY(DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcTop), DTABLE_FIXED_COORDS_ENTRY(DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcRight), DTABLE_FIXED_COORDS_ENTRY(DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcBottom), DTABLE_FIXED_ENTRY (DRAWNINEGRID_ORDER, 2, UNSIGNED_FIELD, bitmapId) }; const OD_ORDER_FIELD_INFO odMultiDrawNineGridFields[] = { DTABLE_FIXED_COORDS_ENTRY(MULTI_DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcLeft), DTABLE_FIXED_COORDS_ENTRY(MULTI_DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcTop), DTABLE_FIXED_COORDS_ENTRY(MULTI_DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcRight), DTABLE_FIXED_COORDS_ENTRY(MULTI_DRAWNINEGRID_ORDER, 2, SIGNED_FIELD, srcBottom), DTABLE_FIXED_ENTRY (MULTI_DRAWNINEGRID_ORDER, 2, UNSIGNED_FIELD, bitmapId), DTABLE_FIXED_ENTRY (MULTI_DRAWNINEGRID_ORDER, 1, UNSIGNED_FIELD, nDeltaEntries), DTABLE_LONG_VARIABLE_ENTRY(MULTI_DRAWNINEGRID_ORDER, 1, UNSIGNED_FIELD, codedDeltaList, Deltas) }; #endif // Order attributes used for decoding, organized to optimize cache line // usage. The fourth and fifth fields of each row are the fast-path decode // and order handler functions, respectively. If a fast-path decode function // is used, neither a decoding table nor a handler function is needed, // since fast-path decode functions also perform the handling. // // This table contains just the static portions it is used to initialise // the per instance table in the constructor below // OD_ORDER_TABLE odInitializeOrderTable[TS_MAX_ORDERS] = { { odDstBltFields, NUM_DSTBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { NULL, /* fastpath */ NUM_PATBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { odScrBltFields, NUM_SCRBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, #ifdef DRAW_NINEGRID { odDrawNineGridFields, NUM_DRAWNINEGRID_FIELDS, NULL, 0, 0, NULL, NULL }, { odMultiDrawNineGridFields, NUM_MULTI_DRAWNINEGRID_FIELDS, NULL, 0, 0, NULL, NULL }, #else { NULL, 0, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, #endif { NULL, /* fastpath */ NUM_LINETO_FIELDS, NULL, 0, 0, NULL, NULL }, { NULL, /* fastpath*/ NUM_OPAQUERECT_FIELDS, NULL, 0, 0, NULL, NULL }, { odSaveBitmapFields, NUM_SAVEBITMAP_FIELDS, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, { NULL, /* fastpath */ NUM_MEMBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { odMem3BltFields, NUM_MEM3BLT_FIELDS, NULL, 0, 0, NULL, NULL }, { odMultiDstBltFields, NUM_MULTIDSTBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { odMultiPatBltFields, NUM_MULTIPATBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { odMultiScrBltFields, NUM_MULTISCRBLT_FIELDS, NULL, 0, 0, NULL, NULL }, { odMultiOpaqueRectFields, NUM_MULTIOPAQUERECT_FIELDS, NULL, 0, 0, NULL, NULL }, { NULL, /* fastpath*/ NUM_FAST_INDEX_FIELDS, NULL, 0, 0, NULL, NULL }, { odPolygonSCFields, NUM_POLYGON_SC_FIELDS, NULL, 0, 0, NULL, NULL }, { odPolygonCBFields, NUM_POLYGON_CB_FIELDS, NULL, 0, 0, NULL, NULL }, { odPolyLineFields, NUM_POLYLINE_FIELDS, NULL, 0, 0, NULL, NULL }, { NULL, 0, NULL, 0, 0, NULL, NULL }, { odFastGlyphFields, NUM_FAST_GLYPH_FIELDS, NULL, 0, 0, NULL, NULL }, { odEllipseSCFields, NUM_ELLIPSE_SC_FIELDS, NULL, 0, 0, NULL, NULL }, { odEllipseCBFields, NUM_ELLIPSE_CB_FIELDS, NULL, 0, 0, NULL, NULL }, { odGlyphIndexFields, NUM_INDEX_FIELDS, NULL, 0, 0, NULL, NULL }, }; #if 0 // // This is the original just here for reference // { { odDstBltFields, NUM_DSTBLT_FIELDS, (PUH_ORDER)&_OD.lastDstblt, NULL, ODHandleDstBlts }, { NULL, /* fastpath */ NUM_PATBLT_FIELDS, (PUH_ORDER)&_OD.lastPatblt, ODDecodePatBlt, NULL }, { odScrBltFields, NUM_SCRBLT_FIELDS, (PUH_ORDER)&_OD.lastScrblt, NULL, ODHandleScrBlts }, { NULL, 0, NULL, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, { NULL, 0, NULL, NULL, NULL }, { NULL, /* fastpath */ NUM_LINETO_FIELDS, (PUH_ORDER)&_OD.lastLineTo, ODDecodeLineTo, NULL }, { NULL, /* fastpath*/ NUM_OPAQUERECT_FIELDS, (PUH_ORDER)&_OD.lastOpaqueRect, ODDecodeOpaqueRect, NULL }, { odSaveBitmapFields, NUM_SAVEBITMAP_FIELDS, (PUH_ORDER)&_OD.lastSaveBitmap, NULL, ODHandleSaveBitmap }, { NULL, 0, NULL, NULL, NULL }, { NULL, /* fastpath */ NUM_MEMBLT_FIELDS, (PUH_ORDER)&_OD.lastMembltR2, ODDecodeMemBlt, NULL }, { odMem3BltFields, NUM_MEM3BLT_FIELDS, (PUH_ORDER)&_OD.lastMem3bltR2, NULL, ODHandleMem3Blt }, { odMultiDstBltFields, NUM_MULTIDSTBLT_FIELDS, (PUH_ORDER)&_OD.lastMultiDstBlt, NULL, ODHandleDstBlts }, { odMultiPatBltFields, NUM_MULTIPATBLT_FIELDS, (PUH_ORDER)&_OD.lastMultiPatBlt, NULL, ODHandleMultiPatBlt }, { odMultiScrBltFields, NUM_MULTISCRBLT_FIELDS, (PUH_ORDER)&_OD.lastMultiScrBlt, NULL, ODHandleScrBlts }, { odMultiOpaqueRectFields, NUM_MULTIOPAQUERECT_FIELDS, (PUH_ORDER)&_OD.lastMultiOpaqueRect, NULL, ODHandleMultiOpaqueRect }, { NULL, /* fastpath*/ NUM_FAST_INDEX_FIELDS, (PUH_ORDER)&_OD.lastFastIndex, ODDecodeFastIndex, NULL }, { odPolygonSCFields, NUM_POLYGON_SC_FIELDS, (PUH_ORDER)&_OD.lastPolygonSC, NULL, ODHandlePolygonSC }, { odPolygonCBFields, NUM_POLYGON_CB_FIELDS, (PUH_ORDER)&_OD.lastPolygonCB, NULL, ODHandlePolygonCB }, { odPolyLineFields, NUM_POLYLINE_FIELDS, (PUH_ORDER)&_OD.lastPolyLine, NULL, ODHandlePolyLine }, { NULL, 0, NULL, NULL, NULL }, { odFastGlyphFields, NUM_FAST_GLYPH_FIELDS, (PUH_ORDER)&_OD.lastFastGlyph, NULL, ODHandleFastGlyph }, { odEllipseSCFields, NUM_ELLIPSE_SC_FIELDS, (PUH_ORDER)&_OD.lastEllipseSC, NULL, ODHandleEllipseSC }, { odEllipseCBFields, NUM_ELLIPSE_CB_FIELDS, (PUH_ORDER)&_OD.lastEllipseCB, NULL, ODHandleEllipseCB }, { odGlyphIndexFields, NUM_INDEX_FIELDS, (PUH_ORDER)&_OD.lastIndex, NULL, ODHandleGlyphIndex } }; #endif #ifdef DC_HICOLOR #ifdef DC_DEBUG // Names of all the order types DCTCHAR orderNames[TS_MAX_ORDERS + TS_NUM_SECONDARY_ORDERS][64] = { _T("DSTBLT "), _T("PATBLT "), _T("SCRBLT "), _T("unused "), _T("unused "), _T("unused "), _T("unused "), #ifdef DRAW_NINEGRID _T("DRAWNINEGRID "), _T("MULTI_DRAWNINEGRID "), #else _T("unused "), _T("unused "), #endif _T("LINETO "), _T("OPAQUERECT "), _T("SAVEBITMAP "), _T("unused "), _T("MEMBLT_R2 "), _T("MEM3BLT_R2 "), _T("MULTIDSTBLT "), _T("MULTIPATBLT "), _T("MULTISCRBLT "), _T("MULTIOPAQUERECT "), _T("FAST_INDEX "), _T("POLYGON_SC (not wince) "), _T("POLYGON_CB (not wince) "), _T("POLYLINE "), _T("unused "), _T("FAST_GLYPH "), _T("ELLIPSE_SC (not wince) "), _T("ELLIPSE_CB (not wince) "), _T("INDEX (not expected) "), _T("unused "), _T("unused "), _T("unused "), _T("unused "), _T("U/C CACHE BMP (legacy) "), _T("C COLOR TABLE (8bpp) "), _T("COM CACHE BMP (legacy) "), _T("C GLYPH "), _T("U/C CACHE BMP R2 "), _T("COM CACHE BMP R2 "), _T("unused "), _T("CACHE BRUSH ") }; #endif #endif COD::COD(CObjs* objs) { _pClientObjects = objs; DC_MEMCPY( odOrderTable, odInitializeOrderTable, sizeof(odOrderTable)); // // Initialize the per instance pointers of the ordertable // //{ odDstBltFields, NUM_DSTBLT_FIELDS, (PUH_ORDER)&_OD.lastDstblt, NULL, ODHandleDstBlts }, odOrderTable[0].LastOrder = (PUH_ORDER)&_OD.lastDstblt; odOrderTable[0].cbMaxOrderLen = sizeof(_OD.lastDstblt); odOrderTable[0].pFastDecode = NULL; odOrderTable[0].pHandler = ODHandleDstBlts; //{ NULL, /* fastpath */ NUM_PATBLT_FIELDS, (PUH_ORDER)&_OD.lastPatblt, ODDecodePatBlt, NULL }, odOrderTable[1].LastOrder = (PUH_ORDER)&_OD.lastPatblt; odOrderTable[1].cbMaxOrderLen = sizeof(_OD.lastPatblt); odOrderTable[1].pFastDecode = ODDecodePatBlt; odOrderTable[1].pHandler = NULL; //{ odScrBltFields, NUM_SCRBLT_FIELDS, (PUH_ORDER)&_OD.lastScrblt, NULL, ODHandleScrBlts }, odOrderTable[2].LastOrder = (PUH_ORDER)&_OD.lastScrblt; odOrderTable[2].cbMaxOrderLen = sizeof(_OD.lastScrblt); odOrderTable[2].pFastDecode = NULL; odOrderTable[2].pHandler = ODHandleScrBlts; //{ NULL, 0, NULL, NULL, NULL }, //{ NULL, 0, NULL, NULL, NULL }, //{ NULL, 0, NULL, NULL, NULL }, //{ NULL, 0, NULL, NULL, NULL }, #ifdef DRAW_NINEGRID odOrderTable[7].LastOrder = (PUH_ORDER)&_OD.lastDrawNineGrid; odOrderTable[7].cbMaxOrderLen = sizeof(_OD.lastDrawNineGrid); odOrderTable[7].pFastDecode = NULL; odOrderTable[7].pHandler = ODHandleDrawNineGrid; odOrderTable[8].LastOrder = (PUH_ORDER)&_OD.lastMultiDrawNineGrid; odOrderTable[8].cbMaxOrderLen = sizeof(_OD.lastMultiDrawNineGrid); odOrderTable[8].pFastDecode = NULL; odOrderTable[8].pHandler = ODHandleMultiDrawNineGrid; #else //{ NULL, 0, NULL, NULL, NULL }, //{ NULL, 0, NULL, NULL, NULL }, #endif //{ NULL, /* fastpath */ NUM_LINETO_FIELDS, (PUH_ORDER)&_OD.lastLineTo, ODDecodeLineTo, NULL }, odOrderTable[9].LastOrder = (PUH_ORDER)&_OD.lastLineTo; odOrderTable[9].cbMaxOrderLen = sizeof(_OD.lastLineTo); odOrderTable[9].pFastDecode = ODDecodeLineTo; odOrderTable[9].pHandler = NULL; //{ NULL, /* fastpath*/ NUM_OPAQUERECT_FIELDS, (PUH_ORDER)&_OD.lastOpaqueRect, ODDecodeOpaqueRect, NULL }, odOrderTable[10].LastOrder = (PUH_ORDER)&_OD.lastOpaqueRect; odOrderTable[10].cbMaxOrderLen = sizeof(_OD.lastOpaqueRect); odOrderTable[10].pFastDecode = ODDecodeOpaqueRect; odOrderTable[10].pHandler = NULL; //{ odSaveBitmapFields, NUM_SAVEBITMAP_FIELDS, (PUH_ORDER)&_OD.lastSaveBitmap, NULL, ODHandleSaveBitmap }, odOrderTable[11].LastOrder = (PUH_ORDER)&_OD.lastSaveBitmap; odOrderTable[11].cbMaxOrderLen = sizeof(_OD.lastSaveBitmap); odOrderTable[11].pFastDecode = NULL; odOrderTable[11].pHandler = ODHandleSaveBitmap; //{ NULL, 0, NULL, NULL, NULL }, // { NULL, /* fastpath */ NUM_MEMBLT_FIELDS, (PUH_ORDER)&_OD.lastMembltR2, ODDecodeMemBlt, NULL }, odOrderTable[13].LastOrder = (PUH_ORDER)&_OD.lastMembltR2; odOrderTable[13].cbMaxOrderLen = sizeof(_OD.lastMembltR2); odOrderTable[13].pFastDecode = ODDecodeMemBlt; odOrderTable[13].pHandler = NULL; //{ odMem3BltFields, NUM_MEM3BLT_FIELDS, (PUH_ORDER)&_OD.lastMem3bltR2, NULL, ODHandleMem3Blt }, odOrderTable[14].LastOrder = (PUH_ORDER)&_OD.lastMem3bltR2; odOrderTable[14].cbMaxOrderLen = sizeof(_OD.lastMem3bltR2); odOrderTable[14].pFastDecode = NULL; odOrderTable[14].pHandler = ODHandleMem3Blt; //{ odMultiDstBltFields, NUM_MULTIDSTBLT_FIELDS, (PUH_ORDER)&_OD.lastMultiDstBlt, NULL, ODHandleDstBlts }, odOrderTable[15].LastOrder = (PUH_ORDER)&_OD.lastMultiDstBlt; odOrderTable[15].cbMaxOrderLen = sizeof(_OD.lastMultiDstBlt); odOrderTable[15].pFastDecode = NULL; odOrderTable[15].pHandler = ODHandleDstBlts; //{ odMultiPatBltFields, NUM_MULTIPATBLT_FIELDS, (PUH_ORDER)&_OD.lastMultiPatBlt, NULL, ODHandleMultiPatBlt }, odOrderTable[16].LastOrder = (PUH_ORDER)&_OD.lastMultiPatBlt; odOrderTable[16].cbMaxOrderLen = sizeof(_OD.lastMultiPatBlt); odOrderTable[16].pFastDecode = NULL; odOrderTable[16].pHandler = ODHandleMultiPatBlt; //{ odMultiScrBltFields, NUM_MULTISCRBLT_FIELDS, (PUH_ORDER)&_OD.lastMultiScrBlt, NULL, ODHandleScrBlts }, odOrderTable[17].LastOrder = (PUH_ORDER)&_OD.lastMultiScrBlt; odOrderTable[17].cbMaxOrderLen = sizeof(_OD.lastMultiScrBlt); odOrderTable[17].pFastDecode = NULL; odOrderTable[17].pHandler = ODHandleScrBlts; //{ odMultiOpaqueRectFields, NUM_MULTIOPAQUERECT_FIELDS, (PUH_ORDER)&_OD.lastMultiOpaqueRect, NULL, ODHandleMultiOpaqueRect }, odOrderTable[18].LastOrder = (PUH_ORDER)&_OD.lastMultiOpaqueRect; odOrderTable[18].cbMaxOrderLen = sizeof(_OD.lastMultiOpaqueRect); odOrderTable[18].pFastDecode = NULL; odOrderTable[18].pHandler = ODHandleMultiOpaqueRect; //{ NULL, /* fastpath*/ NUM_FAST_INDEX_FIELDS, (PUH_ORDER)&_OD.lastFastIndex, ODDecodeFastIndex, NULL }, odOrderTable[19].LastOrder = (PUH_ORDER)&_OD.lastFastIndex; odOrderTable[19].cbMaxOrderLen = sizeof(_OD.lastFastIndex); odOrderTable[19].pFastDecode = ODDecodeFastIndex; odOrderTable[19].pHandler = NULL; //{ odPolygonSCFields, NUM_POLYGON_SC_FIELDS, (PUH_ORDER)&_OD.lastPolygonSC, NULL, ODHandlePolygonSC }, odOrderTable[20].LastOrder = (PUH_ORDER)&_OD.lastPolygonSC; odOrderTable[20].cbMaxOrderLen = sizeof(_OD.lastPolygonSC); odOrderTable[20].pFastDecode = NULL; odOrderTable[20].pHandler = ODHandlePolygonSC; //{ odPolygonCBFields, NUM_POLYGON_CB_FIELDS, (PUH_ORDER)&_OD.lastPolygonCB, NULL, ODHandlePolygonCB }, odOrderTable[21].LastOrder = (PUH_ORDER)&_OD.lastPolygonCB; odOrderTable[21].cbMaxOrderLen = sizeof(_OD.lastPolygonCB); odOrderTable[21].pFastDecode = NULL; odOrderTable[21].pHandler = ODHandlePolygonCB; //{ odPolyLineFields, NUM_POLYLINE_FIELDS, (PUH_ORDER)&_OD.lastPolyLine, NULL, ODHandlePolyLine }, odOrderTable[22].LastOrder = (PUH_ORDER)&_OD.lastPolyLine; odOrderTable[22].cbMaxOrderLen = sizeof(_OD.lastPolyLine); odOrderTable[22].pFastDecode = NULL; odOrderTable[22].pHandler = ODHandlePolyLine; //{ NULL, 0, NULL, NULL, NULL }, //{ odFastGlyphFields, NUM_FAST_GLYPH_FIELDS, (PUH_ORDER)&_OD.lastFastGlyph, NULL, ODHandleFastGlyph }, odOrderTable[24].LastOrder = (PUH_ORDER)&_OD.lastFastGlyph; odOrderTable[24].cbMaxOrderLen = sizeof(_OD.lastFastGlyph); odOrderTable[24].pFastDecode = NULL; odOrderTable[24].pHandler = ODHandleFastGlyph; //{ odEllipseSCFields, NUM_ELLIPSE_SC_FIELDS, (PUH_ORDER)&_OD.lastEllipseSC, NULL, ODHandleEllipseSC }, odOrderTable[25].LastOrder = (PUH_ORDER)&_OD.lastEllipseSC; odOrderTable[25].cbMaxOrderLen = sizeof(_OD.lastEllipseSC); odOrderTable[25].pFastDecode = NULL; odOrderTable[25].pHandler = ODHandleEllipseSC; //{ odEllipseCBFields, NUM_ELLIPSE_CB_FIELDS, (PUH_ORDER)&_OD.lastEllipseCB, NULL, ODHandleEllipseCB }, odOrderTable[26].LastOrder = (PUH_ORDER)&_OD.lastEllipseCB; odOrderTable[26].cbMaxOrderLen = sizeof(_OD.lastEllipseCB); odOrderTable[26].pFastDecode = NULL; odOrderTable[26].pHandler = ODHandleEllipseCB; //{ odGlyphIndexFields, NUM_INDEX_FIELDS, (PUH_ORDER)&_OD.lastIndex, NULL, ODHandleGlyphIndex } odOrderTable[27].LastOrder = (PUH_ORDER)&_OD.lastIndex; odOrderTable[27].cbMaxOrderLen = sizeof(_OD.lastIndex); odOrderTable[27].pFastDecode = NULL; odOrderTable[27].pHandler = ODHandleGlyphIndex; } COD::~COD() { } /****************************************************************************/ /* Name: OD_Init */ /* */ /* Purpose: Initializes the Order Decoder */ /****************************************************************************/ DCVOID DCAPI COD::OD_Init(DCVOID) { DC_BEGIN_FN("OD_Init"); _pOp = _pClientObjects->_pOPObject; _pUh = _pClientObjects->_pUHObject; _pCc = _pClientObjects->_pCcObject; _pUi = _pClientObjects->_pUiObject; _pCd = _pClientObjects->_pCdObject; memset(&_OD, 0, sizeof(_OD)); TRC_NRM((TB, _T("Initialized"))); DC_END_FN(); } /****************************************************************************/ /* Name: OD_Term */ /* */ /* Purpose: Terminates the Order Decoder */ /****************************************************************************/ DCVOID DCAPI COD::OD_Term(DCVOID) { DC_BEGIN_FN("OD_Term"); TRC_NRM((TB, _T("Terminating"))); DC_END_FN(); } /****************************************************************************/ /* Name: OD_Enable */ /* */ /* Purpose: Called to enable _OD. */ /****************************************************************************/ void DCAPI COD::OD_Enable(void) { DC_BEGIN_FN("OD_Enable"); // Reset the OD data. _OD.lastOrderType = TS_ENC_PATBLT_ORDER; _OD.pLastOrder = odOrderTable[_OD.lastOrderType].LastOrder; // Set all prev order buffers buffers to null, then set the order type // for each one, which is used by UHReplayGDIOrders(). #define RESET_ORDER(field, ord) \ { \ memset(&_OD.field, 0, sizeof(_OD.field)); \ ((PATBLT_ORDER*)(((PUH_ORDER)_OD.field)->orderData))->type = DCLO16(ord);\ } RESET_ORDER(lastDstblt, TS_ENC_DSTBLT_ORDER); RESET_ORDER(lastPatblt, TS_ENC_PATBLT_ORDER); RESET_ORDER(lastScrblt, TS_ENC_SCRBLT_ORDER); RESET_ORDER(lastLineTo, TS_ENC_LINETO_ORDER); RESET_ORDER(lastSaveBitmap, TS_ENC_SAVEBITMAP_ORDER); RESET_ORDER(lastMembltR2, TS_ENC_MEMBLT_R2_ORDER); RESET_ORDER(lastMem3bltR2, TS_ENC_MEM3BLT_R2_ORDER); RESET_ORDER(lastOpaqueRect, TS_ENC_OPAQUERECT_ORDER); RESET_ORDER(lastMultiDstBlt, TS_ENC_MULTIDSTBLT_ORDER); RESET_ORDER(lastMultiPatBlt, TS_ENC_MULTIPATBLT_ORDER); RESET_ORDER(lastMultiScrBlt, TS_ENC_MULTISCRBLT_ORDER); RESET_ORDER(lastMultiOpaqueRect, TS_ENC_MULTIOPAQUERECT_ORDER); RESET_ORDER(lastFastIndex, TS_ENC_FAST_INDEX_ORDER); RESET_ORDER(lastPolygonSC, TS_ENC_POLYGON_SC_ORDER); RESET_ORDER(lastPolygonCB, TS_ENC_POLYGON_CB_ORDER); RESET_ORDER(lastPolyLine, TS_ENC_POLYLINE_ORDER); RESET_ORDER(lastFastGlyph, TS_ENC_FAST_GLYPH_ORDER); RESET_ORDER(lastEllipseSC, TS_ENC_ELLIPSE_SC_ORDER); RESET_ORDER(lastEllipseCB, TS_ENC_ELLIPSE_CB_ORDER); RESET_ORDER(lastIndex, TS_ENC_INDEX_ORDER); #ifdef DRAW_NINEGRID RESET_ORDER(lastDrawNineGrid, TS_ENC_DRAWNINEGRID_ORDER); RESET_ORDER(lastMultiDrawNineGrid, TS_ENC_DRAWNINEGRID_ORDER); #endif // Reset the bounds rectangle. memset(&_OD.lastBounds, 0, sizeof(_OD.lastBounds)); for(int i = 0; i < TS_MAX_ORDERS; i++) { odOrderTable[_OD.lastOrderType].cbVariableDataLen = 0; } #ifdef DC_HICOLOR //#ifdef DC_DEBUG /************************************************************************/ /* Reset the list of order types we've seen */ /************************************************************************/ TRC_ALT((TB, _T("Clear order types received list"))); memset(_OD.orderHit, 0, sizeof(_OD.orderHit)); //#endif #endif DC_END_FN(); } /****************************************************************************/ /* Name: OD_Disable */ /* */ /* Purpose: Disables _OD. */ /****************************************************************************/ void DCAPI COD::OD_Disable(void) { DC_BEGIN_FN("OD_Disable"); #ifdef DC_HICOLOR #ifdef DC_DEBUG int i; #endif #endif #ifdef DC_HICOLOR #ifdef DC_DEBUG /************************************************************************/ /* Dump the list of order types we've seen */ /************************************************************************/ TRC_DBG((TB, _T("Received order types:"))); for (i = 0; i < (TS_MAX_ORDERS + TS_NUM_SECONDARY_ORDERS); i++) { TRC_DBG((TB, _T("- %02d %s %s"), i, orderNames[i], _OD.orderHit[i] ? _T("YES") : _T("NO") )); } #endif #endif TRC_NRM((TB, _T("Disabling OD"))); DC_END_FN(); } // Unneeded because we can fast-path single-field deltas below if we don't // have variable-length coord fields. #ifdef USE_VARIABLE_COORDS /****************************************************************************/ /* Given two arrays, a source array and an array of deltas, add each delta */ /* to the corresponding element in the source array, storing the results in */ /* the source array. */ /* */ /* srcArray - The array of source values */ /* srcArrayType - The type of the array of source values */ /* deltaArray - The array of deltas */ /* numElements - The number of elements in the arrays */ /****************************************************************************/ #define COPY_DELTA_ARRAY(srcArray, srcArrayType, deltaArray, numElements) \ { \ DCUINT index; \ for (index = 0; index < (numElements); index++) \ { \ (srcArray)[index] = (srcArrayType) \ ((srcArray)[index] + (deltaArray)[index]); \ } \ } /****************************************************************************/ /* Name: ODCopyFromDeltaCoords */ /* */ /* Purpose: Adjusts an array of coordinate values by the amounts */ /* specified in an array of coordinate deltas. */ /* */ /* Params: IN/OUT: ppSrc - pointer to pointer to source data. */ /* Updated by this function to after the processed */ /* delta coordinate data. */ /* IN/OUT: pDst - pointer to coordinates to adjust. */ /* IN: destFieldLength - size of elements in the dest array.*/ /* IN: signedValue - TRUE if the elements are signed. */ /* IN: number of elements in the arrays. */ /****************************************************************************/ _inline DCVOID DCINTERNAL COD::ODCopyFromDeltaCoords( PPDCINT8 ppSrc, PDCVOID pDst, DCUINT dstFieldLength, DCBOOL signedValue, DCUINT numElements ) { PDCINT8 pSrc; DC_BEGIN_FN("ODCopyFromDeltaCoords"); pSrc = *ppSrc; switch (dstFieldLength) { case 1: if (signedValue) { PDCINT8 pDst8Signed = (PDCINT8)pDst; COPY_DELTA_ARRAY( pDst8Signed, DCINT8, pSrc, numElements ); } else { PDCUINT8 pDst8Unsigned = (PDCUINT8)pDst; COPY_DELTA_ARRAY( pDst8Unsigned, DCUINT8, pSrc, numElements ); } break; case 2: if (signedValue) { PDCINT16 pDst16Signed = (PDCINT16)pDst; COPY_DELTA_ARRAY( pDst16Signed, DCINT16, pSrc, numElements ); } else { PDCUINT16 pDst16Unsigned = (PDCUINT16)pDst; COPY_DELTA_ARRAY( pDst16Unsigned, DCUINT16, pSrc, numElements ); } break; case 4: if (signedValue) { PDCINT32 pDst32Signed = (PDCINT32)pDst; COPY_DELTA_ARRAY( pDst32Signed, DCINT32, pSrc, numElements ); } else { PDCUINT32 pDst32Unsigned = (PDCUINT32)pDst; COPY_DELTA_ARRAY( pDst32Unsigned, DCUINT32, pSrc, numElements ); } break; default: TRC_ERR((TB, _T("Bad destination field length %d"), dstFieldLength)); break; } *ppSrc += numElements; DC_END_FN(); } #endif // USE_VARIABLE_COORDS /****************************************************************************/ /* Name: OD_DecodeOrder */ /* */ /* Purpose: Decodes an encoded order. */ /* */ /* Params: IN: ppEncodedOrderData - pointer to a pointer to the encoded */ /* order data. */ /* OUT: pLengthDecoded - pointer to a variable that receives */ /* the amount of encoded order data used to produce the */ /* decoded order. */ /****************************************************************************/ HRESULT DCAPI COD::OD_DecodeOrder(PPDCVOID ppEncodedOrderData, DCUINT uiEncodedDataLength, PUH_ORDER *ppOrder) { HRESULT hr = E_FAIL; BYTE FAR *pControlFlags; BYTE FAR *pNextDataToCopy; BYTE FAR *pDataEnd; PUINT32_UA pEncodingFlags; unsigned numEncodingFlagBytes; unsigned cZeroEncodingFlagBytes; unsigned encodedFieldLength; unsigned unencodedFieldLength; unsigned numReps; unsigned i; BYTE FAR *pDest; BYTE FAR *pLastOrderEnd; PUH_ORDER rc = NULL; UINT32 fieldChangedBits; const OD_ORDER_FIELD_INFO FAR *pTableEntry; DC_BEGIN_FN("OD_DecodeOrder"); *ppOrder = NULL; pDataEnd = (PBYTE)*ppEncodedOrderData + uiEncodedDataLength; CHECK_READ_ONE_BYTE(*ppEncodedOrderData, pDataEnd, hr, (TB, _T("no data passed in"))) // Control flags are always the first byte. pControlFlags = (BYTE FAR *)(*ppEncodedOrderData); // Check that the order has standard encoding. TRC_ASSERT((*pControlFlags & TS_STANDARD), (TB, _T("Non-standard encoding: %u"), (unsigned)*pControlFlags)); TRC_ASSERT(!(*pControlFlags & TS_SECONDARY), (TB, _T("Unencoded: %u"), (unsigned)*pControlFlags)); // If type has changed, new type will be first byte in encoded order. // Get pointer to last order of this type. The encoding flags follow // this byte (if it is present). if (*pControlFlags & TS_TYPE_CHANGE) { CHECK_READ_ONE_BYTE((pControlFlags + 1), pDataEnd, hr, (TB, _T("no data passed in"))) TRC_DBG((TB, _T("Change type from %d to %d"), _OD.lastOrderType, *(pControlFlags + 1))); if (*(pControlFlags + 1) >= TS_MAX_ORDERS) { TRC_ERR((TB, _T("Invalid order type %u"), *(pControlFlags + 1))); hr = E_TSC_CORE_DECODETYPE; DC_QUIT; } _OD.lastOrderType = *(pControlFlags + 1); if (TS_MAX_ORDERS < _OD.lastOrderType) { TRC_ABORT((TB, _T("invalid order type: %u"), _OD.lastOrderType)); hr = E_TSC_CORE_DECODETYPE; DC_QUIT; } // SECURITY: use the cbMaxOrderLen to be sure this entry in the // table is filled out if (0 == odOrderTable[_OD.lastOrderType].cbMaxOrderLen) { TRC_ABORT((TB, _T("invalid order type: %u"), _OD.lastOrderType)); hr = E_TSC_CORE_DECODETYPE; DC_QUIT; } _OD.pLastOrder = odOrderTable[_OD.lastOrderType].LastOrder; pEncodingFlags = (PUINT32_UA)(pControlFlags + 2); } else { pEncodingFlags = (PUINT32_UA)(pControlFlags + 1); } TRC_DBG((TB, _T("Type %x"), _OD.lastOrderType)); #ifdef DC_HICOLOR //#ifdef DC_DEBUG /************************************************************************/ /* For high color testing, we want to confirm that we've received each */ /* of the order types */ /************************************************************************/ _OD.orderHit[_OD.lastOrderType] += 1; //#endif #endif // Work out how many bytes are used to store the encoding flags for // this order. There is a flag for each field in the order structure. // For historical reasons, add 1 to the real number of fields before // calculating. This means that the first byte of field flags can // only contain 7 field bits. numEncodingFlagBytes = (odOrderTable[_OD.lastOrderType].NumFields + 1 + 7) / 8; TRC_DBG((TB, _T("numEncodingFlagBytes %d"), numEncodingFlagBytes)); TRC_ASSERT((numEncodingFlagBytes <= 3), (TB, _T("Too many flag bytes (%d)"), numEncodingFlagBytes)); // Find out how many zero bytes of encoding flags there are. cZeroEncodingFlagBytes = (*pControlFlags & TS_ZERO_FIELD_COUNT_MASK) >> TS_ZERO_FIELD_COUNT_SHIFT; if (cZeroEncodingFlagBytes > numEncodingFlagBytes) { TRC_ERR((TB, _T("Too many zero encoding flag bytes (%d)"), cZeroEncodingFlagBytes)); hr = E_TSC_CORE_LENGTH; DC_QUIT; } // Now we know how many bytes make up the flags we can get a pointer to // where we start decoding the order data from. pNextDataToCopy = (BYTE FAR *)pEncodingFlags + numEncodingFlagBytes - cZeroEncodingFlagBytes; // Now build up the order header. // If a bounding rectangle is included, copy it into the order header. if (*pControlFlags & TS_BOUNDS) { BYTE FAR *pFlags; // The encoding used is a byte of flags followed by a variable number // of 16-bit coordinate values and 8-bit delta coordinate values // (which may be interleaved). // If there are zero bounds deltas then we are done. if (!(*pControlFlags & TS_ZERO_BOUNDS_DELTAS)) { // The first byte of the encoding will contain the flags that // represent how the coordinates of the rectangle were encoded. pFlags = pNextDataToCopy; pNextDataToCopy++; CHECK_READ_ONE_BYTE(pFlags, pDataEnd, hr, (TB, _T("No data to read flags"))) // If the flags indicate that none of the coordinates have // changed then we are done if (*pFlags != 0) { // For each of the four coordinate values in the rectangle: // If the coordinate was encoded as an 8-bit delta then add // on the delta to the previous value. If the coordinate // was encoded as a 16-bit value then copy the value across. // Otherwise the coordinate was the same as the previous one // so leave it alone. if (*pFlags & TS_BOUND_DELTA_LEFT) { CHECK_READ_ONE_BYTE(pNextDataToCopy, pDataEnd, hr, ( TB, _T("TS_BOUND_DELTA_LEFT; pData %u pEnd %u"), pNextDataToCopy + 1, pDataEnd )) _OD.lastBounds.left += (int)(*((char FAR *) pNextDataToCopy)); pNextDataToCopy++; } else if (*pFlags & TS_BOUND_LEFT) { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, sizeof(UINT16), hr, ( TB, _T("TS_BOUND_LEFT; pData %u pEnd %u"), pNextDataToCopy, pDataEnd )); _OD.lastBounds.left = DC_EXTRACT_INT16_UA(pNextDataToCopy); pNextDataToCopy += sizeof(UINT16); } if (*pFlags & TS_BOUND_DELTA_TOP) { CHECK_READ_ONE_BYTE(pNextDataToCopy, pDataEnd, hr, ( TB, _T("TS_BOUND_DELTA_TOP; pData %u pEnd %u"), pNextDataToCopy + 1, pDataEnd )); _OD.lastBounds.top += (int)(*((char FAR *) pNextDataToCopy)); pNextDataToCopy++; } else if (*pFlags & TS_BOUND_TOP) { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, sizeof(UINT16),hr, ( TB, _T("TS_BOUND_TOP; pData %u pEnd %u"), pNextDataToCopy, pDataEnd )); _OD.lastBounds.top = DC_EXTRACT_INT16_UA(pNextDataToCopy); pNextDataToCopy += sizeof(UINT16); } if (*pFlags & TS_BOUND_DELTA_RIGHT) { CHECK_READ_ONE_BYTE(pNextDataToCopy, pDataEnd, hr, ( TB, _T("TS_BOUND_DELTA_RIGHT; pData %u pEnd %u"), pNextDataToCopy + 1, pDataEnd )); _OD.lastBounds.right += (int)(*((char FAR *) pNextDataToCopy)); pNextDataToCopy++; } else if (*pFlags & TS_BOUND_RIGHT) { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, sizeof(UINT16), hr, ( TB, _T("TS_BOUND_RIGHT; pData %u pEnd %u"), pNextDataToCopy, pDataEnd )); _OD.lastBounds.right = DC_EXTRACT_INT16_UA( pNextDataToCopy); pNextDataToCopy += sizeof(UINT16); } if (*pFlags & TS_BOUND_DELTA_BOTTOM) { CHECK_READ_ONE_BYTE(pNextDataToCopy, pDataEnd, hr, ( TB, _T("TS_BOUND_DELTA_BOTTOM; pData %u pEnd %u"), pNextDataToCopy + 1, pDataEnd )); _OD.lastBounds.bottom += (int)(*((char FAR *) pNextDataToCopy)); pNextDataToCopy++; } else if (*pFlags & TS_BOUND_BOTTOM) { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, sizeof(UINT16), hr, ( TB, _T("TS_BOUND_BOTTOM; pData %u pEnd %u"), pNextDataToCopy, pDataEnd )); _OD.lastBounds.bottom = DC_EXTRACT_INT16_UA( pNextDataToCopy); pNextDataToCopy += sizeof(UINT16); } } } // Copy the (possibly newly calculated) bounds to the order header. _OD.pLastOrder->dstRect = _OD.lastBounds; TRC_NRM((TB, _T("Decoded bounds l %d t %d r %d b %d"), _OD.pLastOrder->dstRect.left, _OD.pLastOrder->dstRect.top, _OD.pLastOrder->dstRect.right, _OD.pLastOrder->dstRect.bottom)); } // Locate the entry in the decoding table for this order type and // extract the encoded order flags from the encoded order. fieldChangedBits = 0; for (i = (numEncodingFlagBytes - cZeroEncodingFlagBytes); i > 0; i--) { fieldChangedBits <<= 8; fieldChangedBits |= (UINT32)((BYTE FAR *)pEncodingFlags)[i - 1]; } // If there is a fast-path decode function, use it. // Fast-path decode functions also do the order handling once decoded. // They must set pOrder->dstRect if (ControlFlags & TS_BOUNDS) == 0. if (odOrderTable[_OD.lastOrderType].pFastDecode != NULL) { hr = callMemberFunction(*this, odOrderTable[_OD.lastOrderType].pFastDecode)(*pControlFlags, &pNextDataToCopy, pDataEnd - pNextDataToCopy, fieldChangedBits); DC_QUIT_ON_FAIL(hr); goto PostFastPathDecode; } // Now decode the order: // while field changed bits are non-zero // if rightmost bit is non-zero // decode the corresponding changed field // skip to next entry in decoding table // shift field changed bits right one bit pTableEntry = odOrderTable[_OD.lastOrderType].pOrderTable; pLastOrderEnd = (BYTE FAR *)_OD.pLastOrder + odOrderTable[_OD.lastOrderType].cbMaxOrderLen; TRC_ASSERT((pTableEntry != NULL), (TB,_T("Unsupported order type %d received!"), _OD.lastOrderType)); while (fieldChangedBits != 0) { // If this field was encoded (ie changed since the last order)... if (fieldChangedBits & 0x1) { // Set up a pointer to the destination (unencoded) field. pDest = (BYTE FAR *)_OD.pLastOrder + pTableEntry->fieldPos + UH_ORDER_HEADER_SIZE; // If the field type is OD_OFI_TYPE_DATA, we just copy the // number of bytes given by the encoded length in the table. if (pTableEntry->fieldType & OD_OFI_TYPE_DATA) { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, pTableEntry->fieldEncodedLen, hr, ( TB, _T("OD_OFI_TYPE_DATA; pData %u pEnd %u"), pNextDataToCopy + pTableEntry->fieldEncodedLen, pDataEnd)); CHECK_WRITE_N_BYTES(pDest, pLastOrderEnd, pTableEntry->fieldEncodedLen, hr, (TB, _T("Decode past end of buffer"))); memcpy(pDest, pNextDataToCopy, pTableEntry->fieldEncodedLen); pNextDataToCopy += pTableEntry->fieldEncodedLen; TRC_TST((TB, _T("Byte data field, len %d"), numReps)); } else { // This is not a straightforward data copy. The length of // the source and destination data is given in the table in // the fieldEncodedLen and fieldUnencodedLen elements // respectively. encodedFieldLength = pTableEntry->fieldEncodedLen; unencodedFieldLength = pTableEntry->fieldUnencodedLen; // If the order was encoded using delta coordinate mode and // this field is a coordinate then convert the coordinate from // the single byte sized delta to a value of the size given by // unencodedFieldLen... // Note that we've already handled the leading length field of // variable length fields above, so we don't have to worry // about fixed/variable issues here. if ((*pControlFlags & TS_DELTA_COORDINATES) && (pTableEntry->fieldType & OD_OFI_TYPE_COORDINATES)) { // Since we are not using variable-length coord fields, // we can fast-path with an assumption that the source is // length 1. Also, all coord fields are currently // signed and destination size is always 4, so we can drop // more branches. if (!(pTableEntry->fieldType & OD_OFI_TYPE_SIGNED)) { TRC_ABORT((TB,_T("Someone added a non-signed COORD") _T(" field - order type %u"), _OD.lastOrderType)); hr = E_TSC_CORE_LENGTH; DC_QUIT; } if (pTableEntry->fieldUnencodedLen != 4) { TRC_ABORT((TB,_T("Someone added a non-4-byte COORD") _T(" field - order type %u"), _OD.lastOrderType)); hr = E_TSC_CORE_LENGTH; DC_QUIT; } CHECK_READ_ONE_BYTE(pNextDataToCopy, pDataEnd, hr,( TB, _T("Reading destination offset past data end"))); CHECK_WRITE_N_BYTES(pDest, pLastOrderEnd, sizeof(INT32), hr, (TB, _T("Decode past end of buffer"))); *((INT32 FAR *)pDest) += *((char FAR *)pNextDataToCopy); pNextDataToCopy++; #ifdef USE_VARIABLE_COORDS CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, (numReps * sizeof(BYTE)), hr, ( TB, _T("Bad offset into lastOrder"))); CHECK_WRITE_N_BYTES(pDest, pLastOrderEnd, pTableEntry->fieldUnencodedLen, hr, (TB, _T("decode off end of buffer" ))); ODCopyFromDeltaCoords((PPDCINT8)&pNextDataToCopy, pDest, pTableEntry->fieldUnencodedLen, pTableEntry->fieldType & OD_OFI_TYPE_SIGNED, numReps); #endif } else { if (pTableEntry->fieldType & OD_OFI_TYPE_FIXED) { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, pTableEntry->fieldEncodedLen, hr, ( TB, _T("OD_OFI_TYPE_FIXED; pData %u pEnd %u"), pNextDataToCopy + pTableEntry->fieldEncodedLen, pDataEnd)); CHECK_READ_N_BYTES(pDest, pLastOrderEnd, pTableEntry->fieldUnencodedLen, hr, ( TB, _T("Bad offset into lastOrder"))); // Copy the field with appropriate field size conversion. hr = ODDecodeFieldSingle(&pNextDataToCopy, pDest, pTableEntry->fieldEncodedLen, pTableEntry->fieldUnencodedLen, pTableEntry->fieldType & OD_OFI_TYPE_SIGNED); DC_QUIT_ON_FAIL(hr); } else { // We assume that variable entries are only bytes // (dest size = 1). if(pTableEntry->fieldUnencodedLen != 1 || pTableEntry->fieldEncodedLen != 1) { TRC_ABORT((TB,_T("Somebody added a variable field with ") _T("non-byte contents - order type %u"), _OD.lastOrderType)); hr = E_TSC_CORE_LENGTH; DC_QUIT; } // This is a variable length field - see if it's long or // short. if (!(pTableEntry->fieldType & OD_OFI_TYPE_LONG_VARIABLE)) { CHECK_READ_ONE_BYTE(pNextDataToCopy, pDataEnd, hr, ( TB, _T("Reading numReps (BYTE)"))); // This is a variable field. The next byte to be // decoded contains the number of BYTES of encoded // data (not elements), so divide by the encoded // field size to get numReps. numReps = *pNextDataToCopy; // (/ pTableEntry->fieldEncodedLen) - bytes only // Step past the length field in the encoded order. pNextDataToCopy++; } else { CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, sizeof(UINT16), hr, ( TB, _T("Reading numReps (UINT16)"))); // This is a long variable field. The next two // bytes to be decoded contain the number of BYTES // of encoded data (not elements), so divide by the // encoded field size to get numReps. numReps = *((PUINT16_UA)pNextDataToCopy); // (/ pTableEntry->fieldEncodedLen) - bytes only // Step past the length field in the encoded order. pNextDataToCopy += sizeof(UINT16); } TRC_TST((TB, _T("Var field: encoded size %d, unencoded ") "size %d, reps %d", pTableEntry->fieldEncodedLen, pTableEntry->fieldUnencodedLen, numReps)); // Cast from unsigned to UINT16 is safe since the numReps read above // is no more than a UINT16 odOrderTable[_OD.lastOrderType].cbVariableDataLen = (UINT16)numReps; // For a variable length field, the unencoded version // contains a UINT32 for the length (in bytes) of the // following variable data, followed by the actual // data. Fill in the length field in the unencoded // order. *(PUINT32)pDest = numReps; // (* pTableEntry->fieldUnencodedLen) pDest += sizeof(UINT32); CHECK_READ_N_BYTES(pNextDataToCopy, pDataEnd, numReps, hr, ( TB, _T("Reading numReps past end of data"))); CHECK_WRITE_N_BYTES(pDest, pLastOrderEnd, numReps, hr, ( TB, _T("Writing numReps bytes past end of last order"))); // We assume that variable entries are only bytes // (dest size = 1), since no one is using anything longer. memcpy(pDest, pNextDataToCopy, numReps); pNextDataToCopy += numReps; } } } } // Move on to the next field in the order structure... fieldChangedBits >>= 1; pTableEntry++; } // Pass to the order handler (non-fast-path). These functions must set // pOrder->dstRect to the bounding rect of the entire operation if // bBoundsSet is FALSE, and set the clip region appropriately. TRC_ASSERT((odOrderTable[_OD.lastOrderType].pHandler != NULL), (TB,_T("Fast-path decoder and order handler funcs both NULL (ord=%u)"), _OD.lastOrderType)); hr = callMemberFunction(*this, odOrderTable[_OD.lastOrderType].pHandler)( _OD.pLastOrder, odOrderTable[_OD.lastOrderType].cbVariableDataLen, *pControlFlags & TS_BOUNDS); DC_QUIT_ON_FAIL(hr); PostFastPathDecode: // Update the source pointer to the start of the next encoded order. TRC_ASSERT( (DCUINT)(pNextDataToCopy - (BYTE*)(*ppEncodedOrderData)) <= uiEncodedDataLength, (TB, _T("Decoded more data than available"))); *ppEncodedOrderData = (PDCVOID)pNextDataToCopy; TRC_DBG((TB, _T("Return %p"), *ppEncodedOrderData)); *ppOrder = _OD.pLastOrder; DC_EXIT_POINT: DC_END_FN(); return hr; }