#include "signpaintercachethread_linux.h" #include "signpenpainter.h" #include "signutils.h" #include "sw_log.h" #include #include #include SignPainterCacheThread_Linux::SignPainterCacheThread_Linux() { #ifdef Q_OS_WIN drawCount = 100;//todo 截断后续需要在切点处 200点后进行截断缓存 #else drawCount = 200;//todo 截断后续需要在切点处 200点后进行截断缓存 #endif drawCountOffset = 40;// 200点后,截断到160 // drawCount = 200; // drawCountOffset = 40; drawStartIndex = 0; stressSwitch = 0; stressSpl = 0;//灵敏度 strokeSpl = 2; curAnnotPath = nullptr; m_BaseBuf = nullptr; m_PaintingBuf = nullptr; isPressed = false; m_fPixmapZoom = 1; currentPageIndex = -1; m_fPixmaps = 3; penType = 2; lasttimestamp = QDateTime::currentMSecsSinceEpoch(); lastPaintTimestamp = lasttimestamp; paintFreq = 20; m_PaintRect = QRect(0,0,0,0); m_OriRect = QRect(0,0,0,0); m_ScrollH = 0; } void SignPainterCacheThread_Linux::SetPainterRect(QRect rect) { m_Size = rect.size(); m_PaintRect = rect; // m_PaintRect = QRect(0,0,rect.width(),rect.height()); if(m_OriRect.width() > 0) { m_ScrollH = m_PaintRect.top() - m_OriRect.top(); } } void SignPainterCacheThread_Linux::Init() { drawStartIndex = 0; //压力灵敏度 stressSpl = 0; strokeSpl = 2; stressSwitch = 0; pointSpeed = 10; curAnnotPath = nullptr; m_lastSectionIndex = 0; m_lastSectionPoint = SWRealPoint(); } void SignPainterCacheThread_Linux::AddPoint(QPointF currPoint,int type,float radius,double force,double maxForce) { // SW_Log::Get()->info(QString("====AddPoint x: %1 y: %2 type: %3 radius: %4 force: %5 maxForce: %6 ts: %7" ) // .arg(currPoint.x()).arg(currPoint.y()).arg(type).arg(radius).arg(force).arg(maxForce).arg(QDateTime::currentMSecsSinceEpoch())); // qDebug() << __FUNCTION__ << "====AddPoint : " << currPoint << " type: " << type << " force: " << force << " maxForce: " << maxForce; SWRealPoint realpoint; realpoint.realPoint = currPoint; realpoint.pointType = type; realpoint.radius = radius; realpoint.finalRadius = radius; realpoint.force = force; realpoint.maxForce = maxForce; realpoint.timestamp = QDateTime::currentMSecsSinceEpoch(); if(type == 0) { if(lasttimestamp == realpoint.timestamp) { if(tempPresspoint.timestamp == -1) return; QMutexLocker locker(&m_mutex); m_RealPoints.append(tempPresspoint); tempPresspoint.timestamp = -1; lasttimestamp = realpoint.timestamp; return; } } if(type == 2 && currPoint.x() == 0 && currPoint.y() == 0) { if(curAnnotPath) { if(tempPresspoint.timestamp != -1) { QMutexLocker locker(&m_mutex); m_RealPoints.append(tempPresspoint); tempPresspoint.timestamp = -1; } if(curAnnotPath->realPoints.count() > 0) { realpoint = curAnnotPath->realPoints.last(); realpoint.pointType = type; } } } else if(type == 1) { if(tempPresspoint.timestamp == -1) { tempPresspoint = realpoint; return; } } lasttimestamp = realpoint.timestamp; QMutexLocker locker(&m_mutex); m_RealPoints.append(realpoint); m_Sem.release(); } //只绘当前笔 void SignPainterCacheThread_Linux::PaintWithPainter(QPainter* painter,QRect currentVisibleRect) { if(!curAnnotPath) return; if(curAnnotPath->currentPathsList.count() <= 0) return; painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing QList paths = curAnnotPath->currentPathsList.back(); qDebug() << __FUNCTION__ << " count: " << paths.count(); for(int i = 0 ; i < paths.count();i++) { QPainterPath path = paths.at(i); path.setFillRule(Qt::WindingFill); painter->fillPath(path,QBrush(m_PenColor)); // painter->fillPath(path,QBrush(Qt::red)); } } void SignPainterCacheThread_Linux::SwPenSectionPathDraw(QList points,SWRealPoint endRealPoint,int endFlag) { QPaintDevice* device = PaintingDevice(); QPainterPath BezierPath; QPainter bufPainter(device); // bufPainter.setBrush(Qt::black); bufPainter.setBrush(m_PenColor); bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing bufPainter.setPen(QPen(Qt::NoPen)); QTransform transform; transform.scale(m_fPixmapZoom, m_fPixmapZoom); bufPainter.setTransform(transform); // bufPainter.translate(-m_PaintRect.left(), -m_PaintRect.top()); bufPainter.translate(-m_OriRect.left(), -m_OriRect.top()+m_Size.height()); QList bezierPaths; //绘制的Path QList bezierEles; //绘制 // annotPath->bezierPaths.clear(); // annotPath->bezierEles.clear(); CGPoint prevPoint = CGPointZero; QList rightPoints; int cursor = 0; QPainterPath pathBizer; pathBizer.setFillRule(Qt::WindingFill); int endIndex = points.count(); for (int i = 0 ; i < endIndex; i++) { SWRealPoint penPoint = points[i]; if (GetPointValid(penPoint)) { if (penPoint.circleCount > 0) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero)) { rightPoints.append(penPoint); bool isBeging = rightPoints.first().timestamp == points.first().timestamp; SwPenSectionPathDrawRightWithBezier(&pathBizer, bezierEles, prevPoint, rightPoints,endRealPoint,endFlag,false,isBeging); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,false); } for (int i = 0; i < penPoint.circleCount; i ++) { SWCirclePoint circleP = penPoint.circlePoints[i]; QPainterPath circleBizer; circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw moveTo x: %1 y: %2" ) // .arg(pp.x()).arg(pp.y())); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointB.x).arg(circleP.pointB.y).arg(circleP.pointC.x).arg(circleP.pointC.y).arg(circleP.pointD.x).arg(circleP.pointD.y)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointE.x).arg(circleP.pointE.y).arg(circleP.pointF.x).arg(circleP.pointF.y).arg(circleP.pointG.x).arg(circleP.pointG.y)); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointH.x).arg(circleP.pointH.y).arg(circleP.pointI.x).arg(circleP.pointI.y).arg(circleP.pointJ.x).arg(circleP.pointJ.y)); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointK.x).arg(circleP.pointK.y).arg(circleP.pointL.x).arg(circleP.pointL.y).arg(circleP.pointM.x).arg(circleP.pointM.y)); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); bezierPaths.append(circleBizer); BezierPath.addPath(circleBizer); // bufPainter.drawPath(circleBizer); DrawSignPath(&bufPainter,circleBizer,false); } cursor = 0; } else { if (cursor == 0) { rightPoints.clear(); prevPoint = CGPointZero; // bufPainter.drawPath(pathBizer); // if(i != 0) // { // DrawSignPath(&bufPainter,pathBizer,false); // } pathBizer = QPainterPath(); pathBizer.setFillRule(Qt::WindingFill); if (i == 0 ) { if(endFlag == 1) { CGPoint endPoint = CGPointMake((endRealPoint.PLeftIntersectPoint.x()+penPoint.PLeftIntersectPoint.x())/2.f, (endRealPoint.PLeftIntersectPoint.y()+penPoint.PLeftIntersectPoint.y())/2.f); pathBizer.moveTo(endPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,endPoint); prevPoint = penPoint.PLeftIntersectPoint; rightPoints.append(penPoint); } else { pathBizer.moveTo(penPoint.pLeftBottomPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,penPoint.pLeftBottomPoint); prevPoint = penPoint.pLeftBottomPoint; rightPoints.append(penPoint); } } else { pathBizer.moveTo(penPoint.pLeftBottomPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,penPoint.pLeftBottomPoint); prevPoint = penPoint.pLeftBottomPoint; rightPoints.append(penPoint); } // bezierPaths.append(pathBizer); } else { 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); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo1 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); pathBizer.quadTo(prevPoint,endPoint); } AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftTopPoint; endPoint = CGPointMake((prevPoint.x()+penPoint.pLeftBottomPoint.x())/2.f, (prevPoint.y()+penPoint.pLeftBottomPoint.y())/2.f); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo2 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); pathBizer.quadTo(prevPoint,endPoint); } AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftBottomPoint; } } 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); // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo3 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.PLeftIntersectPoint; //qDebug() << __FUNCTION__ << " PLeftIntersectPoint: " << penPoint.PLeftIntersectPoint.x() << penPoint.PLeftIntersectPoint.y(); } if(i == endIndex-1) { bool isBeging = rightPoints.first().timestamp == points.first().timestamp; SwPenSectionPathDrawRightWithBezier(&pathBizer,bezierEles, prevPoint, rightPoints,endRealPoint,endFlag,true,isBeging); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,false); } } cursor ++; } } } // m_PaintingBuf->save(QString("d:/painting_%1.png").arg(QDateTime::currentMSecsSinceEpoch())); } void SignPainterCacheThread_Linux::SwPenSectionPathDrawRightWithBezier(QPainterPath *bPath, QList &elementList, CGPoint prevPoint, QList rPoints,SWRealPoint endRealPoint,int endFlag,bool isEnd,bool isBegin) { for (int k = (rPoints.count() - 1); k >= 0 ; k --) { SWRealPoint penPoint = rPoints.at(k); if (GetPointValid(penPoint)) { if (k == (rPoints.count() - 1)) { if (isEnd == true) { SWRealPoint prePenPoint = rPoints.at(k - 1); CGPoint endPoint = CGPointMake((prePenPoint.PRightIntersectPoint.x()+penPoint.PRightIntersectPoint.x())/2.f, (prePenPoint.PRightIntersectPoint.y()+penPoint.PRightIntersectPoint.y())/2.f); bPath->quadTo(endPoint,endPoint); AddQuadToElement(elementList,endPoint,endPoint); prevPoint = prePenPoint.PRightIntersectPoint; } else { bPath->quadTo(prevPoint,penPoint.pLeftTopPoint); AddQuadToElement(elementList,prevPoint,penPoint.pLeftTopPoint); prevPoint = penPoint.pLeftTopPoint; bPath->quadTo(prevPoint,penPoint.pRightTopPoint); AddQuadToElement(elementList,prevPoint,penPoint.pRightTopPoint); 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((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; } if (k == 0 ) { if(endFlag == 1 && isBegin == true) { CGPoint endPoint = CGPointMake((penPoint.PRightIntersectPoint.x() + endRealPoint.PRightIntersectPoint.x())/2.f, (penPoint.PRightIntersectPoint.y() + endRealPoint.PRightIntersectPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = endPoint; endPoint = CGPointMake((penPoint.PLeftIntersectPoint.x() + endRealPoint.PLeftIntersectPoint.x())/2.f, (penPoint.PLeftIntersectPoint.y() + endRealPoint.PLeftIntersectPoint.y())/2.f); bPath->quadTo(prevPoint,endPoint); AddQuadToElement(elementList,prevPoint,endPoint); } 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); } } } } } } void SignPainterCacheThread_Linux::Paint(QPainter* painter,QRect currentVisibleRect) { //使用缓冲画布+实时渲染 qDebug() << __FUNCTION__ << " start Paint: " << QDateTime::currentMSecsSinceEpoch(); PaintWithPainter(painter,currentVisibleRect); if(m_PaintingBuf) { // painter->drawImage(m_PaintRect.left(),m_PaintRect.top(),*m_PaintingBuf); qDebug() << __FUNCTION__ << " 1111111 start Paint: m_PaintRect: " << m_PaintRect << " m_OriRect: " << m_OriRect << " m_ScrollH: " << m_ScrollH; painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing painter->drawImage(m_PaintRect.left(), m_PaintRect.top(),*m_PaintingBuf,0,m_Size.height()+m_ScrollH,m_Size.width(),m_Size.height()); // if(m_drawMutex.tryLock(1)) // { // if((int)abs(m_ScrollH) >= m_PaintRect.height()) // { // delete m_PaintingBuf; // m_PaintingBuf = NULL; // } // else // { // qDebug() << __FUNCTION__ << " 1111111 start Paint: m_PaintRect: " << m_PaintRect << " m_OriRect: " << m_OriRect << " m_ScrollH: " << m_ScrollH; // painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing // painter->drawImage(m_PaintRect.left(), m_PaintRect.top(),*m_PaintingBuf,0,m_Size.height()+m_ScrollH,m_Size.width(),m_Size.height()); // } // m_drawMutex.unlock(); // } } qDebug() << __FUNCTION__ << " end Paint: " << QDateTime::currentMSecsSinceEpoch(); return; //全部使用缓冲画布 // qDebug() << __FUNCTION__ ; if(m_PaintingBuf != nullptr && painter) { // QMutexLocker locker(&m_drawMutex); // if(m_drawMutex.tryLock(1)) // { // QImage img = *m_PaintingBuf; painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing // painter->setPen(Qt::NoPen); // painter->drawImage(m_PaintRect.left(),m_PaintRect.top(),*m_PaintingBuf); int viewOffSetW = m_PaintRect.left()-currentVisibleRect.left(); int viewOffSetH = m_PaintRect.top()-currentVisibleRect.top(); if((int)abs(viewOffSetH) >= m_PaintRect.height()) { delete m_PaintingBuf; m_PaintingBuf = NULL; emit NeedsToRefresh(m_PaintRect); } else { // m_PaintingBuf->save(QString("point_%1.png").arg(QDateTime::currentMSecsSinceEpoch())); // painter->drawImage(m_PaintRect.left()+viewOffSetW,m_PaintRect.top()+viewOffSetH,*m_PaintingBuf); painter->drawImage(m_PaintRect.left(),m_PaintRect.top(),*m_PaintingBuf); } m_drawMutex.unlock(); // } // if(!isPressed) // { // if(m_drawMutex.tryLock(1)) // { // // QImage img = *m_PaintingBuf; // painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing // painter->setPen(Qt::NoPen); // painter->drawImage(m_PaintingBuf->rect(),*m_PaintingBuf); // // painter->drawImage(img.rect(),img); // m_drawMutex.unlock(); // } // } // else // { // painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing); //QPainter::Antialiasing // painter->setPen(Qt::NoPen); // if(!curAnnotPath) // return; // QList paths = curAnnotPath->bezierPaths; // for(int i = 0 ; i < paths.count(); i++) // { // paths[i].setFillRule(Qt::WindingFill); // painter->fillPath(paths[i],QBrush(Qt::black)); // } // } } } void SignPainterCacheThread_Linux::ClearDraw() { // SW_Log::Get()->info(QString("to ClearDraw")); m_AnnotMutex.lock(); if(!isPressed) { SW_Log::Get()->info(QString("!isPressed to ClearDraw")); // if(curAnnotPath != nullptr) // delete curAnnotPath; curAnnotPath = nullptr; for(int i = 0 ; i < drawPaths.count();i++) { drawPaths[i]->bezierEles.clear(); drawPaths[i]->bezierPaths.clear(); drawPaths[i]->currentPathsList.clear(); delete drawPaths[i]; drawPaths[i] = nullptr; } drawPaths.clear(); if(m_BaseBuf != nullptr) { delete m_BaseBuf; m_BaseBuf = nullptr; } if(m_PaintingBuf != nullptr) { delete m_PaintingBuf; m_PaintingBuf = nullptr; } m_lastSectionIndex = 0; } m_AnnotMutex.unlock(); emit NeedsToRefresh(m_PaintRect); } void SignPainterCacheThread_Linux::run() { while(true) { m_Sem.acquire(); if (m_RealPoints.isEmpty()) { continue; } m_mutex.lock(); QList points; points.swap(m_RealPoints); m_RealPoints.clear(); m_mutex.unlock(); bool isEnd = false; //计算点 for(int i = 0 ; i < points.count(); i++) { SWRealPoint realPoint = points[i]; if(realPoint.pointType == 0) { if(!isPressed) continue; MouseMoved(realPoint); } else if(realPoint.pointType == 1) { if(isPressed) continue; //press isPressed = true; MousePressd(realPoint); // emit NeedsToRefresh(m_PaintRect); // if(isEnd) // emit ReleasedExcuted(); } else { if(!isPressed) continue; isPressed = false; MouseReleased(realPoint); isEnd = true; QPainterPath path = SwPenPathDraw(isEnd,false); QRectF rect = path.boundingRect(); if(curAnnotPath && curAnnotPath->points.count() <= 2) emit NeedsToRefresh(m_PaintRect); else emit NeedsToRefresh(QRect(rect.x()-5,rect.y()-5,rect.width()+10,rect.height()+10)); if(isEnd) emit ReleasedExcuted(); } } //检查是否快速写导致部分数据没有刷新到缓存,进行缓存 for(int i = 0 ; i < drawPaths.count();i++) { if(drawPaths.at(i)->bezierEles.isEmpty() && drawPaths.at(i)->realPoints.count()>2 && !drawPaths.at(i)->isPainted&& curAnnotPath!=drawPaths.at(i)) { //需要重绘 SwPenPathDraw(drawPaths[i],true,false); } drawPaths[i]->isPainted = true; } //画到缓冲 if(curAnnotPath) { if(!isEnd) { QPainterPath path; if(curAnnotPath->points.count() > drawStartIndex + drawCount) { drawStartIndex += (drawCount-drawCountOffset); path = SwPenPathDraw(isEnd,true); } else { path = SwPenPathDraw(isEnd,false); } qint64 currentTs = QDateTime::currentMSecsSinceEpoch(); // if(currentTs - lastPaintTimestamp < paintFreq) // continue; lastPaintTimestamp = currentTs; QRectF rect = path.boundingRect(); qDebug() << __FUNCTION__ << " ts: " << QDateTime::currentMSecsSinceEpoch(); // emit NeedsToRefresh(QRect(rect.x()-5,rect.y()-5,rect.width()+10,rect.height()+10)); emit NeedsToRefresh(m_PaintRect); } } } } void SignPainterCacheThread_Linux::MouseMoved(const SWRealPoint& realPoint) { // qDebug() << __FUNCTION__ <realPoints.count() <= 0) { SWRealPoint curPenPoint; curPenPoint.realPoint = currentPoint; curPenPoint.radius = realPoint.radius; curPenPoint.finalRadius = realPoint.radius; curPenPoint.force = realPoint.force; curPenPoint.maxForce = realPoint.maxForce; curPenPoint.timestamp = realPoint.timestamp; curAnnotPath->realPoints.append(curPenPoint); curAnnotPath->points.append(curPenPoint); return; } /** 判断临近相同点,并过滤 */ if (!CGPointEqualToPoint(currentPoint, curAnnotPath->realPoints.last().realPoint) || GetDistanceBetweenPoint(currentPoint, curAnnotPath->realPoints.last().realPoint) > 500) { /** 计算速度半径 */ //todo 计算速度 float penRadius = realPoint.radius; float finalRadius = realPoint.finalRadius; double force = realPoint.force; double maxForce = realPoint.maxForce; float newLineRadius = 0; if (penType == 2) { newLineRadius = penRadius; } else { qint64 currentTimestamp = realPoint.timestamp; float distance = GetDistanceBetweenPoint(curAnnotPath->points.last().realPoint, currentPoint); pointSpeed = distance / ((currentTimestamp - previousTimestamp)) * 1000; newLineRadius = CalculatePointradius(pointSpeed > 0 ? pointSpeed : 0, preLineRadius, penRadius,force,maxForce,stressSpl,stressSwitch,distance); previousTimestamp = realPoint.timestamp; preLineRadius = newLineRadius; // SW_Log::Get()->info(QString("====currentPoint x: %6 y: %7 pointSpeed: %1 newLineRadius: %2 penRadius: %3 stressSwitch: %8 force: %4 maxForce: %5 ") // .arg(pointSpeed).arg(newLineRadius).arg(penRadius).arg(force).arg(maxForce).arg(currentPoint.x()).arg(currentPoint.y()).arg(stressSwitch)); } SWRealPoint curPenPoint; curPenPoint.realPoint = currentPoint; curPenPoint.radius = newLineRadius; curPenPoint.timestamp = realPoint.timestamp; 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(curAnnotPath,centerPoint, newLineRadius, true, false,curAnnotPath->realPoints.at(1).timestamp); 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(curAnnotPath,CGPointMake(x,y), newLineRadius, true, false,curAnnotPath->realPoints.at(realPointCount - 1).timestamp); } // qDebug() << __FUNCTION__ << "after: " << QDateTime::currentMSecsSinceEpoch(); // [self swPenPathDraw]; // SwPenPathDraw(false); //移动过程中,只进行部分绘制 // SwPenPathDraw2(false); } } void SignPainterCacheThread_Linux::MousePressd(const SWRealPoint& realPoint) { qDebug() << __FUNCTION__ <points.append(rPoint); annotPath->realPoints.append(rPoint); annotPath->isShake = false; annotPath->pageIndex = currentPageIndex; annotPath->paintRect = m_PaintRect; m_AnnotMutex.lock(); curAnnotPath = annotPath; m_AnnotMutex.unlock(); SWPosRest(SWPosPointMake(currentPoint.x(), currentPoint.y(), preLineRadius)); } void SignPainterCacheThread_Linux::MouseReleased(const SWRealPoint& realPoint) { SW_Log::Get()->info(QString("SignPainterCacheThread_Linux::MouseReleased: point: %1 %2 ") .arg(realPoint.realPoint.x()).arg(realPoint.realPoint.y())); qDebug() << __FUNCTION__ <isEnd = true; int pointCount = curAnnotPath->points.count(); SW_Log::Get()->info(QString("SignPainterCacheThread_Linux::MouseReleased: before count: %1 ").arg(pointCount)); if(pointCount == 0) { curAnnotPath->points.append(realPoint); curAnnotPath->realPoints.append(realPoint); pointCount = 1; } if (pointCount == 1) { SW_Log::Get()->info(QString("SignPainterCacheThread_Linux::MouseReleased: count: %1 point: %2 %3 ").arg(pointCount) .arg(realPoint.realPoint.x()).arg(realPoint.realPoint.y())); if(!CGPointEqualToPoint(realPoint.realPoint,CGPointZero)) { SwPenPathDrawPoint(curAnnotPath->points.last()); } else { curAnnotPath = nullptr; } } else { if (pointSpeed >= MinSpeed && pointCount > 3 && penType == 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(curAnnotPath,CGPointMake(tempPoint.realPoint.x(), tempPoint.realPoint.y()), tempPoint.radius ,false,false,pointPack[k].timestamp); } //todo refresh // [self swPenPathDraw]; //从头从新绘制 // SwPenPathDraw(true); drawPaths.append(curAnnotPath); free( posAry); } else { if (pointCount > 1) { SWRealPoint firstPoint = curAnnotPath->points.at(pointCount - 2); SWRealPoint secondPoint = curAnnotPath->points.at(pointCount - 1); double distance = GetDistanceBetweenPoint(firstPoint.realPoint,secondPoint.realPoint); if (distance < (firstPoint.radius + secondPoint.radius)*2 && firstPoint.circleCount == 0) { SWRealPoint tempPoint = curAnnotPath->points.at(pointCount - 1); tempPoint.circleCount = 0; curAnnotPath->points.removeAt(pointCount - 1); CalculatePointcutWihtPoint(curAnnotPath,CGPointMake(tempPoint.realPoint.x(), tempPoint.realPoint.y()), tempPoint.radius,false,true,tempPoint.timestamp); } } //todo refresh // [self swPenPathDraw]; // SwPenPathDraw(true); drawPaths.append(curAnnotPath); } } } QPaintDevice *SignPainterCacheThread_Linux::PaintingDevice() { QSize size(m_Size.width() * m_fPixmapZoom,m_Size.height() * m_fPixmapZoom *m_fPixmaps); //绘制buffer if (m_PaintingBuf == NULL) { m_PaintingBuf = new QImage(size, QImage::Format_ARGB32_Premultiplied); m_PaintingBuf->fill(Qt::transparent); m_OriRect = m_PaintRect; m_ScrollH = 0; } else if(m_PaintingBuf->size() != size) { delete m_PaintingBuf; m_PaintingBuf = NULL; m_PaintingBuf = new QImage(size, QImage::Format_ARGB32_Premultiplied); m_PaintingBuf->fill(Qt::transparent); m_OriRect = m_PaintRect; m_ScrollH = 0; } // else // { // delete m_PaintingBuf; // m_PaintingBuf = NULL; // m_PaintingBuf = new QImage(size, QImage::Format_ARGB32_Premultiplied); // m_PaintingBuf->fill(Qt::transparent); // } if (m_BaseBuf == NULL) { m_BaseBuf = new QImage(size, QImage::Format_ARGB32_Premultiplied); // m_BaseBuf->fill(Qt::transparent); } else if(m_BaseBuf->size() != size) { delete m_BaseBuf; m_BaseBuf = NULL; // m_Buf = new QPixmap(m_Size);//new QImage(ur.size(),QImage::Format_ARGB32);// m_BaseBuf = new QImage(size, QImage::Format_ARGB32_Premultiplied);// m_BaseBuf->fill(Qt::transparent); } // QMutexLocker locker(&m_drawMutex); // *m_PaintingBuf = m_BaseBuf->copy(); // m_PaintingBuf = new QImage(m_Size, QImage::Format_ARGB32_Premultiplied); // m_PaintingBuf->fill(Qt::transparent); return m_PaintingBuf; } QPaintDevice *SignPainterCacheThread_Linux::PaintedDevice() { return PaintingDevice();//TODO 不使用二级缓存,减少频闪,存在锯齿大问题 QSize size(m_Size.width() * m_fPixmapZoom,m_Size.height() * m_fPixmapZoom); //绘制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() != size) { delete m_BaseBuf; m_BaseBuf = NULL; m_BaseBuf = new QImage(size, QImage::Format_ARGB32_Premultiplied); m_BaseBuf->fill(Qt::transparent); } return m_BaseBuf; } void SignPainterCacheThread_Linux::DrawSignPath(QPainter *painter, const QPainterPath &path,bool isEnd) { if(isEnd || painter == NULL) return; painter->fillPath(path,QBrush(m_PenColor)); // painter->fillPath(path,QBrush(Qt::red)); } void SignPainterCacheThread_Linux::SwPenPathDrawPoint(SWRealPoint point) { QPaintDevice* device = PaintingDevice(); QPainterPath BezierPath; //todo QPainter bufPainter(device); // bufPainter.setBrush(Qt::black); bufPainter.setBrush(m_PenColor); bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing bufPainter.setPen(QPen(Qt::NoPen)); QTransform transform; transform.scale(m_fPixmapZoom, m_fPixmapZoom); bufPainter.setTransform(transform); bufPainter.translate(-m_PaintRect.left(), -m_PaintRect.top()); m_AnnotMutex.lock(); SWAnnotPath* annotPath = curAnnotPath; m_AnnotMutex.unlock(); annotPath->bezierPaths.clear(); annotPath->bezierEles.clear(); //构建顿笔点 int pathCount = 4; int leftCount = rand()%5 + 2; CGPoint endPoint = CGPointMake(point.realPoint.x() + leftCount,point.realPoint.y()+pathCount); //设置路径点数 int segments = 5; CGPoint onePoint = point.realPoint; CGPoint twoPoint = endPoint; CGPoint ctrPoint = CGPointMake((onePoint.x()+twoPoint.x())/2.f, (onePoint.y()+twoPoint.y())/2.f); for (int i = 0;i < segments;i++) { double t = (double)i/segments; 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(); SWCirclePoint circleP = SWCircleMake(SWPosPointMake(x, y, point.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); DrawSignPath(&bufPainter,circleBizer,false);//todo } drawPaths.append(curAnnotPath); if(m_PaintingBuf != NULL && m_BaseBuf != NULL) { QMutexLocker locker(&m_drawMutex); // *m_PaintingBuf = m_BaseBuf->copy();//TODO 不使用二级缓存,减少频闪,存在锯齿大问题 } } void SignPainterCacheThread_Linux::SwPenPathDrawRightPoint(QPainterPath *bPath, QList &elementList,SWRealPoint prePenPoint, CGPoint prevPoint, QList rPoints,SWRealPoint lastPoint) { CGPoint endPoint = CGPointZero; if (penType == 1) { endPoint = CGPointMake((prePenPoint.pLeftTopPoint.x() + prevPoint.x())/2.f, (prePenPoint.pLeftTopPoint.y() + prevPoint.y())/2.f); if(prevPoint.x() != 0 && prevPoint.y() != 0) { bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); } else { endPoint = prePenPoint.pLeftTopPoint; if(prevPoint.x() != 0 && prevPoint.y() != 0) { bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); } prevPoint = prePenPoint.pLeftTopPoint; for (int k = (rPoints.count() - 1); k >= 0 ; k --) { SWRealPoint penPoint = rPoints.at(k); if (GetPointValid(penPoint)) { if (k == (rPoints.count() - 1)) { if (penType == 1) { CGPoint endPoint = CGPointMake((prevPoint.x() + penPoint.pRightTopPoint.x())/2.f, (prevPoint.y() + penPoint.pRightTopPoint.y())/2.f); if(prevPoint.x() != 0 && prevPoint.y() != 0) { bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = penPoint.pRightTopPoint; SWRealPoint thirdPoint = rPoints.at(k - 1); if (!CGPointEqualToPoint(thirdPoint.PRightIntersectPoint, CGPointZero)) { endPoint = CGPointMake((prevPoint.x() + thirdPoint.PRightIntersectPoint.x())/2.f, (prevPoint.y() + thirdPoint.PRightIntersectPoint.y())/2.f); } else { endPoint = CGPointMake((prevPoint.x() + thirdPoint.pRightBottomPoint.x())/2.f, (prevPoint.y() + thirdPoint.pRightBottomPoint.y())/2.f); } if(prevPoint.x() != 0 && prevPoint.y() != 0) { bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = CGPointEqualToPoint(thirdPoint.PRightIntersectPoint, CGPointZero) ? thirdPoint.pRightBottomPoint : thirdPoint.PRightIntersectPoint; k--; /** * 判断是否到结尾 */ // if (k == startIndex) { if (k == 0) { //绘制开始连接点 if(thirdPoint.pRightBottomPoint.x() != 0 && thirdPoint.pRightBottomPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo8 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(thirdPoint.pRightBottomPoint.x()).arg(thirdPoint.pRightBottomPoint.y()).arg(thirdPoint.pRightBottomPoint.x()).arg(thirdPoint.pRightBottomPoint.y())); bPath->quadTo(thirdPoint.pRightBottomPoint,thirdPoint.pRightBottomPoint); } AddQuadToElement(elementList,thirdPoint.pRightBottomPoint,thirdPoint.pRightBottomPoint); prevPoint = thirdPoint.pRightBottomPoint; SWRealPoint firstPen = rPoints.first(); if(firstPen.pRightBottomPoint.x() != 0 && firstPen.pRightBottomPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo9 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(firstPen.pRightBottomPoint.x()).arg(firstPen.pRightBottomPoint.y()).arg(firstPen.pLeftBottomPoint.x()).arg(firstPen.pRightBottomPoint.y())); 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; if (!CGPointEqualToPoint(lastPoint.realPoint, CGPointZero) && k == 0) { SWRealPoint firstPen = rPoints.first(); endPoint = CGPointMake((lastPoint.PRightIntersectPoint.x()+firstPen.PRightIntersectPoint.x())/2.f, (lastPoint.PRightIntersectPoint.y()+firstPen.PRightIntersectPoint.y())/2.f); bPath->quadTo(penPoint.PRightIntersectPoint,endPoint); AddQuadToElement(elementList,penPoint.PRightIntersectPoint,endPoint); endPoint = CGPointMake((penPoint.PLeftIntersectPoint.x() + lastPoint.PLeftIntersectPoint.x())/2.f, (penPoint.PLeftIntersectPoint.y() + lastPoint.PLeftIntersectPoint.y())/2.f); bPath->quadTo(endPoint,endPoint); } } } } } } void SignPainterCacheThread_Linux::SwPenPathDrawLeftPoint(QList points,SWRealPoint endRealPoint){ QPaintDevice* device = PaintingDevice(); QPainterPath BezierPath; QPainter bufPainter(device); bufPainter.setBrush(m_PenColor); bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing bufPainter.setPen(QPen(Qt::NoPen)); QTransform transform; transform.scale(m_fPixmapZoom, m_fPixmapZoom); bufPainter.setTransform(transform); // bufPainter.translate(-m_PaintRect.left(), -m_PaintRect.top()); bufPainter.translate(-m_OriRect.left(), -m_OriRect.top()+m_Size.height()); qDebug() << __FUNCTION__ << " 1111111 start SwPenPathDrawLeftPoint: m_PaintRect: " << m_PaintRect << " m_OriRect: " << m_OriRect << " m_ScrollH: " << m_ScrollH; // SW_Log::Get()->info(QString("SwPenPathDrawLeftPoint : m_PaintRect: %1,%2,%3,%4 m_OriRect: %5 %6 %7 %8 m_ScrollH: %9") // .arg(m_PaintRect.left()).arg(m_PaintRect.top()).arg(m_PaintRect.width()).arg(m_PaintRect.height()) // .arg(m_OriRect.left()).arg(m_OriRect.top()).arg(m_OriRect.width()).arg(m_OriRect.height()).arg(m_ScrollH)); QList bezierPaths; //绘制的Path QList bezierEles; //绘制 CGPoint prevPoint = CGPointZero; QList rightPoints; int cursor = 0; QPainterPath pathBizer; pathBizer.setFillRule(Qt::WindingFill); int endIndex = points.count(); for (int i = 0 ; i < endIndex; i++) { SWRealPoint penPoint = points[i]; if (GetPointValid(penPoint)) { if (penPoint.circleCount > 0) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero)) { rightPoints.append(penPoint); SwPenPathDrawRightPoint(&pathBizer, bezierEles,penPoint, prevPoint, rightPoints,endRealPoint); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,false); } for (int i = 0; i < penPoint.circleCount; i ++) { SWCirclePoint circleP = penPoint.circlePoints[i]; QPainterPath circleBizer; circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw moveTo x: %1 y: %2" ) // .arg(pp.x()).arg(pp.y())); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointB.x).arg(circleP.pointB.y).arg(circleP.pointC.x).arg(circleP.pointC.y).arg(circleP.pointD.x).arg(circleP.pointD.y)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointE.x).arg(circleP.pointE.y).arg(circleP.pointF.x).arg(circleP.pointF.y).arg(circleP.pointG.x).arg(circleP.pointG.y)); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointH.x).arg(circleP.pointH.y).arg(circleP.pointI.x).arg(circleP.pointI.y).arg(circleP.pointJ.x).arg(circleP.pointJ.y)); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointK.x).arg(circleP.pointK.y).arg(circleP.pointL.x).arg(circleP.pointL.y).arg(circleP.pointM.x).arg(circleP.pointM.y)); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); bezierPaths.append(circleBizer); BezierPath.addPath(circleBizer); // bufPainter.drawPath(circleBizer); DrawSignPath(&bufPainter,circleBizer,false); } cursor = 0; } else { if (cursor == 0) { rightPoints.clear(); prevPoint = CGPointZero; pathBizer = QPainterPath(); pathBizer.setFillRule(Qt::WindingFill); if (i == 0 ) { CGPoint endPoint = CGPointMake((endRealPoint.PLeftIntersectPoint.x()+penPoint.PLeftIntersectPoint.x())/2.f, (endRealPoint.PLeftIntersectPoint.y()+penPoint.PLeftIntersectPoint.y())/2.f); pathBizer.moveTo(endPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,endPoint); prevPoint = penPoint.PLeftIntersectPoint; rightPoints.append(penPoint); } else { pathBizer.moveTo(penPoint.pLeftBottomPoint); AddStartPathElement(bezierEles); AddMoveToElement(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(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(bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftBottomPoint; } else { SwPenPathDrawRightPoint(&pathBizer,bezierEles, penPoint,prevPoint, rightPoints,endRealPoint); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,false); } } else { CGPoint endPoint = CGPointMake((prevPoint.x()+penPoint.PLeftIntersectPoint.x())/2.f, (prevPoint.y()+penPoint.PLeftIntersectPoint.y())/2.f); pathBizer.quadTo(prevPoint,endPoint); AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.PLeftIntersectPoint; } } cursor ++; } } } // m_PaintingBuf->save(QString("d:/painting_%1.png").arg(QDateTime::currentMSecsSinceEpoch())); } // 进行实时的方法 QPainterPath SignPainterCacheThread_Linux::SwPenPathDraw(bool isEnd,bool flushSection) { m_AnnotMutex.lock(); SWAnnotPath* annotPath = curAnnotPath; m_AnnotMutex.unlock(); // QPaintDevice* device; // if(isEnd) // { // device = PaintedDevice(); // } // else // { // device = PaintingDevice(); // } // device = PaintingDevice(); QPainterPath BezierPath; //todo // QPainter bufPainter(device); //// bufPainter.setBrush(Qt::black); // bufPainter.setBrush(m_PenColor); // bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing // bufPainter.setPen(QPen(Qt::NoPen)); // QTransform transform; // transform.scale(m_fPixmapZoom, m_fPixmapZoom); // bufPainter.setTransform(transform); // bufPainter.translate(-m_PaintRect.left(), -m_PaintRect.top()); if(!annotPath) return BezierPath; if (annotPath->points.count() < 2) { return BezierPath; } QList bezierPaths; //绘制的Path QList bezierEles; //绘制 // annotPath->bezierPaths.clear(); // annotPath->bezierEles.clear(); int cutPointFlag = 0; int cutOffSet = 5; if(!isEnd && annotPath) { int pointsCount = annotPath->points.count(); if(pointsCount - m_lastSectionIndex > drawCount) { int cutIndex = -1; //进行截断处判断是否为补点 for(int i = (m_lastSectionIndex + drawCount - cutOffSet - 1);i >= 0 ;i --) { if (i > 0) { SWRealPoint cutPoint = annotPath->points.at(i); SWRealPoint endRealPoint = annotPath->points.at(i - 1); if(cutPoint.circleCount == 0 && !CGPointEqualToPoint(cutPoint.PLeftIntersectPoint, CGPointZero) && endRealPoint.circleCount == 0 && !CGPointEqualToPoint(endRealPoint.PLeftIntersectPoint, CGPointZero)) { cutIndex = i; break; } } } if (cutIndex != -1) { QList points = annotPath->points.mid(m_lastSectionIndex,cutIndex - m_lastSectionIndex +1); m_lastSectionPoint = annotPath->points.at(cutIndex - 1); if (m_lastSectionIndex == 0) { SwPenSectionPathDraw(points,SWRealPoint(),0); } else { SWRealPoint endRealPoint = annotPath->points.at(m_lastSectionIndex - 1); SwPenSectionPathDraw(points,endRealPoint,1); } m_lastSectionIndex = cutIndex; } } } else if(isEnd && annotPath) { QList points = annotPath->points.mid(m_lastSectionIndex,annotPath->points.count() - m_lastSectionIndex); if (m_lastSectionIndex == 0) { SwPenPathDrawLeftPoint(points,SWRealPoint()); } else { SWRealPoint endRealPoint = annotPath->points.at(m_lastSectionIndex - 1); SwPenPathDrawLeftPoint(points,endRealPoint); } } CGPoint prevPoint = CGPointZero; QList rightPoints; int cursor = 0; QPainterPath pathBizer; pathBizer.setFillRule(Qt::WindingFill); int endIndex = annotPath->points.count(); int startIndex = m_lastSectionIndex; if(isEnd) { startIndex = 0; m_lastSectionIndex = 0; m_lastSectionPoint = SWRealPoint(); } for (int i = startIndex ; i < endIndex; i++) { SWRealPoint penPoint = annotPath->points[i]; if (GetPointValid(penPoint)) { /** 判断是否为圆形贝塞尔 */ if (penPoint.circleCount > 0) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero)) { rightPoints.append(penPoint); bool isBeging = rightPoints.first().timestamp == annotPath->points.at(startIndex).timestamp; SwPenPathDrawRightWithBezier(&pathBizer, bezierEles, penPoint, prevPoint, rightPoints,isEnd,flushSection,m_lastSectionPoint,isBeging); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); // DrawSignPath(&bufPainter,pathBizer,isEnd); DrawSignPath(NULL,pathBizer,isEnd); } for (int i = 0; i < penPoint.circleCount; i ++) { SWCirclePoint circleP = penPoint.circlePoints[i]; QPainterPath circleBizer; // circleBizer.lineWidth = 0.3f; CGPoint pp = ConvertToCGPoint(circleP.pointA); circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw moveTo x: %1 y: %2" ) // .arg(pp.x()).arg(pp.y())); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointB.x).arg(circleP.pointB.y).arg(circleP.pointC.x).arg(circleP.pointC.y).arg(circleP.pointD.x).arg(circleP.pointD.y)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointE.x).arg(circleP.pointE.y).arg(circleP.pointF.x).arg(circleP.pointF.y).arg(circleP.pointG.x).arg(circleP.pointG.y)); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointH.x).arg(circleP.pointH.y).arg(circleP.pointI.x).arg(circleP.pointI.y).arg(circleP.pointJ.x).arg(circleP.pointJ.y)); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointK.x).arg(circleP.pointK.y).arg(circleP.pointL.x).arg(circleP.pointL.y).arg(circleP.pointM.x).arg(circleP.pointM.y)); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); bezierPaths.append(circleBizer); BezierPath.addPath(circleBizer); // bufPainter.drawPath(circleBizer); // DrawSignPath(&bufPainter,circleBizer,isEnd); DrawSignPath(NULL,circleBizer,isEnd); } cursor = 0; } else { if (cursor == 0) { rightPoints.clear(); prevPoint = CGPointZero; // bufPainter.drawPath(pathBizer); if(i != startIndex) { // bezierPaths.append(pathBizer); // BezierPath.addPath(pathBizer); // DrawSignPath(&bufPainter,pathBizer,isEnd); DrawSignPath(NULL,pathBizer,isEnd); } pathBizer = QPainterPath(); pathBizer.setFillRule(Qt::WindingFill); if(i != endIndex-1) { //最后一个点不进行添加 // SW_Log::Get()->info(QString("====SwPenPathDraw moveTo x: %1 y: %2" ) // .arg(penPoint.pLeftBottomPoint.x()).arg(penPoint.pLeftBottomPoint.y())); } if (!CGPointEqualToPoint(m_lastSectionPoint.realPoint, CGPointZero) && i == m_lastSectionIndex) { CGPoint endPoint = CGPointMake((m_lastSectionPoint.PLeftIntersectPoint.x()+penPoint.PLeftIntersectPoint.x())/2.f, (m_lastSectionPoint.PLeftIntersectPoint.y()+penPoint.PLeftIntersectPoint.y())/2.f); pathBizer.moveTo(endPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,endPoint); prevPoint = penPoint.PLeftIntersectPoint; rightPoints.append(penPoint); } else { pathBizer.moveTo(penPoint.pLeftBottomPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,penPoint.pLeftBottomPoint); prevPoint = penPoint.pLeftBottomPoint; rightPoints.append(penPoint); } // bezierPaths.append(pathBizer); } else { // qDebug() << __FUNCTION__ << " cursor != 0 "; rightPoints.append(penPoint); if(/*flushSection &&*/ i == endIndex-1 && endIndex != annotPath->points.count()) { bool isBeging = rightPoints.first().timestamp == annotPath->points.at(startIndex).timestamp; SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd,flushSection,m_lastSectionPoint,isBeging); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); // bufPainter.drawPath(pathBizer); // DrawSignPath(&bufPainter,pathBizer,isEnd); DrawSignPath(NULL,pathBizer,isEnd); // bufPainter.setPen(QPen(Qt::green, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // bufPainter.drawPoint(penPoint.realPoint); } else { //判断交点是否有效 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); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo1 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); pathBizer.quadTo(prevPoint,endPoint); } AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftTopPoint; endPoint = CGPointMake((prevPoint.x()+penPoint.pLeftBottomPoint.x())/2.f, (prevPoint.y()+penPoint.pLeftBottomPoint.y())/2.f); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo2 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); pathBizer.quadTo(prevPoint,endPoint); } AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftBottomPoint; } else { bool isBeging = rightPoints.first().timestamp == annotPath->points.at(startIndex).timestamp; SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd,flushSection,m_lastSectionPoint,isBeging); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); // bufPainter.drawPath(pathBizer); // DrawSignPath(&bufPainter,pathBizer,isEnd); DrawSignPath(NULL,pathBizer,isEnd); if(!isEnd) { SWCirclePoint circleP = SWCircleMake(SWPosPointMake(penPoint.realPoint.x(), penPoint.realPoint.y(), penPoint.radius)); QPainterPath circleBizer; CGPoint pp = ConvertToCGPoint(circleP.pointA); // SW_Log::Get()->info(QString("====SwPenPathDraw moveTo x: %1 y: %2" ) // .arg(pp.x()).arg(pp.y())); circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,ConvertToCGPoint(circleP.pointA)); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointB.x).arg(circleP.pointB.y).arg(circleP.pointC.x).arg(circleP.pointC.y).arg(circleP.pointD.x).arg(circleP.pointD.y)); circleBizer.cubicTo(circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); AddCurveToElement(bezierEles,circleP.pointB.x,circleP.pointB.y, circleP.pointC.x,circleP.pointC.y,circleP.pointD.x,circleP.pointD.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointE.x).arg(circleP.pointE.y).arg(circleP.pointF.x).arg(circleP.pointF.y).arg(circleP.pointG.x).arg(circleP.pointG.y)); circleBizer.cubicTo(circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); AddCurveToElement(bezierEles,circleP.pointE.x,circleP.pointE.y, circleP.pointF.x,circleP.pointF.y,circleP.pointG.x,circleP.pointG.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointH.x).arg(circleP.pointH.y).arg(circleP.pointI.x).arg(circleP.pointI.y).arg(circleP.pointJ.x).arg(circleP.pointJ.y)); circleBizer.cubicTo(circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); AddCurveToElement(bezierEles,circleP.pointH.x,circleP.pointH.y, circleP.pointI.x,circleP.pointI.y,circleP.pointJ.x,circleP.pointJ.y); // SW_Log::Get()->info(QString("====SwPenPathDraw cubicTo cx1: %1 cy: %2 cx2: %3 cy2: %4 ex:%5 ey: %6" ) // .arg(circleP.pointK.x).arg(circleP.pointK.y).arg(circleP.pointL.x).arg(circleP.pointL.y).arg(circleP.pointM.x).arg(circleP.pointM.y)); circleBizer.cubicTo(circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); AddCurveToElement(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); // bufPainter.drawPath(circleBizer); // DrawSignPath(&bufPainter,circleBizer,isEnd); DrawSignPath(NULL,circleBizer,isEnd); bezierPaths.append(circleBizer); BezierPath.addPath(circleBizer); // qDebug() << __FUNCTION__ << " cursor != 0 and pLeftTopPoint or pLeftBottomPoint is null ,to write right."; // SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd); // bezierPaths.append(pathBizer); // SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd); // 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); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo3 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); pathBizer.quadTo(prevPoint,endPoint); } AddQuadToElement(bezierEles,prevPoint,endPoint); prevPoint = penPoint.PLeftIntersectPoint; // qDebug() << __FUNCTION__ << " PLeftIntersectPoint: " << penPoint.PLeftIntersectPoint.x() << penPoint.PLeftIntersectPoint.y(); } } } cursor ++; } } } cutPointFlag = 0; //如果抬笔,则进行同步 if(isEnd) { if(annotPath) { annotPath->bezierEles = bezierEles; annotPath->bezierPaths = bezierPaths; annotPath->currentPathsList.clear(); } // if(m_PaintingBuf) // m_PaintingBuf->save(QString("d:/painting_%1.png").arg(QDateTime::currentMSecsSinceEpoch())); } else { annotPath->currentPathsList.append(bezierPaths); } // else // todo 非抬笔,不更新缓存 // { // if(annotPath) // { // annotPath->bezierPaths = bezierPaths; // annotPath->bezierEles = bezierEles; // } // } return BezierPath; // if(isContinue) // { // if(m_PaintingBuf != NULL && m_BaseBuf != NULL) // { // *m_PaintingBuf = m_BaseBuf->copy(); // } // } } // 进行缓存的方法(速度过快没有渲染上的) QPainterPath SignPainterCacheThread_Linux::SwPenPathDraw(SWAnnotPath *annotPath,bool isEnd,bool flushSection) { return QPainterPath(); qDebug() << __FUNCTION__ << "===========================8888888888888888888899999999999999999999999999999999999"; QPaintDevice* device; // if(!flushSection) // { // device = PaintedDevice(); //// qDebug() << __FUNCTION__ << "=========================================="; // } // else // { // device = PaintingDevice(); //// qDebug() << __FUNCTION__ << "******************************************"; // } if(isEnd) { device = PaintedDevice(); } else { device = PaintingDevice(); } // device = PaintingDevice(); QPainterPath BezierPath; //todo QPainter bufPainter(device); // bufPainter.setBrush(Qt::black); bufPainter.setBrush(m_PenColor); bufPainter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::HighQualityAntialiasing | QPainter::NonCosmeticDefaultPen | QPainter::NonCosmeticDefaultPen,true); //QPainter::Antialiasing // bufPainter.setPen(QPen(Qt::NoPen)); QTransform transform; transform.scale(m_fPixmapZoom, m_fPixmapZoom); bufPainter.setTransform(transform); bufPainter.translate(-annotPath->paintRect.left(), -annotPath->paintRect.top()); if(!annotPath) return BezierPath; if (annotPath->points.count() < 2) { return BezierPath; } QList bezierPaths; //绘制的Path QList bezierEles; //绘制 // annotPath->bezierPaths.clear(); // annotPath->bezierEles.clear(); CGPoint prevPoint = CGPointZero; QList rightPoints; int cursor = 0; QPainterPath pathBizer; pathBizer.setFillRule(Qt::WindingFill); int endIndex = flushSection&&!isEnd ? annotPath->points.count() - drawCount/2 : annotPath->points.count(); // int endIndex = annotPath->points.count(); if(flushSection) { endIndex = (drawCount-drawCountOffset); qDebug() << __FUNCTION__ << " startInde: " << drawStartIndex << " endIndex: " << endIndex; } int startIndex = drawStartIndex; if(isEnd) { startIndex = 0; endIndex = annotPath->points.count(); } for (int i = startIndex ; i < endIndex; i++) { SWRealPoint penPoint = annotPath->points[i]; if (GetPointValid(penPoint)) { /** 判断是否为圆形贝塞尔 */ if (penPoint.circleCount > 0) { if (!CGPointEqualToPoint(penPoint.pLeftTopPoint, CGPointZero)) { rightPoints.append(penPoint); SwPenPathDrawRightWithBezier(&pathBizer, bezierEles, penPoint, prevPoint, rightPoints,isEnd,flushSection,SWRealPoint(),false); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,isEnd); } 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(bezierEles); AddMoveToElement(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(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(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(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(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); bezierPaths.append(circleBizer); BezierPath.addPath(circleBizer); // bufPainter.drawPath(circleBizer); DrawSignPath(&bufPainter,circleBizer,isEnd); } cursor = 0; } else { if (cursor == 0) { // pathBizer.lineWidth = 0.3f; rightPoints.clear(); prevPoint = CGPointZero; // bufPainter.drawPath(pathBizer); if(i != startIndex) DrawSignPath(&bufPainter,pathBizer,isEnd); pathBizer = QPainterPath(); pathBizer.setFillRule(Qt::WindingFill); // pathBizer.moveTo(penPoint.pLeftBottomPoint); // if(i != annotPath->points.count()-1) if(i != endIndex-1) { //最后一个点不进行添加 pathBizer.moveTo(penPoint.pLeftBottomPoint); AddStartPathElement(bezierEles); AddMoveToElement(bezierEles,penPoint.pLeftBottomPoint); } prevPoint = penPoint.pLeftBottomPoint; rightPoints.append(penPoint); // bezierPaths.append(pathBizer); } else { // qDebug() << __FUNCTION__ << " cursor != 0 "; rightPoints.append(penPoint); if(/*flushSection &&*/ i == endIndex-1 && endIndex != annotPath->points.count()) { SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd,flushSection,SWRealPoint(),false); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); // bufPainter.drawPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,isEnd); bufPainter.setPen(QPen(Qt::green, 10, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); bufPainter.drawPoint(penPoint.realPoint); // SWCirclePoint circleP = SWCircleMake(SWPosPointMake(penPoint.realPoint.x(), penPoint.realPoint.y(), penPoint.radius)); // QPainterPath circleBizer; // circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); // AddStartPathElement(bezierEles); // AddMoveToElement(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(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(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(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(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); //// bufPainter.drawPath(circleBizer); // DrawSignPath(&bufPainter,circleBizer); // bezierPaths.append(circleBizer); // BezierPath.addPath(circleBizer); } else { //判断交点是否有效 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(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(bezierEles,prevPoint,endPoint); prevPoint = penPoint.pLeftBottomPoint; } else { SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd,flushSection,SWRealPoint(),false); bezierPaths.append(pathBizer); BezierPath.addPath(pathBizer); // bufPainter.drawPath(pathBizer); DrawSignPath(&bufPainter,pathBizer,isEnd); SWCirclePoint circleP = SWCircleMake(SWPosPointMake(penPoint.realPoint.x(), penPoint.realPoint.y(), penPoint.radius)); QPainterPath circleBizer; circleBizer.moveTo(ConvertToCGPoint(circleP.pointA)); AddStartPathElement(bezierEles); AddMoveToElement(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(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(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(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(bezierEles,circleP.pointK.x,circleP.pointK.y, circleP.pointL.x,circleP.pointL.y,circleP.pointM.x,circleP.pointM.y); // bufPainter.drawPath(circleBizer); DrawSignPath(&bufPainter,circleBizer,isEnd); bezierPaths.append(circleBizer); BezierPath.addPath(circleBizer); // qDebug() << __FUNCTION__ << " cursor != 0 and pLeftTopPoint or pLeftBottomPoint is null ,to write right."; // SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd); // bezierPaths.append(pathBizer); // SwPenPathDrawRightWithBezier(&pathBizer,bezierEles, penPoint, prevPoint, rightPoints,isEnd); // 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(bezierEles,prevPoint,endPoint); prevPoint = penPoint.PLeftIntersectPoint; // qDebug() << __FUNCTION__ << " PLeftIntersectPoint: " << penPoint.PLeftIntersectPoint.x() << penPoint.PLeftIntersectPoint.y(); } } } cursor ++; } } } //如果抬笔,则进行同步 if(isEnd) { annotPath->bezierEles = bezierEles; annotPath->bezierPaths = bezierPaths; } return BezierPath; } /** 绘制右侧路径 */ void SignPainterCacheThread_Linux::SwPenPathDrawRightWithBezier(QPainterPath* bPath ,QList& elementList, SWRealPoint prePenPoint,CGPoint prevPoint,QList rPoints,bool end, bool isContinue,SWRealPoint lastPoint,bool isBegin) { CGPoint endPoint = CGPointZero; if (end && penType == 1) { endPoint = CGPointMake((prePenPoint.pLeftTopPoint.x() + prevPoint.x())/2.f, (prePenPoint.pLeftTopPoint.y() + prevPoint.y())/2.f); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo4 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); } else { endPoint = prePenPoint.pLeftTopPoint; if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo5 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); } prevPoint = prePenPoint.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 && penType == 1) { CGPoint endPoint = CGPointMake((prevPoint.x() + penPoint.pRightTopPoint.x())/2.f, (prevPoint.y() + penPoint.pRightTopPoint.y())/2.f); if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo6 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); 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); } if(prevPoint.x() != 0 && prevPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo7 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(prevPoint.x()).arg(prevPoint.y()).arg(endPoint.x()).arg(endPoint.y())); bPath->quadTo(prevPoint,endPoint); } AddQuadToElement(elementList,prevPoint,endPoint); prevPoint = CGPointEqualToPoint(lastPoint.PRightIntersectPoint, CGPointZero) ? lastPoint.pRightBottomPoint : lastPoint.PRightIntersectPoint; k--; /** * 判断是否到结尾 */ // if (k == startIndex) { if (k == 0) { //绘制开始连接点 if(lastPoint.pRightBottomPoint.x() != 0 && lastPoint.pRightBottomPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo8 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(lastPoint.pRightBottomPoint.x()).arg(lastPoint.pRightBottomPoint.y()).arg(lastPoint.pRightBottomPoint.x()).arg(lastPoint.pRightBottomPoint.y())); bPath->quadTo(lastPoint.pRightBottomPoint,lastPoint.pRightBottomPoint); } AddQuadToElement(elementList,lastPoint.pRightBottomPoint,lastPoint.pRightBottomPoint); prevPoint = lastPoint.pRightBottomPoint; SWRealPoint firstPen = rPoints.first(); if(firstPen.pRightBottomPoint.x() != 0 && firstPen.pRightBottomPoint.y() != 0) { // SW_Log::Get()->info(QString("====SwPenPathDraw quadTo9 cx: %1 cy: %2 ex:%3 ey: %4" ) // .arg(firstPen.pRightBottomPoint.x()).arg(firstPen.pRightBottomPoint.y()).arg(firstPen.pLeftBottomPoint.x()).arg(firstPen.pRightBottomPoint.y())); 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; if (!CGPointEqualToPoint(lastPoint.realPoint, CGPointZero) && k == 0 && isBegin == true) { SWRealPoint firstPen = rPoints.first(); endPoint = CGPointMake((lastPoint.PRightIntersectPoint.x()+firstPen.PRightIntersectPoint.x())/2.f, (lastPoint.PRightIntersectPoint.y()+firstPen.PRightIntersectPoint.y())/2.f); bPath->quadTo(penPoint.PRightIntersectPoint,endPoint); AddQuadToElement(elementList,penPoint.PRightIntersectPoint,endPoint); endPoint = CGPointMake((penPoint.PLeftIntersectPoint.x() + lastPoint.PLeftIntersectPoint.x())/2.f, (penPoint.PLeftIntersectPoint.y() + lastPoint.PLeftIntersectPoint.y())/2.f); bPath->quadTo(endPoint,endPoint); } } } } } }