fix: 初始化工程

master
laixingyu 4 years ago
commit 967913691a

@ -0,0 +1,796 @@
//
// SWPosPointcut.c
// DrawTest
//
// Created by 王阳阳 on 2022/9/6.
//
#include "SWPosPointcut.h"
#include <QDebug>
#define MaxPoints 6000.f
#define MaxSegment 100.f
#define MaxWidthScale 1.5f
#define MinRadius 0.3f
#define MaxSteps 0.13f
#define MinShake 130
#define MaxShake 170
#define M_PI 3.14159265358979323846264338327950288f
#define RadianTodegrees(x) (x * 180.f / M_PI)
static SWPosPoint lastePos;
static SWLineSegment *curLeftLine = NULL;
static SWLineSegment *curRightLine = NULL;
static int pointStep = 0;
void SWPosRest(SWPosPoint pos) {
lastePos = pos;
pointStep = 0;
SWLineSegment *onSegment = curLeftLine;
if (curLeftLine != NULL) {
while (onSegment) {
SWLineSegment *tempSeg = (SWLineSegment *)onSegment->preSegment;
onSegment->preSegment = NULL;
free(onSegment);
if (tempSeg != NULL) {
onSegment = tempSeg;
} else {
onSegment = NULL;
}
}
}
onSegment = curRightLine;
if (curRightLine != NULL) {
while (onSegment) {
SWLineSegment *tempSeg = (SWLineSegment *)onSegment->preSegment;
onSegment->preSegment = NULL;
free(onSegment);
if (tempSeg != NULL) {
onSegment = tempSeg;
} else {
onSegment = NULL;
}
}
}
curLeftLine = NULL;
curRightLine = NULL;
}
SWPosRet SWGetTangentcurPoint(SWPosPoint prevPoint,SWPosPoint curPoint,
SWLineSegment leftLine,SWLineSegment rightLine,
int circle) {
double distance = GetPointDistance(prevPoint, curPoint);
double radiusDistance = (prevPoint.radius + curPoint.radius);
if ((distance < radiusDistance) || distance < 1) {
if (prevPoint.realPoint.x != lastePos.realPoint.x && prevPoint.realPoint.y != lastePos.realPoint.y){
double rads = SWBetweenLinesrads(lastePos.realPoint, prevPoint.realPoint,
curPoint.realPoint, prevPoint.realPoint);
double angle = RadianTodegrees(rads);
if (angle > 150) {
SWPosRet retPos;
retPos.prevLeftPoint = SWPointCutMake(0, 0);
retPos.prevLeftIntersectPoint = SWPointCutMake(0, 0);
retPos.prevRightPoint = SWPointCutMake(0, 0);
retPos.prevRightIntersectPoint = SWPointCutMake(0, 0);
retPos.curLeftPoint = SWPointCutMake(0, 0);
retPos.curRightPoint = SWPointCutMake(0, 0);
retPos.circlePoints.clear();
retPos.circleCount = 0;
retPos.status = SWPosRetFail;
return retPos;
}
}
}
if (circle == 1 || pointStep == 0) {
return getCircleSegments(prevPoint, curPoint, leftLine, rightLine, distance,pointStep);
}
if (distance > fabs(prevPoint.radius - curPoint.radius)) {
SWPointcut pointFa= {0,0};//左侧切点
SWPointcut pointFa1 = {0,0};//右侧切点
SWPointcut pointFb = {0,0};//左侧切点
SWPointcut pointFb1 = {0,0};//右侧切点
double base = atan2(curPoint.realPoint.y - prevPoint.realPoint.y, curPoint.realPoint.x - prevPoint.realPoint.x);
double ang = acos((prevPoint.radius - curPoint.radius) / distance);
pointFa = GetMaleTangentPointValue(prevPoint, base + ang);
pointFb = GetMaleTangentPointValue(curPoint, base + ang);
pointFb1 = GetMaleTangentPointValue(curPoint, base - ang);
pointFa1 = GetMaleTangentPointValue(prevPoint, base - ang);
SWPointcut pointLeftIntersect = {0,0};//左侧切点
SWPointcut pointRightIntersect = {0,0};//右侧切点
if (leftLine.status == SWPosRetFail && rightLine.status == SWPosRetFail) {
pointStep++;
lastePos = prevPoint;
SWPosRet retPos1;
retPos1.prevLeftPoint = pointFa;//左侧切点
retPos1.prevLeftIntersectPoint = pointLeftIntersect;//左侧切点交点
retPos1.prevRightPoint = pointFa1;//右侧切点
retPos1.prevRightIntersectPoint = pointRightIntersect;//右侧切点交点
retPos1.curLeftPoint = pointFb;//当前点左侧切点
retPos1.curRightPoint = pointFb1;//当前点右侧切点
retPos1.circlePoints.clear();
retPos1.circleCount = 0;
retPos1.status = SWPosRetSuccess;//计算结果状态
return retPos1;
}
pointRightIntersect = SWgetEdgePoint(rightLine.startPoint,rightLine.endPoint,pointFa1,pointFb1,prevPoint.realPoint,0);
pointLeftIntersect = SWgetEdgePoint(leftLine.startPoint,leftLine.endPoint,pointFa,pointFb,prevPoint.realPoint,1);
if ((pointRightIntersect.x == 0 && pointRightIntersect.y ==0) || (pointLeftIntersect.x == 0 && pointLeftIntersect.y == 0)) {
return getCircleSegments(prevPoint, curPoint, leftLine, rightLine, distance,pointStep);
}
/**
* 00
*/
double lDistance = GetPointDistance(prevPoint,SWPosPointMake(pointLeftIntersect.x,pointLeftIntersect.y,0));
if (lDistance > prevPoint.radius*10) {
pointLeftIntersect = SWPointCutMake((leftLine.endPoint.x + pointFa.x)/2.f,(leftLine.endPoint.y + pointFa.y)/2.f);
}
double rDistance = GetPointDistance(prevPoint,SWPosPointMake(pointRightIntersect.x,pointRightIntersect.y,0));
if (rDistance > prevPoint.radius*10) {
pointRightIntersect = SWPointCutMake((rightLine.endPoint.x + pointFa1.x)/2.f,(rightLine.endPoint.y + pointFa1.y)/2.f);
}
SWPosRet retPos2;
retPos2.prevLeftPoint = pointFa;//左侧切点
retPos2.prevLeftIntersectPoint = pointLeftIntersect;//左侧切点交点
retPos2.prevRightPoint = pointFa1;//右侧切点
retPos2.prevRightIntersectPoint = pointRightIntersect;//右侧切点交点
retPos2.curLeftPoint = pointFb;//当前点左侧切点
retPos2.curRightPoint = pointFb1;//当前点右侧切点
retPos2.circlePoints.clear();
retPos2.circleCount = 0;
retPos2.status = SWPosRetSuccess;//计算结果状态
lastePos = prevPoint;
pointStep++;
return retPos2;
}
SWPosRet retPos;
retPos.prevLeftPoint = SWPointCutMake(0, 0);
retPos.prevLeftIntersectPoint = SWPointCutMake(0, 0);
retPos.prevRightPoint = SWPointCutMake(0, 0);
retPos.prevRightIntersectPoint = SWPointCutMake(0, 0);
retPos.curLeftPoint = SWPointCutMake(0, 0);
retPos.curRightPoint = SWPointCutMake(0, 0);
retPos.circlePoints.clear();
retPos.circleCount = 0;
retPos.status = SWPosRetFail;
return retPos;
}
SWPosRet getCircleSegments(SWPosPoint prevPoint,SWPosPoint curPoint,SWLineSegment leftLine,
SWLineSegment rightLine,double distance,int step) {
SWPointcut controlPoint = SWPointCutMake(prevPoint.realPoint.x, prevPoint.realPoint.y);
int segements = distance/0.2f;
if (segements < 5) {
segements = 5;
}
double preRadius = 0;
if (leftLine.status == SWPosRetSuccess && rightLine.status == SWPosRetSuccess) {
preRadius = GetPointDistance(SWPosPointMake(leftLine.endPoint.x, leftLine.endPoint.y, 0),
SWPosPointMake(rightLine.endPoint.x, rightLine.endPoint.y, 0))/2.f;
} else {
preRadius = prevPoint.radius;
}
double circleRadius = curPoint.radius - preRadius;
QList<SWCirclePoint> circleAry;
for (int i = 0; i < segements; i ++) {
if (i == 0) {
SWCirclePoint cPoint = SWCircleMake(SWPosPointMake(prevPoint.realPoint.x,
prevPoint.realPoint.y, preRadius));
circleAry.append(cPoint);
} else if (i == (segements - 1)) {
SWCirclePoint cPoint = SWCircleMake(SWPosPointMake(curPoint.realPoint.x,
curPoint.realPoint.y, preRadius + circleRadius));
circleAry.append(cPoint);
} else {
double t = (double)i/segements;
double x = pow(1 - t, 2) * prevPoint.realPoint.x + 2.0 * (1 - t) * t * controlPoint.x + t * t * curPoint.realPoint.x;
double y = pow(1 - t, 2) * prevPoint.realPoint.y + 2.0 * (1 - t) * t * controlPoint.y + t * t * curPoint.realPoint.y;
SWCirclePoint cPoint = SWCircleMake(SWPosPointMake(x, y, preRadius + circleRadius*t));
circleAry.append(cPoint);
}
}
pointStep++;
SWPosRet retPos;
retPos.prevLeftPoint = SWPointCutMake(0, 0);//左侧切点
retPos.prevLeftIntersectPoint = SWPointCutMake(0, 0);//左侧切点交点
retPos.prevRightPoint = SWPointCutMake(0, 0);//右侧切点
retPos.prevRightIntersectPoint = SWPointCutMake(0, 0);//右侧切点交点
retPos.curLeftPoint = SWPointCutMake(0, 0);//当前点左侧切点
retPos.curRightPoint = SWPointCutMake(0, 0);//当前点右侧切点
retPos.circlePoints = circleAry;
retPos.circleCount = segements;
retPos.status = SWPosRetSuccess;//计算结果状态
return retPos;
}
QList<SWPosPoint> fillPoints(SWPosPoint prevPoint,SWPosPoint curPoint,double distance) {
SWPointcut controlPoint = SWPointCutMake(prevPoint.realPoint.x, prevPoint.realPoint.y);
int segements = distance/0.5f;
double preRadius = prevPoint.radius;
double circleRadius = curPoint.radius - preRadius;
QList<SWPosPoint> circleAry;
for (int i = 0; i < segements; i ++) {
double t = (double)i/segements;
double x = pow(1 - t, 2) * prevPoint.realPoint.x + 2.0 * (1 - t) * t * controlPoint.x + t * t * curPoint.realPoint.x;
double y = pow(1 - t, 2) * prevPoint.realPoint.y + 2.0 * (1 - t) * t * controlPoint.y + t * t * curPoint.realPoint.y;
SWPosPoint cPoint = SWPosPointMake(x, y, preRadius + circleRadius*t);
circleAry.append(cPoint);
}
return circleAry;
}
SWPosStatus IsPointInMatrix(SWPointcut p1 ,SWPointcut p2,SWPointcut p3 ,SWPointcut p4,SWPointcut p)
{
if (GetCross(p1,p2,p) * GetCross(p3,p4,p) >= 0 && GetCross(p2,p3,p) * GetCross(p4,p1,p) >= 0) {
return SWPosRetSuccess;
} else {
return SWPosRetFail;
}
}
double GetCross(SWPointcut p1, SWPointcut p2,SWPointcut p)
{
return (p2.x - p1.x) * (p.y - p1.y) -(p.x - p1.x) * (p2.y - p1.y);
}
SWPointcut SWratioPoint(SWPointcut startPoint, SWPointcut endPoint, double ratio) {
SWPointcut ret = {0,0};
double x = endPoint.x - startPoint.x;
double y = endPoint.y - startPoint.y;
ret.x = x*ratio + startPoint.x;
ret.y = y*ratio + startPoint.y;
return ret;
}
SWPointcut SWrotatePoint(SWPointcut point, SWPointcut center, double angle) {
SWPointcut ret = {0,0};
double x = point.x - center.x;
double y = point.y - center.y;
ret.x = (x*cos(angle) - y*sin(angle)) + center.x;
ret.y = (x*sin(angle) + y*cos(angle)) + center.y;
return ret;
}
SWPointcut GetMaleTangentPointValue(SWPosPoint point, double a)
{
SWPointcut ret = {0,0};
ret.x = (double) (point.realPoint.x + point.radius * cos(a));
ret.y = (double) (point.realPoint.y + point.radius * sin(a));
return ret;
}
SWPointcut SWgetEdgePoint(SWPointcut a, SWPointcut b, SWPointcut c,SWPointcut d,SWPointcut e,int leftLine) {
double dx1 = a.x - b.x;
double dy1 = a.y - b.y;
double dx2 = d.x - c.x;
double dy2 = d.y - c.y;
SWPointcut edgePointf = {0,0};
SWPointcut pointf = {0,0};
if (dx1 == 0 && dx2 != 0) {//ab垂直x轴
double k2 = dy2 / dx2;//第二条直线斜率
double h2 = d.y - k2 * d.x;//第二条直线截距
//交点在a.x或者b.x
double x = a.x;
double y = k2 * x + h2;
pointf = SWPointCutMake(x,y);
if (isPointOnLine(x, y, a, b) == 1 && isPointOnLine(x, y, c, d) == 1) {//焦点在线段上
edgePointf = pointf;
}
} else if (dx1 != 0 && dx2 == 0) {//cd垂直x轴
double k1 = dy1 / dx1;//第一条直线斜率
double h1 = b.y - k1 * b.x;//第一条直线的截距
//交点在c.x或者d.x
double x = c.x;
double y = k1 * x + h1;
pointf = SWPointCutMake(x,y);
if (isPointOnLine(x, y, a, b) == 1 && isPointOnLine(x, y, c, d) == 1) {//焦点在线段上
edgePointf = pointf;
}
} else if (dx1 == 0 && dx2 == 0) {//ab cd都垂直x轴
//无交点
} else {
double k1 = dy1 / dx1;//第一条直线斜率
double h1 = b.y - k1 * b.x;//第一条直线的截距
double k2 = dy2 / dx2;//第二条直线斜率
double h2 = d.y - k2 * d.x;//第二条直线截距
if (k1 == k2) {//两直线平行
if (h1 == h2) {//重合
} else {//平行
}
} else {
double x = (h1 - h2) / (k2 - k1);
double y = k1 * x + h1;
pointf = SWPointCutMake(x,y);
if (isPointOnLine(x, y, a, b) == 1 && isPointOnLine(x, y, c, d) == 1) {//焦点在线段上
edgePointf = pointf;
}
}
}
if (edgePointf.x > 0 && edgePointf.y > 0) {//有交点
return edgePointf;
} else {//无交点
// // 向量1的坐标:(x1,y1)向量2的坐标:(x2,y2); 则
double tmpDegree = getAngle(dx1, dy1, dx2, dy2);
if ((pointf.x > 0 && pointf.y > 0) && tmpDegree >= 90 && tmpDegree < 180) {
return pointf;
} else if (tmpDegree == 180) {
return b;
} else {
//角度小于阈值进行补点操作
if (tmpDegree <= 90) {
return SWPointCutMake(0,0);
} else {
double rads = SWBetweenLinesrads(b, e, c, e);
double angle = RadianTodegrees(rads);
if (leftLine == 1) {
return SWrotatePoint(b,e,angle/2.f);
} else {
return SWrotatePoint(c,e,angle/2.f);
}
}
}
}
}
int isPointOnLine(double x, double y, SWPointcut start, SWPointcut end) {
if (start.x <= end.x) {
if (x < start.x || x > end.x) return 0;
} else {
if (x < end.x || x > start.x) return 0;
}
if (start.y <= end.y) {
if (y < start.y || y > end.y) return 0;
} else {
if (y < end.y || y > start.y) return 0;
}
return 1;
}
double getAngle(double x1, double y1, double x2, double y2) {
float value = (x1 * x2 + y1 * y2) / (hypot(x1, y1) * hypot(x2, y2)); // 余弦值
if(value < -1) {
value = -1;
}
if(value > 1) {
value = 1;
}
double angle = RadianTodegrees(acos(value)); // 角度
return angle;
}
SWPointcut getSamllAngleVertex(SWPointcut b, SWPointcut c,double cosAngle) {
double dx = c.x - b.x;
double dy = c.y - b.y;
// double disBC = Math.hypot(dx, dy);
// double betweenP = Math.cos((45f / 180f) * Math.PI) * disBC;
double ratio = (double) cos((cosAngle / 180.f) * M_PI);
SWPointcut betweenP = SWPointCutMake(b.x + dx * ratio, b.y + dy * ratio);
SWPointcut anglePointf = calcNewPoint(betweenP, b, (cosAngle / 180.f) * M_PI);
return anglePointf;
}
SWPointcut SWExtendPoint(SWPointcut a, SWPointcut b, SWPointcut c,SWPointcut d) {
SWPointcut point = {0,0};
double k1 = 0;
double k2 = 0;
int k1Vaild = 0;
int k2Vaild = 0;
double b1 = 0;
double b2 = 0;
if (b.x != a.x) {
k1 = (b.y - a.y)/(b.x - a.x);
k1Vaild = 1;
}
if (d.x != c.x) {
k2 = (d.y - c.y)/(d.x - c.x);
k2Vaild = 1;
}
if ( (k1Vaild == k2Vaild) && k1 == k2) {
return point;
}
if (k1Vaild == 1) {
b1 = (b.x*a.y - a.x*b.y)/(b.x - a.x);
}
if (k2Vaild == 1) {
b2 = (d.x*c.y - c.x*d.y)/(d.x - c.x);
}
if (k1Vaild == 0) {
point.x = a.x;
point.y = k2 * point.x + b2;
} else if (k2Vaild == 0) {
point.x = c.x;
point.y = k1 *point.x + b1;
} else if (k1 == 0) {
point.x = (a.y - b2)/k2;
point.y = a.y;
} else if (k2 == 0) {
point.x = (c.y - b1)/k1;
point.y = c.y;
} else {
point.x = (double)((b2 - b1) / (k1 - k2));
point.y = (double)((k2 * b1 - k1 * b2) / (k2 - k1));
}
return point;
}
double GetPointDistance(SWPosPoint start, SWPosPoint end) {
return sqrtf(pow((start.realPoint.x - end.realPoint.x), 2) + pow((start.realPoint.y - end.realPoint.y), 2))/1.f;
}
SWPointcut SWPointCutMake(double x,double y) {
SWPointcut pointCut = {x,y};
return pointCut;
}
SWPosPoint SWPosPointMake(double x,double y,double radius) {
SWPosPoint posPoint = {{x,y},radius};
return posPoint;
}
SWPointcut calcNewPoint(SWPointcut p, SWPointcut pCenter, double theta) {
double cosv = (double) cos(theta);
double sinv = (double) sin(theta);
// calc new point
double newX = (p.x - pCenter.x) * cosv - (p.y - pCenter.y) * sinv + pCenter.x;
double newY = (p.x - pCenter.x) * sinv + (p.y - pCenter.y) * cosv + pCenter.y;
return SWPointCutMake(newX, newY);
}
SWLineSegment SWLineMake(double x1,double y1,double x2, double y2) {
// SWLineSegment linePoint = {{x1,y1},{x2,y2},SWPosRetSuccess,NULL};
SWLineSegment linePoint;
// linePoint.startPoint = {x1,y1};
linePoint.startPoint.x = x1;
linePoint.startPoint.y = y1;
// linePoint.endPoint = {x2,y2};
linePoint.endPoint.x = x2;
linePoint.endPoint.y = y2;
linePoint.status = SWPosRetSuccess;
return linePoint;
}
SWLineSegment SWLineMakeZero(void) {
// SWLineSegment linePoint = {{0,0},{0,0},SWPosRetFail,NULL};
SWLineSegment linePoint;
// linePoint.startPoint = {0,0};
linePoint.startPoint.x = 0;
linePoint.startPoint.y = 0;
// linePoint.endPoint = {0,0};
linePoint.endPoint.x = 0;
linePoint.endPoint.y = 0;
linePoint.status = SWPosRetFail;
return linePoint;
}
double SWBetweenLinesrads(SWPointcut line1Start, SWPointcut line1End, SWPointcut line2Start, SWPointcut line2End) {
double a = line1End.x - line1Start.x;
double b = line1End.y - line1Start.y;
double c = line2End.x - line2Start.x;
double d = line2End.y - line2Start.y;
float value = ((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d)));
if(value < -1) {
value = -1;
}
if(value > 1) {
value = 1;
}
float rads = acos(value);
return rads;
}
double CalculatePointradius(double speed,double prevPointradius,
double radius,double force ,double maxForce,
double stressSpl,int forceEnable,
double distance) {
if (speed > MaxPoints) {
speed = MaxPoints;
}
if (forceEnable == 1) {
double forceScale = force/maxForce;
forceScale = forceScale * (1 + stressSpl);
double newRadius = radius*forceScale;
double dropSize = newRadius - prevPointradius ;
if (dropSize > prevPointradius *MaxSteps) {
dropSize = prevPointradius *MaxSteps;
}
if (dropSize < - prevPointradius *MaxSteps) {
dropSize = - prevPointradius *MaxSteps;
}
newRadius = prevPointradius + dropSize;
newRadius = newRadius > MaxWidthScale*radius ? MaxWidthScale*radius : newRadius;
if(newRadius < 0.7f) {
newRadius = 0.7f;
}
return newRadius;
} else {
double speedScale = MaxPoints/MaxSegment;
double fragments = speed/speedScale;
double radiusScale = fragments/MaxSegment;
double newRadius = radius - radius*radiusScale;
double dropSize = prevPointradius - newRadius;
if (dropSize > prevPointradius *MaxSteps) {
dropSize = prevPointradius *MaxSteps;
}
if (dropSize < - prevPointradius *MaxSteps) {
dropSize = - prevPointradius *MaxSteps;
}
newRadius = prevPointradius - dropSize;
newRadius = newRadius < MinRadius*radius ? MinRadius*radius : newRadius;
if(newRadius < 0.7f) {
newRadius = 0.7f;
}
return newRadius;
}
}
SWPosPoint *CalculateStroke(SWPosPoint posAry[],int length,double preRadius) {
for (int k = 0; k < length; k ++) {
SWPosPoint pos = posAry[k];
double pointRadius = preRadius /(length - 1);
pos.radius = preRadius - pointRadius*k;
if (pos.radius <= 0.4) {
pos.radius = 0.4f;
}
posAry[k] = pos;
}
return posAry;
}
SWPosStatus CalculateShake(SWPosPoint prePoint,SWPosPoint curPoint,SWPosPoint nextPoint) {
double distance = GetPointDistance(curPoint, nextPoint);
double rads = SWBetweenLinesrads(SWPointCutMake(prePoint.realPoint.x, prePoint.realPoint.y),
SWPointCutMake(curPoint.realPoint.x, curPoint.realPoint.y),
SWPointCutMake(nextPoint.realPoint.x, nextPoint.realPoint.y),
SWPointCutMake(curPoint.realPoint.x, curPoint.realPoint.y));
double angle = RadianTodegrees(rads);
if (angle > MinShake && angle < MaxShake && distance < 1) {
return SWPosRetFail;
}
return SWPosRetFail;
}
SWPosStatus SWPosEqualToPos(SWPosPoint pos1,SWPosPoint pos2) {
if (pos1.realPoint.x == pos2.realPoint.x && pos1.realPoint.y == pos2.realPoint.y) {
return SWPosRetSuccess;
} else {
return SWPosRetFail;
}
}
SWPosPoint SWPosPointMakeZero(void) {
return SWPosPointMake(0, 0, 0);
}
SWPointcut ExPandLine(SWPointcut pt1,SWPointcut pt2,double nLen)
{
SWPointcut OutPt = SWPointCutMake(0, 0);
if (pt1.x - pt2.x == 0)
{
OutPt.x = pt1.x;
if (pt1.y - pt2.y > 0)
{
OutPt.y = pt2.y - nLen;
}
else
{
OutPt.y = pt2.y + nLen;
}
}
else if (pt1.y - pt2.y == 0)
{
OutPt.y = pt1.y;
if (pt1.x - pt2.x > 0)
{
OutPt.x = pt2.x - nLen;
}
else
{
OutPt.x = pt2.x + nLen;
}
}
else
{
double k = 0.0;
double b = 0.0;
k = (pt1.y - pt2.y)/(pt1.x-pt2.x);
b = pt1.y - k * pt1.x;
double zoom = 0.0;
zoom = nLen/sqrt((pt2.x-pt1.x)*(pt2.x-pt1.x)+(pt2.y-pt1.y)*(pt2.y-pt1.y));
if(k > 0)
{
if (pt1.x-pt2.x > 0)
{
OutPt.x = pt2.x - zoom * (pt1.x-pt2.x);
OutPt.y = k*OutPt.x + b;
}
else
{
OutPt.x = pt2.x + zoom * (pt2.x-pt1.x);
OutPt.y = k*OutPt.x + b;
}
}
else
{
if (pt1.x-pt2.x > 0)
{
OutPt.x = pt2.x - zoom * (pt1.x-pt2.x) ;
OutPt.y = k*OutPt.x + b;
}
else
{
OutPt.x = pt2.x + zoom * (pt2.x - pt1.x);
OutPt.y = k*OutPt.x + b;
}
}
}
return OutPt;
}
SWCirclePoint SWCircleMake(SWPosPoint center) {
double radian = 2*M_PI/4.f;
double cosa = cos(radian);
double sina = sin(radian);
double h = center.radius*(4*(1 - cos(radian/2.f)))/(3*sin(radian/2.f));
SWPointcut pointA = SWPointCutMake(center.radius + center.realPoint.x, center.realPoint.y);
SWPointcut pointB = SWPointCutMake(center.radius + center.realPoint.x, center.realPoint.y - h);
SWPointcut pointC = SWPointCutMake(center.radius*cosa + h*sina + center.realPoint.x, center.realPoint.y - (center.radius*sina - h*cosa));
SWPointcut pointD = SWPointCutMake(center.realPoint.x,center.realPoint.y - center.radius);
SWPointcut pointE = SWPointCutMake(center.realPoint.x - (center.radius*cosa + h*sina), pointC.y);
SWPointcut pointF = SWPointCutMake(center.realPoint.x - center.radius, pointB.y);
SWPointcut pointG = SWPointCutMake(center.realPoint.x - center.radius, center.realPoint.y);
SWPointcut pointH = SWPointCutMake(pointF.x, center.realPoint.y + h);
SWPointcut pointI = SWPointCutMake(pointE.x, center.realPoint.y + (center.radius*sina - h*cosa));
SWPointcut pointJ = SWPointCutMake(center.realPoint.x, center.realPoint.y + center.radius);
SWPointcut pointK = SWPointCutMake(pointC.x, pointI.y);
SWPointcut pointL = SWPointCutMake(pointB.x, pointH.y);
SWPointcut pointM = SWPointCutMake(center.radius + center.realPoint.x, center.realPoint.y);
SWCirclePoint cPoint = {pointA,pointB,pointC,pointD,pointE,pointF,pointG,pointH,pointI,pointJ,pointK,pointL,pointM};
return cPoint;
}

