//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; }
void VisBezierCurve::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { if(isSelected()){ label->setSelected(true); } QRectF Abox = nodeA->rect(); QRectF Bbox = nodeB->rect(); double Ax = nodeA->pos().x()+Abox.width()/2.0; double Ay = nodeA->pos().y()+Abox.height()/2.0; double Bx = nodeB->pos().x()+Bbox.width()/2.0; double By = nodeB->pos().y()+Bbox.width()/2.0; if(QPointF(Ax, Ay) != nodeApos){ ctrl1->moveBy(Ax-nodeApos.x(), Ay-nodeApos.y()); nodeApos = QPointF(Ax, Ay); } if(QPointF(Bx, By) != nodeBpos){ ctrl2->moveBy(Bx-nodeBpos.x(), By-nodeBpos.y()); nodeBpos = QPointF(Bx, By); } if(is_highlighted == true){ painter->fillPath(shape(), highlight_color); } QPainterPath path; path.moveTo(Ax, Ay); path.cubicTo(ctrl1->vis_pos(),ctrl2->vis_pos(), QPointF(Bx,By)); if (option->state & QStyle::State_Selected){ if(ctrl1 != NULL and ctrl2 != NULL and !ctrl1->isVisible() and !ctrl1->isVisible()){ ctrl1->show(); ctrl2->show(); } }else if(ctrl1 != NULL and ctrl2 != NULL and !ctrl1->isSelected() and !ctrl2->isSelected()){ ctrl1->hide(); ctrl2->hide(); } painter->drawPath(path); if (option->state & QStyle::State_Selected){ QPainterPath select_path = this->shape(); painter->setPen(QPen(QColor(127,127,127), 0, Qt::DashLine)); painter->setBrush(Qt::NoBrush); painter->drawPath(select_path); } double lh = label->boundingRect().height()+6; double lw = label->boundingRect().width()/2.0; label->setPos(path.pointAtPercent(.5).x()-lw, path.pointAtPercent(.5).y()-lh); }
void ArrowItem::updatePath(const QPointF &endPoint) { const double arrowWidth = 15.0; const double headWidth = 40.0; const double headLength = headWidth / pow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++ const double phi = 15; if (!startItem) return; QPointF startPoint = startItem->mapToScene(QPointF(startItem->boundingRect().width() / 2, startItem->boundingRect().height() / 2)); QLineF line(startPoint, endPoint); qreal lineLength = line.length(); prepareGeometryChange(); if (lineLength < 30) path = QPainterPath(); else { QPointF c(lineLength / 2, tan(phi * M_PI / 180) * lineLength); QPainterPath centerLine; centerLine.moveTo(0, 0); centerLine.quadTo(c, QPointF(lineLength, 0)); double percentage = 1 - headLength / lineLength; QPointF arrowBodyEndPoint = centerLine.pointAtPercent(percentage); QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(percentage + 0.001)); qreal alpha = testLine.angle() - 90; QPointF endPoint1 = arrowBodyEndPoint + arrowWidth / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180)); QPointF endPoint2 = arrowBodyEndPoint + arrowWidth / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180)); QPointF point1 = endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180)); QPointF point2 = endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180)); path = QPainterPath(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180))); path.quadTo(c, endPoint1); path.lineTo(point1); path.lineTo(QPointF(lineLength, 0)); path.lineTo(point2); path.lineTo(endPoint2); path.quadTo(c, arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180))); path.lineTo(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180))); } setPos(startPoint); setTransform(QTransform().rotate(-line.angle())); }
qreal Geometry::percentageAt(QPainterPath const &path, QPointF const &point) { // Approximating percentage iteratively. First iterating by delta=1 percent increment, searching for // the closest point on path. Then repeating with found closest percentage value but with delta=0.1 and so on int const approximationLevel = 4; qreal result = 0.5; qreal delta = 0.01; for (int approximationIteration = 0; approximationIteration < approximationLevel; ++approximationIteration) { qreal minimalPercentage = 100; qreal minimalDistance = 10e10; for (int i = -50; i <= 50; ++i) { qreal const percentage = result + delta * i; QPointF const pointAtPercentage = percentage >= 0 && percentage <= 1 ? path.pointAtPercent(percentage) : QPointF(10e5, 10e5); qreal const distanceAtPercentage = distance(pointAtPercentage, point); if (distanceAtPercentage < minimalDistance) { minimalDistance = distanceAtPercentage; minimalPercentage = percentage; } } result = minimalPercentage; delta /= 10; } return result; }
qreal BezierCurve::intersect(const QPainterPath & path) { const int samplePoints = 50; const qreal tau = 1.0 / samplePoints; for (int a = 0; a < samplePoints; ++a) { QLineF line1(pointAtPercent(a * tau), pointAtPercent((a + 1) * tau)); for (int b = 0; b < samplePoints; ++b) { QLineF line2(path.pointAtPercent(b * tau), path.pointAtPercent((b + 1) * tau)); QPointF crossing; if (QLineF::BoundedIntersection == line1.intersect(line2, &crossing)) { return a * tau; } } } return 0.0; }
void TransitionItem::drawFunctions(QPainter *painter, QPainterPath &path) { QFontMetrics metrics(painter->font()); const int height = metrics.height(); QPointF startPos(path.pointAtPercent(0.5) - QPointF(0, 5)); int k = 0; foreach (AcceptState s, m_accepts) { QPointF at(startPos.x() - metrics.width(s.toString()) / 2, startPos.y() - (height + 3) * k); painter->drawText(at, s.toString()); k++; }
QPainterPath PieChart3D::itemExternalPart( qreal angle, qreal delta, bool splitted ) const { QPainterPath ell; ell.addEllipse( myRect ); qreal a = angle / 360.0; if ( a > 1 ) { a -= int(a); } QPointF p1 = ell.pointAtPercent( a ); QPointF offset = QPointF( 0, myHeight ); QPainterPath outside; outside.setFillRule( Qt::WindingFill ); outside.moveTo( p1 ); outside.arcTo( myRect, -angle, -delta ); outside.lineTo( outside.currentPosition() + offset ); outside.arcTo( myRect.translated( 0, myHeight ), -angle - delta, delta ); outside.lineTo( p1 ); if ( splitted == true ) { QPointF p = splittedOffset( angle, delta ); outside.translate( p.x(), p.y() ); } return outside; }
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; } }
void PixmapDial::paintEvent(QPaintEvent*) { QPainter painter(this); if (! m_label.isEmpty()) { painter.setPen(m_color2); painter.setBrush(m_label_gradient); painter.drawRect(m_label_gradient_rect); painter.setPen(m_colorT[isEnabled() ? 0 : 1]); painter.drawText(m_label_pos, m_label); } if (isEnabled()) { float current = value()-minimum(); float divider = maximum()-minimum(); if (divider == 0.0f) return; float value = current/divider; QRectF source, target(0.0f, 0.0f, p_size, p_size); int xpos, ypos, per = (p_count-1)*value; if (m_orientation == HORIZONTAL) { xpos = p_size*per; ypos = 0.0f; } else { xpos = 0.0f; ypos = p_size*per; } source = QRectF(xpos, ypos, p_size, p_size); painter.drawPixmap(target, m_pixmap, source); // Custom knobs (Dry/Wet and Volume) if (m_custom_paint == CUSTOM_PAINT_CARLA_WET || m_custom_paint == CUSTOM_PAINT_CARLA_VOL) { // knob color QColor colorGreen(0x5D, 0xE7, 0x3D, 191 + m_hover_step*7); QColor colorBlue(0x3E, 0xB8, 0xBE, 191 + m_hover_step*7); // draw small circle QRectF ballRect(8.0, 8.0, 15.0, 15.0); QPainterPath ballPath; ballPath.addEllipse(ballRect); //painter.drawRect(ballRect); float tmpValue = (0.375f + 0.75f*value); float ballValue = tmpValue - floorf(tmpValue); QPointF ballPoint(ballPath.pointAtPercent(ballValue)); // draw arc int startAngle = 216*16; int spanAngle = -252*16*value; if (m_custom_paint == CUSTOM_PAINT_CARLA_WET) { painter.setBrush(colorBlue); painter.setPen(QPen(colorBlue, 0)); painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)); QConicalGradient gradient(15.5, 15.5, -45); gradient.setColorAt(0.0, colorBlue); gradient.setColorAt(0.125, colorBlue); gradient.setColorAt(0.625, colorGreen); gradient.setColorAt(0.75, colorGreen); gradient.setColorAt(0.76, colorGreen); gradient.setColorAt(1.0, colorGreen); painter.setBrush(gradient); painter.setPen(QPen(gradient, 3)); } else { painter.setBrush(colorBlue); painter.setPen(QPen(colorBlue, 0)); painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2)); painter.setBrush(colorBlue); painter.setPen(QPen(colorBlue, 3)); } painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle); } // Custom knobs (L and R) else if (m_custom_paint == CUSTOM_PAINT_CARLA_L || m_custom_paint == CUSTOM_PAINT_CARLA_R) { // knob color QColor color(0xAD + m_hover_step*5, 0xD5 + m_hover_step*4, 0x4B + m_hover_step*5); // draw small circle QRectF ballRect(7.0, 8.0, 11.0, 12.0); QPainterPath ballPath; ballPath.addEllipse(ballRect); //painter.drawRect(ballRect); float tmpValue = (0.375f + 0.75f*value); float ballValue = tmpValue - floorf(tmpValue); QPointF ballPoint(ballPath.pointAtPercent(ballValue)); painter.setBrush(color); painter.setPen(QPen(color, 0)); painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0f, 2.0f)); int startAngle, spanAngle; // draw arc if (m_custom_paint == CUSTOM_PAINT_CARLA_L) { startAngle = 216*16; spanAngle = -252.0*16*value; } else if (m_custom_paint == CUSTOM_PAINT_CARLA_R) { startAngle = 324.0*16; spanAngle = 252.0*16*(1.0-value); } else return; painter.setPen(QPen(color, 2)); painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle); if (HOVER_MIN < m_hover_step && m_hover_step < HOVER_MAX) { m_hover_step += m_hovered ? 1 : -1; QTimer::singleShot(20, this, SLOT(update())); } } if (HOVER_MIN < m_hover_step && m_hover_step < HOVER_MAX) { m_hover_step += m_hovered ? 1 : -1; QTimer::singleShot(20, this, SLOT(update())); } } else { QRectF target(0.0, 0.0, p_size, p_size); painter.drawPixmap(target, m_pixmap, target); } }
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); } } } }
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 PageItem_PathText::DrawObj_Item(ScPainter *p, QRectF cullingArea) { itemText.invalidateAll(); firstChar = 0; MaxChars = 0; int a; double chs; QString chstr, chstr2, chstr3; ScText *hl; double dx; FPoint point = FPoint(0, 0); FPoint tangent = FPoint(0, 0); uint seg = 0; double segLen = 0; QColor tmp; CurX = Extra; QString cachedStroke = ""; QString cachedFill = ""; double cachedFillShade = -1; double cachedStrokeShade = -1; QString actStroke = ""; QString actFill = ""; double actFillShade = -1; double actStrokeShade = -1; QColor cachedFillQ; QColor cachedStrokeQ; if (!m_Doc->layerOutline(LayerID)) { if (PoShow) { p->setupPolygon(&PoLine, false); if (NamedLStyle.isEmpty()) { if ((!patternStrokeVal.isEmpty()) && (m_Doc->docPatterns.contains(patternStrokeVal))) { if (patternStrokePath) { QPainterPath guidePath = PoLine.toQPainterPath(false); DrawStrokePattern(p, guidePath); } else { p->setPattern(&m_Doc->docPatterns[patternStrokeVal], patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY); p->setStrokeMode(ScPainter::Pattern); p->strokePath(); } } else if (GrTypeStroke > 0) { if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal))) gradientStrokeVal = ""; if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal))) stroke_gradient = m_Doc->docGradients[gradientStrokeVal]; if (stroke_gradient.Stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient. { if (lineColor() != CommonStrings::None) { p->setBrush(strokeQColor); p->setStrokeMode(ScPainter::Solid); } else p->setStrokeMode(ScPainter::None); } else { p->setStrokeMode(ScPainter::Gradient); p->stroke_gradient = stroke_gradient; if (GrTypeStroke == 6) p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew); else p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew); } p->strokePath(); } else if (lineColor() != CommonStrings::None) { p->setStrokeMode(ScPainter::Solid); p->strokePath(); } } else { p->setStrokeMode(ScPainter::Solid); multiLine ml = m_Doc->MLineStyles[NamedLStyle]; QColor tmp; for (int it = ml.size()-1; it > -1; it--) { if (ml[it].Color != CommonStrings::None) // && (ml[it].Width != 0)) { SetQColor(&tmp, ml[it].Color, ml[it].Shade); p->setPen(tmp, ml[it].Width, static_cast<Qt::PenStyle>(ml[it].Dash), static_cast<Qt::PenCapStyle>(ml[it].LineEnd), static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)); p->strokePath(); } } } } } double totalTextLen = 0.0; double totalCurveLen = 0.0; double extraOffset = 0.0; if (itemText.length() != 0) { CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; totalTextLen += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; } segLen = PoLine.lenPathSeg(seg); for (a = firstChar; a < itemText.length(); ++a) { hl = itemText.item(a); chstr = hl->ch; if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; if (a < itemText.length()-1) chstr += itemText.text(a+1, 1); hl->glyph.yadvance = 0; layoutGlyphs(itemText.charStyle(a), chstr, hl->glyph); hl->glyph.shrink(); if (hl->ch == SpecialChars::OBJECT) totalTextLen += (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH; else totalTextLen += hl->glyph.wide()+hl->fontSize() * hl->tracking() / 10000.0; } for (uint segs = 0; segs < PoLine.size()-3; segs += 4) { totalCurveLen += PoLine.lenPathSeg(segs); } if ((itemText.defaultStyle().alignment() != 0) && (totalCurveLen >= totalTextLen + Extra)) { if (itemText.defaultStyle().alignment() == 2) { CurX = totalCurveLen - totalTextLen; CurX -= Extra; } if (itemText.defaultStyle().alignment() == 1) CurX = (totalCurveLen - totalTextLen) / 2.0; if ((itemText.defaultStyle().alignment() == 3) || (itemText.defaultStyle().alignment() == 4)) extraOffset = (totalCurveLen - Extra - totalTextLen) / static_cast<double>(itemText.length()); } #ifndef NLS_PROTO QPainterPath guidePath = PoLine.toQPainterPath(false); QList<QPainterPath> pathList = decomposePath(guidePath); QPainterPath currPath = pathList[0]; int currPathIndex = 0; for (a = firstChar; a < itemText.length(); ++a) { CurY = 0; hl = itemText.item(a); chstr = hl->ch; if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; chs = hl->fontSize(); if (a < itemText.length()-1) chstr += itemText.text(a+1, 1); hl->glyph.yadvance = 0; layoutGlyphs(itemText.charStyle(a), chstr, hl->glyph); hl->glyph.shrink(); // HACK if (hl->ch == SpecialChars::OBJECT) dx = (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH / 2.0; else dx = hl->glyph.wide() / 2.0; CurX += dx; double currPerc = currPath.percentAtLength(CurX); if (currPerc >= 0.9999999) { currPathIndex++; if (currPathIndex == pathList.count()) { MaxChars = a; break; } currPath = pathList[currPathIndex]; CurX = dx; currPerc = currPath.percentAtLength(CurX); } double currAngle = currPath.angleAtPercent(currPerc); #if QT_VERSION >= 0x040400 if (currAngle <= 180.0) currAngle *= -1.0; else currAngle = 360.0 - currAngle; #endif QPointF currPoint = currPath.pointAtPercent(currPerc); tangent = FPoint(cos(currAngle * M_PI / 180.0), sin(currAngle * M_PI / 180.0)); point = FPoint(currPoint.x(), currPoint.y()); hl->glyph.xoffset = 0; hl->PtransX = point.x(); hl->PtransY = point.y(); hl->PRot = currAngle * M_PI / 180.0; hl->PDx = dx; QTransform trafo = QTransform( 1, 0, 0, -1, -dx, 0 ); if (textPathFlipped) trafo *= QTransform(1, 0, 0, -1, 0, 0); if (textPathType == 0) trafo *= QTransform( tangent.x(), tangent.y(), tangent.y(), -tangent.x(), point.x(), point.y() ); // ID's Rainbow mode else if (textPathType == 1) trafo *= QTransform( 1, 0, 0, -1, point.x(), point.y() ); // ID's Stair Step mode else if (textPathType == 2) { double a = 1; if (tangent.x() < 0) a = -1; if (fabs(tangent.x()) > 0.1) trafo *= QTransform( a, (tangent.y() / tangent.x()) * a, 0, -1, point.x(), point.y() ); // ID's Skew mode else trafo *= QTransform( a, 4 * a, 0, -1, point.x(), point.y() ); } QTransform sca = p->worldMatrix(); trafo *= sca; p->save(); QTransform savWM = p->worldMatrix(); p->setWorldMatrix(trafo); if (!m_Doc->RePos) { actFill = itemText.charStyle(a).fillColor(); actFillShade = itemText.charStyle(a).fillShade(); if (actFill != CommonStrings::None) { p->setFillMode(ScPainter::Solid); if ((cachedFillShade != actFillShade) || (cachedFill != actFill)) { SetQColor(&tmp, actFill, actFillShade); p->setBrush(tmp); cachedFillQ = tmp; cachedFill = actFill; cachedFillShade = actFillShade; } else p->setBrush(cachedFillQ); } else p->setFillMode(ScPainter::None); actStroke = itemText.charStyle(a).strokeColor(); actStrokeShade = itemText.charStyle(a).strokeShade(); if (actStroke != CommonStrings::None) { if ((cachedStrokeShade != actStrokeShade) || (cachedStroke != actStroke)) { SetQColor(&tmp, actStroke, actStrokeShade); p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); cachedStrokeQ = tmp; cachedStroke = actStroke; cachedStrokeShade = actStrokeShade; } else p->setPen(cachedStrokeQ, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); } p->translate(0.0, BaseOffs); if (hl->ch == SpecialChars::OBJECT) DrawObj_Embedded(p, cullingArea, itemText.charStyle(a), hl->embedded.getItem()); else drawGlyphs(p, itemText.charStyle(a), hl->glyph); } p->setWorldMatrix(savWM); p->restore(); MaxChars = a+1; CurX -= dx; if (hl->ch == SpecialChars::OBJECT) CurX += (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH; else CurX += hl->glyph.wide()+hl->fontSize() * hl->tracking() / 10000.0 + extraOffset; } #endif }
//! //! Updates the path end points according to the positions of start and end //! nodes. //! void ConnectionGraphicsItem::updatePath () { prepareGeometryChange(); // calculate positions of the end points QPointF startPoint = m_startPoint; QPointF endPoint = m_endPoint; if (m_startNodeItem) startPoint += m_startNodeItem->pos(); if (m_endNodeItem) endPoint += m_endNodeItem->pos(); // calculate the rectangles to help calculating the positions of the node's anchor points const qreal offset = 10; QRectF baseAnchorRect = QRectF(-offset, -offset, 2 * offset, 2 * offset); QRectF startAnchorRect = baseAnchorRect.translated(startPoint); QRectF endAnchorRect = baseAnchorRect.translated(endPoint); if (m_startNodeItem) startAnchorRect = m_startNodeItem->rect().adjusted(-offset, -offset, offset, offset).translated(m_startNodeItem->pos()); if (m_endNodeItem) endAnchorRect = m_endNodeItem->rect().adjusted(-offset, -offset, offset, offset).translated(m_endNodeItem->pos()); // // Diagram of anchor points for start and end nodes: // // x x sU2, sU1 eU1, eU2 x x // ,----, ,----, // | | | | // | | | | // | x| x sP, sO eO, eP x |x | // '----' '----' // x x sL2, sL1 eL1, eL2 x x // QPointF sP = startPoint; QPointF sO = QPointF(startAnchorRect.right(), startPoint.y()); QPointF sU1 = startAnchorRect.topRight(); QPointF sU2 = startAnchorRect.topLeft(); QPointF sL1 = startAnchorRect.bottomRight(); QPointF sL2 = startAnchorRect.bottomLeft(); QPointF eP = endPoint; QPointF eO = QPointF(endAnchorRect.left(), endPoint.y()); QPointF eU1 = endAnchorRect.topLeft(); QPointF eU2 = endAnchorRect.topRight(); QPointF eL1 = endAnchorRect.bottomLeft(); QPointF eL2 = endAnchorRect.bottomRight(); // declare path segments QList<QPointF> startPoints; QPainterPath cubicPath; QList<QPointF> endPoints; // construct the path segments if (eO.x() < sO.x() && eU2.x() > sL2.x() && eU2.y() < sL2.y() && eL2.y() > sU2.y()) { //> case 1V: elements very close to each other startPoints << sP << sO; QPointF offsetVector = QPointF(0, 0.75 * (eO.y() - sO.y())); cubicPath.moveTo(sO); cubicPath.cubicTo(sO + offsetVector, eO - offsetVector, eO); endPoints << eO << eP; } else if (eO.x() >= sO.x()) { //> case 1H: end node is right of start node startPoints << sP << sO; QPointF offsetVector = QPointF(0.75 * (eO.x() - sO.x()), 0); cubicPath.moveTo(sO); cubicPath.cubicTo(sO + offsetVector, eO - offsetVector, eO); endPoints << eO << eP; } else if (eU1.y() >= sL1.y()) { //> case 2LV startPoints << sP << sO << sL1; QPointF offsetVector = QPointF(0, 0.75 * (eU1.y() - sL1.y())); cubicPath.moveTo(sL1); cubicPath.cubicTo(sL1 + offsetVector, eU1 - offsetVector, eU1); endPoints << eU1 << eO << eP; } else if (eL1.y() <= sU1.y()) { //> case 2UV startPoints << sP << sO << sU1; QPointF offsetVector = QPointF(0, 0.75 * (eL1.y() - sU1.y())); cubicPath.moveTo(sU1); cubicPath.cubicTo(sU1 + offsetVector, eL1 - offsetVector, eL1); endPoints << eL1 << eO << eP; } else if (eP.y() >= sP.y()) { //> case 3L startPoints << sP << sO << sL1 << sL2; QPointF offsetVector = QPointF(0.75 * (eU2.x() - sL2.x()), 0); cubicPath.moveTo(sL2); cubicPath.cubicTo(sL2 + offsetVector, eU2 - offsetVector, eU2); endPoints << eU2 << eU1 << eO << eP; } else { //> case 3U startPoints << sP << sO << sU1 << sU2; QPointF offsetVector = QPointF(0.75 * (eL2.x() - sU2.x()), 0); cubicPath.moveTo(sU2); cubicPath.cubicTo(sU2 + offsetVector, eL2 - offsetVector, eL2); endPoints << eL2 << eL1 << eO << eP; } // build the main path from the path segments m_mainPath = QPainterPath(); for (int i = 0; i < startPoints.size(); ++i) if (i == 0) m_mainPath.moveTo(startPoints[0]); else m_mainPath.lineTo(startPoints[i]); m_mainPath.addPath(cubicPath); for (int i = 0; i < endPoints.size(); ++i) if (i == 0) m_mainPath.moveTo(endPoints[0]); else m_mainPath.lineTo(endPoints[i]); // create the shadow path as a copy of the main path m_shadowPath = QPainterPath(m_mainPath); // move the path elements of the shadow path one pixel down and to the right for (int i = 1; i < m_shadowPath.elementCount(); ++i) { QPainterPath::Element element = m_shadowPath.elementAt(i); m_shadowPath.setElementPositionAt(i, element.x + 1, element.y + 1); } // get the center point for the arrow and the angle at that point static const qreal t = 0.5; QPointF arrowPoint = cubicPath.pointAtPercent(t); qreal angle = cubicPath.angleAtPercent(t) * Pi / 180; // calculate the polygon for the arrow head qreal pathLengthFraction = m_mainPath.length() / 10; static const qreal maxArrowSize = 10; qreal arrowSize = pathLengthFraction < maxArrowSize ? pathLengthFraction : maxArrowSize; QPointF arrowPoint1 = arrowPoint - QPointF(arrowSize * sin(angle - Pi / 2), arrowSize * cos(angle - Pi / 2)); QPointF arrowPoint2 = arrowPoint - QPointF(arrowSize * sin(angle + Pi / 3), arrowSize * cos(angle + Pi / 3)); QPointF arrowPoint3 = arrowPoint - QPointF(arrowSize * sin(angle + Pi - Pi / 3), arrowSize * cos(angle + Pi - Pi / 3)); m_arrowHeadPolygon.clear(); m_arrowHeadPolygon << arrowPoint1 << arrowPoint2 << arrowPoint3; // repaint the graphics item update(); }
void PixmapDial::paintEvent(QPaintEvent* event) { event->accept(); QPainter painter(this); painter.save(); painter.setRenderHint(QPainter::Antialiasing, true); if (! fLabel.isEmpty()) { if (fCustomPaint == CUSTOM_PAINT_NULL) { painter.setPen(fColor2); painter.setBrush(fLabelGradient); painter.drawRect(fLabelGradientRect); } painter.setFont(fLabelFont); painter.setPen(fColorT[isEnabled() ? 0 : 1]); painter.drawText(fLabelPos, fLabel); } if (isEnabled()) { float current = value()-minimum(); float divider = maximum()-minimum(); if (divider == 0.0f) return; float value = current/divider; QRectF source, target(0.0f, 0.0f, fSize, fSize); int xpos, ypos, per = (fCount-1)*value; if (fOrientation == HORIZONTAL) { xpos = fSize*per; ypos = 0.0f; } else { xpos = 0.0f; ypos = fSize*per; } source = QRectF(xpos, ypos, fSize, fSize); painter.drawPixmap(target, fPixmap, source); // Custom knobs (Dry/Wet and Volume) if (fCustomPaint == CUSTOM_PAINT_CARLA_WET || fCustomPaint == CUSTOM_PAINT_CARLA_VOL) { // knob color QColor colorGreen(0x5D, 0xE7, 0x3D, 191 + fHoverStep*7); QColor colorBlue(0x3E, 0xB8, 0xBE, 191 + fHoverStep*7); // draw small circle QRectF ballRect(8.0f, 8.0f, 15.0f, 15.0f); QPainterPath ballPath; ballPath.addEllipse(ballRect); //painter.drawRect(ballRect); float tmpValue = (0.375f + 0.75f*value); float ballValue = tmpValue - std::floor(tmpValue); QPointF ballPoint(ballPath.pointAtPercent(ballValue)); // draw arc int startAngle = 216*16; int spanAngle = -252*16*value; if (fCustomPaint == CUSTOM_PAINT_CARLA_WET) { painter.setBrush(colorBlue); painter.setPen(QPen(colorBlue, 0)); painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2f, 2.2f)); QConicalGradient gradient(15.5f, 15.5f, -45); gradient.setColorAt(0.0f, colorBlue); gradient.setColorAt(0.125f, colorBlue); gradient.setColorAt(0.625f, colorGreen); gradient.setColorAt(0.75f, colorGreen); gradient.setColorAt(0.76f, colorGreen); gradient.setColorAt(1.0f, colorGreen); painter.setBrush(gradient); painter.setPen(QPen(gradient, 3)); } else { painter.setBrush(colorBlue); painter.setPen(QPen(colorBlue, 0)); painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2f, 2.2f)); painter.setBrush(colorBlue); painter.setPen(QPen(colorBlue, 3)); } painter.drawArc(4.0f, 4.0f, 26.0f, 26.0f, startAngle, spanAngle); } // Custom knobs (L and R) else if (fCustomPaint == CUSTOM_PAINT_CARLA_L || fCustomPaint == CUSTOM_PAINT_CARLA_R) { // knob color QColor color(0xAD + fHoverStep*5, 0xD5 + fHoverStep*4, 0x4B + fHoverStep*5); // draw small circle QRectF ballRect(7.0f, 8.0f, 11.0f, 12.0f); QPainterPath ballPath; ballPath.addEllipse(ballRect); //painter.drawRect(ballRect); float tmpValue = (0.375f + 0.75f*value); float ballValue = tmpValue - std::floor(tmpValue); QPointF ballPoint(ballPath.pointAtPercent(ballValue)); painter.setBrush(color); painter.setPen(QPen(color, 0)); painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0f, 2.0f)); int startAngle, spanAngle; // draw arc if (fCustomPaint == CUSTOM_PAINT_CARLA_L) { startAngle = 216*16; spanAngle = -252.0*16*value; } else if (fCustomPaint == CUSTOM_PAINT_CARLA_R) { startAngle = 324.0*16; spanAngle = 252.0*16*(1.0-value); } else return; painter.setPen(QPen(color, 2)); painter.drawArc(3.5f, 4.5f, 22.0f, 22.0f, startAngle, spanAngle); if (HOVER_MIN < fHoverStep && fHoverStep < HOVER_MAX) { fHoverStep += fHovered ? 1 : -1; QTimer::singleShot(20, this, SLOT(update())); } } if (HOVER_MIN < fHoverStep && fHoverStep < HOVER_MAX) { fHoverStep += fHovered ? 1 : -1; QTimer::singleShot(20, this, SLOT(update())); } } else { QRectF target(0.0f, 0.0f, fSize, fSize); painter.drawPixmap(target, fPixmap, target); } painter.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 PageItem_PathText::DrawObj_Item(ScPainter *p, QRectF cullingArea) { itemText.invalidateAll(); firstChar = 0; MaxChars = 0; int a; QString chstr, chstr2, chstr3; double dx; FPoint point = FPoint(0, 0); FPoint tangent = FPoint(0, 0); QColor tmp; CurX = m_textDistanceMargins.left(); QString cachedStroke = ""; QString cachedFill = ""; double cachedFillShade = -1; double cachedStrokeShade = -1; QString actStroke = ""; QString actFill = ""; double actFillShade = -1; double actStrokeShade = -1; QColor cachedFillQ; QColor cachedStrokeQ; if (!m_Doc->layerOutline(LayerID)) { if (PoShow) { p->setupPolygon(&PoLine, false); if (NamedLStyle.isEmpty()) { if ((!patternStrokeVal.isEmpty()) && (m_Doc->docPatterns.contains(patternStrokeVal))) { if (patternStrokePath) { QPainterPath guidePath = PoLine.toQPainterPath(false); DrawStrokePattern(p, guidePath); } else { p->setPattern(&m_Doc->docPatterns[patternStrokeVal], patternStrokeScaleX, patternStrokeScaleY, patternStrokeOffsetX, patternStrokeOffsetY, patternStrokeRotation, patternStrokeSkewX, patternStrokeSkewY, patternStrokeMirrorX, patternStrokeMirrorY); p->setStrokeMode(ScPainter::Pattern); p->strokePath(); } } else if (GrTypeStroke > 0) { if ((!gradientStrokeVal.isEmpty()) && (!m_Doc->docGradients.contains(gradientStrokeVal))) gradientStrokeVal = ""; if (!(gradientStrokeVal.isEmpty()) && (m_Doc->docGradients.contains(gradientStrokeVal))) stroke_gradient = m_Doc->docGradients[gradientStrokeVal]; if (stroke_gradient.Stops() < 2) // fall back to solid stroking if there are not enough colorstops in the gradient. { if (lineColor() != CommonStrings::None) { p->setBrush(strokeQColor); p->setStrokeMode(ScPainter::Solid); } else p->setStrokeMode(ScPainter::None); } else { p->setStrokeMode(ScPainter::Gradient); p->stroke_gradient = stroke_gradient; if (GrTypeStroke == 6) p->setGradient(VGradient::linear, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeStartX, GrStrokeStartY), GrStrokeScale, GrStrokeSkew); else p->setGradient(VGradient::radial, FPoint(GrStrokeStartX, GrStrokeStartY), FPoint(GrStrokeEndX, GrStrokeEndY), FPoint(GrStrokeFocalX, GrStrokeFocalY), GrStrokeScale, GrStrokeSkew); } p->strokePath(); } else if (lineColor() != CommonStrings::None) { p->setStrokeMode(ScPainter::Solid); p->strokePath(); } } else { p->setStrokeMode(ScPainter::Solid); multiLine ml = m_Doc->MLineStyles[NamedLStyle]; QColor tmp; for (int it = ml.size()-1; it > -1; it--) { if (ml[it].Color != CommonStrings::None) // && (ml[it].Width != 0)) { SetQColor(&tmp, ml[it].Color, ml[it].Shade); p->setPen(tmp, ml[it].Width, static_cast<Qt::PenStyle>(ml[it].Dash), static_cast<Qt::PenCapStyle>(ml[it].LineEnd), static_cast<Qt::PenJoinStyle>(ml[it].LineJoin)); p->strokePath(); } } } } } double totalTextLen = 0.0; double totalCurveLen = 0.0; double extraOffset = 0.0; if (itemText.length() != 0) { CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; totalTextLen += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0; } itemRenderText.clear(); itemRenderText.setDoc(m_Doc); itemRenderText.setDefaultStyle(itemText.defaultStyle()); for (a = firstChar; a < itemText.length(); ++a) { CharStyle nstyle = itemText.charStyle(a); ParagraphStyle pstyle = itemText.paragraphStyle(a); chstr = itemText.text(a, 1); if ((chstr[0] == SpecialChars::OBJECT) && (itemText.hasObject(a))) { int pot = itemRenderText.length(); itemRenderText.insertObject(pot, itemText.object(a)->inlineCharID); } else { if (!(chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK)) chstr = ExpandToken(a); for (int cc = 0; cc < chstr.count(); cc++) { int pot = itemRenderText.length(); itemRenderText.insertChars(pot, chstr.mid(cc, 1)); itemRenderText.applyStyle(pot, pstyle); itemRenderText.applyCharStyle(pot, 1, nstyle); } } chstr.clear(); } textLayout.setStory(&itemRenderText); int spaceCount = 0; double wordExtra = 0; for (a = firstChar; a < itemRenderText.length(); ++a) { GlyphLayout* glyphs = itemRenderText.getGlyphs(a); chstr = itemRenderText.text(a, 1); if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; if (chstr[0] == SpecialChars::BLANK) spaceCount++; if (a < itemRenderText.length()-1) chstr += itemRenderText.text(a+1, 1); glyphs->yadvance = 0; layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a), *glyphs); glyphs->shrink(); if (itemRenderText.hasObject(a)) totalTextLen += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH; else totalTextLen += glyphs->wide()+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0; } for (int segs = 0; segs < PoLine.size()-3; segs += 4) { totalCurveLen += PoLine.lenPathSeg(segs); } if ((itemRenderText.paragraphStyle(0).alignment() != 0) && (totalCurveLen >= totalTextLen + m_textDistanceMargins.left())) { if (itemRenderText.paragraphStyle(0).alignment() == 2) { CurX = totalCurveLen - totalTextLen; CurX -= m_textDistanceMargins.left(); } if (itemRenderText.paragraphStyle(0).alignment() == 1) CurX = (totalCurveLen - totalTextLen) / 2.0; if (itemRenderText.paragraphStyle(0).alignment() == 3) { if (spaceCount != 0) { extraOffset = 0; wordExtra = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(spaceCount); } else { extraOffset = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(itemRenderText.length()); wordExtra = 0; } } if (itemRenderText.paragraphStyle(0).alignment() == 4) extraOffset = (totalCurveLen - m_textDistanceMargins.left() - totalTextLen) / static_cast<double>(itemRenderText.length()); } QPainterPath guidePath = PoLine.toQPainterPath(false); QList<QPainterPath> pathList = decomposePath(guidePath); QPainterPath currPath = pathList[0]; int currPathIndex = 0; for (a = firstChar; a < itemRenderText.length(); ++a) { CurY = 0; GlyphLayout* glyphs = itemRenderText.getGlyphs(a); PathData* pdata = & (textLayout.point(a)); chstr = itemRenderText.text(a,1); if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK) continue; if (a < itemRenderText.length()-1) chstr += itemRenderText.text(a+1, 1); glyphs->yadvance = 0; layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a), *glyphs); glyphs->shrink(); // HACK if (itemRenderText.hasObject(a)) dx = (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH / 2.0; else dx = glyphs->wide() / 2.0; CurX += dx; double currPerc = currPath.percentAtLength(CurX); if (currPerc >= 0.9999999) { currPathIndex++; if (currPathIndex == pathList.count()) { MaxChars = a; break; } currPath = pathList[currPathIndex]; CurX = dx; currPerc = currPath.percentAtLength(CurX); } double currAngle = currPath.angleAtPercent(currPerc); if (currAngle <= 180.0) currAngle *= -1.0; else currAngle = 360.0 - currAngle; QPointF currPoint = currPath.pointAtPercent(currPerc); tangent = FPoint(cos(currAngle * M_PI / 180.0), sin(currAngle * M_PI / 180.0)); point = FPoint(currPoint.x(), currPoint.y()); glyphs->xoffset = 0; pdata->PtransX = point.x(); pdata->PtransY = point.y(); pdata->PRot = currAngle * M_PI / 180.0; pdata->PDx = dx; QTransform trafo = QTransform( 1, 0, 0, -1, -dx, 0 ); if (textPathFlipped) trafo *= QTransform(1, 0, 0, -1, 0, 0); if (textPathType == 0) trafo *= QTransform( tangent.x(), tangent.y(), tangent.y(), -tangent.x(), point.x(), point.y() ); // ID's Rainbow mode else if (textPathType == 1) trafo *= QTransform( 1, 0, 0, -1, point.x(), point.y() ); // ID's Stair Step mode else if (textPathType == 2) { double a = 1; if (tangent.x() < 0) a = -1; if (fabs(tangent.x()) > 0.1) trafo *= QTransform( a, (tangent.y() / tangent.x()) * a, 0, -1, point.x(), point.y() ); // ID's Skew mode else trafo *= QTransform( a, 4 * a, 0, -1, point.x(), point.y() ); } QTransform sca = p->worldMatrix(); trafo *= sca; p->save(); QTransform savWM = p->worldMatrix(); p->setWorldMatrix(trafo); if (!m_Doc->RePos) { actFill = itemRenderText.charStyle(a).fillColor(); actFillShade = itemRenderText.charStyle(a).fillShade(); if (actFill != CommonStrings::None) { p->setFillMode(ScPainter::Solid); if ((cachedFillShade != actFillShade) || (cachedFill != actFill)) { SetQColor(&tmp, actFill, actFillShade); p->setBrush(tmp); cachedFillQ = tmp; cachedFill = actFill; cachedFillShade = actFillShade; } else p->setBrush(cachedFillQ); } else p->setFillMode(ScPainter::None); actStroke = itemRenderText.charStyle(a).strokeColor(); actStrokeShade = itemRenderText.charStyle(a).strokeShade(); if (actStroke != CommonStrings::None) { if ((cachedStrokeShade != actStrokeShade) || (cachedStroke != actStroke)) { SetQColor(&tmp, actStroke, actStrokeShade); p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); cachedStrokeQ = tmp; cachedStroke = actStroke; cachedStrokeShade = actStrokeShade; } else p->setPen(cachedStrokeQ, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); } p->translate(0.0, BaseOffs); if (itemRenderText.hasObject(a)) DrawObj_Embedded(p, cullingArea, itemRenderText.charStyle(a), itemRenderText.object(a)); else drawGlyphs(p, itemRenderText.charStyle(a), itemRenderText.flags(a), *glyphs); } p->setWorldMatrix(savWM); p->restore(); MaxChars = a+1; CurX -= dx; if (itemRenderText.hasObject(a)) CurX += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH + extraOffset; else if (chstr[0] == SpecialChars::BLANK) CurX += glyphs->wide()+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0 + wordExtra + extraOffset; else CurX += glyphs->wide()+itemRenderText.charStyle(a).fontSize() *itemRenderText.charStyle(a).tracking() / 10000.0 + extraOffset; } }