Windows2003-3790/termsrv/newclient/core/odapi.cpp
2020-09-30 16:53:55 +02:00

1546 lines
80 KiB
C++

/****************************************************************************/
// odapi.cpp
//
// Order Decoder API functions.
//
// Copyright (c) 1997-2000 Microsoft Corp.
// Portions copyright (c) 1992-2000 Microsoft
/****************************************************************************/
#include <adcg.h>
extern "C" {
#define TRC_GROUP TRC_GROUP_CORE
#define TRC_FILE "aodapi"
#include <atrcapi.h>
}
#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;
}