@ -0,0 +1,327 @@
//
// SWPosPointcut.h
// DrawTest
//
// Created by 王阳阳 on 2022/9/6.
//
#ifndef SWPosPointcut_h
#define SWPosPointcut_h
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <QList>
enum SWPosStatus {
SWPosRetFail = 0,
SWPosRetSuccess = 1,
};
typedef enum SWPosStatus SWPosStatus;
struct SWPointcut {
double x;
double y;
};
typedef struct SWPointcut SWPointcut;
struct SWPosPoint {
SWPointcut realPoint;
double radius;
};
typedef struct SWPosPoint SWPosPoint;
struct SWLineSegment {
SWPointcut startPoint;
SWPointcut endPoint;
SWPosStatus status;
void *preSegment;
SWLineSegment()
{
preSegment = nullptr;
}
};
typedef struct SWLineSegment SWLineSegment;
/**
*
* @brief The SWCirclePoint struct
*/
struct SWCirclePoint {
SWPointcut pointA;
SWPointcut pointB;
SWPointcut pointC;
SWPointcut pointD;
SWPointcut pointE;
SWPointcut pointF;
SWPointcut pointG;
SWPointcut pointH;
SWPointcut pointI;
SWPointcut pointJ;
SWPointcut pointK;
SWPointcut pointL;
SWPointcut pointM;
};
typedef struct SWCirclePoint SWCirclePoint;
struct SWPosRet {
SWPointcut prevLeftPoint;//左侧切点
SWPointcut prevLeftIntersectPoint;//左侧切点交点
SWPointcut prevRightPoint;//右侧切点
SWPointcut prevRightIntersectPoint;//右侧切点交点
SWPointcut curLeftPoint;//当前点左侧切点
SWPointcut curRightPoint;//当前点右侧切点
QList<SWCirclePoint> circlePoints;//补点数据
int circleCount;//补点数量
SWPosStatus status;//计算结果状态
};
typedef struct SWPosRet SWPosRet;
/**
*
* @brief SWPosRest
* @param pos
*/
void SWPosRest(SWPosPoint pos);
/**
*
* @brief SWGetTangentcurPoint
* @param prevPoint
* @param curPoint
* @param leftLine 线
* @param rightLine 线
* @param circle 1 true 0 false
* @return
*/
SWPosRet SWGetTangentcurPoint(SWPosPoint prevPoint,SWPosPoint curPoint,SWLineSegment leftLine,SWLineSegment rightLine,int circle);
/**
*
* @brief GetPointDistance
* @param start
* @param end
* @return
*/
double GetPointDistance(SWPosPoint start, SWPosPoint end);
/**
* 线
* @brief SWratioPoint
* @param startPoint 线
* @param endPoint 线
* @param ratio 线
* @return
*/
SWPointcut SWratioPoint(SWPointcut startPoint, SWPointcut endPoint, double ratio);
/**
*
* @brief SWrotatePoint
* @param point
* @param center
* @param angle ()
* @return
*/
SWPointcut SWrotatePoint(SWPointcut point, SWPointcut center, double angle);
/**
* 线(线)
* @brief SWgetEdgePoint
* @param a 线
* @param b 线
* @param c 线
* @param d 线
* @param e
* @param directionLine 线(1线0线)
* @return
*/
SWPointcut SWgetEdgePoint(SWPointcut a, SWPointcut b, SWPointcut c,
SWPointcut d,SWPointcut e,int directionLine);
/**
* 线
* @brief SWLineMakeZero
* @return
*/
SWLineSegment SWLineMakeZero(void);
/**
*
* @brief SWPosPointMakeZero
* @return
*/
SWPosPoint SWPosPointMakeZero(void);
/**
* 线
* @brief SWLineMake
* @param x1
* @param y1
* @param x2
* @param y2
* @return
*/
SWLineSegment SWLineMake(double x1,double y1,double x2, double y2);
/**
*
* @brief SWPointCutMake
* @param x
* @param y
* @return
*/
SWPointcut SWPointCutMake(double x,double y);
/**
*
* @brief SWPosPointMake
* @param x
* @param y
* @param radius
* @return
*/
SWPosPoint SWPosPointMake(double x,double y,double radius);
/**
* 线线
* @brief SWExtendPoint
* @param a 线
* @param b 线
* @param c 线
* @param d 线
* @return
*/
SWPointcut SWExtendPoint(SWPointcut a, SWPointcut b, SWPointcut c,SWPointcut d);
/**
* 线(线)
* @brief SWBetweenLinesrads
* @param line1Start 线
* @param line1End 线
* @param line2Start 线
* @param line2End 线
* @return
*/\
double SWBetweenLinesrads(SWPointcut line1Start, SWPointcut line1End,
SWPointcut line2Start, SWPointcut line2End);
/**
*
* @brief CalculatePointradius
* @param speed
* @param prevPointradius
* @param radius
* @param force
* @param maxForce
* @param stressSpl
* @param forceEnable 10
* @param distance
* @return
*/
double CalculatePointradius(double speed,double prevPointradius,double radius,
double force ,double maxForce,double stressSpl,
int forceEnable,double distance);
/**
*
* @brief CalculateStroke
* @param posAry 线
* @param length
* @param preRadius
* @return
*/
SWPosPoint * CalculateStroke(SWPosPoint posAry[],int length,double preRadius);
/**
*
* @brief CalculateShake
* @param prePoint
* @param curPoint
* @param nextPoint
* @return
*/
SWPosStatus CalculateShake(SWPosPoint prePoint,SWPosPoint curPoint,SWPosPoint nextPoint);
/**
*
* @brief SWPosEqualToPos
* @param pos1
* @param pos2
* @return
*/
SWPosStatus SWPosEqualToPos(SWPosPoint pos1,SWPosPoint pos2);
SWPointcut GetMaleTangentPointValue(SWPosPoint point, double a);
/**
*/
SWPosStatus IsPointInMatrix(SWPointcut p1 ,SWPointcut p2,SWPointcut p3 ,SWPointcut p4,SWPointcut p);
double GetCross(SWPointcut p1, SWPointcut p2,SWPointcut p);
SWPointcut ExPandLine(SWPointcut pt1,SWPointcut pt2,double nLen);
/**
线
*/
SWCirclePoint SWCircleMake(SWPosPoint center);
double getAngle(double x1, double y1, double x2, double y2);
SWPointcut getSamllAngleVertex(SWPointcut b, SWPointcut c,double cosAngle);
SWPointcut calcNewPoint(SWPointcut p, SWPointcut pCenter, double theta);
/**
* 线
* @brief getCircleSegments
* @param prevPoint
* @param curPoint
* @param leftLine
* @param rightLine
* @param distance
* @param step
* @return
*/
SWPosRet getCircleSegments(SWPosPoint prevPoint,SWPosPoint curPoint,
SWLineSegment leftLine,SWLineSegment rightLine,
double distance,int step);
int isPointOnLine(double x, double y, SWPointcut start, SWPointcut end);
/**
*
* @brief fillPoints
* @param prevPoint
* @param curPoint
* @param distance
* @return
*/
QList<SWPosPoint> fillPoints(SWPosPoint prevPoint,SWPosPoint curPoint,double distance);
#endif /* SWPosPointcut_h */

