#include "signpenpainter.h" #include #include #include #include "signpaintercachethread.h" #include "signpaintercachethread_linux.h" #include "signutils.h" //#include "sw_log.h" SignPenPainter::SignPenPainter() { // SW_Log::Get()->info("signPenPainter: 2022-11-23 02:46"); isUseCache = true; isOutDebug = false; CGPointZero = QPointF(0,0); m_BaseBuf = NULL; m_PaintingBuf = NULL; SyncCount = 10; m_ToImageIndex = 0; #ifdef Q_OS_WIN cacheThread = nullptr; cacheThread = new SignPainterCacheThread; #else cacheThread = nullptr; cacheThread = new SignPainterCacheThread_Linux; #endif // connect(cacheThread,SIGNAL(NeedsToRefresh()),this,SIGNAL(NeedsRefresh())); connect(cacheThread,SIGNAL(NeedsToRefresh(QRect)),this,SIGNAL(NeedsDisplay(QRect))); connect(cacheThread,SIGNAL(ReleasedExcuted()),this,SIGNAL(ReleasedExcuted())); cacheThread->start(); Init(); } SignPenPainter::~SignPenPainter() { if(cacheThread && cacheThread->isRunning()) { cacheThread->terminate(); cacheThread->wait(); cacheThread->deleteLater(); cacheThread = nullptr; } } void SignPenPainter::SetPainterRect(QRect rect) { qDebug() << rect; m_Size = rect.size(); m_PaintRect = rect; // m_PaintRect = QRect(0,0,0,0); if(isUseCache && cacheThread) cacheThread->SetPainterRect(rect); } void SignPenPainter::SetPenType(int type) { if(isUseCache && cacheThread) cacheThread->SetPenType(type); } void SignPenPainter::SetPenColor(QColor penColor) { if(isUseCache && cacheThread) cacheThread->SetPenColor(penColor); } void SignPenPainter::SetCurrentPageIndex(int page) { if(isUseCache && cacheThread) cacheThread->SetCurrentPageIndex(page); } void SignPenPainter::Init() { stressSpl = 0; // penRadius = (2*2.8345)/2.f; penRadius = 2.f; strokeSpl = 2; stressSwitch = 0; pointSpeed = 10; isRelease = false; curAnnotPath = nullptr; m_FreshCount = 1; } void SignPenPainter::ClearDraw() { curAnnotPath = nullptr; drawPaths.clear(); m_ToImageIndex = 0; if(m_BaseBuf != NULL) { delete m_BaseBuf; m_BaseBuf = NULL; } if(m_PaintingBuf != NULL) { delete m_PaintingBuf; m_PaintingBuf = NULL; } if(cacheThread) cacheThread->ClearDraw(); // emit NeedsDisplay(m_PaintRect); } typedef QPainterPath CCA_Path ; void SignPenPainter::DrawRect(QPainter* painter,QRect currentVisibleRect) { if(painter == nullptr) return; if(isUseCache && cacheThread) { cacheThread->Paint(painter,currentVisibleRect); return; } if(isRelease) { // painter->translate(-m_PaintRect.left(), -m_PaintRect.top()); painter->setBrush(Qt::black); // painter->setBrush(Qt::green); painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing // painter->setPen(QPen(Qt::NoPen)); painter->setPen(QPen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); QPainter bufPainter(PaintDevice()); // bufPainter.setBrush(penColor); // bufPainter.setBrush(Qt::green); bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing bufPainter.setPen(QPen(Qt::NoPen)); //bufPainter.setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // bufPainter.setPen(QPen(Qt::red, radius, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); bufPainter.translate(-m_PaintRect.left(), -m_PaintRect.top()); QList m_DrawPaths = GetAnnotPathLists(); bool isToImage = false; for(int i = m_ToImageIndex; i< m_DrawPaths.size(); i++) { isToImage = true; // isToImage = false; // if(i == m_DrawPaths.size()-m_FreshCount) // isToImage = true; QList signEleList = m_DrawPaths[i]->bezierEles; // qDebug() << __FUNCTION__ << "signEleList size" << signEleList.count(); QPainterPath pathData; QList paths = GetPenPathData(pathData, -1, signEleList); for(int j = 0 ; j < paths.count(); j++) { // bufPainter.drawPath(paths[j]); // painter->fillPath(paths[j],QBrush(Qt::black)); // painter->drawPath(paths[j]); if(isToImage) { // qDebug() << __FUNCTION__ << " save to image."; paths[j].setFillRule(Qt::WindingFill); bufPainter.drawPath(paths[j]); bufPainter.fillPath(paths[j],QBrush(Qt::black)); } } } if(isToImage) { qDebug() << __FUNCTION__ << " save to image." << m_ToImageIndex; // m_BaseBuf->save(QString("d:/painting_%1.png").arg(QDateTime::currentMSecsSinceEpoch())); } // m_ToImageIndex = m_DrawPaths.size()-m_FreshCount > 0 ? m_DrawPaths.size()-m_FreshCount : 0; m_ToImageIndex = m_DrawPaths.size() > 0 ? m_DrawPaths.size() : 0; if(PaintDevice() != NULL) { painter->drawImage(m_BaseBuf->rect(),*m_BaseBuf); } } else { //qDebug() << __FUNCTION__ << " ========================= 1 =========================" << QDateTime::currentMSecsSinceEpoch(); // painter->setBrush(penColor); // painter->translate(-m_PaintRect.left(), -m_PaintRect.top()); painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing painter->setPen(QPen(Qt::NoPen)); painter->setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // painter->setPen(QPen(Qt::red, radius, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // SwPenPathDraw4(painter,false); //qDebug() << __FUNCTION__ << " ========================= 2 =========================" << QDateTime::currentMSecsSinceEpoch(); if( !curAnnotPath) return; if(m_BaseBuf != NULL) painter->drawImage(m_BaseBuf->rect(),*m_BaseBuf); // painter->setPen(QPen(Qt::black, 0.5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // for (int i = 0; i < drawPaths.count(); i++) // { // SWAnnotPath* annotPath = drawPaths[i]; SWAnnotPath* annotPath = curAnnotPath; QPainterPath pathBizer; QPainterPath rpathBizer; QList signEleList = annotPath->bezierEles; // qDebug() << __FUNCTION__ << "signEleList size" << signEleList.count(); QPainterPath pathData; QList paths = GetPenPathData(pathData, -1, signEleList); for(int j = 0 ; j < paths.count(); j++) { paths[j].setFillRule(Qt::WindingFill); // painter->drawPath(paths[j]); painter->fillPath(paths[j],QBrush(Qt::black)); } // for(int j = 0; j < annotPath->points.count() ; j++) // { // SWRealPoint point = annotPath->points[j]; //// if (j == 0) { //// pathBizer.moveTo(point.pLeftBottomPoint); //// rpathBizer.moveTo(point.pRightBottomPoint); //// } else { //// if (!CGPointEqualToPoint(point.pLeftTopPoint, CGPointZero) && !CGPointEqualToPoint(point.pLeftBottomPoint, CGPointZero)) { //// pathBizer.lineTo(point.pLeftTopPoint); //// pathBizer.lineTo(point.pLeftBottomPoint); //// } //// if (!CGPointEqualToPoint(point.pRightTopPoint, CGPointZero) && !CGPointEqualToPoint(point.pRightBottomPoint, CGPointZero)) { //// rpathBizer.lineTo(point.pRightTopPoint); //// rpathBizer.lineTo(point.pRightBottomPoint); //// } //// } // painter->drawPoint(point.realPoint); // // // // painter->drawEllipse(point.realPoint,point.radius,point.radius); //// painter->drawEllipse(QRectF(point.realPoint,QSize(20,20))); // } //painter->drawPath(pathBizer); //painter->drawPath(rpathBizer); // } } } void SignPenPainter::MousePressed(CGPoint currentPoint,float radius,double force,double maxForce) { // radius = 2; qDebug() << __FUNCTION__ << radius << currentPoint; if(isUseCache && cacheThread) { cacheThread->AddPoint(currentPoint,1,radius,force,maxForce); return; } m_StartIndex = 0; Init(); isRelease = false; previousTimestamp = QDateTime::currentMSecsSinceEpoch(); penRadius = radius; preLineRadius = penRadius; float newLineRadius = CalculatePointradius(0, preLineRadius, penRadius,force,maxForce,stressSpl,stressSwitch,1); preLineRadius = newLineRadius; SWRealPoint rPoint; rPoint.realPoint = currentPoint; rPoint.radius = newLineRadius; SWAnnotPath *annotPath = new SWAnnotPath; annotPath->points.append(rPoint); annotPath->realPoints.append(rPoint); annotPath->isShake = false; // drawPaths.append(annotPath); curAnnotPath = annotPath; SWPosRest(SWPosPointMake(currentPoint.x(), currentPoint.y(), newLineRadius)); } void SignPenPainter::MouseMoved(CGPoint currentPoint,float radius,double force,double maxForce) { // radius = 2; // CGPoint currentPoint(point.x() + m_PaintRect.left(),point.y()+m_PaintRect.top()); // qDebug() << __FUNCTION__ << radius << QDateTime::currentMSecsSinceEpoch() << currentPoint; if(isUseCache && cacheThread) { cacheThread->AddPoint(currentPoint,0,radius,force,maxForce); return; } penRadius = radius; /** 判断临近相同点,并过滤 */ if (!CGPointEqualToPoint(currentPoint, curAnnotPath->points.last().realPoint)) { /** 计算速度半径 */ //todo 计算速度 // pointSpeed = [self getPointSpeedWithTouch:touch andEvent:event]; qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch(); float distance = GetDistanceBetweenPoint(curAnnotPath->points.last().realPoint, currentPoint); pointSpeed = distance / ((currentTimestamp - previousTimestamp)) * 1000; float newLineRadius = CalculatePointradius(pointSpeed > 0 ? pointSpeed : 0, preLineRadius, penRadius,force,maxForce,stressSpl,stressSwitch,distance); previousTimestamp = QDateTime::currentMSecsSinceEpoch(); preLineRadius = newLineRadius; SWRealPoint curPenPoint; curPenPoint.realPoint = currentPoint; curPenPoint.radius = newLineRadius; curAnnotPath->realPoints.append(curPenPoint); /** * 对原始点进行预贝塞尔加工处理 */ int realPointCount = curAnnotPath->realPoints.count(); if (realPointCount == 2) { CGPoint onePoint = curAnnotPath->realPoints.at(0).realPoint; CGPoint twoPoint = curAnnotPath->realPoints.at(1).realPoint; CGPoint centerPoint = CGPointMake((onePoint.x()+twoPoint.x())/2.f,(onePoint.y()+twoPoint.y())/2.f); CalculatePointcutWihtPoint(centerPoint, newLineRadius, true, false); preBezierPoint = centerPoint; } else { CGPoint onePoint = curAnnotPath->points.last().realPoint; CGPoint ctrPoint = curAnnotPath->realPoints.at(realPointCount - 2).realPoint; CGPoint twoPoint = curAnnotPath->realPoints.at(realPointCount - 1).realPoint; double t = 0.5f; double x = pow(1 - t, 2) * onePoint.x() + 2.0 * (1 - t) * t * ctrPoint.x() + t * t * twoPoint.x(); double y = pow(1 - t, 2) * onePoint.y() + 2.0 * (1 - t) * t * ctrPoint.y() + t * t * twoPoint.y(); CalculatePointcutWihtPoint(CGPointMake(x,y), newLineRadius, true, false); } // [self swPenPathDraw]; SwPenPathDraw(false); //移动过程中,只进行部分绘制 // SwPenPathDraw2(false); } } void SignPenPainter::MouseReleased(CGPoint currentPoint,float radius) { // radius = 2; penRadius = radius; if(isUseCache && cacheThread) { cacheThread->AddPoint(currentPoint,2,radius,10,10); return; } //todo 速度 // self.pointSpeed = [self getPointSpeedWithTouch:touch andEvent:event]; qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch(); float distance = GetDistanceBetweenPoint(curAnnotPath->points.last().realPoint, currentPoint); // pointSpeed = distance / ((currentTimestamp - previousTimestamp)) * 1000; qDebug() << __FUNCTION__ << " speed: " << pointSpeed; int pointCount = curAnnotPath->points.count(); if (pointSpeed >= MinSpeed && pointCount > 1) { int tempStrokeSpl = pointCount > strokeSpl ? strokeSpl : (pointCount - 1); SWRealPoint lastPenPoint = curAnnotPath->points.at(pointCount - tempStrokeSpl - 1); lastPenPoint.PRightIntersectPoint = CGPointZero; lastPenPoint.PLeftIntersectPoint = CGPointZero; SWPosPoint *posAry = (SWPosPoint *)malloc(tempStrokeSpl*sizeof(SWPosPoint)); QList pointPack; int j = 0; for (int k = (pointCount - tempStrokeSpl); k < pointCount; k ++) { SWRealPoint tempPoint = curAnnotPath->points.at(k); tempPoint.circleCount = 0; posAry [j] = SWPosPointMake(tempPoint.realPoint.x(), tempPoint.realPoint.y(), tempPoint.radius); j ++; pointPack.append(tempPoint); } SWPosPoint *newposAry = CalculateStroke(posAry, (int)tempStrokeSpl,lastPenPoint.radius); // [curAnnotPath->points removeObjectsInArray:pointPack]; //todo 删除相同点 int pointPackCount = pointPack.count(); for(int i = 0 ; i < pointPackCount; i++) { for(int m = curAnnotPath->points.count() - 1; m >=0 ; m--) { if(CGPointEqualToPoint(curAnnotPath->points.at(m).realPoint,pointPack.at(i).realPoint)) { curAnnotPath->points.removeAt(m); break; } } } for (int k = 0; k < pointPack.count(); k ++) { SWPosPoint postPoint = newposAry[k]; SWRealPoint tempPoint = pointPack[k]; tempPoint.radius = postPoint.radius; CalculatePointcutWihtPoint(CGPointMake(tempPoint.realPoint.x(), tempPoint.realPoint.y()), tempPoint.radius ,false,false); } //todo refresh // [self swPenPathDraw]; //从头从新绘制 SwPenPathDraw(true); drawPaths.append(curAnnotPath); free( posAry); } else { if (pointCount > 1) { SWRealPoint prevPoint = curAnnotPath->points.at(pointCount - 2); if (prevPoint.circleCount == 0) { SWRealPoint tempPoint = curAnnotPath->points.at(pointCount - 1); tempPoint.circleCount = 0; curAnnotPath->points.removeAt(pointCount - 1); CalculatePointcutWihtPoint(CGPointMake(tempPoint.realPoint.x(), tempPoint.realPoint.y()), tempPoint.radius,false,true); } } //todo refresh // [self swPenPathDraw]; SwPenPathDraw(true); drawPaths.append(curAnnotPath); } emit ReleasedExcuted(); } void SignPenPainter::SetStressSwitch(bool isStressSwitch) { cacheThread->SetStressSwitch(isStressSwitch); } bool SignPenPainter::GetStressSwitch() { return cacheThread->GetStressSwitch(); } QList SignPenPainter::GetAnnotPathLists() { // return drawPaths; if(isUseCache && cacheThread) return cacheThread->GetAnnotPathLists(); return drawPaths; } //构建绘制路径,非绘图 void SignPenPainter::SwPenPathDraw(bool isEnd) { //todo // QPainter bufPainter(PaintDevice()); // QPainter bufPainter(PaintingDevice()); // bufPainter.setBrush(Qt::black); // bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing // bufPainter.setPen(QPen(Qt::NoPen)); // bufPainter.translate(-m_PaintRect.left(), -m_PaintRect.top()); // SWAnnotPath* annotPath = drawPaths.last(); SWAnnotPath* annotPath = curAnnotPath; if (annotPath->points.count() < 2) { return; } annotPath->bezierPaths.clear(); annotPath->bezierEles.clear(); CGPoint prevPoint = CGPointZero; QList rightPoints; QPainterPath pathBizer; pathBizer.setFillRule(Qt::WindingFill); prevPoint = CGPointZero; int cursor = 0; for (int i = 0 ; i < annotPath->points.count(); i++) { SWRealPoint penPoint = annotPath->points[i]; if (GetPointValid(penPoint)) { if (penPoint.circleCount > 0) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero)) { rightPoints.append(penPoint); SwPenPathDrawRightWithBezier(&pathBizer, annotPath->bezierEles, penPoint, prevPoint, rightPoints,isEnd); annotPath->bezierPaths.append(pathBizer); } for (int i = 0; i < penPoint.circleCount; i ++) { SWCirclePoint circleP = penPoint.circlePoints[i]; QPainterPath circleBizer; circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); AddStartPathElement(annotPath->bezierEles); AddMoveToElement(annotPath->bezierEles,ConvertToCGPoint(circleP.pointA)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(annotPath->bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(annotPath->bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(annotPath->bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(annotPath->bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); annotPath->bezierPaths.append(circleBizer); } cursor = 0; } else { if (cursor == 0) { rightPoints.clear(); prevPoint = CGPointZero; pathBizer = QPainterPath(); pathBizer.setFillRule(Qt::WindingFill); pathBizer.moveTo(penPoint.pLeftBottomPoint); if(i != annotPath->points.count()-1) { //最后一个点不进行添加 AddStartPathElement(annotPath->bezierEles); AddMoveToElement(annotPath->bezierEles,penPoint.pLeftBottomPoint); } prevPoint = penPoint.pLeftBottomPoint; rightPoints.append(penPoint); } else { rightPoints.append(penPoint); //判断交点是否有效 if (CGPointEqualToPoint(penPoint.PLeftIntersectPoint, CGPointZero)) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero) && !CGPointEqualToPoint(penPoint.pLeftBottomPoint, CGPointZero)) { CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.pLeftTopPoint.x())/2.f, (prevPoint.y()+penPoint.pLeftTopPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(annotPath->bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftTopPoint; endPoint = CGPointMake((prevPoint.x()+penPoint.pLeftBottomPoint.x())/2.f, (prevPoint.y()+penPoint.pLeftBottomPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(annotPath->bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftBottomPoint; } else { SwPenPathDrawRightWithBezier(&pathBizer,annotPath->bezierEles, penPoint, prevPoint, rightPoints,isEnd); annotPath->bezierPaths.append(pathBizer); SWCirclePoint circleP = SWCircleMake(SWPosPointMake(penPoint.realPoint.x(), penPoint.realPoint.y(), penPoint.radius)); QPainterPath circleBizer; circleBizer.setFillRule(Qt::WindingFill); circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); AddStartPathElement(annotPath->bezierEles); AddMoveToElement(annotPath->bezierEles,ConvertToCGPoint(circleP.pointA)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(annotPath->bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(annotPath->bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(annotPath->bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(annotPath->bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); annotPath->bezierPaths.append(circleBizer); } } else { CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.PLeftIntersectPoint.x())/2.f, (prevPoint.y()+penPoint.PLeftIntersectPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(annotPath->bezierEles,prevPoint,endPoint); prevPoint = penPoint.PLeftIntersectPoint; } } cursor++; } } } // [self setNeedsDisplay]; // bufPainter.drawPath(pathBizer); //如果抬笔,则进行同步 if(isEnd) { SynToBaseDevice(); isRelease = true; } emit NeedsDisplay(m_PaintRect); // emit NeedsRefresh(); } /** 绘制右侧路径 */ void SignPenPainter::SwPenPathDrawRightWithBezier(QPainterPath* bPath ,QList& elementList, SWRealPoint penPoint,CGPoint prevPoint, QList rPoints,bool end) { CGPoint endPoint = CGPointZero; if (end) { endPoint = CGPointMake((penPoint.pLeftTopPoint.x() + prevPoint.x())/2.f, (penPoint.pLeftTopPoint.y() + prevPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); } else { endPoint = penPoint.pLeftTopPoint; bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); } prevPoint = penPoint.pLeftTopPoint; for (int k = (rPoints.count() - 1); k >= 0 ; k --) { SWRealPoint penPoint = rPoints.at(k); if (GetPointValid(penPoint)) { if (k == (rPoints.count() - 1)) { if (end) { CGPoint endPoint = CGPointMake((prevPoint.x() + penPoint.pRightTopPoint.x())/2.f, (prevPoint.y() + penPoint.pRightTopPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = penPoint.pRightTopPoint; SWRealPoint lastPoint = rPoints.at(k - 1); if (!CGPointEqualToPoint(lastPoint.PRightIntersectPoint, CGPointZero)) { endPoint = CGPointMake((prevPoint.x() + lastPoint.PRightIntersectPoint.x())/2.f, (prevPoint.y() + lastPoint.PRightIntersectPoint.y())/2.f); } else { endPoint = CGPointMake((prevPoint.x() + lastPoint.pRightBottomPoint.x())/2.f, (prevPoint.y() + lastPoint.pRightBottomPoint.y())/2.f); } bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = CGPointEqualToPoint(lastPoint.PRightIntersectPoint, CGPointZero) ? lastPoint.pRightBottomPoint : lastPoint.PRightIntersectPoint; k--; /** * 判断是否到结尾 */ if (k == 0) { //绘制开始连接点 bPath->quadTo(lastPoint.pRightBottomPoint,lastPoint.pRightBottomPoint); AddQuadToElement(elementList,lastPoint.pRightBottomPoint,lastPoint.pRightBottomPoint); prevPoint = lastPoint.pRightBottomPoint; SWRealPoint firstPen = rPoints.first(); bPath->quadTo(firstPen.pRightBottomPoint,firstPen.pLeftBottomPoint); AddQuadToElement(elementList,firstPen.pRightBottomPoint,firstPen.pLeftBottomPoint); } } else { CGPoint endPoint = penPoint.pRightTopPoint; bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = penPoint.pRightTopPoint; } } else { //判断交点是否有效 if (CGPointEqualToPoint(penPoint.PRightIntersectPoint, CGPointZero)) { if (!CGPointEqualToPoint(penPoint.pRightTopPoint, CGPointZero) && !CGPointEqualToPoint(penPoint.pRightBottomPoint, CGPointZero)) { CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.pRightBottomPoint.x())/2.f, (prevPoint.y()+penPoint.pRightBottomPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = penPoint.pRightBottomPoint; endPoint = CGPointMake((prevPoint.x()+penPoint.pRightTopPoint.x())/2.f, (prevPoint.y()+penPoint.pRightTopPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = penPoint.pRightTopPoint; } else { CGPoint endPoint = CGPointMake((penPoint.pRightBottomPoint.x() + prevPoint.x())/2.f, (penPoint.pRightBottomPoint.y() + prevPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); bPath->quadTo(penPoint.pRightBottomPoint,penPoint.pRightBottomPoint); AddQuadToElement(elementList,penPoint.pRightBottomPoint,penPoint.pRightBottomPoint); prevPoint = penPoint.pRightBottomPoint; //绘制开始连接点 SWRealPoint firstPen = rPoints.first(); bPath->quadTo(firstPen.pRightBottomPoint,firstPen.pLeftBottomPoint); AddQuadToElement(elementList,firstPen.pRightBottomPoint,firstPen.pLeftBottomPoint); } } else { CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.PRightIntersectPoint.x())/2.f, (prevPoint.y()+penPoint.PRightIntersectPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = penPoint.PRightIntersectPoint; } } } } } void SignPenPainter::CalculatePointcutWihtPoint(CGPoint point, float radius, bool stroke, bool circle) { /** 进行切点计算 */ SWRealPoint curPenPoint; curPenPoint.realPoint = point; curPenPoint.radius = radius; 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(); } } } } bool SignPenPainter::CGPointEqualToPoint(const CGPoint &point1, const CGPoint &point2) { return point1.x() == point2.x() && point1.y() == point2.y(); } bool SignPenPainter::GetPointValid(SWRealPoint penPoint) { return true; } CGPoint SignPenPainter::ConvertToCGPoint(SWPointcut cPoint) { return CGPointMake(cPoint.x, cPoint.y); } float SignPenPainter::GetDistanceBetweenPoint(QPointF start, QPointF end) { return sqrt(pow(start.y()-end.y(), 2.0) + pow(start.x()-end.x(), 2.0)); } QPaintDevice *SignPenPainter::PaintDevice() { //绘制buffer if (m_BaseBuf == NULL) { m_BaseBuf = new QImage(m_Size, QImage::Format_ARGB32_Premultiplied);// m_BaseBuf->fill(Qt::transparent); } else if(m_BaseBuf->size() != m_Size) { delete m_BaseBuf; m_BaseBuf = NULL; // m_Buf = new QPixmap(m_Size);//new QImage(ur.size(),QImage::Format_ARGB32);// m_BaseBuf = new QImage(m_Size, QImage::Format_ARGB32_Premultiplied);// m_BaseBuf->fill(Qt::transparent); } return m_BaseBuf; } void SignPenPainter::SynToBaseDevice() { if(m_PaintingBuf != NULL && m_BaseBuf != NULL) { *m_BaseBuf = m_PaintingBuf->copy(); // m_BaseBuf->save(QString("d:/painting_%1.png").arg(previousTimestamp)); } } typedef QPointF CCA_Point; typedef QPointF CCA_GPoint; QList SignPenPainter::GetPenPathData(QPainterPath &data, int pageIndex, QList penDataList, float factorW, float factorH, int offsetX, int offsetY) { QList paths; QPainterPath path; QRect m_VisibleRect = m_PaintRect; // qDebug() << __FUNCTION__ << "========================penDataList.size()=============================" << penDataList.size(); for (int j = 0; j < penDataList.size(); j++) { Element element = penDataList[j]; float x;//控制点x float y;//控制点y float x2; //控制点x2 float y2; //控制点y2 float endX;//结束点X float endY;//结束点Y QPointF point = element.GetEndPoint(); CCA_Point viewPt(point.rx()*factorW + offsetX, point.ry()*factorH + offsetY); // IRF_PageView* pPageView = m_pDocView->GetPageViewAt(pageIndex); // if( pPageView == NULL ) return path; // CCA_GPoint docPt = pPageView->DocPointFromViewPoint(viewPt); CCA_GPoint docPt = viewPt; float ofdX = docPt.x(); float ofdY = docPt.y(); endX = ofdX; endY = ofdY; QPointF controlPoint = element.GetControlPoint(); CCA_Point controlPt(controlPoint.rx()*factorW + offsetX, controlPoint.ry()*factorH + offsetY); // CCA_GPoint docControlPt = pPageView->DocPointFromViewPoint(controlPt); CCA_GPoint docControlPt = controlPt; x = docControlPt.x(); y = docControlPt.y(); QPointF controlPoint2 = element.GetControlPoint2(); CCA_Point controlPt2(controlPoint2.rx()*factorW + offsetX, controlPoint2.ry()*factorH + offsetY); // CCA_GPoint docControlPt2 = pPageView->DocPointFromViewPoint(controlPt2); CCA_GPoint docControlPt2 = controlPt2; x2 = docControlPt2.x(); y2 = docControlPt2.y(); QPointF tempPoint(point.x() + m_VisibleRect.left(), point.y() + m_VisibleRect.top()); QPointF tempConPoint(controlPoint.x() + m_VisibleRect.left(), controlPoint.y() + m_VisibleRect.top()); QPointF tempConPoint2(controlPoint2.x() + m_VisibleRect.left(), controlPoint2.y() + m_VisibleRect.top()); if (j == 0) { // data.StartFigure(docPt.x(), docPt.y()); // qDebug() << __FUNCTION__ << " ==========StartFigure========="; if(element.GetElementType() == MoveToElement) { // qDebug() << __FUNCTION__ << " MoveToElement " << tempPoint; path.moveTo(tempPoint); } else if(element.GetElementType() == QuadToElement) { // qDebug() << __FUNCTION__ << " QuadToElement c: " << tempConPoint << " e: " << tempPoint; path.quadTo(tempConPoint, tempPoint); } else if(element.GetElementType() == CurveToElement) { // qDebug() << __FUNCTION__ << " CurveToElement c1: " << tempConPoint << " c2: " << tempConPoint2 << " e: " << tempPoint; path.cubicTo(tempConPoint, tempConPoint2, tempPoint); } } else if(j == penDataList.size() -1) { // qDebug() << __FUNCTION__ << " ==========CloseFigure========="; if(element.GetElementType() == MoveToElement) { data.moveTo(endX,endX); path.moveTo(tempPoint); } else if(element.GetElementType() == QuadToElement) { data.quadTo(x, y, endX, endY); path.quadTo(tempConPoint, tempPoint); } else if(element.GetElementType() == CurveToElement) { data.cubicTo(x, y, x2, y2, endX, endY); path.cubicTo(tempConPoint, tempConPoint2, tempPoint); } // data.CloseFigure(); paths.append(path); } else { if(element.GetElementType() == StartFigure) { // qDebug() << __FUNCTION__ << " ==========StartFigure========="; paths.append(path); path = QPainterPath(); } else if(element.GetElementType() == MoveToElement) { // qDebug() << __FUNCTION__ << " MoveToElement " << tempPoint; data.moveTo(endX,endX); path.moveTo(tempPoint); } else if(element.GetElementType() == QuadToElement) { // qDebug() << __FUNCTION__ << " QuadToElement c: " << tempConPoint << " e: " << tempPoint; data.quadTo(x, y, endX, endY); path.quadTo(tempConPoint, tempPoint); } else if(element.GetElementType() == CurveToElement) { // qDebug() << __FUNCTION__ << " CurveToElement c1: " << tempConPoint << " c2: " << tempConPoint2 << " e: " << tempPoint; data.cubicTo(x, y, x2, y2, endX, endY); path.cubicTo(tempConPoint, tempConPoint2, tempPoint); } } } // data.CloseFigure(); return paths; } void SignPenPainter::SwPenPathDrawWithPainter(QPainter* bufPainter,bool isEnd) { qDebug() << __FUNCTION__; if( !curAnnotPath) return; //todo // QPainter bufPainter(PaintDevice()); // QPainter bufPainter(PaintingDevice()); bufPainter->setBrush(Qt::black); bufPainter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing bufPainter->setPen(QPen(Qt::NoPen)); bufPainter->translate(-m_PaintRect.left(), -m_PaintRect.top()); // SWAnnotPath* annotPath = drawPaths.last(); SWAnnotPath* annotPath = curAnnotPath; int n = 0; do { // SWAnnotPath* annotPath = curAnnotPath; if (annotPath->points.count() < 2) { return; } // for (QPainterPath bBizer:annotPath.bezierPaths) // { // [bBizer removeAllPoints]; // } // [annotPath.bezierPaths removeAllObjects]; annotPath->bezierPaths.clear(); annotPath->bezierEles.clear(); CGPoint prevPoint = CGPointZero; QList rightPoints; int cursor = 0; QPainterPath pathBizer; pathBizer.setFillRule(Qt::WindingFill); int cIndex = 0; for (int i = 0 ; i < annotPath->points.count(); i++) { SWRealPoint penPoint = annotPath->points[i]; cIndex++; // qDebug() << __FUNCTION__ << cursor; if(i == 0 && isEnd) int jjj = 0; if (GetPointValid(penPoint)) { /** 判断是否为圆形贝塞尔 */ if (penPoint.circleCount > 0) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero)) { rightPoints.append(penPoint); SwPenPathDrawRightWithBezier(&pathBizer, annotPath->bezierEles, penPoint, prevPoint, rightPoints,isEnd); annotPath->bezierPaths.append(pathBizer); } for (int i = 0; i < penPoint.circleCount; i ++) { SWCirclePoint circleP = penPoint.circlePoints[i]; QPainterPath circleBizer; // circleBizer.lineWidth = 0.3f; circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); AddStartPathElement(annotPath->bezierEles); AddMoveToElement(annotPath->bezierEles,ConvertToCGPoint(circleP.pointA)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(annotPath->bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(annotPath->bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(annotPath->bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(annotPath->bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); annotPath->bezierPaths.append(circleBizer); // bufPainter->drawPath(circleBizer); bufPainter->fillPath(circleBizer,QBrush(Qt::black)); } cursor = 0; } else { if (cursor == 0) { // pathBizer.lineWidth = 0.3f; rightPoints.clear(); prevPoint = CGPointZero; if(i != annotPath->points.count()-1) { //最后一个点不进行添加 // bufPainter->drawPath(pathBizer); bufPainter->fillPath(pathBizer,QBrush(Qt::black)); } pathBizer = QPainterPath(); pathBizer.setFillRule(Qt::WindingFill); pathBizer.moveTo(penPoint.pLeftBottomPoint); if(i != annotPath->points.count()-1) { //最后一个点不进行添加 AddStartPathElement(annotPath->bezierEles); AddMoveToElement(annotPath->bezierEles,penPoint.pLeftBottomPoint); } prevPoint = penPoint.pLeftBottomPoint; rightPoints.append(penPoint); // annotPath->bezierPaths.append(pathBizer); } else { // qDebug() << __FUNCTION__ << " cursor != 0 "; rightPoints.append(penPoint); //判断交点是否有效 if (CGPointEqualToPoint(penPoint.PLeftIntersectPoint, CGPointZero)) { // qDebug() << __FUNCTION__ << " cursor != 0 and PLeftIntersectPoint is null"; if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero) && !CGPointEqualToPoint(penPoint.pLeftBottomPoint, CGPointZero)) { // qDebug() << __FUNCTION__ << " cursor != 0 and pLeftTopPoint and pLeftBottomPoint is not null"; CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.pLeftTopPoint.x())/2.f, (prevPoint.y()+penPoint.pLeftTopPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(annotPath->bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftTopPoint; endPoint = CGPointMake((prevPoint.x()+penPoint.pLeftBottomPoint.x())/2.f, (prevPoint.y()+penPoint.pLeftBottomPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(annotPath->bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftBottomPoint; } else { SwPenPathDrawRightWithBezier(&pathBizer,annotPath->bezierEles, penPoint, prevPoint, rightPoints,isEnd); annotPath->bezierPaths.append(pathBizer); // bufPainter->drawPath(pathBizer); bufPainter->fillPath(pathBizer,QBrush(Qt::black)); SWCirclePoint circleP = SWCircleMake(SWPosPointMake(penPoint.realPoint.x(), penPoint.realPoint.y(), penPoint.radius)); QPainterPath circleBizer; circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); AddStartPathElement(annotPath->bezierEles); AddMoveToElement(annotPath->bezierEles,ConvertToCGPoint(circleP.pointA)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(annotPath->bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(annotPath->bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(annotPath->bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(annotPath->bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); // bufPainter->drawPath(circleBizer); bufPainter->fillPath(circleBizer,QBrush(Qt::black)); annotPath->bezierPaths.append(circleBizer); // qDebug() << __FUNCTION__ << " cursor != 0 and pLeftTopPoint or pLeftBottomPoint is null ,to write right."; // SwPenPathDrawRightWithBezier(&pathBizer,annotPath->bezierEles, penPoint, prevPoint, rightPoints,isEnd); // annotPath->bezierPaths.append(pathBizer); // SwPenPathDrawRightWithBezier(&pathBizer,annotPath->bezierEles, penPoint, prevPoint, rightPoints,isEnd); // annotPath->bezierPaths.append(pathBizer); } } else { // qDebug() << __FUNCTION__ << " cursor != 0 PLeftIntersectPoint not null"; CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.PLeftIntersectPoint.x())/2.f, (prevPoint.y()+penPoint.PLeftIntersectPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(annotPath->bezierEles,prevPoint,endPoint); prevPoint = penPoint.PLeftIntersectPoint; // qDebug() << __FUNCTION__ << " PLeftIntersectPoint: " << penPoint.PLeftIntersectPoint.x() << penPoint.PLeftIntersectPoint.y(); } } cursor ++; } } } // bufPainter->drawPath(pathBizer); bufPainter->fillPath(pathBizer,QBrush(Qt::black)); if(drawPaths.count() > n) { annotPath = drawPaths[n]; } n++; // }while(n <= drawPaths.count()); }while(false); //如果抬笔,则进行同步 // if(isEnd) // { // SynToBaseDevice(); // isRelease = true; // } // emit NeedsDisplay(); }