#include <DPS/dpsXclient.h>
#include <DPS/dpsops.h>
#include <DPS/dpsXuserpath.h>
typedef struct _t_NumStrHeader {
unsigned char type;
unsigned char representation;
unsigned short length;
} NumStrHeader;
void PSDoUserPath(coords, numCoords, numType, ops, numOps, bbox, action)
DPSPointer coords;
int numCoords;
DPSNumberFormat numType;
DPSUserPathOp *ops;
int numOps;
DPSPointer bbox;
DPSUserPathAction action;
{
DPSDoUserPath(DPSGetCurrentContext(), coords, numCoords, numType, ops,
numOps, bbox, action);
}
void DPSDoUserPath(ctxt, coords, numCoords, numType, ops, numOps, bbox, action)
DPSContext ctxt;
DPSPointer coords;
int numCoords;
DPSNumberFormat numType;
DPSUserPathOp *ops;
int numOps;
DPSPointer bbox;
DPSUserPathAction action;
{
typedef struct {
unsigned char tokenType;
unsigned char topLevelCount;
unsigned short nBytes;
DPSBinObjGeneric obj0;
DPSBinObjGeneric obj1;
DPSBinObjGeneric obj2;
DPSBinObjGeneric obj3;
} _dpsQ;
static _dpsQ _dpsF = {
DPS_DEF_TOKENTYPE, 0, 36,
{DPS_LITERAL|DPS_ARRAY, 0, 2, 16},
{DPS_EXEC|DPS_NAME, 0, DPSSYSNAME, 0},
{DPS_LITERAL|DPS_STRING, 0, 0, 32},
{DPS_LITERAL|DPS_STRING, 0, 0, 32},
};
register DPSBinObjRec *_dpsP = (DPSBinObjRec *)&_dpsF.obj0;
register int _dps_offset = 32;
int needBBox, hasUCache, numberSize;
DPSUserPathOp setbboxOp;
NumStrHeader nsHeader;
if (numType >= dps_short && numType < dps_float) numberSize = 2;
else numberSize = 4;
hasUCache = (*ops == dps_ucache);
if (hasUCache) {
needBBox = (numOps > 1 && ops[1] != dps_setbbox);
} else needBBox = (*ops != dps_setbbox);
if (needBBox) {
numOps += 1;
setbboxOp = dps_setbbox;
}
numCoords += 4;
nsHeader.type = 149;
nsHeader.representation = numType;
nsHeader.length = numCoords;
if (action == dps_send) _dpsF.topLevelCount = 1;
else _dpsF.topLevelCount = 2;
_dpsP[1].val.nameVal = action;
_dpsP[2].length = (sizeof(NumStrHeader) + numCoords * numberSize);
_dpsP[3].length = numOps;
_dpsP[3].val.stringVal = _dps_offset;
_dps_offset += numOps;
_dpsP[2].val.stringVal = _dps_offset;
_dps_offset += _dpsP[2].length;
_dpsF.nBytes = _dps_offset+4;
if (needBBox) numOps -= 1;
numCoords -= 4;
DPSBinObjSeqWrite(ctxt, (char *) &_dpsF, 36);
if (needBBox) {
if (hasUCache) {
DPSWriteStringChars(ctxt, (char *) ops, 1);
ops++; numOps--;
}
DPSWriteStringChars(ctxt, (char *) &setbboxOp, 1);
}
DPSWriteStringChars(ctxt, (char *) ops, numOps);
DPSWriteStringChars(ctxt, (char *) &nsHeader, sizeof(NumStrHeader));
DPSWriteStringChars(ctxt, (char *) bbox, 4 * numberSize);
DPSWriteStringChars(ctxt, (char *) coords, numCoords * numberSize);
}
Bool PSHitUserPath(x, y, radius,
coords, numCoords, numType, ops, numOps, bbox, action)
double x, y, radius;
DPSPointer coords;
int numCoords;
DPSNumberFormat numType;
DPSUserPathOp *ops;
int numOps;
DPSPointer bbox;
DPSUserPathAction action;
{
return DPSHitUserPath(DPSGetCurrentContext(), x, y, radius,
coords, numCoords, numType, ops,
numOps, bbox, action);
}
Bool DPSHitUserPath(ctxt, x, y, radius,
coords, numCoords, numType, ops, numOps, bbox, action)
DPSContext ctxt;
double x, y, radius;
DPSPointer coords;
int numCoords;
DPSNumberFormat numType;
DPSUserPathOp *ops;
int numOps;
DPSPointer bbox;
DPSUserPathAction action;
{
float aCoords[5];
DPSUserPathOp aOps[1];
float aBbox[4];
int result;
if (radius != 0.0) {
aCoords[0] = x;
aCoords[1] = y;
aCoords[2] = radius;
aCoords[3] = 0.0;
aCoords[4] = 360.0;
aOps[0] = dps_arc;
aBbox[0] = x - radius;
aBbox[1] = y - radius;
aBbox[2] = x + radius;
aBbox[3] = y + radius;
switch (action) {
case dps_infill:
case dps_ineofill:
case dps_instroke:
DPSDoUserPath(ctxt, (DPSPointer) aCoords, 5, dps_float,
aOps, 1, (DPSPointer) aBbox, action);
break;
case dps_inufill:
case dps_inueofill:
case dps_inustroke:
DPSDoUserPath(ctxt, (DPSPointer) aCoords, 5, dps_float,
aOps, 1, (DPSPointer) aBbox, dps_send);
DPSDoUserPath(ctxt, coords, numCoords, numType, ops,
numOps, bbox, action);
break;
default:
return False;
}
DPSgetboolean(ctxt, &result);
} else {
switch (action) {
case dps_infill:
DPSinfill(ctxt, x, y, &result);
break;
case dps_ineofill:
DPSineofill(ctxt, x, y, &result);
break;
case dps_instroke:
DPSinstroke(ctxt, x, y, &result);
break;
case dps_inufill:
case dps_inueofill:
case dps_inustroke:
DPSsendfloat(ctxt, x);
DPSsendfloat(ctxt, y);
DPSDoUserPath(ctxt, coords, numCoords, numType, ops,
numOps, bbox, action);
DPSgetboolean(ctxt, &result);
break;
default:
return False;
}
}
return result;
}