@ -0,0 +1,52 @@
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
SWPosPointcut.cpp \
main.cpp \
mainwindow.cpp \
signpaintercachethread.cpp \
signpaintercachethread_linux.cpp \
signpenpainter.cpp \
signutils.cpp \
sw_log.cpp \
wintab/Utils.cpp
HEADERS += \
SWPosPointcut.h \
mainwindow.h \
signpaintercachethread.h \
signpaintercachethread_linux.h \
signpenpainter.h \
signpenstructs.h \
signutils.h \
sw_log.h \
wintab/Utils.h \
wintab/WINTAB.H
FORMS += \
mainwindow.ui
LIBS+= -lUser32
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
SignPenAppTablet.qrc

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/qt">
<file>etc/qt.conf</file>
</qresource>
</RCC>

@ -0,0 +1,2 @@
[Platforms]
WindowsArguments = dpiawareness=0

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

@ -0,0 +1,507 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QPainter>
#include <QMouseEvent>
#ifdef Q_OS_WIN32
#include <Windows.h>
#include <windowsx.h>
#include <tchar.h>
#include "wintab/WINTAB.H"
#include "wintab/Utils.h"
#include "Dbt.h"
#include "devguid.h"
#endif
#include "signpenpainter.h"
//#include <chrono>
using namespace std;
//inline long long vk_timestamp()
//{
// return chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now().time_since_epoch()).count();
//}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pImage = nullptr;
m_pPainter = nullptr;//后台绘图器
m_wintab_handle = 0;
m_mouse_pressed = false;
isUsedMouse = false;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
isUsedInk = false;
ui->checkBox_ink->setVisible(false);
#else
ui->checkBox_ink->setVisible(false);
#endif
ui->plainTextEdit->setVisible(true);
ResetBufferImage();
//动态加载Wintab库
if(!LoadWintab())
{
QMessageBox::warning(nullptr,"Load Wintab","加载Wintab32.dll失败");
}
else
{
gpWTInfoW(0, 0, NULL);
// AXIS axis{0};
AXIS axis;
// //获取x范围
// gpWTInfoW(WTI_DEVICES,DVC_X,&axis);
// m_tablet_ctx.max_x = axis.axMax;
// //获取y范围
// memset(&axis,0,sizeof(AXIS));
// gpWTInfoW(WTI_DEVICES,DVC_Y,&axis);
// m_tablet_ctx.max_y = axis.axMax;
//获取压力范围
memset(&axis,0,sizeof(AXIS));
gpWTInfoW(WTI_DEVICES,DVC_NPRESSURE,&axis);
m_tablet_ctx.max_p = axis.axMax;
// LOGCONTEXTW wintab_ctx{};
LOGCONTEXTW wintab_ctx;
gpWTInfoW(WTI_DEFCONTEXT, 0, &wintab_ctx);
//关心的数据项x y 压力
wintab_ctx.lcPktData = PK_X |PK_Y |PK_NORMAL_PRESSURE;
wintab_ctx.lcOptions = CXO_MESSAGES | CXO_CSRMESSAGES;
//设置Wintab的输出坐标范围 = 数位板设备的逻辑范围
//默认情况下lcOutExtX lcOutExtY 为系统桌面大小
//wintab_ctx.lcOutExtX = wintab_ctx.lcInExtX;
// wintab_ctx.lcOutExtY =wintab_ctx.lcInExtY*-1;
wintab_ctx.lcOutExtY *=-1;
//Wintab返回的系统桌面区域wintab_ctx.lcSysExtX wintab_ctx.lcSysExtY 受系统显示缩放影响
//同时受调用进程的DPI感知特性影响
m_tablet_ctx.sys_x = wintab_ctx.lcSysOrgX;
m_tablet_ctx.sys_y = wintab_ctx.lcSysOrgY;
m_tablet_ctx.sys_w = wintab_ctx.lcSysExtX;
m_tablet_ctx.sys_h = wintab_ctx.lcSysExtY;
//lcInExtX lcInExtY 为设备的输入最大范围
m_tablet_ctx.max_x = wintab_ctx.lcOutExtX;
m_tablet_ctx.max_y = qAbs(wintab_ctx.lcOutExtY);
HWND hwnd = (HWND)this->winId();
m_wintab_handle = (unsigned int)gpWTOpenW((HWND)this->winId(),&wintab_ctx,TRUE);
}
m_SignPenpainter = new SignPenPainter;
m_SignPenpainter->SetPainterRect(this->rect());
penRadius = 1.7;
connect(m_SignPenpainter,SIGNAL(NeedsDisplay(QRect)),this,SLOT(NeedToUpdate(QRect)));
// connect(m_SignPenpainter,SIGNAL(log(QString)),this,SLOT(log(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
if(QString(eventType)=="windows_generic_MSG")
{
PMSG msg = static_cast<PMSG>(message);
switch(msg->message)
{
case WT_CTXOPEN:
{
qDebug()<<"Tablet wintab open."<<endl;
}break;
case WT_CTXCLOSE:
{
qDebug()<<"Tablet wintab close."<<endl;
}break;
case WT_PROXIMITY:
{
qDebug()<<"Tablet pen proximity event="<<(msg->lParam&0x01?"enter":"leave")<<endl;
}break;
case WT_PACKET:
{
//qDebug()<<"Tablet wintab packet."<<endl;
unsigned char buf[256]{0};
HCTX hctx = (HCTX)msg->lParam;
DWORD num = msg->wParam;
if(gpWTPacket(hctx,num,buf))
{
unsigned x = *(unsigned*)&buf[0];
unsigned y = *(unsigned*)&buf[4];
unsigned p = *(unsigned*)&buf[8];
// qDebug()<<"x:"<<x<<" y:"<<y<<" pressure:"<<p<<endl;
//
TabletDataPacket pkt;
pkt.x = x;
pkt.y = y;
pkt.p = p;
DrawSign_Wintab(pkt);
}
}break;
case WM_POINTERUPDATE:
{
//获取系统指针ID
UINT32 pointerId = GET_POINTERID_WPARAM(msg->wParam);
//获取系统指针设备类型
POINTER_INPUT_TYPE pointerType = PT_POINTER;
if(GetPointerType(pointerId,&pointerType))
{
//判断当前系统指针是否是为笔设备
if(pointerType==PT_PEN)
{
POINTER_PEN_INFO ppi{};
//获取与数字笔相关的信息
if(GetPointerPenInfo(pointerId,&ppi))
{
//获取桌面坐标和笔压力
int x = GET_X_LPARAM(msg->lParam);
int y = GET_Y_LPARAM(msg->lParam);
int pressure = ppi.pressure*8; //统一转化为8192级压力
\
//通常绘图软件会使用Wintab/Windows Ink其中一种进行绘图取决于系统环境支持和绘图软件设计
//Windows Ink的返回坐标与鼠标的全局坐标一致不关心屏幕摆放位置只要光标能到
//**注意:手写板/手写屏在未安装驱动的情况下,光标默认到不了扩展屏幕,通常是由驱动控制到达扩展屏幕或通过系统设置映射到扩展屏。
DrawSign_Ink(x,y,pressure);
//qDebug()<<"ink x:"<<x<<" y:"<<y << " pressure:"<<pressure<<endl;
}
}
}
}break;
}
}
return false;
}
#else
bool MainWindow::winEvent(MSG *message, long *result)
{
// if(QString(eventType)=="windows_generic_MSG")
// {
PMSG msg = static_cast<PMSG>(message);
switch(msg->message)
{
case WT_CTXOPEN:
{
qDebug()<<"Tablet wintab open."<<endl;
}break;
case WT_CTXCLOSE:
{
qDebug()<<"Tablet wintab close."<<endl;
}break;
case WT_PROXIMITY:
{
qDebug()<<"Tablet pen proximity event="<<(msg->lParam&0x01?"enter":"leave")<<endl;
}break;
case WT_PACKET:
{
qDebug()<<"Tablet wintab packet."<<endl;
unsigned char buf[256] = {0};
HCTX hctx = (HCTX)msg->lParam;
DWORD num = msg->wParam;
if(gpWTPacket(hctx,num,buf))
{
unsigned x = *(unsigned*)&buf[0];
unsigned y = *(unsigned*)&buf[4];
unsigned p = *(unsigned*)&buf[8];
// qDebug()<<"x:"<<x<<" y:"<<y<<" pressure:"<<p<<endl;
//
TabletDataPacket pkt;
pkt.x = x;
pkt.y = y;
pkt.p = p;
DrawSign_Wintab(pkt);
}
}break;
// case WM_POINTERUPDATE:
// {
// //获取系统指针ID
// UINT32 pointerId = GET_POINTERID_WPARAM(msg->wParam);
// //获取系统指针设备类型
// POINTER_INPUT_TYPE pointerType = PT_POINTER;
// if(GetPointerType(pointerId,&pointerType))
// {
// //判断当前系统指针是否是为笔设备
// if(pointerType==PT_PEN)
// {
// POINTER_PEN_INFO ppi{};
// //获取与数字笔相关的信息
// if(GetPointerPenInfo(pointerId,&ppi))
// {
// //获取桌面坐标和笔压力
// int x = GET_X_LPARAM(msg->lParam);
// int y = GET_Y_LPARAM(msg->lParam);
// int pressure = ppi.pressure*8; //统一转化为8192级压力
// \
// //通常绘图软件会使用Wintab/Windows Ink其中一种进行绘图取决于系统环境支持和绘图软件设计
// //Windows Ink的返回坐标与鼠标的全局坐标一致不关心屏幕摆放位置只要光标能到
// //**注意:手写板/手写屏在未安装驱动的情况下,光标默认到不了扩展屏幕,通常是由驱动控制到达扩展屏幕或通过系统设置映射到扩展屏。
// // DrawSign_Ink(x,y,pressure);
// //qDebug()<<"ink x:"<<x<<" y:"<<y << " pressure:"<<pressure<<endl;
// }
// }
// }
// }break;
}
// }
return false;
}
#endif
void MainWindow::on_pushButton_clicked()
{
m_SignPenpainter->ClearDraw();
ui->plainTextEdit->clear();
update();
}
void MainWindow::NeedToUpdate(QRect rect)
{
// this->update(QRect(0,0,120,120));
this->update(rect);
}
void MainWindow::paintEvent(QPaintEvent *event)
{
// QPainter painter(this);
// painter.setRenderHints(QPainter::SmoothPixmapTransform
// |QPainter::TextAntialiasing |QPainter::HighQualityAntialiasing);
// if(m_pImage)
// painter.drawImage(rect(),*m_pImage,m_pImage->rect());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
m_SignPenpainter->DrawRect(&painter,this->rect());
QWidget::paintEvent(event);
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
ResetBufferImage();
QMainWindow::resizeEvent(event);
m_SignPenpainter->SetPainterRect(this->rect());
m_SignPenpainter->SetPenType(1);
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
// qDebug() << __FUNCTION__ << event->pos();
if(!isUsedMouse)
return;
QPoint pt1 = event->pos();
QPoint p2 = mapToGlobal(pt1);
m_mouse_pressed = false;
m_SignPenpainter->SetStressSwitch(false);
m_SignPenpainter->MousePressed(event->pos(),penRadius * 1.3,10,10);
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
// qDebug() << __FUNCTION__ << event->pos();
if(!isUsedMouse)
return;
QString msg = QString("use ink. pos: %1 %2").arg(event->pos().x()).arg(event->pos().y());
ui->plainTextEdit->appendPlainText(msg);
ui->plainTextEdit->appendPlainText("use mouse.");
m_SignPenpainter->SetStressSwitch(false);
m_SignPenpainter->MouseMoved(event->pos(),penRadius * 1.3,10,10);
}
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
// qDebug() << __FUNCTION__ << event->pos();
if(!isUsedMouse)
return;
m_mouse_pressed = true;
m_SignPenpainter->MouseReleased(event->pos(),penRadius);
m_SignPenpainter->SetStressSwitch(false);
}
void MainWindow::ResetBufferImage()
{
int w = width();
int h = height();
if(w<0 || h<0)
return;
if(m_pPainter!=nullptr)
{
delete m_pPainter;
}
if(m_pImage!=nullptr)
{
delete m_pImage;
}
//重新创建新的后台缓冲图像对象
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
m_pImage = new QImage(w,h,QImage::Format_RGBA8888);
#else
m_pImage = new QImage(w,h,QImage::Format_ARGB32_Premultiplied);
#endif
m_pImage->fill(Qt::transparent);
//重新创建新的绘图器
m_pPainter = new QPainter(m_pImage);
m_pPainter->setRenderHints(QPainter::SmoothPixmapTransform
|QPainter::TextAntialiasing |QPainter::HighQualityAntialiasing);
}
void MainWindow::DrawSign_Base(int x, int y, int p,bool is_ink)
{
if(isUsedMouse)
return;
if(m_pImage==nullptr )
return;
if(m_tablet_ctx.max_x==0 || m_tablet_ctx.sys_w==0)
return ;
static QPoint last_pt(0,0);
static unsigned last_pressure = 0;
static bool down = false;
//接触时第一个点只保存不画
if(last_pressure==0 && p>0)
{
down = true;
last_pressure = p;
last_pt = QPoint(x,y);
MousePressed(last_pt,p,m_tablet_ctx.max_p,true);
return;
}
//离开时
if(last_pressure>0 && p==0)
{
last_pressure = 0;
MouseReleased(last_pt);
//抬笔时强制更新
update();
down = false;
return;
}
if(p==0)
{
return;
}
int ps = 6; //笔宽
int pw = (int)(ps*(p*1.0/m_tablet_ctx.max_p)+0.5);
QPen pen(is_ink?Qt::blue:Qt::red,pw,Qt::SolidLine);
pen.setCapStyle(Qt::RoundCap);
m_pPainter->setPen(pen);
QPoint cur_pt(x,y);
// m_pPainter->drawLine(last_pt, cur_pt);
MouseMoved(cur_pt,p,m_tablet_ctx.max_p,true);
//todo 刷新机制
// static long long t1 = vk_timestamp();
// long long t2 = vk_timestamp();
// if(t2-t1>33)
// {
// //FPS=30
// update();
// t1 = t2;
// }
update();
last_pressure = p;
//保存当前点
last_pt = cur_pt;
}
void MainWindow::DrawSign_Wintab(const TabletDataPacket &pkt)
{
if(isUsedMouse)
return;
qDebug() << __FUNCTION__ << "wintab.";
ui->plainTextEdit->appendPlainText("wintab.");
//计算Wintab坐标--->全局桌面屏幕坐标
//当扩展屏幕摆放在左边时系统起始坐标为负加上系统原始点得到正确的桌面坐标dx dy
double dx = (pkt.x*1.0/m_tablet_ctx.max_x)*m_tablet_ctx.sys_w+m_tablet_ctx.sys_x;
double dy = (pkt.y*1.0/m_tablet_ctx.max_y)*m_tablet_ctx.sys_h+m_tablet_ctx.sys_y;
QPoint wpt = mapFromGlobal(QPoint(dx,dy));
DrawSign_Base(wpt.x(),wpt.y(),pkt.p,false);
qDebug()<< __FUNCTION__ << "pkt.x:"<<pkt.x<<" pkt.y"<<pkt.y<<" dx:"<<dx<<"dy:"<<dy<<"wx:"<<wpt.x()<<" wy:"<<wpt.y()<<endl;
}
void MainWindow::DrawSign_Ink(int ink_x, int ink_y, int ink_p)
{
if(isUsedMouse)
return;
qDebug() << __FUNCTION__ << "ink.";
QString msg = QString("use ink. pos: %1 %2 press: %3").arg(ink_x).arg(ink_y).arg(ink_p);
ui->plainTextEdit->appendPlainText(msg);
QPoint pt = mapFromGlobal(QPoint(ink_x,ink_y));
DrawSign_Base(pt.x(),pt.y(),ink_p,true);
}
void MainWindow::MousePressed(QPointF currentPoint, double force, double maxForce,bool isStressSwitch)
{
m_SignPenpainter->SetStressSwitch(isStressSwitch);
m_SignPenpainter->MousePressed(currentPoint,penRadius * 1.3,force,maxForce);
}
void MainWindow::MouseMoved(QPointF currentPoint, double force, double maxForce,bool isStressSwitch)
{
m_SignPenpainter->SetStressSwitch(isStressSwitch);
m_SignPenpainter->MouseMoved(currentPoint,penRadius * 1.3,force,maxForce);
}
void MainWindow::MouseReleased(QPointF currentPoint)
{
m_SignPenpainter->MouseReleased(currentPoint,penRadius);
m_SignPenpainter->SetStressSwitch(false);
}
void MainWindow::on_checkBox_stateChanged(int arg1)
{
if(ui->checkBox->isChecked())
isUsedMouse = true;
else
isUsedMouse = false;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
isUsedInk = ui->checkBox_ink->isChecked();
#endif
}

