//FIXME: width and length for arrow QPolygonF QNEConnection::createArrowPoly(QPainterPath& p, QNEPort* conn) { float arrowStartPercentage; float arrowEndPercentage; if (conn->isOutput()) { arrowStartPercentage = p.percentAtLength(p.length() - conn->radius() - arrowSize); arrowEndPercentage = p.percentAtLength(p.length() - conn->radius()); } else { //assuming is start connector, should throw exception otherwise? arrowStartPercentage = p.percentAtLength(conn->radius() + arrowSize); arrowEndPercentage = p.percentAtLength(conn->radius()); } QPointF headStartP = p.pointAtPercent(arrowStartPercentage); QPointF headEndP = p.pointAtPercent(arrowEndPercentage); QLineF arrowMiddleLine(headStartP, headEndP); //QLineF normHead = arrowMiddleLine.normalVector(); arrowMiddleLine.unitVector(); QPointF normHead(arrowMiddleLine.dy(), -arrowMiddleLine.dx()); QPointF arrowP1 = headStartP + normHead * 0.4; QPointF arrowP2 = headStartP - normHead * 0.4; QPolygonF arrowHeadEnd; arrowHeadEnd << headEndP << arrowP1 << arrowP2 << headEndP /*<< headEndP*/; return arrowHeadEnd; }
QPolygonF mafNodeConnectionGraphicWidget::createArrowPoly(QPainterPath& p, mafNodeConnectorGraphicWidget* conn) { float arrowStartPercentage; float arrowEndPercentage; if (conn == mEndConnector) { arrowStartPercentage = p.percentAtLength(p.length() - conn->mRadius - arrowSize); arrowEndPercentage = p.percentAtLength(p.length() - conn->mRadius); } else { arrowStartPercentage = p.percentAtLength(conn->mRadius + arrowSize); arrowEndPercentage = p.percentAtLength(conn->mRadius); } QPointF headStartP = p.pointAtPercent(arrowStartPercentage); QPointF headEndP = p.pointAtPercent(arrowEndPercentage); QLineF arrowMiddleLine(headStartP, headEndP); //QLineF normHead = arrowMiddleLine.normalVector(); arrowMiddleLine.unitVector(); QPointF normHead(arrowMiddleLine.dy(), -arrowMiddleLine.dx()); QPointF arrowP1 = headStartP + normHead * 0.4; QPointF arrowP2 = headStartP - normHead * 0.4; QPolygonF arrowHeadEnd; arrowHeadEnd << headEndP << arrowP1 << arrowP2 /*<< headEndP*/; return arrowHeadEnd; }
/** * @brief LengthBezier return spline length using 4 spline point. * @param p1 first spline point * @param p2 first control point. * @param p3 second control point. * @param p4 last spline point. * @return length. */ qreal VSpline::LengthBezier ( const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4 ) const { QPainterPath splinePath; QVector<QPointF> points = GetPoints (p1, p2, p3, p4); splinePath.moveTo(points.at(0)); for (qint32 i = 1; i < points.count(); ++i) { splinePath.lineTo(points.at(i)); } return splinePath.length(); }
bool PathAlongPathPlugin::run(ScribusDoc* doc, QString) { firstUpdate = true; currDoc = doc; originalPathG.clear(); originalRotG.clear(); originalXPosG.clear(); originalYPosG.clear(); patternItemG.clear(); if (currDoc == 0) currDoc = ScCore->primaryMainWindow()->doc; if (currDoc->m_Selection->count() > 1) { if ((currDoc->m_Selection->itemAt(0)->Groups.count() != 0) || (currDoc->m_Selection->itemAt(1)->Groups.count() != 0)) { selOffs = 0; selCount = currDoc->m_Selection->count() - 1; if (currDoc->m_Selection->itemAt(0)->Groups.count() == 0) { pathItem = currDoc->m_Selection->itemAt(0); selOffs = 1; } else pathItem = currDoc->m_Selection->itemAt(selCount); effectPath = pathItem->PoLine.copy(); QTransform mp; mp.rotate(pathItem->rotation()); effectPath.map(mp); for (int bx = 0; bx < selCount; ++bx) { PageItem* bxi = currDoc->m_Selection->itemAt(bx + selOffs); originalPathG.append(bxi->PoLine.copy()); originalXPosG.append(bxi->xPos()); originalYPosG.append(bxi->yPos()); originalRotG.append(bxi->rotation()); patternItemG.append(bxi); } QPainterPath tmpPath = effectPath.toQPainterPath(false); PathDialog *dia = new PathDialog(currDoc->scMW(), currDoc->unitIndex(), tmpPath.length(), true); connect(dia, SIGNAL(updateValues(int, double, double, double, int)), this, SLOT(updateEffectG(int, double, double, double, int))); if (dia->exec()) { updateEffectG(dia->effectType, dia->offset, dia->offsetY, dia->gap, dia->rotate); currDoc->changed(); } else { updateEffectG(-1, dia->offset, dia->offsetY, dia->gap, dia->rotate); currDoc->view()->DrawNew(); } delete dia; } else {
void BitmapImage::drawPath(QPainterPath path, QPen pen, QBrush brush, QPainter::CompositionMode cm, bool antialiasing) { int width = pen.width(); // qreal inc = 1.0 + width / 20.0; setCompositionModeBounds(path.controlPointRect().adjusted(-width, -width, width, width).toRect(), true, cm); if (!image()->isNull()) { QPainter painter(image()); painter.setCompositionMode(cm); painter.setRenderHint(QPainter::Antialiasing, antialiasing); painter.setPen(pen); painter.setBrush(brush); painter.setTransform(QTransform().translate(-mBounds.left(), -mBounds.top())); painter.setMatrixEnabled(true); if (path.length() > 0) { /* for (int pt = 0; pt < path.elementCount() - 1; pt++) { qreal dx = path.elementAt(pt + 1).x - path.elementAt(pt).x; qreal dy = path.elementAt(pt + 1).y - path.elementAt(pt).y; qreal m = sqrt(dx*dx + dy*dy); qreal factorx = dx / m; qreal factory = dy / m; for (float h = 0.f; h < m; h += inc) { qreal x = path.elementAt(pt).x + factorx * h; qreal y = path.elementAt(pt).y + factory * h; painter.drawPoint(QPointF(x, y)); } } */ painter.drawPath( path ); } else { // forces drawing when points are coincident (mousedown) painter.drawPoint(static_cast<int>(path.elementAt(0).x), static_cast<int>(path.elementAt(0).y)); } painter.end(); } modification(); }
PencilItem::PencilItem(const QString & svgFileName, QGraphicsItem *parent) : QGraphicsObject(parent) , m_alpha(0) { FloodPolys polys = FloodGenerator::fromSvgPaths(svgFileName); if (polys.isEmpty()) return; // generate the steps from the loaded FloodPolys QPainterPath completePath; foreach (const FloodPoly & poly, polys) { Step step; step.move = true; const QPainterPath path = poly.toPainterPath(); completePath.addPath(path); qreal length = path.length(); int breaks = (int)(length / 2.0); for (int i = 0; i < breaks; i++) { step.point = path.pointAtPercent((qreal)i / ((qreal)breaks - 1)); m_steps.append(step); step.move = false; } }
bool PathAlongPathPlugin::run(ScribusDoc* doc, QString) { firstUpdate = true; m_doc = doc; originalPathG.clear(); originalRotG.clear(); originalXPosG.clear(); originalYPosG.clear(); patternItemG.clear(); if (m_doc == 0) m_doc = ScCore->primaryMainWindow()->doc; if (m_doc->m_Selection->count() > 1) { if ((m_doc->m_Selection->itemAt(0)->isGroup()) || (m_doc->m_Selection->itemAt(1)->isGroup())) { selOffs = 0; selCount = m_doc->m_Selection->count() - 1; if (!m_doc->m_Selection->itemAt(0)->isGroup()) { pathItem = m_doc->m_Selection->itemAt(0); selOffs = 1; } else pathItem = m_doc->m_Selection->itemAt(selCount); effectPath = pathItem->PoLine.copy(); QTransform mp; mp.rotate(pathItem->rotation()); effectPath.map(mp); PageItem* bxi = m_doc->m_Selection->itemAt(selOffs); bxi->asGroupFrame()->adjustXYPosition(); originalPathG.append(bxi->PoLine.copy()); originalXPosG.append(bxi->xPos()); originalYPosG.append(bxi->yPos()); originalXPosGi.append(bxi->gXpos); originalYPosGi.append(bxi->gYpos); originalRotG.append(bxi->rotation()); originalWidth.append(bxi->width()); originalHeight.append(bxi->height()); originalWidthG.append(bxi->groupWidth); originalHeightG.append(bxi->groupHeight); patternItemG.append(bxi); QList<PageItem*> bxiL = bxi->getItemList(); for (int bx = 0; bx < bxiL.count(); ++bx) { PageItem* cIte = bxiL.at(bx); originalPathG.append(cIte->PoLine.copy()); originalXPosG.append(cIte->xPos()); originalYPosG.append(cIte->yPos()); originalWidth.append(cIte->width()); originalHeight.append(cIte->height()); originalWidthG.append(cIte->groupWidth); originalHeightG.append(cIte->groupHeight); originalXPosGi.append(cIte->gXpos); originalYPosGi.append(cIte->gYpos); originalRotG.append(cIte->rotation()); patternItemG.append(cIte); } QPainterPath tmpPath = effectPath.toQPainterPath(false); PathDialog *dia = new PathDialog(m_doc->scMW(), m_doc->unitIndex(), tmpPath.length(), true); connect(dia, SIGNAL(updateValues(int, double, double, double, int)), this, SLOT(updateEffectG(int, double, double, double, int))); if (dia->exec()) { updateEffectG(dia->effectType, dia->offset, dia->offsetY, dia->gap, dia->rotate); m_doc->changed(); } else { updateEffectG(-1, dia->offset, dia->offsetY, dia->gap, dia->rotate); m_doc->view()->DrawNew(); } delete dia; } else {
void PrimitivePainter::drawLabel(QPainterPath* R, QPainter* thePainter, qreal PixelPerM, QString str, QString strBg) const { if (!DrawLabel) return; if (str.isEmpty() && strBg.isEmpty()) return; thePainter->save(); if (getLabelArea()) { QPointF C(R->boundingRect().center()); drawPointLabel(C, str, strBg, thePainter, PixelPerM); thePainter->restore(); return; } LineParameters lp = labelBoundary(); qreal WW = PixelPerM*lp.Proportional+lp.Fixed; if (WW < 10) return; //qreal WWR = qMax(PixelPerM*R->widthOf()*BackgroundScale+BackgroundOffset, PixelPerM*R->widthOf()*ForegroundScale+ForegroundOffset); QPainterPath textPath; QPainterPath tranformedRoadPath = *R; QFont font = getLabelFont(); if (!str.isEmpty()) { QRegion rg = thePainter->clipRegion(); font.setPixelSize(int(WW)); QFontMetrics metrics(font); if (font.pixelSize() >= 5 && tranformedRoadPath.length() > metrics.width(str)) { thePainter->setFont(font); int repeat = int((tranformedRoadPath.length() / ((metrics.width(str) * LABEL_PATH_DISTANCE))) - 0.5); int numSegment = repeat+1; qreal lenSegment = tranformedRoadPath.length() / numSegment; qreal startSegment = 0; QPainterPath textPath; do { QRegion rg = thePainter->clipRegion(); qreal curLen = startSegment + ((lenSegment - metrics.width(str)) / 2); int modIncrement = 1; qreal modAngle = 0; int modY = 0; if (cos(angToRad(tranformedRoadPath.angleAtPercent((startSegment+(lenSegment/2))/tranformedRoadPath.length()))) < 0) { modIncrement = -1; modAngle = 180.0; curLen += metrics.width(str); } for (int i = 0; i < str.length(); ++i) { qreal t = tranformedRoadPath.percentAtLength(curLen); QPointF pt = tranformedRoadPath.pointAtPercent(t); qreal angle = tranformedRoadPath.angleAtPercent(t); modY = (metrics.ascent()/2)-3; QMatrix m; m.translate(pt.x(), pt.y()); m.rotate(-angle+modAngle); QPainterPath charPath; charPath.addText(0, modY, font, str.mid(i, 1)); charPath = charPath * m; textPath.addPath(charPath); qreal incremenet = metrics.width(str[i]); curLen += (incremenet * modIncrement); } startSegment += lenSegment; } while (--repeat >= 0); if (getLabelHalo()) { thePainter->setPen(QPen(Qt::white, font.pixelSize()/6)); thePainter->drawPath(textPath); } thePainter->setPen(Qt::NoPen); thePainter->setBrush(LabelColor); thePainter->drawPath(textPath); thePainter->setClipRegion(rg); } } if (DrawLabelBackground && !strBg.isEmpty()) { QRegion rg = thePainter->clipRegion(); font.setPixelSize(int(WW)); QFontMetrics metrics(font); int repeat = int((tranformedRoadPath.length() / (metrics.width(strBg) * LABEL_STRAIGHT_DISTANCE)) - 0.5); int numSegment = repeat+1; qreal lenSegment = tranformedRoadPath.length() / numSegment; qreal startSegment = 0; do { int modX = 0; int modY = 0; qreal curLen = startSegment + (lenSegment / 2); qreal t = tranformedRoadPath.percentAtLength(curLen); QPointF pt = tranformedRoadPath.pointAtPercent(t); modX = - (metrics.width(strBg)/2); //modX = WW; modY = (metrics.ascent()/2); QPainterPath textPath, bgPath; textPath.addText(modX, modY, font, strBg); bgPath.addRect(textPath.boundingRect().adjusted(-BG_SPACING, -BG_SPACING, BG_SPACING, BG_SPACING)); bool rgContains = false; for (int i=0; i<rg.rects().size(); i++) { if (rg.rects()[i].contains(bgPath.boundingRect().toRect().translated(pt.toPoint()))) { rgContains = true; break; } } if (rgContains) { thePainter->translate(pt); thePainter->setPen(QPen(LabelColor, BG_PEN_SZ)); thePainter->setBrush(LabelBackgroundColor); thePainter->drawPath(bgPath); if (getLabelHalo()) { thePainter->setPen(QPen(Qt::white, font.pixelSize()/5)); thePainter->drawPath(textPath); } thePainter->setPen(Qt::NoPen); thePainter->setBrush(LabelColor); thePainter->drawPath(textPath); rg -= bgPath.boundingRect().toRect().translated(pt.toPoint()); } startSegment += lenSegment; } while (--repeat >= 0); thePainter->setClipRegion(rg); } thePainter->restore(); }
void SCgAlphabet::paintPair(QPainter *painter, SCgPair *pair) { Q_ASSERT(pair != 0); QVector<QPointF> points = pair->points(); Q_ASSERT(points.size() > 1); static float arrowLength = 10.f; static float arrowWidth = LINE_FAT_WIDTH; if (pair->isOrient()) { static const QPointF arrowPoints[3] = {QPointF(-arrowWidth / 2.f, 0.f), QPointF(arrowWidth / 2.f, 0.f), QPointF(0.f, arrowLength)}; // draw arrow for orient pairs QLineF line(points[points.size() - 2], points.last()); double angle = ::atan2(line.dx(), line.dy()); painter->save(); painter->translate(line.p2()); painter->rotate(-angle * 180.f / M_PI); painter->translate(0.f, -arrowLength); painter->setBrush(QBrush(pair->color(), Qt::SolidPattern)); painter->setPen(Qt::NoPen); painter->drawConvexPolygon(arrowPoints, 3); painter->restore(); // correct last point points.last() -= QPointF((arrowLength) * ::sin(angle), (arrowLength) * ::cos(angle)); } // get type data SCgPosType posType = pair->posType(); SCgConstType constType = pair->constType(); SCgPermType permType = pair->permType(); painter->setBrush(Qt::NoBrush); QPen pen(pair->color()); pen.setCapStyle(Qt::FlatCap); pen.setJoinStyle(Qt::RoundJoin); // draw all cases if (pair->isAccessory()) { pen.setWidthF(LINE_THIN_WIDTH); QPen markPen = pen; if (constType == ConstUnknown && posType == PosUnknown) { painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); markPen.setWidthF(LINE_COM_ACCESS_MARK_WIDTH); markPen.setDashPattern(msCommonAccessoryDashPattern); painter->setPen(markPen); painter->drawPolyline(&(points[0]), points.size()); }else { if (permType == Permanent && constType == Var) pen.setDashPattern(msPermVarAccesDashPattern); if (permType == Temporary) { if (constType == Const) pen.setDashPattern(msTempConstAccesDashPattern); else pen.setDashPattern(msTempVarAccesDashPattern); } painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); // draw negative lines if (posType == Negative) { painter->setPen(markPen); QPainterPath path = pair->shapeNormal(); float length = path.length() - arrowLength - 3; int i = 0; qreal mult = 28.f; qreal offset = 22.f; qreal l = offset; while (l < length) { qreal perc = path.percentAtLength(l); painter->save(); painter->translate(path.pointAtPercent(perc)); painter->rotate(-path.angleAtPercent(perc)); painter->drawLine(0.f, -LINE_MARK_NEG_LENGTH, 0.f, LINE_MARK_NEG_LENGTH); painter->restore(); l = (++i) * mult + offset; } }else // draw fuzzy lines if (posType == Fuzzy) { painter->setPen(markPen); QPainterPath path = pair->shapeNormal(); float length = path.length() - arrowLength - 3; int i = 0; qreal mult = 28.f; qreal offset = 22.f; qreal l = offset; while (l < length) { qreal perc = path.percentAtLength(l); painter->save(); painter->translate(path.pointAtPercent(perc)); painter->rotate(-path.angleAtPercent(perc)); if (i % 2 == 0) painter->drawLine(0.f, -LINE_MARK_FUZ_LENGTH, 0.f, 0.f); else painter->drawLine(0.f, LINE_MARK_FUZ_LENGTH, 0.f, 0.f); painter->restore(); l = (++i) * mult + offset; } } } }else // draw binary pairs { pen.setWidthF(LINE_FAT_WIDTH); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); if (constType == Var) { pen.setWidthF(LINE_FATIN_WIDTH); pen.setDashPattern(msPermVarNoAccesDashPattern); pen.setDashOffset(20); pen.setColor(QColor(255, 255, 255)); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); }else { pen.setWidthF(LINE_FATIN_WIDTH); pen.setColor(Qt::white); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); if (constType == ConstUnknown) { pen.setWidthF(LINE_THIN_WIDTH); pen.setDashPattern(msPermVarAccesDashPattern); pen.setColor(pair->color()); painter->setPen(pen); painter->drawPolyline(&(points[0]), points.size()); } } } }
void LabelScheme::Draw(MapTranslator *renderer, Feature *feature, QPainter *painter) { if(p_label_paint_func) { if(p_label_paint_func(painter, renderer, feature, this)) return; } if(!p_fieldName.isEmpty()) { QString name = feature->GetFieldValue(p_fieldName); if(p_position == QSimpleSpatial::FollowPath && feature->getScheme()->getShapeType() == QSimpleSpatial::PolyLine) { PolylineFeature *pf = static_cast<PolylineFeature *>(feature); if(pf) { const QVector<Points *> *array = pf->getPointsArray(); QPainterPath path; QPointF pathpoint; for(int i = 0;i < array->count();i ++) { Points *points = array->at(i); if(i > 0 && renderer->Coord2ScreenPoint(points->x[0],points->y[0]) != pathpoint) break; pathpoint = renderer->Coord2ScreenPoint(points->x[0],points->y[0]); path.moveTo(pathpoint); for(int j = 1;j < points->count;j ++) { pathpoint = renderer->Coord2ScreenPoint(points->x[j],points->y[j]); path.lineTo(pathpoint); } } painter->setPen(p_pen); painter->setFont(p_font); qreal pathLength = path.length(); qreal textLength = painter->fontMetrics().boundingRect(name).width() * 1.5; if(pathLength > textLength) { qreal length = (pathLength - textLength) / 2; for ( int i = 0; i < name.size(); i++ ) { qreal currentPos = length / pathLength; QPointF point = path.pointAtPercent(currentPos); QRect charRect = painter->fontMetrics().boundingRect(name[i]); charRect.translate(point.x(),point.y()); renderer->addLabelRect(charRect.marginsAdded(QMargins(5,5,5,5))); qreal angle = path.angleAtPercent(currentPos); angle = 360 - angle; painter->save(); painter->translate(point); painter->rotate(angle); painter->drawText(QPoint(p_offset.X, p_offset.Y),QString(name[i])); painter->restore(); length += charRect.width(); length += p_font.pointSize() / 2; } } } } else { QSimpleSpatial::SimplePoint labelPosition = feature->getLabelPosition(p_position); QSimpleSpatial::SimplePoint point = renderer->Coord2Screen(labelPosition); QRect rect = painter->fontMetrics().boundingRect(name); rect.moveTo(point.X - rect.width() / 2 + p_offset.X,point.Y - rect.height() / 2 + p_offset.Y); if(p_allowOverlap || !renderer->isLabelIntersects(rect)) { painter->setPen(p_pen); painter->setFont(p_font); painter->drawText(rect,Qt::AlignVCenter,name); if(!p_allowOverlap) renderer->addLabelRect(rect); } } } }