@ -0,0 +1,97 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
struct TabletContext
{
int max_x;
int max_y;
int max_p;
int sys_x;
int sys_y;
int sys_w;
int sys_h;
};
struct TabletDataPacket
{
unsigned int x; //Wintab X
unsigned int y; //Wintab Y
unsigned int p; //压力
};
class QImage;
class SignPenPainter;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void on_pushButton_clicked();
void NeedToUpdate(QRect rect);
protected:
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
virtual bool nativeEvent(const QByteArray &eventType, void *message, long *result);
#else
virtual bool winEvent(MSG *message, long *result);
#endif
virtual void paintEvent(QPaintEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
private slots:
void on_checkBox_stateChanged(int arg1);
private:
//初始化后台缓冲区
void ResetBufferImage();
//绘制笔迹
void DrawSign_Base(int x,int y,int p,bool is_ink=false);
void DrawSign_Wintab(const TabletDataPacket &pkt);
void DrawSign_Ink(int ink_x,int ink_y,int ink_p);
void MousePressed(QPointF currentPoint,double force,double maxForce,bool isStressSwitch);//force 压感力度
void MouseMoved(QPointF currentPoint,double force,double maxForce,bool isStressSwitch);
void MouseReleased(QPointF currentPoint);
private:
Ui::MainWindow *ui;
// QImage *m_pImage{nullptr};
// QPainter *m_pPainter{nullptr};//后台绘图器
// TabletContext m_tablet_ctx{0};
// unsigned int m_wintab_handle{0};
// bool m_mouse_pressed{false};
QImage *m_pImage;
QPainter *m_pPainter;//后台绘图器
TabletContext m_tablet_ctx;
unsigned int m_wintab_handle;
bool m_mouse_pressed;
// QList<TabletDataPacket> m_list_buffer;
SignPenPainter* m_SignPenpainter;
float penRadius;
bool isUsedMouse;
bool isUsedInk;
};
#endif // MAINWINDOW_H

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1279</width>
<height>787</height>
</rect>
</property>
<property name="tabletTracking">
<bool>false</bool>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="geometry">
<rect>
<x>20</x>
<y>590</y>
<width>1241</width>
<height>181</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>30</x>
<y>10</y>
<width>80</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>清空</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>180</x>
<y>10</y>
<width>181</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>是否使用鼠标</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_ink">
<property name="geometry">
<rect>
<x>330</x>
<y>10</y>
<width>171</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>是否使用ink</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,125 @@
#ifndef SIGNPAINTERCACHETHREAD_H
#define SIGNPAINTERCACHETHREAD_H
#include <QObject>
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <QImage>
#include <QColor>
#include "signpenstructs.h"
class SignPainterCacheThread : public QThread
{
Q_OBJECT
public:
SignPainterCacheThread();
void SetPainterRect(QRect rect);
void SetCurrentPageIndex(int page){currentPageIndex = page;}
void AddPoint(QPointF currPoint,int type,float radius,double force,double maxForce);
void Paint(QPainter* painter,QRect currentVisibleRect);
void ClearDraw();
QList<SWAnnotPath*> GetAnnotPathLists(){return drawPaths;}
void SetStressSwitch(bool isStressSwitch) { stressSwitch = isStressSwitch; }
bool GetStressSwitch(){return stressSwitch;}
void SetPenType(int type){penType = type;}
void SetPenColor(QColor penColor){m_PenColor = penColor;}
protected:
void run();
private:
void PaintWithPainter(QPainter* painter,QRect currentVisibleRect);
void SwPenSectionPathDraw(QList<SWRealPoint> points,SWRealPoint endRealPoint,int endFlag);
void SwPenSectionPathDrawRightWithBezier(QPainterPath* bPath ,QList<Element>& elementList,CGPoint prevPoint,QList<SWRealPoint> rPoints,
SWRealPoint endRealPoint,int endFlag,bool isEnd,bool isBegin);
void SwPenPathDrawPoint(SWRealPoint point);
QPainterPath SwPenPathDraw(bool isEnd,bool flushSection);
QPainterPath SwPenPathDraw(SWAnnotPath *annotPath,bool isEnd,bool flushSection);
void SwPenPathDrawRightWithBezier(QPainterPath* bPath ,QList<Element>& elementList,SWRealPoint prePenPoint,
CGPoint prevPoint,QList<SWRealPoint> rPoints,bool end,bool isContinue,SWRealPoint lastPoint,bool isBegin);
void SwPenPathDrawLeftPoint(QList<SWRealPoint> points,SWRealPoint endRealPoint);
void SwPenPathDrawRightPoint(QPainterPath *bPath, QList<Element> &elementList,SWRealPoint prePenPoint,
CGPoint prevPoint, QList<SWRealPoint> rPoints,SWRealPoint endRealPoint);
void MouseMoved(const SWRealPoint& realPoint);
void MousePressd(const SWRealPoint& realPoint);
void MouseReleased(const SWRealPoint& realPoint);
void Init();
QPaintDevice *PaintingDevice();
QPaintDevice *PaintedDevice();
void DrawSignPath(QPainter* painter,const QPainterPath &path,bool isEnd);
signals:
void NeedsToRefresh(QRect rect);
void ReleasedExcuted();
private:
QList<SWRealPoint> m_RealPoints;
//原始点的互斥锁
QMutex m_mutex;
QSemaphore m_Sem;
float preLineRadius;
int strokeSpl;
int stressSwitch;//是否开启压感 1开启 0关闭
float stressSpl;
int currentPageIndex;
qint64 previousTimestamp;
float pointSpeed;
SWAnnotPath *curAnnotPath;
qint64 lastPaintTimestamp;
int paintFreq;
//currentAnnot mutex
QMutex m_AnnotMutex;
QList<SWAnnotPath*> drawPaths;
QImage* m_BaseBuf;
//渲染bug基于m_BaseBuf从上一次倒数10个点开始绘制绘制到倒数10个点时数据保存回m_BaseBuf
QImage* m_PaintingBuf;
QSize m_Size;
QRect m_PaintRect;
QRect m_OriRect;//新建画布原始
int m_ScrollH;
int drawStartIndex;
QMutex m_drawMutex;
int drawCount;
int drawCountOffset;
//标记上次计算贝塞尔点
CGPoint preBezierPoint;
bool isPressed;
float m_fPixmapZoom;
int m_fPixmaps;
int penType;//画笔类型1软笔2签字笔
QColor m_PenColor;
qint64 lasttimestamp;
int m_BufZoomWidth;
int m_lastSectionIndex;
SWRealPoint m_lastSectionPoint;
};
#endif // SIGNPAINTERCACHETHREAD_H

File diff suppressed because it is too large Load Diff

@ -0,0 +1,127 @@
#ifndef SIGNPAINTERCACHETHREADLINUX_H
#define SIGNPAINTERCACHETHREADLINUX_H
#include <QObject>
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <QImage>
#include <QColor>
#include "signpenstructs.h"
class SignPainterCacheThread_Linux : public QThread
{
Q_OBJECT
public:
SignPainterCacheThread_Linux();
void SetPainterRect(QRect rect);
void SetCurrentPageIndex(int page){currentPageIndex = page;}
void AddPoint(QPointF currPoint,int type,float radius,double force,double maxForce);
void Paint(QPainter* painter,QRect currentVisibleRect);
void ClearDraw();
QList<SWAnnotPath*> GetAnnotPathLists(){return drawPaths;}
void SetStressSwitch(bool isStressSwitch) { stressSwitch = isStressSwitch; }
bool GetStressSwitch(){return stressSwitch;}
void SetPenType(int type){penType = type;}
void SetPenColor(QColor penColor){m_PenColor = penColor;}
protected:
void run();
private:
void PaintWithPainter(QPainter* painter,QRect currentVisibleRect);
void SwPenSectionPathDraw(QList<SWRealPoint> points,SWRealPoint endRealPoint,int endFlag);
void SwPenSectionPathDrawRightWithBezier(QPainterPath* bPath ,QList<Element>& elementList,CGPoint prevPoint,QList<SWRealPoint> rPoints,
SWRealPoint endRealPoint,int endFlag,bool isEnd,bool isBegin);
void SwPenPathDrawPoint(SWRealPoint point);
QPainterPath SwPenPathDraw(bool isEnd,bool flushSection);
QPainterPath SwPenPathDraw(SWAnnotPath *annotPath,bool isEnd,bool flushSection);
void SwPenPathDrawRightWithBezier(QPainterPath* bPath ,QList<Element>& elementList,SWRealPoint prePenPoint,
CGPoint prevPoint,QList<SWRealPoint> rPoints,bool end,bool isContinue,SWRealPoint lastPoint,bool isBegin);
void SwPenPathDrawLeftPoint(QList<SWRealPoint> points,SWRealPoint endRealPoint);
void SwPenPathDrawRightPoint(QPainterPath *bPath, QList<Element> &elementList,SWRealPoint prePenPoint,
CGPoint prevPoint, QList<SWRealPoint> rPoints,SWRealPoint endRealPoint);
void MouseMoved(const SWRealPoint& realPoint);
void MousePressd(const SWRealPoint& realPoint);
void MouseReleased(const SWRealPoint& realPoint);
void Init();
QPaintDevice *PaintingDevice();
QPaintDevice *PaintedDevice();
void DrawSignPath(QPainter* painter,const QPainterPath &path,bool isEnd);
signals:
void NeedsToRefresh(QRect rect);
void ReleasedExcuted();
private:
QList<SWRealPoint> m_RealPoints;
//原始点的互斥锁
QMutex m_mutex;
QSemaphore m_Sem;
float preLineRadius;
int strokeSpl;
int stressSwitch;//是否开启压感 1开启 0关闭
float stressSpl;
int currentPageIndex;
qint64 previousTimestamp;
float pointSpeed;
SWAnnotPath *curAnnotPath;
qint64 lastPaintTimestamp;
int paintFreq;
//currentAnnot mutex
QMutex m_AnnotMutex;
QList<SWAnnotPath*> drawPaths;
QImage* m_BaseBuf;
//渲染bug基于m_BaseBuf从上一次倒数10个点开始绘制绘制到倒数10个点时数据保存回m_BaseBuf
QImage* m_PaintingBuf;
QSize m_Size;
QRect m_PaintRect;
QRect m_OriRect;//新建画布原始
int m_ScrollH;
int drawStartIndex;
QMutex m_drawMutex;
int drawCount;
int drawCountOffset;
//标记上次计算贝塞尔点
CGPoint preBezierPoint;
bool isPressed;
float m_fPixmapZoom;
int m_fPixmaps;
int penType;//画笔类型1软笔2签字笔
QColor m_PenColor;
qint64 lasttimestamp;
int m_BufZoomWidth;
int m_lastSectionIndex;
SWRealPoint m_lastSectionPoint;
SWRealPoint tempPresspoint;//缓冲的按压点
};
#endif // SIGNPAINTERCACHETHREADLINUX_H

File diff suppressed because it is too large Load Diff

@ -0,0 +1,108 @@
#ifndef SIGNPENPAINTER_H
#define SIGNPENPAINTER_H
#include <QObject>
#include <QPointF>
#include <QPainterPath>
#include "SWPosPointcut.h"
#include "signpenstructs.h"
#define MaxBrushCount 2
#define MinSpeed 300
#define MaxSpeed 400
#define MaxBrush 0.2f
class SignPainterCacheThread;
class SignPainterCacheThread_Linux;
class QPainter;
class SignPenPainter : public QObject
{
Q_OBJECT
public:
SignPenPainter();
~SignPenPainter();
void SetPainterRect(QRect rect);
void SetPenType(int type);
void SetPenColor(QColor penColor);
void SetCurrentPageIndex(int page);
void SetOffSetRect(QRect rect);
void Init();
void ClearDraw();
void DrawRect(QPainter* painter,QRect currentVisibleRect);
void MousePressed(CGPoint currentPoint,float radius,double force,double maxForce);//force 压感力度
void MouseMoved(CGPoint currentPoint,float radius,double force,double maxForce);
void MouseReleased(CGPoint currentPoint,float radius);
void SetUseCache(bool use){ isUseCache = use;}
bool GetUseCache(){return isUseCache;}
void SetUseDebug(bool use){ isOutDebug = use;}
bool GetUseDebug(){return isOutDebug;}
void SetStressSwitch(bool isStressSwitch);
bool GetStressSwitch();//是否使用压感设备
QList<SWAnnotPath*> GetAnnotPathLists();
QList<QPainterPath> GetPenPathData(QPainterPath &data, int pageIndex, QList<Element> penDataList, float factorW = 1.0, float factorH = 1.0, int offsetX = 0, int offsetY = 0);
private:
void SwPenPathDrawWithPainter(QPainter* bufPainter,bool isEnd);
void SwPenPathDraw(bool isEnd);
void SwPenPathDrawRightWithBezier(QPainterPath* bPath ,QList<Element>& elementList,SWRealPoint penPoint,CGPoint prevPoint,QList<SWRealPoint> rPoints,bool end);
bool CGPointEqualToPoint(const CGPoint &point1, const CGPoint &point2);
void CalculatePointcutWihtPoint(CGPoint point, float radius, bool stroke, bool circle);
bool GetPointValid(SWRealPoint penPoint);
CGPoint ConvertToCGPoint(SWPointcut cPoint);
float GetDistanceBetweenPoint(QPointF start, QPointF end);
QPaintDevice *PaintDevice();
void SynToBaseDevice();
signals:
void NeedsDisplay(QRect rect);
void NeedsRefresh();
void ReleasedExcuted();
//记录日志
void log(QString);
private:
QPointF CGPointZero;
int strokeSpl;
float stressSpl;
float penRadius;
SWAnnotPath *curAnnotPath;
QList<SWAnnotPath*> drawPaths;
CGPoint selectPoint;
//标记上次计算贝塞尔点
CGPoint preBezierPoint;
qint64 previousTimestamp;
float pointSpeed;
float preLineRadius;
int stressSwitch;//是否开启压感 1开启 0关闭
QImage* m_BaseBuf;
//渲染bug基于m_BaseBuf从上一次倒数10个点开始绘制绘制到倒数10个点时数据保存回m_BaseBuf
QImage* m_PaintingBuf;
QSize m_Size;
QRect m_PaintRect;
int m_StartIndex;//渲染开始的节点
int SyncCount;// 重新绘制的数据
bool isRelease;
int m_ToImageIndex;//图片后的开始渲染点
int m_FreshCount;//实时渲染的笔画数
#ifdef Q_OS_WIN
SignPainterCacheThread* cacheThread;
#else
SignPainterCacheThread_Linux* cacheThread;
#endif
bool isUseCache;
bool isOutDebug;
};
#endif // SIGNPENPAINTER_H

@ -0,0 +1,122 @@
#ifndef SIGNPENSTRUCTS_H
#define SIGNPENSTRUCTS_H
#include <QObject>
#include <QPointF>
#include <QPainterPath>
#include "SWPosPointcut.h"
typedef QPointF CGPointMake ;
typedef QPointF CGPoint;
struct SWRealPoint
{
CGPoint realPoint; // 原始点
int pointType;//0 moved 1 press 2 releas
double force;
double maxForce;
qint64 timestamp;//当前点的时间戳
float radius;
float finalRadius;
CGPoint pLeftTopPoint;
CGPoint pLeftBottomPoint;
CGPoint PLeftIntersectPoint;
CGPoint pRightTopPoint;
CGPoint pRightBottomPoint;
CGPoint PRightIntersectPoint;
// SWCirclePoint *circlePoints;
QList<SWCirclePoint> circlePoints;
int circleCount;
SWRealPoint()
{
timestamp = -1;
circleCount = 0;
pointType = 2;
force = 10;
maxForce = 10;
radius = 3;
}
};
enum ElementType {
StartFigure,
MoveToElement,
LineToElement,
CurveToElement,
QuadToElement
};
class Element {
public:
Element(ElementType type){
this->type = type;
point = QPointF(0,0);
control = QPointF(0,0);//CurveToElement时的控制点 point为结束点
control2 = QPointF(0,0);}
~Element(){}
ElementType GetElementType(){return type;}
void AddEndPoint(QPointF point){
this->point = point;
x = point.x();
y = point.y();
}
//二阶贝塞尔控制点三阶贝塞尔控制点1, 非CurveToElement和QuadToElement时此点为空
void AddControlPoint(QPointF point){control = point;}
//三阶贝塞尔控制点2,非QuadToElement时此点为空
void AddControlPoint2(QPointF point){control2 = point;}
QPointF GetEndPoint(){return point;}
QPointF GetControlPoint(){return (type == CurveToElement || type == QuadToElement) ? control : QPointF(0,0);}
QPointF GetControlPoint2(){return (type == CurveToElement) ? control2 : QPointF(0,0);}
bool IsMoveTo() const { return type == MoveToElement; }
bool IsLineTo() const { return type == LineToElement; }
bool IsCurveTo() const { return type == CurveToElement; }
bool IsQuadTo() const { return type == QuadToElement; }
operator QPointF () const { return point; }
bool operator==(const Element &e) const { return qFuzzyCompare(x, e.x)
&& qFuzzyCompare(y, e.y) && type == e.type; }
inline bool operator!=(const Element &e) const { return !operator==(e); }
ElementType type;
QPointF point;
QPointF control;//CurveToElement时的控制点 point为结束点
QPointF control2;
private:
qreal x;
qreal y;
// ElementType type;
// QPointF point;
// QPointF control;//CurveToElement时的控制点 point为结束点
// QPointF control2;
};
// 一笔的Path数据抬笔前
struct SWAnnotPath
{
QList<SWRealPoint> points;
QList<SWRealPoint> realPoints;
QList<QPainterPath> bezierPaths; //绘制的Path
QList<QList<QPainterPath> > currentPathsList;
QList<Element> bezierEles; //绘制
bool isShake; //是否防抖
int pageIndex;
bool isEnd;
bool isPainted;//是否已经缓冲绘制
QRect paintRect;//手写时的区域
SWAnnotPath()
{
isShake = false;
isEnd = false;
isPainted = false;
}
};
#endif // SIGNPENSTRUCTS_H

@ -0,0 +1,253 @@
#include "signutils.h"
#include <QtDebug>
#include "sw_log.h"
QPointF CGPointZero = QPointF(0,0);
void CalculatePointcutWihtPoint(SWAnnotPath *curAnnotPath,CGPoint point, float radius, bool stroke, bool circle,qint64 ts)
{
/**
*/
SWRealPoint curPenPoint;
curPenPoint.realPoint = point;
curPenPoint.radius = radius;
curPenPoint.timestamp = ts;
curAnnotPath->points.append(curPenPoint);
int realPointCount = curAnnotPath->points.count();
/**
* 2
*/
if (realPointCount > 3)
{
SWRealPoint penPoint0 = curAnnotPath->points.at(realPointCount - 3);
SWRealPoint penPoint1 = curAnnotPath->points.at(realPointCount - 2);
SWRealPoint penPoint2 = curAnnotPath->points.at(realPointCount - 1);
SWPosStatus ret = CalculateShake(SWPosPointMake(penPoint0.realPoint.x(), penPoint0.realPoint.y(),penPoint0.radius),
SWPosPointMake(penPoint1.realPoint.x(), penPoint1.realPoint.y(),penPoint1.radius),
SWPosPointMake(penPoint2.realPoint.x(), penPoint2.realPoint.y(),penPoint2.radius));
if (ret == SWPosRetSuccess)
{
if (penPoint0.circleCount != 0)
{
penPoint0.circleCount = 0;
penPoint0.circlePoints.clear();
}
penPoint0.pLeftBottomPoint = CGPointZero;
penPoint0.pRightBottomPoint = CGPointZero;
penPoint0.PLeftIntersectPoint = CGPointZero;
penPoint0.PRightIntersectPoint = CGPointZero;
if (curAnnotPath->isShake)
{
/**
*
**/
double distance = GetDistanceBetweenPoint(penPoint0.realPoint,penPoint2.realPoint);
if (distance >= 3) {
curAnnotPath->isShake = false;
} else {
curAnnotPath->points.removeAt(realPointCount - 2);
}
}
else
{
curAnnotPath->points.removeAt(realPointCount - 2);
curAnnotPath->isShake = true;
}
}
else
{
curAnnotPath->isShake = false;
}
}
realPointCount = curAnnotPath->points.count();
if (realPointCount == 2)
{
SWRealPoint penPoint0 = curAnnotPath->points.at(0);
SWRealPoint penPoint1 = curAnnotPath->points.at(1);
SWPosRet ret = SWGetTangentcurPoint(SWPosPointMake(penPoint0.realPoint.x(), penPoint0.realPoint.y(), penPoint0.radius),
SWPosPointMake(penPoint1.realPoint.x(), penPoint1.realPoint.y(), penPoint1.radius),
SWLineMakeZero(), SWLineMakeZero(),circle ? 1 : 0);
if (ret.status == SWPosRetSuccess)
{
if (ret.circleCount > 0)
{
curAnnotPath->points[0].circleCount = ret.circleCount;
curAnnotPath->points[0].circlePoints = ret.circlePoints;
}
else
{
curAnnotPath->points[0].pLeftBottomPoint = CGPointMake(ret.prevLeftPoint.x, ret.prevLeftPoint.y);
curAnnotPath->points[0].pRightBottomPoint = CGPointMake(ret.prevRightPoint.x, ret.prevRightPoint.y);
curAnnotPath->points[1].pLeftTopPoint = CGPointMake(ret.curLeftPoint.x, ret.curLeftPoint.y);
curAnnotPath->points[1].pRightTopPoint = CGPointMake(ret.curRightPoint.x, ret.curRightPoint.y);
}
}
else
{
curAnnotPath->points.removeLast();
}
}
else if (realPointCount > 2)
{
SWRealPoint penPoint0 = curAnnotPath->points.at(realPointCount - 3);
SWRealPoint penPoint1 = curAnnotPath->points.at(realPointCount - 2);
SWRealPoint penPoint2 = curAnnotPath->points.at(realPointCount - 1);
if (penPoint0.circleCount == 0)
{
CGPoint penPoint0Left = CGPointEqualToPoint(penPoint0.PLeftIntersectPoint, CGPointZero) ? penPoint0.pLeftBottomPoint : penPoint0.PLeftIntersectPoint;
CGPoint penPoint1Left = CGPointEqualToPoint(penPoint1.PLeftIntersectPoint, CGPointZero) ? penPoint1.pLeftTopPoint : penPoint1.PLeftIntersectPoint;
CGPoint penPoint0Right = CGPointEqualToPoint(penPoint0.PRightIntersectPoint, CGPointZero) ? penPoint0.pRightBottomPoint : penPoint0.PRightIntersectPoint;
CGPoint penPoint1Right = CGPointEqualToPoint(penPoint1.PRightIntersectPoint, CGPointZero) ? penPoint1.pRightTopPoint : penPoint1.PRightIntersectPoint;
SWPosRet ret = SWGetTangentcurPoint(SWPosPointMake(penPoint1.realPoint.x(), penPoint1.realPoint.y(), penPoint1.radius), SWPosPointMake(penPoint2.realPoint.x(), penPoint2.realPoint.y(), penPoint2.radius), SWLineMake(penPoint0Left.x(), penPoint0Left.y(), penPoint1Left.x(), penPoint1Left.y()), SWLineMake(penPoint0Right.x(), penPoint0Right.y(), penPoint1Right.x(), penPoint1Right.y()),circle ? 1 : 0);
if (ret.status == SWPosRetSuccess )
{
if (ret.circleCount > 0)
{
curAnnotPath->points[realPointCount - 2].circleCount = ret.circleCount;
curAnnotPath->points[realPointCount - 2].circlePoints = ret.circlePoints;
}
else
{
curAnnotPath->points[realPointCount - 2].PLeftIntersectPoint = CGPointMake(ret.prevLeftIntersectPoint.x, ret.prevLeftIntersectPoint.y);
curAnnotPath->points[realPointCount - 2].PRightIntersectPoint = CGPointMake(ret.prevRightIntersectPoint.x, ret.prevRightIntersectPoint.y);
curAnnotPath->points[realPointCount - 2].pLeftBottomPoint = CGPointMake(ret.prevLeftPoint.x, ret.prevLeftPoint.y);
curAnnotPath->points[realPointCount - 2].pRightBottomPoint = CGPointMake(ret.prevRightPoint.x, ret.prevRightPoint.y);
curAnnotPath->points[realPointCount - 1].pLeftTopPoint = CGPointMake(ret.curLeftPoint.x, ret.curLeftPoint.y);
curAnnotPath->points[realPointCount - 1].pRightTopPoint = CGPointMake(ret.curRightPoint.x, ret.curRightPoint.y);
}
}
else if (ret.status == SWPosRetFail)
{
curAnnotPath->points.removeLast();
}
}
else
{
SWPosRet ret = SWGetTangentcurPoint(SWPosPointMake(penPoint1.realPoint.x(), penPoint1.realPoint.y(), penPoint1.radius), SWPosPointMake(penPoint2.realPoint.x(), penPoint2.realPoint.y(), penPoint2.radius), SWLineMakeZero(), SWLineMakeZero(),circle ? 1 : 0);
if (ret.status == SWPosRetSuccess)
{
if (ret.circleCount > 0)
{
curAnnotPath->points[realPointCount - 2].circleCount = ret.circleCount;
curAnnotPath->points[realPointCount - 2].circlePoints = ret.circlePoints;
}
else
{
curAnnotPath->points[realPointCount - 2].pLeftBottomPoint = CGPointMake(ret.prevLeftPoint.x, ret.prevLeftPoint.y);
curAnnotPath->points[realPointCount - 2].pRightBottomPoint = CGPointMake(ret.prevRightPoint.x, ret.prevRightPoint.y);
curAnnotPath->points[realPointCount - 1].pLeftTopPoint = CGPointMake(ret.curLeftPoint.x, ret.curLeftPoint.y);
curAnnotPath->points[realPointCount - 1].pRightTopPoint = CGPointMake(ret.curRightPoint.x, ret.curRightPoint.y);
}
}
else
{
curAnnotPath->points.removeLast();
}
}
}
}
float GetDistanceBetweenPoint(QPointF start, QPointF end)
{
return sqrt(pow(start.y()-end.y(), 2.0) + pow(start.x()-end.x(), 2.0));
}
bool CGPointEqualToPoint(const CGPoint &point1, const CGPoint &point2)
{
return point1.x() == point2.x() && point1.y() == point2.y();
}
bool GetPointValid(SWRealPoint penPoint)
{
return true;
}
CGPoint ConvertToCGPoint(SWPointcut cPoint)
{
return CGPointMake(cPoint.x, cPoint.y);
}
void AddStartPathElement(QList<Element> &elementList)
{
Element ele(StartFigure);
elementList.append(ele);
}
void AddMoveToElement(QList<Element> &elementList, QPointF point)
{
// qDebug() << __FUNCTION__ << point;
// SW_Log::Get()->info(QString("====AddMoveToElement x: %1 y: %2====").arg(point.x()).arg(point.y()));
Element ele(MoveToElement);
ele.AddEndPoint(point);
elementList.append(ele);
}
void AddCurveToElement(QList<Element> &elementList, QPointF control, QPointF control2, QPointF end)
{
// SW_Log::Get()->info(QString("====AddCurveToElement cx: %1 cy: %2 c2x: %3 c2y: %4 ex: %5 ey: %6====")
// .arg(control.x()).arg(control.y()).arg(control2.x()).arg(control2.y()).arg(end.x()).arg(end.y()));
Element ele(CurveToElement);
ele.AddEndPoint(end);
ele.AddControlPoint(control);
ele.AddControlPoint2(control2);
elementList.append(ele);
}
void AddCurveToElement(QList<Element> &elementList, qreal ctrlPt1x, qreal ctrlPt1y, qreal ctrlPt2x, qreal ctrlPt2y, qreal endPtx, qreal endPty)
{
// SW_Log::Get()->info(QString("====AddCurveToElement cx: %1 cy: %2 c2x: %3 c2y: %4 ex: %5 ey: %6====")
// .arg(ctrlPt1x).arg(ctrlPt1y).arg(ctrlPt2x).arg(ctrlPt2y).arg(endPtx).arg(endPty));
AddCurveToElement(elementList,QPointF(ctrlPt1x,ctrlPt1y),QPointF(ctrlPt2x,ctrlPt2y),QPointF(endPtx,endPty));
}
void AddQuadToElement(QList<Element> &elementList, QPointF control, QPointF end)
{
// SW_Log::Get()->info(QString("====AddQuadToElement cx: %1 cy: %2 ex: %5 ey: %6====")
// .arg(control.x()).arg(control.y()).arg(end.x()).arg(end.y()));
Element ele(QuadToElement);
ele.AddEndPoint(end);
ele.AddControlPoint(control);
elementList.append(ele);
}

@ -0,0 +1,18 @@
#ifndef SIGNUTILS_H
#define SIGNUTILS_H
#include "signpenstructs.h"
extern QPointF CGPointZero;
extern bool CGPointEqualToPoint(const CGPoint &point1, const CGPoint &point2);
extern void CalculatePointcutWihtPoint(SWAnnotPath *curAnnotPath,CGPoint point, float radius, bool stroke, bool circle,qint64 ts);
extern bool GetPointValid(SWRealPoint penPoint);
extern CGPoint ConvertToCGPoint(SWPointcut cPoint);
extern float GetDistanceBetweenPoint(QPointF start, QPointF end);
extern void AddStartPathElement(QList<Element>& elementList);
extern void AddMoveToElement(QList<Element>& elementList,QPointF point);
extern void AddCurveToElement(QList<Element>& elementList,QPointF control,QPointF control2,QPointF end);
extern void AddCurveToElement(QList<Element>& elementList,qreal ctrlPt1x, qreal ctrlPt1y, qreal ctrlPt2x, qreal ctrlPt2y,
qreal endPtx, qreal endPty);
extern void AddQuadToElement(QList<Element>& elementList,QPointF control,QPointF end);
#endif // SIGNUTILS_H

@ -0,0 +1,114 @@
#include "sw_log.h"
#include <QtDebug>
static SW_Log *m_pLogInstance = NULL;
QString SW_Log::m_appInfo = "";
void SW_Log::Create(const QString& appPath,const QString appInfo)
{
m_appInfo = appInfo;
if(m_pLogInstance == NULL)
{
m_pLogInstance = new SW_Log;
}
}
SW_Log* SW_Log::Get()
{
if(m_pLogInstance == NULL)
{
m_pLogInstance = new SW_Log;
}
return m_pLogInstance;
}
void SW_Log::Destroy()
{
SW_Log::Get()->warning("SW_Log::Destroy");
if (m_pLogInstance)
{
delete m_pLogInstance;
m_pLogInstance = NULL;
}
}
void SW_Log::error(const char *message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.error(message);
qDebug() << message;
}
void SW_Log::error(const QString &message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.error(message.toStdString());
qDebug() << message;
}
void SW_Log::warning(const char *message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.warn(message);
qDebug() << message;
}
void SW_Log::warning(const QString &message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.warn(message.toStdString());
qDebug() << message;
}
void SW_Log::debug(const char *message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.debug(message);
qDebug() << message;
}
void SW_Log::debug(const QString &message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.debug(message.toStdString());
qDebug() << message;
}
void SW_Log::info(const char *message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.info(message);
qDebug() << message;
}
void SW_Log::info(const QString &message)
{
// log4cpp::Category& root = log4cpp::Category::getRoot();
// root.info(message.toStdString());
qDebug() << message;
}
QString SW_Log::GetUserDir()
{
return m_userDir;
}
QString SW_Log::GetConfFile()
{
return m_confFile;
}
QString SW_Log::GetEnvUserDir()
{
return m_envUserDir;
}
SW_Log::SW_Log()
{
}
SW_Log::~SW_Log()
{
// log4cpp::Category::shutdown();
}

@ -0,0 +1,36 @@
#ifndef SW_LOG_H
#define SW_LOG_H
#include <QString>
#include <QtDebug>
class SW_Log
{
public:
static void Create(const QString& appPath,const QString appInfo="");
static SW_Log* Get();
static void Destroy();
void error(const char *message);
void error(const QString &message);
void warning(const char *message);
void warning(const QString &message);
void debug(const char *message);
void debug(const QString &message);
void info(const char *message);
void info(const QString &message);
QString GetUserDir();
QString GetConfFile();
QString GetEnvUserDir();
protected:
SW_Log();
~SW_Log();
private:
static QString m_appInfo;
QString m_userDir;
QString m_envUserDir;
QString m_confFile;
};
#endif // SW_LOG_H

@ -0,0 +1,171 @@
/*----------------------------------------------------------------------------
NAME
Utils.c
PURPOSE
Some general-purpose functions for the WinTab demos.
COPYRIGHT
Copyright (c) Wacom Company, Ltd. 2014 All Rights Reserved
All rights reserved.
The text and information contained in this file may be freely used,
copied, or distributed without compensation or licensing restrictions.
---------------------------------------------------------------------------- */
#include "Utils.h"
#ifdef WACOM_DEBUG
void WacomTrace( char *lpszFormat, ...);
#define WACOM_ASSERT( x ) assert( x )
#define WACOM_TRACE(...) WacomTrace(__VA_ARGS__)
#else
#define WACOM_TRACE(...)
#define WACOM_ASSERT( x )
#endif // WACOM_DEBUG
//////////////////////////////////////////////////////////////////////////////
HINSTANCE ghWintab = NULL;
WTINFOA gpWTInfoA = NULL;
WTINFOW gpWTInfoW = NULL;
WTOPENW gpWTOpenW = NULL;
WTGETW gpWTGetW = NULL;
WTSETW gpWTSetW = NULL;
WTCLOSE gpWTClose = NULL;
WTPACKET gpWTPacket = NULL;
WTENABLE gpWTEnable = NULL;
WTOVERLAP gpWTOverlap = NULL;
WTSAVE gpWTSave = NULL;
WTCONFIG gpWTConfig = NULL;
WTRESTORE gpWTRestore = NULL;
WTEXTSET gpWTExtSet = NULL;
WTEXTGET gpWTExtGet = NULL;
WTQUEUESIZESET gpWTQueueSizeSet = NULL;
WTQUEUESIZEGET gpWTQueueSizeGet = NULL;
WTDATAPEEK gpWTDataPeek = NULL;
WTPACKETSGET gpWTPacketsGet = NULL;
// TODO - add more wintab32 function pointers as needed
char* pszProgramName = NULL;
#define GETPROCADDRESS(type, func) \
gp##func = (type)GetProcAddress(ghWintab, #func); \
if (!gp##func){ WACOM_ASSERT(FALSE); UnloadWintab(); return FALSE; }
//////////////////////////////////////////////////////////////////////////////
// Purpose
// Find wintab32.dll and load it.
// Find the exported functions we need from it.
//
// Returns
// TRUE on success.
// FALSE on failure.
//
BOOL LoadWintab( void )
{
ghWintab = LoadLibraryW( L"Wintab32.dll" );
if ( !ghWintab )
{
DWORD err = GetLastError();
//WACOM_TRACE("LoadLibrary error: %i\n", err);
OutputDebugStringA("Could not load Wintab32.dll");
return FALSE;
}
// Explicitly find the exported Wintab functions in which we are interested.
// We are using the ASCII, not unicode versions (where applicable).
GETPROCADDRESS( WTOPENW, WTOpenW );
GETPROCADDRESS( WTINFOW, WTInfoW );
GETPROCADDRESS(WTINFOA, WTInfoA);
GETPROCADDRESS( WTGETW, WTGetW );
GETPROCADDRESS( WTSETW, WTSetW );
GETPROCADDRESS( WTPACKET, WTPacket );
GETPROCADDRESS( WTCLOSE, WTClose );
GETPROCADDRESS( WTENABLE, WTEnable );
GETPROCADDRESS( WTOVERLAP, WTOverlap );
GETPROCADDRESS( WTSAVE, WTSave );
GETPROCADDRESS( WTCONFIG, WTConfig );
GETPROCADDRESS( WTRESTORE, WTRestore );
GETPROCADDRESS( WTEXTSET, WTExtSet );
GETPROCADDRESS( WTEXTGET, WTExtGet );
GETPROCADDRESS( WTQUEUESIZESET, WTQueueSizeSet );
GETPROCADDRESS(WTQUEUESIZEGET, WTQueueSizeGet);
GETPROCADDRESS( WTDATAPEEK, WTDataPeek );
GETPROCADDRESS( WTPACKETSGET, WTPacketsGet );
// TODO - don't forget to NULL out pointers in UnloadWintab().
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// Purpose
// Uninitializes use of wintab32.dll
//
// Returns
// Nothing.
//
void UnloadWintab( void )
{
//WACOM_TRACE( "UnloadWintab()\n" );
if ( ghWintab )
{
FreeLibrary( ghWintab );
ghWintab = NULL;
}
gpWTOpenW = NULL;
gpWTClose = NULL;
gpWTInfoW = NULL;
gpWTPacket = NULL;
gpWTEnable = NULL;
gpWTOverlap = NULL;
gpWTSave = NULL;
gpWTConfig = NULL;
gpWTGetW = NULL;
gpWTSetW = NULL;
gpWTRestore = NULL;
gpWTExtSet = NULL;
gpWTExtGet = NULL;
gpWTQueueSizeSet = NULL;
gpWTQueueSizeGet = NULL;
gpWTDataPeek = NULL;
gpWTPacketsGet = NULL;
}
#ifdef WACOM_DEBUG
//////////////////////////////////////////////////////////////////////////////
void WacomTrace(char *lpszFormat, ...)
{
char szTraceMessage[ 128 ];
int nBytesWritten;
va_list args;
WACOM_ASSERT( lpszFormat );
va_start( args, lpszFormat );
nBytesWritten = _vsnprintf( szTraceMessage, sizeof( szTraceMessage ) - 1,
lpszFormat, args );
if ( nBytesWritten > 0 )
{
OutputDebugStringA( szTraceMessage );
}
va_end( args );
}
#endif // WACOM_DEBUG

@ -0,0 +1,97 @@
/*----------------------------------------------------------------------------
NAME
Utils.h
PURPOSE
Defines for the general-purpose functions for the WinTab demos.
COPYRIGHT
Copyright (c) Wacom Company, Ltd. 2014 All Rights Reserved
All rights reserved.
The text and information contained in this file may be freely used,
copied, or distributed without compensation or licensing restrictions.
---------------------------------------------------------------------------- */
#pragma once
#include <windows.h>
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include "wintab.h" // NOTE: get from wactab header package
//////////////////////////////////////////////////////////////////////////////
#define WACOM_DEBUG
// Ignore warnings about using unsafe string functions.
#pragma warning( disable : 4996 )
//////////////////////////////////////////////////////////////////////////////
// Function pointers to Wintab functions exported from wintab32.dll.
typedef UINT ( API * WTINFOW ) ( UINT, UINT, LPVOID );
typedef UINT(API * WTINFOA) (UINT, UINT, LPVOID);
typedef HCTX ( API * WTOPENW )( HWND, LPLOGCONTEXTW, BOOL );
typedef BOOL ( API * WTGETW ) ( HCTX, LPLOGCONTEXT );
typedef BOOL ( API * WTSETW ) ( HCTX, LPLOGCONTEXT );
typedef BOOL ( API * WTCLOSE ) ( HCTX );
typedef BOOL ( API * WTENABLE ) ( HCTX, BOOL );
typedef BOOL ( API * WTPACKET ) ( HCTX, UINT, LPVOID );
typedef BOOL ( API * WTOVERLAP ) ( HCTX, BOOL );
typedef BOOL ( API * WTSAVE ) ( HCTX, LPVOID );
typedef BOOL ( API * WTCONFIG ) ( HCTX, HWND );
typedef HCTX ( API * WTRESTORE ) ( HWND, LPVOID, BOOL );
typedef BOOL ( API * WTEXTSET ) ( HCTX, UINT, LPVOID );
typedef BOOL ( API * WTEXTGET ) ( HCTX, UINT, LPVOID );
typedef BOOL ( API * WTQUEUESIZESET ) ( HCTX, int );
typedef BOOL(API * WTQUEUESIZEGET) (HCTX);
typedef int ( API * WTDATAPEEK ) ( HCTX, UINT, UINT, int, LPVOID, LPINT);
typedef int ( API * WTPACKETSGET ) (HCTX, int, LPVOID);
// TODO - add more wintab32 function defs as needed
//////////////////////////////////////////////////////////////////////////////
// Loaded Wintab32 API functions.
extern HINSTANCE ghWintab;
extern WTINFOW gpWTInfoW;
extern WTINFOA gpWTInfoA;
extern WTOPENW gpWTOpenW;
extern WTGETW gpWTGetW;
extern WTSETW gpWTSetW;
extern WTCLOSE gpWTClose;
extern WTPACKET gpWTPacket;
extern WTENABLE gpWTEnable;
extern WTOVERLAP gpWTOverlap;
extern WTSAVE gpWTSave;
extern WTCONFIG gpWTConfig;
extern WTRESTORE gpWTRestore;
extern WTEXTSET gpWTExtSet;
extern WTEXTGET gpWTExtGet;
extern WTQUEUESIZESET gpWTQueueSizeSet;
extern WTQUEUESIZEGET gpWTQueueSizeGet;
extern WTDATAPEEK gpWTDataPeek;
extern WTPACKETSGET gpWTPacketsGet;
// TODO - add more wintab32 function pointers as needed
//////////////////////////////////////////////////////////////////////////////
BOOL LoadWintab( void );
void UnloadWintab( void );
//////////////////////////////////////////////////////////////////////////////
#ifdef WACOM_DEBUG
void WacomTrace( char *lpszFormat, ...);
#define WACOM_ASSERT( x ) assert( x )
#define WACOM_TRACE(...) WacomTrace(__VA_ARGS__)
#else
#define WACOM_TRACE(...)
#define WACOM_ASSERT( x )
#endif // WACOM_DEBUG

@ -0,0 +1,930 @@
/* -------------------------------- wintab.h -------------------------------- */
/* Combined 16 & 32-bit version. */
/*------------------------------------------------------------------------------
The text and information contained in this file may be freely used,
copied, or distributed without compensation or licensing restrictions.
This file is Copyright (c) Wacom Company, Ltd. 2010 All Rights Reserved
with portions copyright 1991-1998 by LCS/Telegraphics.
------------------------------------------------------------------------------*/
#ifndef _INC_WINTAB /* prevent multiple includes */
#define _INC_WINTAB
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* -------------------------------------------------------------------------- */
/* Messages */
#ifndef NOWTMESSAGES
#define WT_DEFBASE 0x7FF0
#define WT_MAXOFFSET 0xF
#define _WT_PACKET(b) ((b)+0)
#define _WT_CTXOPEN(b) ((b)+1)
#define _WT_CTXCLOSE(b) ((b)+2)
#define _WT_CTXUPDATE(b) ((b)+3)
#define _WT_CTXOVERLAP(b) ((b)+4)
#define _WT_PROXIMITY(b) ((b)+5)
#define _WT_INFOCHANGE(b) ((b)+6)
#define _WT_CSRCHANGE(b) ((b)+7) /* 1.1 */
#define _WT_PACKETEXT(b) ((b)+8) /* 1.4 */
#define _WT_MAX(b) ((b)+WT_MAXOFFSET)
#define WT_PACKET _WT_PACKET(WT_DEFBASE)
#define WT_CTXOPEN _WT_CTXOPEN(WT_DEFBASE)
#define WT_CTXCLOSE _WT_CTXCLOSE(WT_DEFBASE)
#define WT_CTXUPDATE _WT_CTXUPDATE(WT_DEFBASE)
#define WT_CTXOVERLAP _WT_CTXOVERLAP(WT_DEFBASE)
#define WT_PROXIMITY _WT_PROXIMITY(WT_DEFBASE)
#define WT_INFOCHANGE _WT_INFOCHANGE(WT_DEFBASE)
#define WT_CSRCHANGE _WT_CSRCHANGE(WT_DEFBASE) /* 1.1 */
#define WT_PACKETEXT _WT_PACKETEXT(WT_DEFBASE) /* 1.4 */
#define WT_MAX _WT_MAX(WT_DEFBASE)
#endif
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Data Types */
/* -------------------------------------------------------------------------- */
/* COMMON DATA DEFS */
DECLARE_HANDLE(HMGR); /* manager handle */
DECLARE_HANDLE(HCTX); /* context handle */
DECLARE_HANDLE(HWTHOOK); /* hook handle */
typedef DWORD WTPKT; /* packet mask */
#ifndef NOWTPKT
/* WTPKT bits */
#define PK_CONTEXT 0x0001 /* reporting context */
#define PK_STATUS 0x0002 /* status bits */
#define PK_TIME 0x0004 /* time stamp */
#define PK_CHANGED 0x0008 /* change bit vector */
#define PK_SERIAL_NUMBER 0x0010 /* packet serial number */
#define PK_CURSOR 0x0020 /* reporting cursor */
#define PK_BUTTONS 0x0040 /* button information */
#define PK_X 0x0080 /* x axis */
#define PK_Y 0x0100 /* y axis */
#define PK_Z 0x0200 /* z axis */
#define PK_NORMAL_PRESSURE 0x0400 /* normal or tip pressure */
#define PK_TANGENT_PRESSURE 0x0800 /* tangential or barrel pressure */
#define PK_ORIENTATION 0x1000 /* orientation info: tilts */
#define PK_ROTATION 0x2000 /* rotation info; 1.1 */
#endif
typedef DWORD FIX32; /* fixed-point arithmetic type */
#ifndef NOFIX32
#define INT(x) HIWORD(x)
#define FRAC(x) LOWORD(x)
#define CASTFIX32(x) ((FIX32)((x)*65536L))
#define ROUND(x) (INT(x) + (FRAC(x) > (WORD)0x8000))
#define FIX_MUL(c, a, b) \
(c = (((DWORD)FRAC(a) * FRAC(b)) >> 16) + \
(DWORD)INT(a) * FRAC(b) + \
(DWORD)INT(b) * FRAC(a) + \
((DWORD)INT(a) * INT(b) << 16))
#ifdef _WINDLL
#define FIX_DIV_SC static
#else
#define FIX_DIV_SC
#endif
#define FIX_DIV(c, a, b) \
{ \
FIX_DIV_SC DWORD temp, rem, btemp; \
\
/* fraction done bytewise */ \
temp = ((a / b) << 16); \
rem = a % b; \
btemp = b; \
if (INT(btemp) < 256) { \
rem <<= 8; \
} \
else { \
btemp >>= 8; \
} \
temp += ((rem / btemp) << 8); \
rem %= btemp; \
rem <<= 8; \
temp += rem / btemp; \
c = temp; \
}
#endif
/* -------------------------------------------------------------------------- */
/* INFO DATA DEFS */
#ifndef NOWTINFO
#ifndef NOWTAXIS
typedef struct tagAXIS {
LONG axMin;
LONG axMax;
UINT axUnits;
FIX32 axResolution;
tagAXIS()
{
axMin = 0;
axMax = 0;
axUnits = 0;
axResolution = 0;
}
} AXIS, *PAXIS, NEAR *NPAXIS, FAR *LPAXIS;
/* unit specifiers */
#define TU_NONE 0
#define TU_INCHES 1
#define TU_CENTIMETERS 2
#define TU_CIRCLE 3
#endif
#ifndef NOWTSYSBUTTONS
/* system button assignment values */
#define SBN_NONE 0x00
#define SBN_LCLICK 0x01
#define SBN_LDBLCLICK 0x02
#define SBN_LDRAG 0x03
#define SBN_RCLICK 0x04
#define SBN_RDBLCLICK 0x05
#define SBN_RDRAG 0x06
#define SBN_MCLICK 0x07
#define SBN_MDBLCLICK 0x08
#define SBN_MDRAG 0x09
/* for Pen Windows */
#define SBN_PTCLICK 0x10
#define SBN_PTDBLCLICK 0x20
#define SBN_PTDRAG 0x30
#define SBN_PNCLICK 0x40
#define SBN_PNDBLCLICK 0x50
#define SBN_PNDRAG 0x60
#define SBN_P1CLICK 0x70
#define SBN_P1DBLCLICK 0x80
#define SBN_P1DRAG 0x90
#define SBN_P2CLICK 0xA0
#define SBN_P2DBLCLICK 0xB0
#define SBN_P2DRAG 0xC0
#define SBN_P3CLICK 0xD0
#define SBN_P3DBLCLICK 0xE0
#define SBN_P3DRAG 0xF0
#endif
#ifndef NOWTCAPABILITIES
/* hardware capabilities */
#define HWC_INTEGRATED 0x0001
#define HWC_TOUCH 0x0002
#define HWC_HARDPROX 0x0004
#define HWC_PHYSID_CURSORS 0x0008 /* 1.1 */
#endif
#ifndef NOWTIFC
#ifndef NOWTCURSORS
/* cursor capabilities */
#define CRC_MULTIMODE 0x0001 /* 1.1 */
#define CRC_AGGREGATE 0x0002 /* 1.1 */
#define CRC_INVERT 0x0004 /* 1.1 */
#endif
/* info categories */
#define WTI_INTERFACE 1
#define IFC_WINTABID 1
#define IFC_SPECVERSION 2
#define IFC_IMPLVERSION 3
#define IFC_NDEVICES 4
#define IFC_NCURSORS 5
#define IFC_NCONTEXTS 6
#define IFC_CTXOPTIONS 7
#define IFC_CTXSAVESIZE 8
#define IFC_NEXTENSIONS 9
#define IFC_NMANAGERS 10
#define IFC_MAX 10
#endif
#ifndef NOWTSTATUS
#define WTI_STATUS 2
#define STA_CONTEXTS 1
#define STA_SYSCTXS 2
#define STA_PKTRATE 3
#define STA_PKTDATA 4
#define STA_MANAGERS 5
#define STA_SYSTEM 6
#define STA_BUTTONUSE 7
#define STA_SYSBTNUSE 8
#define STA_MAX 8
#endif
#ifndef NOWTDEFCONTEXT
#define WTI_DEFCONTEXT 3
#define WTI_DEFSYSCTX 4
#define WTI_DDCTXS 400 /* 1.1 */
#define WTI_DSCTXS 500 /* 1.1 */
#define CTX_NAME 1
#define CTX_OPTIONS 2
#define CTX_STATUS 3
#define CTX_LOCKS 4
#define CTX_MSGBASE 5
#define CTX_DEVICE 6
#define CTX_PKTRATE 7
#define CTX_PKTDATA 8
#define CTX_PKTMODE 9
#define CTX_MOVEMASK 10
#define CTX_BTNDNMASK 11
#define CTX_BTNUPMASK 12
#define CTX_INORGX 13
#define CTX_INORGY 14
#define CTX_INORGZ 15
#define CTX_INEXTX 16
#define CTX_INEXTY 17
#define CTX_INEXTZ 18
#define CTX_OUTORGX 19
#define CTX_OUTORGY 20
#define CTX_OUTORGZ 21
#define CTX_OUTEXTX 22
#define CTX_OUTEXTY 23
#define CTX_OUTEXTZ 24
#define CTX_SENSX 25
#define CTX_SENSY 26
#define CTX_SENSZ 27
#define CTX_SYSMODE 28
#define CTX_SYSORGX 29
#define CTX_SYSORGY 30
#define CTX_SYSEXTX 31
#define CTX_SYSEXTY 32
#define CTX_SYSSENSX 33
#define CTX_SYSSENSY 34
#define CTX_MAX 34
#endif
#ifndef NOWTDEVICES
#define WTI_DEVICES 100
#define DVC_NAME 1
#define DVC_HARDWARE 2
#define DVC_NCSRTYPES 3
#define DVC_FIRSTCSR 4
#define DVC_PKTRATE 5
#define DVC_PKTDATA 6
#define DVC_PKTMODE 7
#define DVC_CSRDATA 8
#define DVC_XMARGIN 9
#define DVC_YMARGIN 10
#define DVC_ZMARGIN 11
#define DVC_X 12
#define DVC_Y 13
#define DVC_Z 14
#define DVC_NPRESSURE 15
#define DVC_TPRESSURE 16
#define DVC_ORIENTATION 17
#define DVC_ROTATION 18 /* 1.1 */
#define DVC_PNPID 19 /* 1.1 */
#define DVC_MAX 19
#endif
#ifndef NOWTCURSORS
#define WTI_CURSORS 200
#define CSR_NAME 1
#define CSR_ACTIVE 2
#define CSR_PKTDATA 3
#define CSR_BUTTONS 4
#define CSR_BUTTONBITS 5
#define CSR_BTNNAMES 6
#define CSR_BUTTONMAP 7
#define CSR_SYSBTNMAP 8
#define CSR_NPBUTTON 9
#define CSR_NPBTNMARKS 10
#define CSR_NPRESPONSE 11
#define CSR_TPBUTTON 12
#define CSR_TPBTNMARKS 13
#define CSR_TPRESPONSE 14
#define CSR_PHYSID 15 /* 1.1 */
#define CSR_MODE 16 /* 1.1 */
#define CSR_MINPKTDATA 17 /* 1.1 */
#define CSR_MINBUTTONS 18 /* 1.1 */
#define CSR_CAPABILITIES 19 /* 1.1 */
#define CSR_TYPE 20 /* 1.2 */
#define CSR_MAX 20
#endif
#ifndef NOWTEXTENSIONS
#define WTI_EXTENSIONS 300
#define EXT_NAME 1
#define EXT_TAG 2
#define EXT_MASK 3
#define EXT_SIZE 4
#define EXT_AXES 5
#define EXT_DEFAULT 6
#define EXT_DEFCONTEXT 7
#define EXT_DEFSYSCTX 8
#define EXT_CURSORS 9
#define EXT_DEVICES 110 /* Allow 100 cursors */
#define EXT_MAX 210 /* Allow 100 devices */
#endif
#endif
/* -------------------------------------------------------------------------- */
/* CONTEXT DATA DEFS */
#define LCNAMELEN 40
#define LC_NAMELEN 40
#ifdef WIN32
typedef struct tagLOGCONTEXTA {
char lcName[LCNAMELEN];
UINT lcOptions;
UINT lcStatus;
UINT lcLocks;
UINT lcMsgBase;
UINT lcDevice;
UINT lcPktRate;
WTPKT lcPktData;
WTPKT lcPktMode;
WTPKT lcMoveMask;
DWORD lcBtnDnMask;
DWORD lcBtnUpMask;
LONG lcInOrgX;
LONG lcInOrgY;
LONG lcInOrgZ;
LONG lcInExtX;
LONG lcInExtY;
LONG lcInExtZ;
LONG lcOutOrgX;
LONG lcOutOrgY;
LONG lcOutOrgZ;
LONG lcOutExtX;
LONG lcOutExtY;
LONG lcOutExtZ;
FIX32 lcSensX;
FIX32 lcSensY;
FIX32 lcSensZ;
BOOL lcSysMode;
int lcSysOrgX;
int lcSysOrgY;
int lcSysExtX;
int lcSysExtY;
FIX32 lcSysSensX;
FIX32 lcSysSensY;
} LOGCONTEXTA, *PLOGCONTEXTA, NEAR *NPLOGCONTEXTA, FAR *LPLOGCONTEXTA;
typedef struct tagLOGCONTEXTW {
WCHAR lcName[LCNAMELEN];
UINT lcOptions;
UINT lcStatus;
UINT lcLocks;
UINT lcMsgBase;
UINT lcDevice;
UINT lcPktRate;
WTPKT lcPktData;
WTPKT lcPktMode;
WTPKT lcMoveMask;
DWORD lcBtnDnMask;
DWORD lcBtnUpMask;
LONG lcInOrgX;
LONG lcInOrgY;
LONG lcInOrgZ;
LONG lcInExtX;
LONG lcInExtY;
LONG lcInExtZ;
LONG lcOutOrgX;
LONG lcOutOrgY;
LONG lcOutOrgZ;
LONG lcOutExtX;
LONG lcOutExtY;
LONG lcOutExtZ;
FIX32 lcSensX;
FIX32 lcSensY;
FIX32 lcSensZ;
BOOL lcSysMode;
int lcSysOrgX;
int lcSysOrgY;
int lcSysExtX;
int lcSysExtY;
FIX32 lcSysSensX;
FIX32 lcSysSensY;
} LOGCONTEXTW, *PLOGCONTEXTW, NEAR *NPLOGCONTEXTW, FAR *LPLOGCONTEXTW;
#ifdef UNICODE
typedef LOGCONTEXTW LOGCONTEXT;
typedef PLOGCONTEXTW PLOGCONTEXT;
typedef NPLOGCONTEXTW NPLOGCONTEXT;
typedef LPLOGCONTEXTW LPLOGCONTEXT;
#else
typedef LOGCONTEXTA LOGCONTEXT;
typedef PLOGCONTEXTA PLOGCONTEXT;
typedef NPLOGCONTEXTA NPLOGCONTEXT;
typedef LPLOGCONTEXTA LPLOGCONTEXT;
#endif /* UNICODE */
#else /* WIN32 */
typedef struct tagLOGCONTEXT {
char lcName[LCNAMELEN];
UINT lcOptions;
UINT lcStatus;
UINT lcLocks;
UINT lcMsgBase;
UINT lcDevice;
UINT lcPktRate;
WTPKT lcPktData;
WTPKT lcPktMode;
WTPKT lcMoveMask;
DWORD lcBtnDnMask;
DWORD lcBtnUpMask;
LONG lcInOrgX;
LONG lcInOrgY;
LONG lcInOrgZ;
LONG lcInExtX;
LONG lcInExtY;
LONG lcInExtZ;
LONG lcOutOrgX;
LONG lcOutOrgY;
LONG lcOutOrgZ;
LONG lcOutExtX;
LONG lcOutExtY;
LONG lcOutExtZ;
FIX32 lcSensX;
FIX32 lcSensY;
FIX32 lcSensZ;
BOOL lcSysMode;
int lcSysOrgX;
int lcSysOrgY;
int lcSysExtX;
int lcSysExtY;
FIX32 lcSysSensX;
FIX32 lcSysSensY;
} LOGCONTEXT, *PLOGCONTEXT, NEAR *NPLOGCONTEXT, FAR *LPLOGCONTEXT;
#endif /* WIN32 */
/* context option values */
#define CXO_SYSTEM 0x0001
#define CXO_PEN 0x0002
#define CXO_MESSAGES 0x0004
#define CXO_MARGIN 0x8000
#define CXO_MGNINSIDE 0x4000
#define CXO_CSRMESSAGES 0x0008 /* 1.1 */
/* context status values */
#define CXS_DISABLED 0x0001
#define CXS_OBSCURED 0x0002
#define CXS_ONTOP 0x0004
/* context lock values */
#define CXL_INSIZE 0x0001
#define CXL_INASPECT 0x0002
#define CXL_SENSITIVITY 0x0004
#define CXL_MARGIN 0x0008
#define CXL_SYSOUT 0x0010
/* -------------------------------------------------------------------------- */
/* EVENT DATA DEFS */
/* For packet structure definition, see pktdef.h */
/* packet status values */
#define TPS_PROXIMITY 0x0001
#define TPS_QUEUE_ERR 0x0002
#define TPS_MARGIN 0x0004
#define TPS_GRAB 0x0008
#define TPS_INVERT 0x0010 /* 1.1 */
typedef struct tagORIENTATION {
int orAzimuth;
int orAltitude;
int orTwist;
} ORIENTATION, *PORIENTATION, NEAR *NPORIENTATION, FAR *LPORIENTATION;
typedef struct tagROTATION { /* 1.1 */
int roPitch;
int roRoll;
int roYaw;
} ROTATION, *PROTATION, NEAR *NPROTATION, FAR *LPROTATION;
// grandfather in obsolete member names.
#define rotPitch roPitch
#define rotRoll roRoll
#define rotYaw roYaw
/* relative buttons */
#define TBN_NONE 0
#define TBN_UP 1
#define TBN_DOWN 2
/* -------------------------------------------------------------------------- */
/* DEVICE CONFIG CONSTANTS */
#ifndef NOWTDEVCFG
#define WTDC_NONE 0
#define WTDC_CANCEL 1
#define WTDC_OK 2
#define WTDC_RESTART 3
#endif
/* -------------------------------------------------------------------------- */
/* HOOK CONSTANTS */
#ifndef NOWTHOOKS
#define WTH_PLAYBACK 1
#define WTH_RECORD 2
#define WTHC_GETLPLPFN (-3)
#define WTHC_LPLPFNNEXT (-2)
#define WTHC_LPFNNEXT (-1)
#define WTHC_ACTION 0
#define WTHC_GETNEXT 1
#define WTHC_SKIP 2
#endif
/* -------------------------------------------------------------------------- */
/* PREFERENCE FUNCTION CONSTANTS */
#ifndef NOWTPREF
#define WTP_LPDEFAULT ((LPVOID)-1L)
#define WTP_DWDEFAULT ((DWORD)-1L)
#endif
/* -------------------------------------------------------------------------- */
/* EXTENSION TAGS AND CONSTANTS */
#ifndef NOWTEXTENSIONS
/* constants for use with pktdef.h */
#define PKEXT_ABSOLUTE 1
#define PKEXT_RELATIVE 2
/* Extension tags. */
#define WTX_OBT 0 /* Out of bounds tracking */
#define WTX_FKEYS 1 /* Function keys */
#define WTX_TILT 2 /* Raw Cartesian tilt; 1.1 */
#define WTX_CSRMASK 3 /* select input by cursor type; 1.1 */
#define WTX_XBTNMASK 4 /* Extended button mask; 1.1 */
#define WTX_EXPKEYS 5 /* ExpressKeys; 1.3 - DEPRECATED: see WTX_EXPKEYS2 */
#define WTX_TOUCHSTRIP 6 /* TouchStrips; 1.4 */
#define WTX_TOUCHRING 7 /* TouchRings; 1.4 */
#define WTX_EXPKEYS2 8 /* ExpressKeys; 1.4 */
typedef struct tagXBTNMASK {
BYTE xBtnDnMask[32];
BYTE xBtnUpMask[32];
} XBTNMASK;
typedef struct tagTILT { /* 1.1 */
int tiltX;
int tiltY;
} TILT;
typedef struct tagEXTENSIONBASE { /* 1.4 */
HCTX nContext;
UINT nStatus;
DWORD nTime;
UINT nSerialNumber;
} EXTENSIONBASE;
typedef struct tagEXPKEYSDATA { /* 1.4 */
BYTE nTablet;
BYTE nControl;
BYTE nLocation;
BYTE nReserved;
DWORD nState;
} EXPKEYSDATA;
typedef struct tagSLIDERDATA { /* 1.4 */
BYTE nTablet;
BYTE nControl;
BYTE nMode;
BYTE nReserved;
DWORD nPosition;
} SLIDERDATA;
typedef struct tagEXTPROPERTY { /* 1.4 */
BYTE version; // Structure version, 0 for now
BYTE tabletIndex; // 0-based index for tablet
BYTE controlIndex; // 0-based index for control
BYTE functionIndex; // 0-based index for control's sub-function
WORD propertyID; // property ID
WORD reserved; // DWORD-alignment filler
DWORD dataSize; // number of bytes in data[] buffer
BYTE data[1]; // raw data
} EXTPROPERTY;
#define TABLET_PROPERTY_CONTROLCOUNT 0 // UINT32: number of physical controls on tablet
#define TABLET_PROPERTY_FUNCCOUNT 1 // UINT32: number of functions of control
#define TABLET_PROPERTY_AVAILABLE 2 // BOOL: control/mode is available for override
#define TABLET_PROPERTY_MIN 3 // UINT32: minimum value
#define TABLET_PROPERTY_MAX 4 // UINT32: maximum value
#define TABLET_PROPERTY_OVERRIDE 5 // BOOL: control is overridden
#define TABLET_PROPERTY_OVERRIDE_NAME 6 // UTF-8: Displayable name when control is overridden
#define TABLET_PROPERTY_LOCATION 11 // UINT32: Physical location of control (see TABLET_LOC_*)
#define TABLET_LOC_LEFT 0
#define TABLET_LOC_RIGHT 1
#define TABLET_LOC_TOP 2
#define TABLET_LOC_BOTTOM 3
#define TABLET_LOC_TRANSDUCER 4
#endif
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Functions */
#ifndef API
#ifndef WINAPI
#define API FAR PASCAL
#else
#define API WINAPI
#endif
#endif
#ifndef NOWTCALLBACKS
#ifndef CALLBACK
#define CALLBACK FAR PASCAL
#endif
#ifndef NOWTMANAGERFXNS
/* callback function types */
typedef BOOL (WINAPI * WTENUMPROC)(HCTX, LPARAM); /* changed CALLBACK->WINAPI, 1.1 */
typedef BOOL (WINAPI * WTCONFIGPROC)(HCTX, HWND);
typedef LRESULT (WINAPI * WTHOOKPROC)(int, WPARAM, LPARAM);
typedef WTHOOKPROC FAR *LPWTHOOKPROC;
#endif
#endif
#ifndef NOWTFUNCTIONS
#ifndef NOWTBASICFXNS
/* BASIC FUNCTIONS */
#ifdef WIN32
UINT API WTInfoA(UINT, UINT, LPVOID);
#define ORD_WTInfoA 20
UINT API WTInfoW(UINT, UINT, LPVOID);
#define ORD_WTInfoW 1020
#ifdef UNICODE
#define WTInfo WTInfoW
#define ORD_WTInfo ORD_WTInfoW
#else
#define WTInfo WTInfoA
#define ORD_WTInfo ORD_WTInfoA
#endif /* !UNICODE */
#else
UINT API WTInfo(UINT, UINT, LPVOID);
#define ORD_WTInfo 20
#endif
#ifdef WIN32
HCTX API WTOpenA(HWND, LPLOGCONTEXTA, BOOL);
#define ORD_WTOpenA 21
HCTX API WTOpenW(HWND, LPLOGCONTEXTW, BOOL);
#define ORD_WTOpenW 1021
#ifdef UNICODE
#define WTOpen WTOpenW
#define ORD_WTOpen ORD_WTOpenW
#else
#define WTOpen WTOpenA
#define ORD_WTOpen ORD_WTOpenA
#endif /* !UNICODE */
#else
HCTX API WTOpen(HWND, LPLOGCONTEXT, BOOL);
#define ORD_WTOpen 21
#endif
BOOL API WTClose(HCTX);
#define ORD_WTClose 22
int API WTPacketsGet(HCTX, int, LPVOID);
#define ORD_WTPacketsGet 23
BOOL API WTPacket(HCTX, UINT, LPVOID);
#define ORD_WTPacket 24
#endif
#ifndef NOWTVISIBILITYFXNS
/* VISIBILITY FUNCTIONS */
BOOL API WTEnable(HCTX, BOOL);
#define ORD_WTEnable 40
BOOL API WTOverlap(HCTX, BOOL);
#define ORD_WTOverlap 41
#endif
#ifndef NOWTCTXEDITFXNS
/* CONTEXT EDITING FUNCTIONS */
BOOL API WTConfig(HCTX, HWND);
#define ORD_WTConfig 60
#ifdef WIN32
BOOL API WTGetA(HCTX, LPLOGCONTEXTA);
#define ORD_WTGetA 61
BOOL API WTGetW(HCTX, LPLOGCONTEXTW);
#define ORD_WTGetW 1061
#ifdef UNICODE
#define WTGet WTGetW
#define ORD_WTGet ORD_WTGetW
#else
#define WTGet WTGetA
#define ORD_WTGet ORD_WTGetA
#endif /* !UNICODE */
#else
BOOL API WTGet(HCTX, LPLOGCONTEXT);
#define ORD_WTGet 61
#endif
#ifdef WIN32
BOOL API WTSetA(HCTX, LPLOGCONTEXTA);
#define ORD_WTSetA 62
BOOL API WTSetW(HCTX, LPLOGCONTEXTW);
#define ORD_WTSetW 1062
#ifdef UNICODE
#define WTSet WTSetW
#define ORD_WTSet ORD_WTSetW
#else
#define WTSet WTSetA
#define ORD_WTSet ORD_WTSetA
#endif /* !UNICODE */
#else
BOOL API WTSet(HCTX, LPLOGCONTEXT);
#define ORD_WTSet 62
#endif
BOOL API WTExtGet(HCTX, UINT, LPVOID);
#define ORD_WTExtGet 63
BOOL API WTExtSet(HCTX, UINT, LPVOID);
#define ORD_WTExtSet 64
BOOL API WTSave(HCTX, LPVOID);
#define ORD_WTSave 65
HCTX API WTRestore(HWND, LPVOID, BOOL);
#define ORD_WTRestore 66
#endif
#ifndef NOWTQUEUEFXNS
/* ADVANCED PACKET AND QUEUE FUNCTIONS */
int API WTPacketsPeek(HCTX, int, LPVOID);
#define ORD_WTPacketsPeek 80
int API WTDataGet(HCTX, UINT, UINT, int, LPVOID, LPINT);
#define ORD_WTDataGet 81
int API WTDataPeek(HCTX, UINT, UINT, int, LPVOID, LPINT);
#define ORD_WTDataPeek 82
#ifndef WIN32
/* OBSOLETE IN WIN32! */
DWORD API WTQueuePackets(HCTX);
#define ORD_WTQueuePackets 83
#endif
int API WTQueueSizeGet(HCTX);
#define ORD_WTQueueSizeGet 84
BOOL API WTQueueSizeSet(HCTX, int);
#define ORD_WTQueueSizeSet 85
#endif
#ifndef NOWTHMGRFXNS
/* MANAGER HANDLE FUNCTIONS */
HMGR API WTMgrOpen(HWND, UINT);
#define ORD_WTMgrOpen 100
BOOL API WTMgrClose(HMGR);
#define ORD_WTMgrClose 101
#endif
#ifndef NOWTMGRCTXFXNS
/* MANAGER CONTEXT FUNCTIONS */
BOOL API WTMgrContextEnum(HMGR, WTENUMPROC, LPARAM);
#define ORD_WTMgrContextEnum 120
HWND API WTMgrContextOwner(HMGR, HCTX);
#define ORD_WTMgrContextOwner 121
HCTX API WTMgrDefContext(HMGR, BOOL);
#define ORD_WTMgrDefContext 122
HCTX API WTMgrDefContextEx(HMGR, UINT, BOOL); /* 1.1 */
#define ORD_WTMgrDefContextEx 206
#endif
#ifndef NOWTMGRCONFIGFXNS
/* MANAGER CONFIG BOX FUNCTIONS */
UINT API WTMgrDeviceConfig(HMGR, UINT, HWND);
#define ORD_WTMgrDeviceConfig 140
#ifndef WIN32
/* OBSOLETE IN WIN32! */
BOOL API WTMgrConfigReplace(HMGR, BOOL, WTCONFIGPROC);
#define ORD_WTMgrConfigReplace 141
#endif
#endif
#ifndef NOWTMGRHOOKFXNS
/* MANAGER PACKET HOOK FUNCTIONS */
#ifndef WIN32
/* OBSOLETE IN WIN32! */
WTHOOKPROC API WTMgrPacketHook(HMGR, BOOL, int, WTHOOKPROC);
#define ORD_WTMgrPacketHook 160
LRESULT API WTMgrPacketHookDefProc(int, WPARAM, LPARAM, LPWTHOOKPROC);
#define ORD_WTMgrPacketHookDefProc 161
#endif
#endif
#ifndef NOWTMGRPREFFXNS
/* MANAGER PREFERENCE DATA FUNCTIONS */
BOOL API WTMgrExt(HMGR, UINT, LPVOID);
#define ORD_WTMgrExt 180
BOOL API WTMgrCsrEnable(HMGR, UINT, BOOL);
#define ORD_WTMgrCsrEnable 181
BOOL API WTMgrCsrButtonMap(HMGR, UINT, LPBYTE, LPBYTE);
#define ORD_WTMgrCsrButtonMap 182
BOOL API WTMgrCsrPressureBtnMarks(HMGR, UINT, DWORD, DWORD);
#define ORD_WTMgrCsrPressureBtnMarks 183
BOOL API WTMgrCsrPressureResponse(HMGR, UINT, UINT FAR *, UINT FAR *);
#define ORD_WTMgrCsrPressureResponse 184
BOOL API WTMgrCsrExt(HMGR, UINT, UINT, LPVOID);
#define ORD_WTMgrCsrExt 185
#endif
/* Win32 replacements for non-portable functions. */
#ifndef NOWTQUEUEFXNS
/* ADVANCED PACKET AND QUEUE FUNCTIONS */
BOOL API WTQueuePacketsEx(HCTX, UINT FAR *, UINT FAR *);
#define ORD_WTQueuePacketsEx 200
#endif
#ifndef NOWTMGRCONFIGFXNS
/* MANAGER CONFIG BOX FUNCTIONS */
#ifdef WIN32
BOOL API WTMgrConfigReplaceExA(HMGR, BOOL, LPSTR, LPSTR);
#define ORD_WTMgrConfigReplaceExA 202
BOOL API WTMgrConfigReplaceExW(HMGR, BOOL, LPWSTR, LPSTR);
#define ORD_WTMgrConfigReplaceExW 1202
#ifdef UNICODE
#define WTMgrConfigReplaceEx WTMgrConfigReplaceExW
#define ORD_WTMgrConfigReplaceEx ORD_WTMgrConfigReplaceExW
#else
#define WTMgrConfigReplaceEx WTMgrConfigReplaceExA
#define ORD_WTMgrConfigReplaceEx ORD_WTMgrConfigReplaceExA
#endif /* !UNICODE */
#else
BOOL API WTMgrConfigReplaceEx(HMGR, BOOL, LPSTR, LPSTR);
#define ORD_WTMgrConfigReplaceEx 202
#endif
#endif
#ifndef NOWTMGRHOOKFXNS
/* MANAGER PACKET HOOK FUNCTIONS */
#ifdef WIN32
HWTHOOK API WTMgrPacketHookExA(HMGR, int, LPSTR, LPSTR);
#define ORD_WTMgrPacketHookExA 203
HWTHOOK API WTMgrPacketHookExW(HMGR, int, LPWSTR, LPSTR);
#define ORD_WTMgrPacketHookExW 1203
#ifdef UNICODE
#define WTMgrPacketHookEx WTMgrPacketHookExW
#define ORD_WTMgrPacketHookEx ORD_WTMgrPacketHookExW
#else
#define WTMgrPacketHookEx WTMgrPacketHookExA
#define ORD_WTMgrPacketHookEx ORD_WTMgrPacketHookExA
#endif /* !UNICODE */
#else
HWTHOOK API WTMgrPacketHookEx(HMGR, int, LPSTR, LPSTR);
#define ORD_WTMgrPacketHookEx 203
#endif
BOOL API WTMgrPacketUnhook(HWTHOOK);
#define ORD_WTMgrPacketUnhook 204
LRESULT API WTMgrPacketHookNext(HWTHOOK, int, WPARAM, LPARAM);
#define ORD_WTMgrPacketHookNext 205
#endif
#ifndef NOWTMGRPREFFXNS
/* MANAGER PREFERENCE DATA FUNCTIONS */
BOOL API WTMgrCsrPressureBtnMarksEx(HMGR, UINT, UINT FAR *, UINT FAR *);
#define ORD_WTMgrCsrPressureBtnMarksEx 201
#endif
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* #define _INC_WINTAB */
Loading…
Cancel
Save