void TruckMapWidget::paintEvent(QPaintEvent *evt) { Lock l(m_scaleFactorMutex); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); const double scaleMax = 5; const double scaleMin = 1e-4; const double offsetViewMaxFactor = 8; if (m_scaleFactor < scaleMin) { m_scaleFactor = scaleMin; } else if (m_scaleFactor > scaleMax) { m_scaleFactor = scaleMax; } // White background. painter.fillRect(evt->rect(), QBrush(Qt::white)); // Variables for displaying labels on the map. QString description; QPointF pt_description; QRectF rect_description; QFont fontSettings = this->font(); QPen pen; // Map coordinate system transformation according to DIN 70000: x = 12am, y = 9am --> m_rotation = +90 (http://www.isupia.de/download/Fahrdynamische%20Größen.pdf) QTransform transformationDIN70000; transformationDIN70000.translate(evt->rect().width() / 2, evt->rect().height() / 2); transformationDIN70000.scale(m_scaleFactor, -m_scaleFactor); transformationDIN70000.rotate(m_rotation); // Transformation into the regular coordinate system. QTransform transformationCartesianCoordinateSystem; transformationCartesianCoordinateSystem.translate(evt->rect().width() / 2, evt->rect().height() / 2); transformationCartesianCoordinateSystem.scale(m_scaleFactor, -m_scaleFactor); transformationCartesianCoordinateSystem.rotate(m_rotation - 90); // Transformation into the regular coordinate system for descriptions. QTransform transformationCartesianCoordinateSystemForDescriptions; transformationCartesianCoordinateSystemForDescriptions.translate(evt->rect().width() / 2, evt->rect().height() / 2); transformationCartesianCoordinateSystemForDescriptions.scale(1, 1); transformationCartesianCoordinateSystemForDescriptions.rotate(m_rotation - 90); // Transformation for descriptions label in image coordinates. QTransform descriptionTrans; descriptionTrans.translate(0, 0); descriptionTrans.scale(1, 1); descriptionTrans.rotate(0); // Setup fonts. fontSettings.setPointSize(10); painter.setFont(fontSettings); // Setup axes parameters. const double scaleMultiplier = ceil((1 / ((m_scaleFactor * 100) / 50))); const double step = 100 * scaleMultiplier; const double zeroAxisWidth = 3; const QColor zeroAxisColor = Qt::black; const QColor gridAxisColor = Qt::gray; const QColor textColor = QPalette::Foreground; const double xStepFact = ceil(width() * offsetViewMaxFactor / step / m_scaleFactor); const double yStepFact = ceil(height() * offsetViewMaxFactor / step / m_scaleFactor); // Draw X-axes. for (double i = -yStepFact * step;i < yStepFact * step;i += step) { if ((int)(i / step) % 2) { painter.setPen(gridAxisColor); } else { description.sprintf("%.0f", i/1000.0); pt_description.setY(i); painter.setTransform(descriptionTrans); pt_description = transformationCartesianCoordinateSystem.map(pt_description); pt_description.setX(10); pt_description.setY(pt_description.y() - 5); painter.setPen(QPen(textColor)); painter.drawText(pt_description, description); if (fabs(i) < 1e-5) { pen.setWidthF(zeroAxisWidth / m_scaleFactor); pen.setColor(zeroAxisColor); } else { pen.setWidth(0); } painter.setPen(pen); } painter.setTransform(transformationDIN70000); painter.drawLine(-xStepFact * step, i, xStepFact * step, i); } // Draw Y-axis segments for (double i = -xStepFact * step;i < xStepFact * step;i += step) { if ((int)(i / step) % 2) { painter.setPen(gridAxisColor); } else { description.sprintf("%.0f", i/1000.0*-1); pt_description.setX(i); pt_description.setY(0); painter.setTransform(descriptionTrans); pt_description = transformationCartesianCoordinateSystem.map(pt_description); pt_description.setX(pt_description.x() + 5); pt_description.setY(height() - 10); painter.setPen(QPen(textColor)); painter.drawText(pt_description, description); if (fabs(i) < 1e-5) { pen.setWidthF(zeroAxisWidth / m_scaleFactor); pen.setColor(zeroAxisColor); } else { pen.setWidth(0); } painter.setPen(pen); } painter.setTransform(transformationDIN70000); painter.drawLine(i, -yStepFact * step, i, yStepFact * step); } // Draw objects. { Lock l2(m_objectsMutex); TimeStamp now; TimeStamp validUntil = m_environment.getValidUntil(); if((validUntil-now).toMicroseconds() > 0){ std::vector<from::opendlv::perception::Object> objectList = m_environment.getListOfObjects(); auto it = objectList.begin(); while (it != objectList.end()){ from::opendlv::perception::Object obj = *it; from::opendlv::model::Direction dir = obj.getDirection(); Point3 measurementPoint(obj.getDistance(), 0, 0); measurementPoint.rotateZ(dir.getAzimuth()); int _width = 200 * (m_scaleFactor * 300); int _height = 200 * (m_scaleFactor * 300); painter.setTransform(transformationDIN70000); painter.fillRect(measurementPoint.getX() * 1000,measurementPoint.getY() * 1000, _width, _height, QBrush(Qt::red)); { const QColor objInfoColor = Qt::black; pen.setColor(objInfoColor); pt_description.setX(measurementPoint.getX() * 1000); pt_description.setY(measurementPoint.getY() * 1000); pt_description = transformationDIN70000.map(pt_description); painter.setTransform(descriptionTrans); painter.setPen(pen); fontSettings.setPointSize(10); painter.setFont(fontSettings); stringstream sstr; sstr << "Id=" << obj.getObjectId() << ", d=" << obj.getDistance() << "m."; const string s = sstr.str(); description = s.c_str(); painter.drawText(pt_description, description); } it++; } } } // Draw axes labels. pen.setColor(zeroAxisColor); painter.setPen(pen); painter.setTransform(descriptionTrans); fontSettings.setPointSize(10); painter.setFont(fontSettings); description = "x [m]"; painter.drawText(evt->rect().width() / 2 + 15, 15, description); description = "y [m]"; painter.drawText(15, evt->rect().height() / 2 + 15, description); // Arrows for the axes. pen.setWidthF(zeroAxisWidth); pen.setColor(zeroAxisColor); painter.setPen(pen); // Arrow X axis. painter.drawLine(evt->rect().width() / 2, 0, evt->rect().width() / 2 - 15, 15); painter.drawLine(evt->rect().width() / 2, 0, evt->rect().width() / 2 + 15, 15); // Arrow Y axis. painter.drawLine(0, evt->rect().height() / 2, 15, evt->rect().height() / 2 - 15); painter.drawLine(0, evt->rect().height() / 2, 15, evt->rect().height() / 2 + 15); painter.end(); }
void PageItem_Line::getVisualBoundingRect(double * x1, double * y1, double * x2, double * y2) const { double minx = std::numeric_limits<double>::max(); double miny = std::numeric_limits<double>::max(); double maxx = -std::numeric_limits<double>::max(); double maxy = -std::numeric_limits<double>::max(); double extraSpace = 0.0; if (NamedLStyle.isEmpty()) { if ((lineColor() != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) { extraSpace = m_lineWidth / 2.0; if ((extraSpace == 0) && m_Doc->view()) // Hairline case extraSpace = 0.5 / m_Doc->view()->scale(); } if ((!patternStrokeVal.isEmpty()) && (m_Doc->docPatterns.contains(patternStrokeVal)) && (patternStrokePath)) { ScPattern *pat = &m_Doc->docPatterns[patternStrokeVal]; QTransform mat; mat.rotate(patternStrokeRotation); mat.scale(patternStrokeScaleX / 100.0, patternStrokeScaleY / 100.0); QRectF p1R = QRectF(0, 0, pat->width / 2.0, pat->height / 2.0); QRectF p2R = mat.map(p1R).boundingRect(); extraSpace = p2R.height(); } } else { multiLine ml = m_Doc->MLineStyles[NamedLStyle]; const SingleLine& sl = ml.last(); if (sl.Color != CommonStrings::None) { extraSpace = sl.Width / 2.0; if ((extraSpace == 0) && m_Doc->view()) // Hairline case extraSpace = 0.5 / m_Doc->view()->scale(); } } if (m_rotation != 0) { FPointArray pb; pb.resize(0); pb.addPoint(FPoint(0.0, -extraSpace, xPos(), yPos(), m_rotation, 1.0, 1.0)); pb.addPoint(FPoint(visualWidth(), -extraSpace, xPos(), yPos(), m_rotation, 1.0, 1.0)); pb.addPoint(FPoint(visualWidth(), +extraSpace, xPos(), yPos(), m_rotation, 1.0, 1.0)); pb.addPoint(FPoint(0.0, +extraSpace, xPos(), yPos(), m_rotation, 1.0, 1.0)); for (uint pc = 0; pc < 4; ++pc) { minx = qMin(minx, pb.point(pc).x()); miny = qMin(miny, pb.point(pc).y()); maxx = qMax(maxx, pb.point(pc).x()); maxy = qMax(maxy, pb.point(pc).y()); } *x1 = minx; *y1 = miny; *x2 = maxx; *y2 = maxy; } else { *x1 = m_xPos; *y1 = m_yPos - extraSpace; *x2 = m_xPos + visualWidth(); *y2 = m_yPos + extraSpace; } QRectF totalRect(QPointF(*x1, *y1), QPointF(*x2, *y2)); if (m_startArrowIndex != 0) { QTransform arrowTrans; FPointArray arrow = m_Doc->arrowStyles().at(m_startArrowIndex-1).points.copy(); arrowTrans.translate(m_xPos, m_yPos); arrowTrans.rotate(m_rotation); arrowTrans.translate(0, 0); arrowTrans.scale(m_startArrowScale / 100.0, m_startArrowScale / 100.0); if (NamedLStyle.isEmpty()) { if (m_lineWidth != 0.0) arrowTrans.scale(m_lineWidth, m_lineWidth); } else { multiLine ml = m_Doc->MLineStyles[NamedLStyle]; if (ml[ml.size()-1].Width != 0.0) arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width); } arrowTrans.scale(-1,1); arrow.map(arrowTrans); FPoint minAr = getMinClipF(&arrow); FPoint maxAr = getMaxClipF(&arrow); totalRect = totalRect.united(QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y()))); } if (m_endArrowIndex != 0) { QTransform arrowTrans; FPointArray arrow = m_Doc->arrowStyles().at(m_endArrowIndex-1).points.copy(); arrowTrans.translate(m_xPos, m_yPos); arrowTrans.rotate(m_rotation); arrowTrans.translate(m_width, 0); arrowTrans.scale(m_endArrowScale / 100.0, m_endArrowScale / 100.0); if (NamedLStyle.isEmpty()) { if (m_lineWidth != 0.0) arrowTrans.scale(m_lineWidth, m_lineWidth); } else { multiLine ml = m_Doc->MLineStyles[NamedLStyle]; if (ml[ml.size()-1].Width != 0.0) arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width); } arrow.map(arrowTrans); FPoint minAr = getMinClipF(&arrow); FPoint maxAr = getMaxClipF(&arrow); totalRect = totalRect.united(QRectF(QPointF(minAr.x(), minAr.y()), QPointF(maxAr.x(), maxAr.y()))); } totalRect.getCoords(x1, y1, x2, y2); }
QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom) const { QPainterPath path; switch(baseGeom->geomType) { case TechDrawGeometry::CIRCLE: { TechDrawGeometry::Circle *geom = static_cast<TechDrawGeometry::Circle *>(baseGeom); double x = geom->center.fX - geom->radius; double y = geom->center.fY - geom->radius; path.addEllipse(x, y, geom->radius * 2, geom->radius * 2); //topleft@(x,y) radx,rady //Base::Console().Message("TRACE -drawPainterPath - making an CIRCLE @(%.3f,%.3f) R:%.3f\n",x, y, geom->radius); } break; case TechDrawGeometry::ARCOFCIRCLE: { TechDrawGeometry::AOC *geom = static_cast<TechDrawGeometry::AOC *>(baseGeom); //double x = geom->center.fX - geom->radius; //double y = geom->center.fY - geom->radius; pathArc(path, geom->radius, geom->radius, 0., geom->largeArc, geom->cw, geom->endPnt.fX, geom->endPnt.fY, geom->startPnt.fX, geom->startPnt.fY); //Base::Console().Message("TRACE -drawPainterPath - making an ARCOFCIRCLE @(%.3f,%.3f) R:%.3f\n",x, y, geom->radius); } break; case TechDrawGeometry::ELLIPSE: { TechDrawGeometry::Ellipse *geom = static_cast<TechDrawGeometry::Ellipse *>(baseGeom); // Calculate start and end points as ellipse with theta = 0 and pi double startX = geom->center.fX + geom->major * cos(geom->angle), startY = geom->center.fY + geom->major * sin(geom->angle), endX = geom->center.fX - geom->major * cos(geom->angle), endY = geom->center.fY - geom->major * sin(geom->angle); pathArc(path, geom->major, geom->minor, geom->angle, false, false, endX, endY, startX, startY); pathArc(path, geom->major, geom->minor, geom->angle, false, false, startX, startY, endX, endY); //Base::Console().Message("TRACE -drawPainterPath - making an ELLIPSE @(%.3f,%.3f) R1:%.3f R2:%.3f\n",x, y, geom->major, geom->minor); } break; case TechDrawGeometry::ARCOFELLIPSE: { TechDrawGeometry::AOE *geom = static_cast<TechDrawGeometry::AOE *>(baseGeom); pathArc(path, geom->major, geom->minor, geom->angle, geom->largeArc, geom->cw, geom->endPnt.fX, geom->endPnt.fY, geom->startPnt.fX, geom->startPnt.fY); //Base::Console().Message("TRACE -drawPainterPath - making an ARCOFELLIPSE R1:%.3f R2:%.3f From: (%.3f,%.3f) To: (%.3f,%.3f)\n",geom->major, geom->minor,geom->startPnt.fX, geom->startPnt.fY,geom->endPnt.fX, geom->endPnt.fY); } break; case TechDrawGeometry::BSPLINE: { TechDrawGeometry::BSpline *geom = static_cast<TechDrawGeometry::BSpline *>(baseGeom); std::vector<TechDrawGeometry::BezierSegment>::const_iterator it = geom->segments.begin(); // Move painter to the beginning of our first segment path.moveTo(it->pnts[0].fX, it->pnts[0].fY); //Base::Console().Message("TRACE -drawPainterPath - making an BSPLINE From: (%.3f,%.3f)\n",it->pnts[0].fX,it->pnts[0].fY); for ( ; it != geom->segments.end(); ++it) { // At this point, the painter is either at the beginning // of the first segment, or end of the last if ( it->poles == 2 ) { // Degree 1 bezier = straight line... path.lineTo(it->pnts[1].fX, it->pnts[1].fY); } else if ( it->poles == 3 ) { path.quadTo(it->pnts[1].fX, it->pnts[1].fY, it->pnts[2].fX, it->pnts[2].fY); } else if ( it->poles == 4 ) { path.cubicTo(it->pnts[1].fX, it->pnts[1].fY, it->pnts[2].fX, it->pnts[2].fY, it->pnts[3].fX, it->pnts[3].fY); } else { //can only handle lines,quads,cubes Base::Console().Error("Bad pole count (%d) for BezierSegment of BSpline geometry\n",it->poles); path.lineTo(it->pnts[1].fX, it->pnts[1].fY); //show something for debugging } } } break; case TechDrawGeometry::GENERIC: { TechDrawGeometry::Generic *geom = static_cast<TechDrawGeometry::Generic *>(baseGeom); path.moveTo(geom->points[0].fX, geom->points[0].fY); std::vector<Base::Vector2D>::const_iterator it = geom->points.begin(); //Base::Console().Message("TRACE -drawPainterPath - making an GENERIC From: (%.3f,%.3f)\n",geom->points[0].fX, geom->points[0].fY); for(++it; it != geom->points.end(); ++it) { path.lineTo((*it).fX, (*it).fY); //Base::Console().Message(">>>> To: (%.3f,%.3f)\n",(*it).fX, (*it).fY); } } break; default: Base::Console().Error("Error - drawPainterPath - UNKNOWN geomType: %d\n",baseGeom->geomType); break; } double rot = getViewObject()->Rotation.getValue(); if (rot) { QTransform t; t.rotate(-rot); path = t.map(path); } return path; }
/*! \reimp */ void QDeclarativePaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativePaintedItem); const QRect content(0,0,qCeil(d->contentsSize.width()*d->contentsScale), qCeil(d->contentsSize.height()*d->contentsScale)); if (content.width() <= 0 || content.height() <= 0) return; ++inpaint; const QTransform &x = p->deviceTransform(); QTransform xinv = x.inverted(); QRegion effectiveClip; QRegion sysClip = p->paintEngine()->systemClip(); if (xinv.type() <= QTransform::TxScale && sysClip.numRects() < 5) { // simple transform, region gets no more complicated... effectiveClip = xinv.map(sysClip); } else { // do not make complicated regions... effectiveClip = xinv.mapRect(sysClip.boundingRect()); } QRegion topaint = p->clipRegion(); if (topaint.isEmpty()) { if (effectiveClip.isEmpty()) topaint = QRect(0,0,p->device()->width(),p->device()->height()); else topaint = effectiveClip; } else if (!effectiveClip.isEmpty()) { topaint &= effectiveClip; } topaint &= content; QRegion uncached(content); p->setRenderHints(QPainter::SmoothPixmapTransform, d->smooth); int cachesize=0; for (int i=0; i<d->imagecache.count(); ++i) { QRect area = d->imagecache[i]->area; if (topaint.contains(area)) { QRectF target(area.x(), area.y(), area.width(), area.height()); if (!d->cachefrozen) { if (!d->imagecache[i]->dirty.isNull() && topaint.contains(d->imagecache[i]->dirty)) { QPainter qp(&d->imagecache[i]->image); qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache); qp.translate(-area.x(), -area.y()); qp.scale(d->contentsScale,d->contentsScale); QRect clip = d->imagecache[i]->dirty; QRect sclip(qFloor(clip.x()/d->contentsScale), qFloor(clip.y()/d->contentsScale), qCeil(clip.width()/d->contentsScale+clip.x()/d->contentsScale-qFloor(clip.x()/d->contentsScale)), qCeil(clip.height()/d->contentsScale+clip.y()/d->contentsScale-qFloor(clip.y()/d->contentsScale))); qp.setClipRect(sclip); if (d->fillColor.isValid()){ if(d->fillColor.alpha() < 255){ // ### Might not work outside of raster paintengine QPainter::CompositionMode prev = qp.compositionMode(); qp.setCompositionMode(QPainter::CompositionMode_Source); qp.fillRect(sclip,d->fillColor); qp.setCompositionMode(prev); }else{ qp.fillRect(sclip,d->fillColor); } } drawContents(&qp, sclip); d->imagecache[i]->dirty = QRect(); } } p->drawPixmap(target.toRect(), d->imagecache[i]->image); topaint -= area; d->imagecache[i]->age=0; } else { d->imagecache[i]->age++; } cachesize += area.width()*area.height(); uncached -= area; } if (!topaint.isEmpty()) { if (!d->cachefrozen) { // Find a sensible larger area, otherwise will paint lots of tiny images. QRect biggerrect = topaint.boundingRect().adjusted(-64,-64,128,128); cachesize += biggerrect.width() * biggerrect.height(); while (d->imagecache.count() && cachesize > d->max_imagecache_size) { int oldest=-1; int age=-1; for (int i=0; i<d->imagecache.count(); ++i) { int a = d->imagecache[i]->age; if (a > age) { oldest = i; age = a; } } cachesize -= d->imagecache[oldest]->area.width()*d->imagecache[oldest]->area.height(); uncached += d->imagecache[oldest]->area; delete d->imagecache.takeAt(oldest); } const QRegion bigger = QRegion(biggerrect) & uncached; const QVector<QRect> rects = bigger.rects(); for (int i = 0; i < rects.count(); ++i) { const QRect &r = rects.at(i); QPixmap img(r.size()); if (d->fillColor.isValid()) img.fill(d->fillColor); { QPainter qp(&img); qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache); qp.translate(-r.x(),-r.y()); qp.scale(d->contentsScale,d->contentsScale); QRect sclip(qFloor(r.x()/d->contentsScale), qFloor(r.y()/d->contentsScale), qCeil(r.width()/d->contentsScale+r.x()/d->contentsScale-qFloor(r.x()/d->contentsScale)), qCeil(r.height()/d->contentsScale+r.y()/d->contentsScale-qFloor(r.y()/d->contentsScale))); drawContents(&qp, sclip); } QDeclarativePaintedItemPrivate::ImageCacheItem *newitem = new QDeclarativePaintedItemPrivate::ImageCacheItem; newitem->area = r; newitem->image = img; d->imagecache.append(newitem); p->drawPixmap(r, newitem->image); } } else { const QVector<QRect> rects = uncached.rects(); for (int i = 0; i < rects.count(); ++i) p->fillRect(rects.at(i), Qt::lightGray); } } if (inpaint_clearcache) { clearCache(); inpaint_clearcache = 0; } --inpaint; }
void Tie::computeBezier(SlurSegment* ss, QPointF p6o) { qreal _spatium = spatium(); qreal shoulderW; // height as fraction of slur-length qreal shoulderH; // // pp1 start of slur // pp2 end of slur // pp3 bezier 1 // pp4 bezier 2 // pp5 drag // pp6 shoulder // QPointF pp1 = ss->ups[GRIP_START].p + ss->ups[GRIP_START].off * _spatium; QPointF pp2 = ss->ups[GRIP_END].p + ss->ups[GRIP_END].off * _spatium; QPointF p2 = pp2 - pp1; // normalize to zero if (p2.x() == 0.0) { qDebug("zero tie"); return; } qreal sinb = atan(p2.y() / p2.x()); QTransform t; t.rotateRadians(-sinb); p2 = t.map(p2); p6o = t.map(p6o); double smallH = 0.38; qreal d = p2.x() / _spatium; shoulderH = d * 0.4 * smallH; if (shoulderH > 1.3) // maximum tie shoulder height shoulderH = 1.3; shoulderH *= _spatium; shoulderW = .6; shoulderH -= p6o.y(); if (!up()) shoulderH = -shoulderH; qreal c = p2.x(); qreal c1 = (c - c * shoulderW) * .5 + p6o.x(); qreal c2 = c1 + c * shoulderW + p6o.x(); QPointF p5 = QPointF(c * .5, 0.0); QPointF p3(c1, -shoulderH); QPointF p4(c2, -shoulderH); qreal w = (score()->styleS(ST_SlurMidWidth).val() - score()->styleS(ST_SlurEndWidth).val()) * _spatium; QPointF th(0.0, w); // thickness of slur QPointF p3o = p6o + t.map(ss->ups[GRIP_BEZIER1].off * _spatium); QPointF p4o = p6o + t.map(ss->ups[GRIP_BEZIER2].off * _spatium); if(!p6o.isNull()) { QPointF p6i = t.inverted().map(p6o) / _spatium; ss->ups[GRIP_BEZIER1].off += p6i ; ss->ups[GRIP_BEZIER2].off += p6i; } //-----------------------------------calculate p6 QPointF pp3 = p3 + p3o; QPointF pp4 = p4 + p4o; QPointF ppp4 = pp4 - pp3; qreal r2 = atan(ppp4.y() / ppp4.x()); t.reset(); t.rotateRadians(-r2); QPointF p6 = QPointF(t.map(ppp4).x() * .5, 0.0); t.rotateRadians(2 * r2); p6 = t.map(p6) + pp3 - p6o; //----------------------------------- ss->path = QPainterPath(); ss->path.moveTo(QPointF()); ss->path.cubicTo(p3 + p3o - th, p4 + p4o - th, p2); if (lineType() == 0) ss->path.cubicTo(p4 +p4o + th, p3 + p3o + th, QPointF()); th = QPointF(0.0, 3.0 * w); ss->shapePath = QPainterPath(); ss->shapePath.moveTo(QPointF()); ss->shapePath.cubicTo(p3 + p3o - th, p4 + p4o - th, p2); ss->shapePath.cubicTo(p4 +p4o + th, p3 + p3o + th, QPointF()); // translate back t.reset(); t.translate(pp1.x(), pp1.y()); t.rotateRadians(sinb); ss->path = t.map(ss->path); ss->shapePath = t.map(ss->shapePath); ss->ups[GRIP_BEZIER1].p = t.map(p3); ss->ups[GRIP_BEZIER2].p = t.map(p4); ss->ups[GRIP_END].p = t.map(p2) - ss->ups[GRIP_END].off * _spatium; ss->ups[GRIP_DRAG].p = t.map(p5); ss->ups[GRIP_SHOULDER].p = t.map(p6); }
bool DataConverter::digitalPattern_Rotate(QPolygonF &points, qreal angle) { if (angle == 0.0) return true; if (angle < -180.0 || angle > 180.0) { qDebug("[DataConverter::digitalPattern_Rotate] Error: Angle: [%f]", angle); return false; } if (points.size() < 10) { qDebug("[DataConverter::digitalPattern_Rotate] Error: Polygon Point Count: [%d]", points.size()); return false; } // QTransform transform; transform.rotate(angle); points = transform.map(points); // int bottomIndex = 0; { qreal tmpX = -9999.99; for (int i = 0; i < points.size(); i++) { if (points.at(i).y() < 0.0) continue; if (points.at(i).x() > 0.0) continue; if (points.at(i).x() > tmpX) { tmpX = points.at(i).x(); bottomIndex = i; } } } qDebug("** bottomIndex: [%d]", bottomIndex); if (bottomIndex > 0) { QPointF tmpPoint; for (int i = points.size() - 1; i >= bottomIndex; i--) { tmpPoint = points.last(); points.pop_back(); points.push_front(tmpPoint); } } return true; }
void CanvasMode_Rotate::mousePressEvent(QMouseEvent *m) { const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos()); m_canvasPressCoord = mousePointDoc; double Rxp = 0, Ryp = 0; PageItem *currItem; m_canvas->PaintSizeRect(QRect()); QRect tx; QTransform pm; m_canvas->m_viewMode.m_MouseButtonPressed = true; m_canvas->m_viewMode.operItemMoving = false; m_view->HaveSelRect = false; m_doc->leaveDrag = false; m->accept(); m_view->registerMousePress(m->globalPos()); QRect mpo(m->x()-m_doc->guidesPrefs().grabRadius, m->y()-m_doc->guidesPrefs().grabRadius, m_doc->guidesPrefs().grabRadius*2, m_doc->guidesPrefs().grabRadius*2); Rxp = m_doc->ApplyGridF(m_canvasPressCoord).x(); m_canvasPressCoord.setX( qRound(Rxp) ); Ryp = m_doc->ApplyGridF(m_canvasPressCoord).y(); m_canvasPressCoord.setY( qRound(Ryp) ); if (m->button() == Qt::MidButton) { m_view->MidButt = true; if (m->modifiers() & Qt::ControlModifier) m_view->DrawNew(); return; } if (m->button() != Qt::LeftButton) return; if (GetItem(&currItem)) { m_inItemRotation = true; m_oldRotMode = m_rotMode = m_doc->RotMode(); m_oldRotCenter = m_rotCenter = m_view->RCenter; if (m_doc->m_Selection->isMultipleSelection()) { double gx, gy, gh, gw; double gxR, gyR, ghR, gwR; m_view->getGroupRectScreen(&gx, &gy, &gw, &gh); m_doc->m_Selection->getGroupRect(&gxR, &gyR, &gwR, &ghR); if (QRect(static_cast<int>(gx), static_cast<int>(gy), static_cast<int>(gw), static_cast<int>(gh)).intersects(mpo)) { m_rotMode = 2; m_rotCenter = FPoint(gxR+gwR/2.0, gyR+ghR/2.0); if (QRect(static_cast<int>(gx+gw)-6, static_cast<int>(gy+gh)-6, 6, 6).intersects(mpo)) { m_rotCenter = FPoint(gxR, gyR); m_rotMode = 0; } m_doc->RotMode ( m_rotMode ); m_view->RCenter = m_rotCenter; } m_startAngle = xy2Deg(mousePointDoc.x() - m_view->RCenter.x(), mousePointDoc.y() - m_view->RCenter.y()); m_view->oldW = m_startAngle; } else { QTransform mat; m_canvas->Transform(currItem, mat); m_rotMode = 2; m_rotCenter = FPoint(currItem->width()/2, currItem->height()/2, 0, 0, currItem->rotation(), 1, 1, false); // if (!currItem->asLine()) // { if (QRegion(mat.map(QPolygon(QRect(0, 0, static_cast<int>(currItem->width()), static_cast<int>(currItem->height()))))).contains(mpo)) { if (mat.mapRect(QRect(0, 0, 6, 6)).intersects(mpo)) { m_rotCenter = FPoint(currItem->width(), currItem->height(), 0, 0, currItem->rotation(), 1, 1, false); m_rotMode = 4; } else if (mat.mapRect(QRect(static_cast<int>(currItem->width())-6, 0, 6, 6)).intersects(mpo)) { m_rotCenter = FPoint(0, currItem->height(), 0, 0, currItem->rotation(), 1, 1, false); m_rotMode = 3; } else if (mat.mapRect(QRect(static_cast<int>(currItem->width())-6, static_cast<int>(currItem->height())-6, 6, 6)).intersects(mpo)) { m_rotCenter = FPoint(0, 0); m_rotMode = 0; } else if (mat.mapRect(QRect(0, static_cast<int>(currItem->height())-6, 6, 6)).intersects(mpo)) { m_rotCenter = FPoint(currItem->width(), 0, 0, 0, currItem->rotation(), 1, 1, false); m_rotMode = 1; } } m_doc->RotMode ( m_rotMode ); m_view->RCenter = m_rotCenter; // } m_view->RCenter = m_rotCenter = FPoint(currItem->xPos()+ m_view->RCenter.x(), currItem->yPos()+ m_view->RCenter.y()); //????? m_view->oldW = m_startAngle = xy2Deg(mousePointDoc.x() - m_view->RCenter.x(), mousePointDoc.y() - m_view->RCenter.y()); } } }
void MiamStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *opt, QPainter *painter, const QWidget *widget) const { switch (element) { // On Linux, don't fill the rectangular area where lives the PE_IndicatorBranch. Keep this area transparent // On Windows, this is the default behaviour case PE_PanelItemViewRow: { if (widget && widget->inherits("Playlist")) { QProxyStyle::drawPrimitive(element, opt, painter, widget); } break; } case PE_IndicatorTabClose: { if (opt->state.testFlag(State_MouseOver)) { QFileSelector fs; painter->drawPixmap(0, 0, 16, 16, QPixmap(fs.select(":/icons/config/close_tabs_hover.png"))); } else { painter->drawPixmap(0, 0, 16, 16, QPixmap(":/icons/closeTabs")); } break; } case PE_IndicatorBranch: { // Draw sort indicator static const QPointF downArrow[3] = { QPointF(0.0, 0.0), QPointF(2.0, 0.0), QPointF(1.0, 1.0) }; static const QPointF leftArrow[3] = { QPointF(0.0, 1.0), QPointF(1.0, 0.0), QPointF(1.0, 2.0) }; static const QPointF rightArrow[3] = { QPointF(0.0, 0.0), QPointF(1.0, 1.0), QPointF(0.0, 2.0) }; QTransform t; float ratio = opt->rect.width() / 4.0; //qDebug() << "ratio" << ratio << opt->rect << opt->fontMetrics.height(); t.scale(ratio, ratio); QPolygonF arrow; if (QGuiApplication::isLeftToRight()) { QPolygonF right; right.append(t.map(rightArrow[0])); right.append(t.map(rightArrow[1])); right.append(t.map(rightArrow[2])); arrow = right; } else { QPolygonF left; left.append(t.map(leftArrow[0])); left.append(t.map(leftArrow[1])); left.append(t.map(leftArrow[2])); arrow = left; } if (opt->state.testFlag(State_Children)) { painter->save(); if (opt->state.testFlag(State_MouseOver)) { painter->setPen(opt->palette.highlight().color()); painter->setBrush(opt->palette.highlight().color().lighter()); } else { painter->setPen(opt->palette.mid().color()); painter->setBrush(Qt::NoBrush); } if (opt->state.testFlag(State_Open)) { QPolygonF down; down.append(t.map(downArrow[0])); down.append(t.map(downArrow[1])); down.append(t.map(downArrow[2])); painter->translate(opt->rect.x() + opt->rect.width() / 2 - down.boundingRect().width() / 2, opt->rect.y() + opt->rect.height() / 2 - down.boundingRect().height() / 2); painter->drawPolygon(down); } else { painter->translate(opt->rect.x() + opt->rect.width() / 2 - arrow.boundingRect().width() / 2, opt->rect.y() + opt->rect.height() / 2 - arrow.boundingRect().height() / 2); painter->drawPolygon(arrow); } painter->restore(); } break; } case PE_PanelLineEdit: { QPen pen = opt->palette.window().color(); QBrush brush = opt->palette.base(); painter->setPen(pen); painter->setBrush(brush); painter->drawRect(widget->rect().adjusted(0, 0, -1, -1)); break; } case PE_FrameGroupBox: { QPen pen = opt->palette.window().color(); QBrush brush = opt->palette.base(); painter->setPen(pen); painter->setBrush(brush); //painter->drawRect(widget->rect()); QProxyStyle::drawPrimitive(element, opt, painter, widget); break; } case PE_FrameStatusBarItem: case PE_FrameButtonTool: case PE_FrameButtonBevel: case PE_FrameFocusRect: break; case PE_FrameMenu: { QPen pen = opt->palette.mid().color(); QBrush brush = opt->palette.window(); painter->setPen(pen); painter->setBrush(brush); painter->drawRect(widget->rect().adjusted(0, 0, -1, -1)); break; } case PE_FrameTabBarBase: if (widget) { painter->fillRect(widget->rect(), QApplication::palette().window()); } else { painter->fillRect(opt->rect, QApplication::palette().window()); } break; default: { QProxyStyle::drawPrimitive(element, opt, painter, widget); break; } } }
int main(int argc, char **argv) { if (argc < 4) { fprintf(stderr, "import <maps.json> <map id> <file.tif>\n"); return -1; } OGRRegisterAll(); GDALAllRegister(); QFile rootFile(argv[1]); QString mapId(argv[2]); QFileInfo filename(argv[3]); RootData rootData(NULL); Map *map = rootData.maps()[mapId]; Projection *pjGeo = Geographic::getProjection(NAD27); Projection *pj = map->projection(); readQuadIndex(0, "/Users/hawkinsp/geo/drg/index/drg100.shp", "drg100", pj); readQuadIndex(1, "/Users/hawkinsp/geo/drg/index/drg24.shp", "drg24", pj); // Index information seems buggy for these quads -- just use the regular grid. quads.remove("o37122g4"); // San Francisco North quads.remove("o37122g5"); // Point Bonita GDALDataset *ds = (GDALDataset *)GDALOpen(filename.filePath().toLatin1().data(), GA_ReadOnly); if (!ds) { fprintf(stderr, "ERROR: Could not open dataset.\n"); return -1; } const char *proj = ds->GetProjectionRef(); Quad quad; getQuadInfo(filename, pj, quad); // Read projection OGRSpatialReference srs; srs.importFromWkt((char **)&proj); // Size of the DRG QSize drgSize = QSize(ds->GetRasterXSize(), ds->GetRasterYSize()); printf("DRG id: %s, name %s, size %dx%d\n", quad.id.toLatin1().data(), quad.name.toLatin1().data(), drgSize.width(), drgSize.height()); // ------------------------------------------ // Read geotransform coefficients. The geotransform describe the mapping from // DRG image space to projection space. double geoTransformCoeff[6]; ds->GetGeoTransform(geoTransformCoeff); // Top left coordinate of the drg in projection space QPointF fProjTopLeft = QPointF(geoTransformCoeff[0], geoTransformCoeff[3]); // Size of a drg pixel in projection space QSizeF fPixelSize = QSizeF(geoTransformCoeff[1], geoTransformCoeff[5]); // Check Y pixel size is the negation of the X pixel size if (fabs(fPixelSize.width() + fPixelSize.height()) >= epsilon) { fprintf(stderr, "Invalid pixel sizes\n"); return -1; } // We assume the geotransform consists of only translation and scaling. // We'd need to do a more general image transformation to handle shearing. if (fabs(geoTransformCoeff[2]) >= epsilon || fabs(geoTransformCoeff[4]) >= epsilon) { fprintf(stderr, "ERROR: DRG geotransform has shear component.\n"); return -1; } // Transforms from drg space to projection space and vice versa QTransform drgProjTransform; drgProjTransform.translate(fProjTopLeft.x(), fProjTopLeft.y()); drgProjTransform.scale(fPixelSize.width(), fPixelSize.height()); QTransform projDrgTransform = drgProjTransform.inverted(); // Size of the DRG in projection space QSizeF fProjSize = QSizeF(qreal(ds->GetRasterXSize()) * fPixelSize.width(), qreal(ds->GetRasterYSize()) * fPixelSize.height()); QRectF projRect = QRectF(fProjTopLeft, fProjSize); // Rectangle covered by the entire map image QRectF mapRect = map->projToMap().mapRect(projRect); printf("Map Rect: %lf %lf %lf %lf\n", mapRect.left(), mapRect.top(), mapRect.right(), mapRect.bottom()); // Compute the initial scale factor and tile level QSizeF mapPixelSize = map->mapPixelSize(); assert(mapPixelSize.width() + mapPixelSize.height() < epsilon); QSizeF scale(fPixelSize.width() / mapPixelSize.width(), fPixelSize.height() / mapPixelSize.height()); int maxLevel = map->maxLevel(); while (scale.width() >= 1.1) { maxLevel--; scale /= 2.0; } // printf("scale %lf %lf\n", scale.width(), scale.height()); //return 0; // Compute the quad boundary QPolygonF projQuad(quad.boundary); QPolygonF geoQuad = pjGeo->transformFrom(pj, projQuad); QRectF geoQuadBounds(geoQuad.boundingRect()); printf("Series: %d %s\n", quad.series, map->layer(quad.series).name().toLatin1().data()); printf("Geographic quad boundary: %lf %lf %lf %lf\n", geoQuadBounds.left(), geoQuadBounds.top(), geoQuadBounds.right(), geoQuadBounds.bottom()); // Quad bounding rectangle in map space QRectF projQuadBounds = projQuad.boundingRect(); QRectF mapQuadBounds = map->projToMap().mapRect(projQuadBounds); printf("Quad bounding rectangle in map space: %lf %lf %lf %lf\n", mapQuadBounds.left(), mapQuadBounds.top(), mapQuadBounds.right(), mapQuadBounds.bottom()); // Quad bounding rectangle in drg space QPolygonF drgBounds = projDrgTransform.map(projQuad); QRectF drgQuadBounds = drgBounds.boundingRect(); printf("Quad bounding rectangle in drg space: %lf %lf %lf %lf\n", drgQuadBounds.left(), drgQuadBounds.top(), drgQuadBounds.right(), drgQuadBounds.bottom()); // Read the image QImage drg(filename.filePath()); if (drgQuadBounds.left() < -drgQuadSlackPixels || drgQuadBounds.right() > drgSize.width() + drgQuadSlackPixels || drgQuadBounds.top() < -drgQuadSlackPixels || drgQuadBounds.bottom() > drgSize.height() + drgQuadSlackPixels) { QString mfile("misalign-" + filename.baseName() + ".png"); fprintf(stderr, "WARNING: DRG and quadrangle boundaries are misaligned; diagnostic saved to '%s'!\n", mfile.toLatin1().data()); QImage image = drg.convertToFormat(QImage::Format_RGB32); QPainter p; p.begin(&image); QPainterPath pp; pp.addPolygon(drgBounds); p.setPen(QPen(Qt::blue, 2)); p.drawPath(pp); p.end(); image.save(mfile, "png"); } /*printf("top left %lf %lf\n", fProjTopLeft.x(), fProjTopLeft.y());*/ /*for (int i = 0; i< projectedQuad.size(); i++) { printf("quad proj %lf %lf\n", projectedQuad[i].x(), projectedQuad[i].y()); }*/ QDir dir; // for (int level = maxLevel; level >= 0; level--, scale /= 2.0) { int level = maxLevel; QSizeF rasterSizeF = QSizeF(ds->GetRasterXSize() * scale.width(), ds->GetRasterYSize() * scale.height()); QSize rasterSize = rasterSizeF.toSize(); printf("level %d size %dx%d\n", level, rasterSize.width(), rasterSize.height()); QImage drgScaled = drg.scaled(rasterSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); QPolygonF imageQuad; for (int i = 0; i < projQuad.size(); i++) { QPointF p = projQuad[i] - fProjTopLeft; imageQuad << QPointF(p.x() * scale.width() / fPixelSize.width(), p.y() * scale.height() / fPixelSize.height()); } QSizeF baseTileSize(map->baseTileSize(), map->baseTileSize()); int tileSize = map->tileSize(level); QRectF tileRectF = QRectF(mapQuadBounds.topLeft() / qreal(tileSize), mapQuadBounds.bottomRight() / qreal(tileSize)); QRect tileRect(QPoint(int(floor(tileRectF.left())), int(floor(tileRectF.top()))), QPoint(int(ceil(tileRectF.right())), int(ceil(tileRectF.bottom())))); /* printf("tile rect %d %d %d %d\n", tileRect.left(), tileRect.top(), tileRect.right(), tileRect.bottom());*/ for (int tileY = tileRect.top(); tileY <= tileRect.bottom(); tileY++) { for (int tileX = tileRect.left(); tileX <= tileRect.right(); tileX++) { Tile key(tileX, tileY, level, quad.series); QPointF tileTopLeft(tileX * tileSize, tileY * tileSize); QPointF deltaTileTopLeft = tileTopLeft - mapRect.topLeft(); qreal s = qreal(1 << (map->maxLevel() - level)); QPointF topLeft(deltaTileTopLeft.x() / s, deltaTileTopLeft.y() / s); QRectF src(topLeft, baseTileSize); QFileInfo tilePath(map->tilePath(key)); dir.mkpath(tilePath.path()); QImage image; if (tilePath.exists()) { QImage idxImage = QImage(tilePath.filePath()); image = idxImage.convertToFormat(QImage::Format_RGB32); } else { image = QImage(256, 256, QImage::Format_RGB32); image.setColorTable(drg.colorTable()); image.fill(QColor(255, 255, 255).rgb()); } QPainterPath pp; pp.addPolygon(imageQuad.translated(-topLeft)); QPainter painter; painter.begin(&image); painter.setClipPath(pp); painter.drawImage(-topLeft, drgScaled); // painter.setPen(QPen(QColor(0, 0, 255))); // painter.drawPath(pp); painter.end(); QImage tile = image.convertToFormat(QImage::Format_Indexed8, drg.colorTable(), Qt::ThresholdDither); tile.save(tilePath.filePath(), "png"); // printf("tile: %s\n", tilePath.filePath().toLatin1().data()); } } // } return 0; }
WebTouchEvent WebEventFactory::createWebTouchEvent(const QTouchEvent* event, const QTransform& fromItemTransform) { WebEvent::Type type = webEventTypeForEvent(event); WebPlatformTouchPoint::TouchPointState state = static_cast<WebPlatformTouchPoint::TouchPointState>(0); unsigned int id; WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers()); double timestamp = currentTimeForEvent(event); const QList<QTouchEvent::TouchPoint>& points = event->touchPoints(); Vector<WebPlatformTouchPoint, 6> m_touchPoints; for (int i = 0; i < points.count(); ++i) { const QTouchEvent::TouchPoint& touchPoint = points.at(i); id = static_cast<unsigned>(touchPoint.id()); switch (touchPoint.state()) { case Qt::TouchPointReleased: state = WebPlatformTouchPoint::TouchReleased; break; case Qt::TouchPointMoved: state = WebPlatformTouchPoint::TouchMoved; break; case Qt::TouchPointPressed: state = WebPlatformTouchPoint::TouchPressed; break; case Qt::TouchPointStationary: state = WebPlatformTouchPoint::TouchStationary; break; default: ASSERT_NOT_REACHED(); break; } // Qt does not have a Qt::TouchPointCancelled point state, so if we receive a touch cancel event, // simply cancel all touch points here. if (type == WebEvent::TouchCancel) state = WebPlatformTouchPoint::TouchCancelled; m_touchPoints.append(WebPlatformTouchPoint(id, state, touchPoint.screenPos().toPoint(), fromItemTransform.map(touchPoint.pos()).toPoint())); } return WebTouchEvent(type, m_touchPoints, modifiers, timestamp); }
/// XXX void MiamStyle::drawScrollBar(QPainter *p, const QWidget *widget) const { QStyleOptionSlider scrollbar; scrollbar.palette = QApplication::palette(); const QScrollBar *sc = qobject_cast<const QScrollBar *>(widget); scrollbar.initFrom(sc); QRect subLineRect = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, &scrollbar, QStyle::SC_ScrollBarSubLine, sc); QRect addLineRect = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, &scrollbar, QStyle::SC_ScrollBarAddLine, sc); QRect sliderRect = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, &scrollbar, QStyle::SC_ScrollBarSlider, sc); //qDebug() << subLineRect << sliderRect << addLineRect; if (sc->orientation() == Qt::Vertical) { subLineRect.adjust(0, 0, -1, 0); addLineRect.adjust(0, 0, -1, 0); sliderRect.adjust(0, 0, -1, 0); } else { subLineRect.adjust(0, 0, 0, -1); addLineRect.adjust(0, 0, 0, -1); sliderRect.adjust(0, 0, 0, -1); } p->setPen(Qt::NoPen); p->setBrush(scrollbar.palette.window()); p->drawRect(sc->rect()); p->setBrush(scrollbar.palette.base().color().darker(125)); p->drawRect(sliderRect); // Highlight p->save(); QPoint pos = sc->mapFromGlobal(QCursor::pos()); p->setPen(scrollbar.palette.highlight().color()); if (!sc->isSliderDown()) { p->setBrush(scrollbar.palette.highlight().color().lighter()); if (subLineRect.contains(pos)) { p->drawRect(subLineRect); } else if (sliderRect.contains(pos)) { p->drawRect(sliderRect); } else if (addLineRect.contains(pos)) { p->drawRect(addLineRect); } } else { p->setBrush(scrollbar.palette.highlight().color()); //if (_isDown == 0) { // p->drawRect(subLineRect); //} else if (_isDown == 1) { // p->drawRect(sliderRect); //} else if (_isDown == 2) { // p->drawRect(addLineRect); //} } p->restore(); // Draw sort indicator static const QPointF upArrow[3] = { QPointF(0.0, 1.0), QPointF(1.0, 0.0), QPointF(2.0, 1.0) }; static const QPointF downArrow[3] = { QPointF(0.0, 0.0), QPointF(2.0, 0.0), QPointF(1.0, 1.0) }; static const QPointF leftArrow[3] = { QPointF(0.0, 1.0), QPointF(1.0, 0.0), QPointF(1.0, 2.0) }; static const QPointF rightArrow[3] = { QPointF(0.0, 0.0), QPointF(1.0, 1.0), QPointF(0.0, 2.0) }; // Arrows p->save(); if (scrollbar.palette.windowText().color().value() < 128) { p->setPen(scrollbar.palette.dark().color()); p->setBrush(scrollbar.palette.dark()); } else { p->setPen(scrollbar.palette.mid().color()); p->setBrush(scrollbar.palette.mid()); } QTransform t; float ratio = (float) subLineRect.height() / 4.0; t.scale(ratio, ratio); if (sc->orientation() == Qt::Vertical) { QPolygonF up, down; up.append(t.map(upArrow[0])); up.append(t.map(upArrow[1])); up.append(t.map(upArrow[2])); down.append(t.map(downArrow[0])); down.append(t.map(downArrow[1])); down.append(t.map(downArrow[2])); p->translate(subLineRect.width() / 4.0, subLineRect.height() / 3.0); p->drawPolygon(up); p->translate(0, addLineRect.y()); p->drawPolygon(down); } else { QPolygonF left, right; left.append(t.map(leftArrow[0])); left.append(t.map(leftArrow[1])); left.append(t.map(leftArrow[2])); right.append(t.map(rightArrow[0])); right.append(t.map(rightArrow[1])); right.append(t.map(rightArrow[2])); p->translate(subLineRect.height() / 3.0, subLineRect.width() / 4.0); p->drawPolygon(left); p->translate(addLineRect.x(), 0); p->drawPolygon(right); } p->restore(); }
void Slur::computeBezier(SlurSegment* ss, QPointF p6o) { qreal _spatium = spatium(); qreal shoulderW; // height as fraction of slur-length qreal shoulderH; // // p1 and p2 are the end points of the slur // QPointF pp1 = ss->ups[GRIP_START].p + ss->ups[GRIP_START].off * _spatium; QPointF pp2 = ss->ups[GRIP_END].p + ss->ups[GRIP_END].off * _spatium; QPointF p2 = pp2 - pp1; if ((p2.x() == 0.0) && (p2.y() == 0.0)) { qDebug("zero slur"); abort(); Measure* m1 = startChord()->segment()->measure(); Measure* m2 = endChord()->segment()->measure(); Page* page = m1->system()->page(); qDebug(" at tick %d in measure %d-%d page %d", m1->tick(), m1->no(), m2->no(), page->no()); return; } qreal sinb = atan(p2.y() / p2.x()); QTransform t; t.rotateRadians(-sinb); p2 = t.map(p2); p6o = t.map(p6o); double smallH = 0.5; qreal d = p2.x() / _spatium; if (d <= 2.0) { shoulderH = d * 0.5 * smallH * _spatium; shoulderW = .6; } else { qreal dd = log10(1.0 + (d - 2.0) * .5) * 2.0; if (dd > 3.0) dd = 3.0; shoulderH = (dd + smallH) * _spatium; if (d > 18.0) shoulderW = 0.7; // 0.8; else if (d > 10) shoulderW = 0.6; // 0.7; else shoulderW = 0.5; // 0.6; } shoulderH -= p6o.y(); if (!up()) shoulderH = -shoulderH; qreal c = p2.x(); qreal c1 = (c - c * shoulderW) * .5 + p6o.x(); qreal c2 = c1 + c * shoulderW + p6o.x(); QPointF p5 = QPointF(c * .5, 0.0); QPointF p3(c1, -shoulderH); QPointF p4(c2, -shoulderH); qreal w = (score()->styleS(ST_SlurMidWidth).val() - score()->styleS(ST_SlurEndWidth).val()) * _spatium; if (((c2 - c1) / _spatium) <= _spatium) w *= .5; QPointF th(0.0, w); // thickness of slur QPointF p3o = p6o + t.map(ss->ups[GRIP_BEZIER1].off * _spatium); QPointF p4o = p6o + t.map(ss->ups[GRIP_BEZIER2].off * _spatium); if(!p6o.isNull()) { QPointF p6i = t.inverted().map(p6o) / _spatium; ss->ups[GRIP_BEZIER1].off += p6i ; ss->ups[GRIP_BEZIER2].off += p6i; } //-----------------------------------calculate p6 QPointF pp3 = p3 + p3o; QPointF pp4 = p4 + p4o; QPointF ppp4 = pp4 - pp3; qreal r2 = atan(ppp4.y() / ppp4.x()); t.reset(); t.rotateRadians(-r2); QPointF p6 = QPointF(t.map(ppp4).x() * .5, 0.0); t.rotateRadians(2 * r2); p6 = t.map(p6) + pp3 - p6o; //----------------------------------- ss->path = QPainterPath(); ss->path.moveTo(QPointF()); ss->path.cubicTo(p3 + p3o - th, p4 + p4o - th, p2); if (lineType() == 0) ss->path.cubicTo(p4 +p4o + th, p3 + p3o + th, QPointF()); th = QPointF(0.0, 3.0 * w); ss->shapePath = QPainterPath(); ss->shapePath.moveTo(QPointF()); ss->shapePath.cubicTo(p3 + p3o - th, p4 + p4o - th, p2); ss->shapePath.cubicTo(p4 +p4o + th, p3 + p3o + th, QPointF()); // translate back t.reset(); t.translate(pp1.x(), pp1.y()); t.rotateRadians(sinb); ss->path = t.map(ss->path); ss->shapePath = t.map(ss->shapePath); ss->ups[GRIP_BEZIER1].p = t.map(p3); ss->ups[GRIP_BEZIER2].p = t.map(p4); ss->ups[GRIP_END].p = t.map(p2) - ss->ups[GRIP_END].off * _spatium; ss->ups[GRIP_DRAG].p = t.map(p5); ss->ups[GRIP_SHOULDER].p = t.map(p6); }
int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject) { const QGradient *gradient = b.gradient(); if (!gradient) return 0; QTransform inv = matrix.inverted(); QPointF page_rect[4] = { inv.map(QPointF(0, 0)), inv.map(QPointF(width_, 0)), inv.map(QPointF(0, height_)), inv.map(QPointF(width_, height_)) }; bool opaque = b.isOpaque(); QByteArray shader; QByteArray alphaShader; if (gradient->type() == QGradient::LinearGradient) { const QLinearGradient *lg = static_cast<const QLinearGradient *>(gradient); shader = QPdf::generateLinearGradientShader(lg, page_rect); if (!opaque) alphaShader = QPdf::generateLinearGradientShader(lg, page_rect, true); } else { // ############# return 0; } int shaderObject = addXrefEntry(-1); write(shader); QByteArray str; QPdf::ByteStream s(&str); s << "<<\n" "/Type /Pattern\n" "/PatternType 2\n" "/Shading " << shaderObject << "0 R\n" "/Matrix [" << matrix.m11() << matrix.m12() << matrix.m21() << matrix.m22() << matrix.dx() << matrix.dy() << "]\n"; s << ">>\n" "endobj\n"; int patternObj = addXrefEntry(-1); write(str); currentPage->patterns.append(patternObj); if (!opaque) { bool ca = true; QGradientStops stops = gradient->stops(); int a = stops.at(0).second.alpha(); for (int i = 1; i < stops.size(); ++i) { if (stops.at(i).second.alpha() != a) { ca = false; break; } } if (ca) { *gStateObject = addConstantAlphaObject(stops.at(0).second.alpha()); } else { int alphaShaderObject = addXrefEntry(-1); write(alphaShader); QByteArray content; QPdf::ByteStream c(&content); c << "/Shader" << alphaShaderObject << "sh\n"; QByteArray form; QPdf::ByteStream f(&form); f << "<<\n" "/Type /XObject\n" "/Subtype /Form\n" "/BBox [0 0 " << width_ << height_ << "]\n" "/Group <</S /Transparency >>\n" "/Resources <<\n" "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n" ">>\n"; f << "/Length " << content.length() << "\n" ">>\n" "stream\n" << content << "endstream\n" "endobj\n"; int softMaskFormObject = addXrefEntry(-1); write(form); *gStateObject = addXrefEntry(-1); xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n" "endobj\n", softMaskFormObject); currentPage->graphicStates.append(*gStateObject); } } return patternObj; }
void IsometricRenderer::drawMapObject(QPainter *painter, const MapObject *object, const QColor &color) const { painter->save(); QPen pen(Qt::black); if (object->tile()) { const QPixmap &img = object->tile()->image(); QPointF paintOrigin(-img.width() / 2, -img.height()); paintOrigin += tileToPixelCoords(object->position()).toPoint(); painter->drawPixmap(paintOrigin, img); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, img.width() + 2); if (!name.isEmpty()) painter->drawText(QPoint(paintOrigin.x(), paintOrigin.y() - 5 + 1), name); pen.setStyle(Qt::SolidLine); painter->setPen(pen); painter->drawRect(QRectF(paintOrigin, img.size())); pen.setStyle(Qt::DotLine); pen.setColor(color); painter->setPen(pen); painter->drawRect(QRectF(paintOrigin, img.size())); if (!name.isEmpty()) painter->drawText(QPoint(paintOrigin.x(), paintOrigin.y() - 5), name); } else { QColor brushColor = color; brushColor.setAlpha(50); QBrush brush(brushColor); pen.setJoinStyle(Qt::RoundJoin); pen.setCapStyle(Qt::RoundCap); pen.setWidth(2); painter->setPen(pen); painter->setRenderHint(QPainter::Antialiasing); // TODO: Draw the object name // TODO: Do something sensible to make null-sized objects usable switch (object->shape()) { case MapObject::Ellipse: { QPointF topLeft(tileToPixelCoords(object->bounds().topLeft())); QPointF bottomLeft(tileToPixelCoords(object->bounds().bottomLeft())); QPointF topRight(tileToPixelCoords(object->bounds().topRight())); const qreal headerX = bottomLeft.x(); const qreal headerY = topLeft.y(); QRectF rect(bottomLeft, topRight); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); QPolygonF polygon = tileRectToPolygon(object->bounds()); float tw = map()->tileWidth(); float th = map()->tileHeight(); QPointF transformScale(1, 1); if (tw > th) transformScale = QPointF(1, th/tw); else transformScale = QPointF(tw/th, 1); QPointF l1 = polygon.at(1) - polygon.at(0); QPointF l2 = polygon.at(3) - polygon.at(0); QTransform trans; trans.scale(transformScale.x(), transformScale.y()); trans.rotate(45); QTransform iTrans = trans.inverted(); QPointF l1x = iTrans.map(l1); QPointF l2x = iTrans.map(l2); QSizeF ellipseSize(l1x.manhattanLength(), l2x.manhattanLength()); painter->save(); painter->setPen(pen); painter->translate(polygon.at(0)); painter->scale(transformScale.x(), transformScale.y()); painter->rotate(45); painter->drawEllipse(QRectF(QPointF(0, 0), ellipseSize)); painter->restore(); painter->setBrush(Qt::NoBrush); painter->drawPolygon(polygon); if (!name.isEmpty()) painter->drawText(QPoint(headerX, headerY - 5), name); pen.setColor(color); painter->setPen(pen); painter->setBrush(Qt::NoBrush); painter->translate(QPointF(0, -1)); painter->drawPolygon(polygon); painter->setBrush(brush); painter->save(); painter->translate(polygon.at(0)); painter->scale(transformScale.x(), transformScale.y()); painter->rotate(45); painter->drawEllipse(QRectF(QPointF(0, 0), ellipseSize)); painter->restore(); if (!name.isEmpty()) painter->drawText(QPoint(headerX, headerY - 5), name); break; } case MapObject::Rectangle: { QPointF topLeft(tileToPixelCoords(object->bounds().topLeft())); QPointF bottomLeft(tileToPixelCoords(object->bounds().bottomLeft())); QPointF topRight(tileToPixelCoords(object->bounds().topRight())); const qreal headerX = bottomLeft.x(); const qreal headerY = topLeft.y(); QRectF rect(bottomLeft, topRight); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); QPolygonF polygon = tileRectToPolygon(object->bounds()); painter->drawPolygon(polygon); if (!name.isEmpty()) painter->drawText(QPoint(headerX, headerY - 5 + 1), name); pen.setColor(color); painter->setPen(pen); painter->setBrush(brush); polygon.translate(0, -1); painter->drawPolygon(polygon); if (!name.isEmpty()) painter->drawText(QPoint(headerX, headerY - 5), name); break; } case MapObject::Polygon: { const QPointF &pos = object->position(); const QPolygonF polygon = object->polygon().translated(pos); QPolygonF screenPolygon = tileToPixelCoords(polygon); const QRectF polygonBoundingRect = screenPolygon.boundingRect(); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, polygonBoundingRect.width() + 2); if (!name.isEmpty()) painter->drawText(QPoint(polygonBoundingRect.left(), polygonBoundingRect.top() - 5 + 1), name); painter->drawPolygon(screenPolygon); pen.setColor(color); painter->setPen(pen); painter->setBrush(brush); screenPolygon.translate(0, -1); painter->drawPolygon(screenPolygon); if (!name.isEmpty()) painter->drawText(QPoint(polygonBoundingRect.left(), polygonBoundingRect.top() - 5), name); break; } case MapObject::Polyline: { const QPointF &pos = object->position(); const QPolygonF polygon = object->polygon().translated(pos); QPolygonF screenPolygon = tileToPixelCoords(polygon); painter->drawPolyline(screenPolygon); pen.setColor(color); painter->setPen(pen); screenPolygon.translate(0, -1); painter->drawPolyline(screenPolygon); break; } } } painter->restore(); }
void CanvasMode_EditArc::applyValues(double start, double end, double height, double width) { PageItem *currItem = m_doc->m_Selection->itemAt(0); QRectF oldR = currItem->getBoundingRect().adjusted(-5, -5, 10, 10); PageItem_Arc *item = currItem->asArc(); QTransform bb; bb.scale(height / width, 1.0); QLineF inp = QLineF(QPointF(width / 2.0, height / 2.0), QPointF(width, height / 2.0)); inp.setAngle(start); QLineF res = bb.map(inp); inp.setAngle(end); QLineF ena = bb.map(inp); m_startAngle = res.angle(); m_endAngle = ena.angle(); double nSweep = m_endAngle - m_startAngle; if (nSweep < 0) nSweep += 360; double oldX = currItem->xPos(); double oldY = currItem->yPos(); double newX = oldX + m_centerPoint.x() - (width / 2.0); double newY = oldY + m_centerPoint.y() - (height / 2.0); item->setXYPos(newX, newY, true); FPointArray old = item->PoLine; QPainterPath pp; pp.moveTo(width / 2.0, height / 2.0); pp.arcTo(QRectF(0, 0, width, height), m_startAngle, nSweep); pp.closeSubpath(); currItem->PoLine.fromQPainterPath(pp, true); FPoint wh = getMaxClipF(&currItem->PoLine); currItem->setWidthHeight(wh.x(),wh.y()); m_doc->adjustItemSize(currItem); currItem->OldB2 = currItem->width(); currItem->OldH2 = currItem->height(); if (UndoManager::undoEnabled()) { ScItemState<QPair<FPointArray, FPointArray> > *ss = new ScItemState<QPair<FPointArray, FPointArray> >(Um::EditArc,"",Um::IPolygon); ss->set("ARC"); ss->set("OLD_WIDTH",item->arcWidth); ss->set("NEW_WIDTH",width); ss->set("OLD_XPOS",oldX); ss->set("OLD_YPOS",oldY); ss->set("OLD_HEIGHT",item->arcHeight); ss->set("NEW_HEIGHT",height); ss->set("OLD_START",item->arcStartAngle); ss->set("NEW_START",m_startAngle); ss->set("OLD_SWEEP",item->arcSweepAngle); ss->set("NEW_SWEEP",nSweep); ss->setItem(qMakePair(old,item->PoLine)); ss->set("NEW_XPOS",item->xPos()); ss->set("NEW_YPOS",item->yPos()); undoManager->action(currItem,ss); } item->arcStartAngle = m_startAngle; item->arcSweepAngle = nSweep; item->arcWidth = width; item->arcHeight = height; m_startPoint = currItem->PoLine.pointQF(2); m_endPoint = currItem->PoLine.pointQF(currItem->PoLine.size() - 4); m_centerPoint = currItem->PoLine.pointQF(0); m_widthPoint = QPointF(m_centerPoint.x() - item->arcWidth / 2.0, m_centerPoint.y()); m_heightPoint = QPointF(m_centerPoint.x(), m_centerPoint.y() - item->arcHeight / 2.0); m_doc->setRedrawBounding(currItem); QRectF newR(currItem->getBoundingRect()); m_doc->regionsChanged()->update(newR.united(oldR)); // QTransform itemMatrix = currItem->getTransform(); // m_doc->regionsChanged()->update(itemMatrix.mapRect(QRectF(0, 0, currItem->width(), currItem->height())).adjusted(-currItem->width() / 2.0, -currItem->height() / 2.0, currItem->width(), currItem->height())); }
void QgsLineStringV2::transform( const QTransform& t ) { mCoords = t.map( mCoords ); }
bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, QgsSymbolV2RenderContext *context, const QgsFeature*, QPointF shift ) const { //width double symbolWidth = mSymbolWidth; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH ) ) //1. priority: data defined setting on symbol layer le { context->setOriginalValueVariable( mSymbolWidth ); symbolWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH, *context, mSymbolWidth ).toDouble(); } else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level { symbolWidth = mSize; } if ( mSymbolWidthUnit == QgsSymbolV2::MM ) { symbolWidth *= mmMapUnitScaleFactor; } //height double symbolHeight = mSymbolHeight; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT ) ) //1. priority: data defined setting on symbol layer level { context->setOriginalValueVariable( mSymbolHeight ); symbolHeight = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT, *context, mSymbolHeight ).toDouble(); } else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level { symbolHeight = mSize; } if ( mSymbolHeightUnit == QgsSymbolV2::MM ) { symbolHeight *= mmMapUnitScaleFactor; } //outline width double outlineWidth = mOutlineWidth; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) ) { context->setOriginalValueVariable( mOutlineWidth ); outlineWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH, *context, mOutlineWidth ).toDouble(); } if ( mOutlineWidthUnit == QgsSymbolV2::MM ) { outlineWidth *= outlineWidth; } //fill color bool ok; QColor fc = mColor; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR ) ) { context->setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mColor ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR, *context, QVariant(), &ok ).toString(); if ( ok ) fc = QgsSymbolLayerV2Utils::decodeColor( colorString ); } //outline color QColor oc = mOutlineColor; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR ) ) { context->setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mOutlineColor ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR, *context, QVariant(), &ok ).toString(); if ( ok ) oc = QgsSymbolLayerV2Utils::decodeColor( colorString ); } //symbol name QString symbolName = mSymbolName; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME ) ) { context->setOriginalValueVariable( mSymbolName ); symbolName = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME, *context, mSymbolName ).toString(); } //offset double offsetX = 0; double offsetY = 0; markerOffset( *context, offsetX, offsetY ); QPointF off( offsetX, offsetY ); //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle) double rotation = 0.0; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION ) ) { context->setOriginalValueVariable( mAngle ); rotation = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION, *context, mAngle ).toDouble() + mLineAngle; } else if ( !qgsDoubleNear( mAngle + mLineAngle, 0.0 ) ) { rotation = mAngle + mLineAngle; } rotation = -rotation; //rotation in Qt is counterclockwise if ( rotation ) off = _rotatedOffset( off, rotation ); QTransform t; t.translate( shift.x() + offsetX, shift.y() + offsetY ); if ( !qgsDoubleNear( rotation, 0.0 ) ) t.rotate( rotation ); double halfWidth = symbolWidth / 2.0; double halfHeight = symbolHeight / 2.0; if ( symbolName == "circle" ) { if ( qgsDoubleNear( halfWidth, halfHeight ) ) { QPointF pt( t.map( QPointF( 0, 0 ) ) ); e.writeFilledCircle( layerName, oc, pt, halfWidth ); } else { QgsPolyline line; line.reserve( 40 ); double stepsize = 2 * M_PI / 40; for ( int i = 0; i < 39; ++i ) { double angle = stepsize * i; double x = halfWidth * cos( angle ); double y = halfHeight * sin( angle ); QPointF pt( t.map( QPointF( x, y ) ) ); line.push_back( pt ); } //close ellipse with first point line.push_back( line.at( 0 ) ); if ( mBrush.style() != Qt::NoBrush ) e.writePolygon( QgsPolygon() << line, layerName, "SOLID", fc ); if ( mPen.style() != Qt::NoPen ) e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth ); } } else if ( symbolName == "rectangle" ) { QgsPolygon p( 1 ); p[0].resize( 5 ); p[0][0] = t.map( QPointF( -halfWidth, -halfHeight ) ); p[0][1] = t.map( QPointF( halfWidth, -halfHeight ) ); p[0][2] = t.map( QPointF( halfWidth, halfHeight ) ); p[0][3] = t.map( QPointF( -halfWidth, halfHeight ) ); p[0][4] = p[0][0]; if ( mBrush.style() != Qt::NoBrush ) e.writePolygon( p, layerName, "SOLID", fc ); if ( mPen.style() != Qt::NoPen ) e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth ); return true; } else if ( symbolName == "cross" && mPen.style() != Qt::NoPen ) { QgsPolyline line( 2 ); line[0] = t.map( QPointF( -halfWidth, 0 ) ); line[1] = t.map( QPointF( halfWidth, 0 ) ); e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth ); line[0] = t.map( QPointF( 0, halfHeight ) ); line[1] = t.map( QPointF( 0, -halfHeight ) ); e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth ); return true; } else if ( symbolName == "triangle" ) { QgsPolygon p( 1 ); p[0].resize( 4 ); p[0][0] = QPointF( t.map( QPointF( -halfWidth, -halfHeight ) ) ); p[0][1] = QPointF( t.map( QPointF( halfWidth, -halfHeight ) ) ); p[0][2] = QPointF( t.map( QPointF( 0, halfHeight ) ) ); p[0][3] = p[0][0]; if ( mBrush.style() != Qt::NoBrush ) e.writePolygon( p, layerName, "SOLID", fc ); if ( mPen.style() != Qt::NoPen ) e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth ); return true; } return false; //soon... }
QPointF Body::fromLocal( const QPointF& p ) const { QTransform transform; transform.translate(position().x(),position().y()); transform.rotateRadians(-angle()); return transform.map(p); }
void QgsComposerShape::drawShapeUsingSymbol( QPainter* p ) { p->save(); p->setRenderHint( QPainter::Antialiasing ); //setup painter scaling to dots so that raster symbology is drawn to scale double dotsPerMM = p->device()->logicalDpiX() / 25.4; //setup render context QgsMapSettings ms = mComposition->mapSettings(); //context units should be in dots ms.setOutputDpi( p->device()->logicalDpiX() ); QgsRenderContext context = QgsRenderContext::fromMapSettings( ms ); context.setPainter( p ); context.setForceVectorOutput( true ); QgsExpressionContext expressionContext = createExpressionContext(); context.setExpressionContext( expressionContext ); p->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots //generate polygon to draw QList<QPolygonF> rings; //empty list QPolygonF shapePolygon; //shapes with curves must be enlarged before conversion to QPolygonF, or //the curves are approximated too much and appear jaggy QTransform t = QTransform::fromScale( 100, 100 ); //inverse transform used to scale created polygons back to expected size QTransform ti = t.inverted(); switch ( mShape ) { case Ellipse: { //create an ellipse QPainterPath ellipsePath; ellipsePath.addEllipse( QRectF( 0, 0, rect().width() * dotsPerMM, rect().height() * dotsPerMM ) ); QPolygonF ellipsePoly = ellipsePath.toFillPolygon( t ); shapePolygon = ti.map( ellipsePoly ); break; } case Rectangle: { //if corner radius set, then draw a rounded rectangle if ( mCornerRadius > 0 ) { QPainterPath roundedRectPath; roundedRectPath.addRoundedRect( QRectF( 0, 0, rect().width() * dotsPerMM, rect().height() * dotsPerMM ), mCornerRadius * dotsPerMM, mCornerRadius * dotsPerMM ); QPolygonF roundedPoly = roundedRectPath.toFillPolygon( t ); shapePolygon = ti.map( roundedPoly ); } else { shapePolygon = QPolygonF( QRectF( 0, 0, rect().width() * dotsPerMM, rect().height() * dotsPerMM ) ); } break; } case Triangle: { shapePolygon << QPointF( 0, rect().height() * dotsPerMM ); shapePolygon << QPointF( rect().width() * dotsPerMM, rect().height() * dotsPerMM ); shapePolygon << QPointF( rect().width() / 2.0 * dotsPerMM, 0 ); shapePolygon << QPointF( 0, rect().height() * dotsPerMM ); break; } } mShapeStyleSymbol->startRender( context ); mShapeStyleSymbol->renderPolygon( shapePolygon, &rings, nullptr, context ); mShapeStyleSymbol->stopRender( context ); p->restore(); }
QPointF Body::toLocal( const QPointF& p ) const { QTransform transform; //transform.translate(-position().x(),-position().y()); transform.rotateRadians(-angle()); return transform.map(p-position()); }
void CanvasMode_Rotate::mouseMoveEvent(QMouseEvent *m) { const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos()); m_canvasCurrCoord = mousePointDoc; m_angleConstrained = false; PageItem *currItem; QRect tx; m->accept(); if (GetItem(&currItem)) { m_angleConstrained = ((m->modifiers() & Qt::ControlModifier) != Qt::NoModifier); if (m_view->moveTimerElapsed() && m_canvas->m_viewMode.m_MouseButtonPressed) { m_canvas->repaint(); double itemRotation; FPoint itemPos; getNewItemPosition(currItem, itemPos, itemRotation); m_canvas->displayRotHUD(m->globalPos(), itemRotation); } if (!m_canvas->m_viewMode.m_MouseButtonPressed) { if (m_doc->m_Selection->isMultipleSelection()) { double gx, gy, gh, gw; m_doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh); int how = m_canvas->frameHitTest(QPointF(mousePointDoc.x(),mousePointDoc.y()), QRectF(gx, gy, gw, gh)); if (how >= 0) { if (how > 0) { setResizeCursor(how); } m_view->setCursor(IconManager::instance()->loadCursor("Rotieren2.png")); } else { setModeCursor(); } return; } for (int a = 0; a < m_doc->m_Selection->count(); ++a) { currItem = m_doc->m_Selection->itemAt(a); if (currItem->locked()) break; QTransform p; m_canvas->Transform(currItem, p); QRect mpo = QRect(m->x()-m_doc->guidesPrefs().grabRadius, m->y()-m_doc->guidesPrefs().grabRadius, m_doc->guidesPrefs().grabRadius*2, m_doc->guidesPrefs().grabRadius*2); if ((QRegion(p.map(QPolygon(QRect(-3, -3, static_cast<int>(currItem->width()+6), static_cast<int>(currItem->height()+6))))).contains(mpo))) { tx = p.mapRect(QRect(0, 0, static_cast<int>(currItem->width()), static_cast<int>(currItem->height()))); if ((tx.intersects(mpo)) && (!currItem->locked())) { m_view->setCursor(IconManager::instance()->loadCursor("Rotieren2.png")); if (!currItem->sizeLocked()) m_view->HandleCurs(currItem, mpo); } } else { // setModeCursor(); } } } } else { if ((m_canvas->m_viewMode.m_MouseButtonPressed) && (m->buttons() & Qt::LeftButton)) { QPoint startP = m_canvas->canvasToGlobal(m_canvasPressCoord); m_view->redrawMarker->setGeometry(QRect(m_view->mapFromGlobal(startP), m_view->mapFromGlobal(m->globalPos())).normalized()); m_view->setRedrawMarkerShown(true); m_view->HaveSelRect = true; } } }
// -------------------------------------------------------- void TouchWidgetRenderer::drawResizers( GLResourceContainer * container, const SceneTouchPoint * resizing_point, const QPointF & circle_center, float circle_radius, const QPointF & base_target, QList<float> resizer_angles ) const { static Warping<qreal> resizer_activeness(0.0f, 0.2f); static bool resizer_active = false; static QPointF last_resizer_pos; static float touch_angle_target = 0; QPointF base_pos = QLineF(circle_center, base_target).unitVector().pointAt(circle_radius); float base_angle = QLineF(base_target, circle_center).angleTo(QLineF(0,0,1,0)); // trigger the warp towards 1 or 0 if the status just changed and evaluate it if((resizing_point != NULL) != resizer_active) { resizer_active = (resizing_point != NULL); resizer_activeness.setTarget(resizer_active ? 1.0f : 0.0f); } float activeness = resizer_activeness.value(); // update resizer position and angle based on current touch if(resizer_active) { last_resizer_pos = resizing_point->pos(); touch_angle_target = QLineF(last_resizer_pos, circle_center).angleTo(QLineF(0,0,1,0));; touch_angle_target += 60; while(touch_angle_target>120) touch_angle_target-=120; while(touch_angle_target<-120) touch_angle_target+=120; touch_angle_target -= 60; } // compute resizer size const float resizer_diameter = 0.3f * circle_radius * (activeness*0.5+1); QSizeF resizer_size(resizer_diameter, resizer_diameter); // draw individual angles foreach(float resizer_angle, resizer_angles) { // compute desired angle float blended_angle = (touch_angle_target+resizer_angle)*activeness + resizer_angle*(1-activeness); // compute resizer handle location QTransform transform; transform.translate(circle_center.x(), circle_center.y()); transform.rotate(blended_angle); transform.translate(-circle_center.x(), -circle_center.y()); QPointF resizer_pos = transform.map(base_pos); // draw resizer handle if(activeness < 1) { drawTexturedQuad(container->texture("mglass_resizer"), resizer_pos, resizer_size, blended_angle+base_angle+180); } if(activeness > 0) { drawTexturedQuad(container->texture("mglass_resizer_active"), resizer_pos, resizer_size, blended_angle+base_angle+180, activeness); } }
QBezier QBezier::mapBy(const QTransform &transform) const { return QBezier::fromPoints(transform.map(pt1()), transform.map(pt2()), transform.map(pt3()), transform.map(pt4())); }
static inline void qwtExecCommand( QPainter *painter, const QwtPainterCommand &cmd, QwtGraphic::RenderHints renderHints, const QTransform &transform ) { switch( cmd.type() ) { case QwtPainterCommand::Path: { bool doMap = false; if ( renderHints.testFlag( QwtGraphic::RenderPensUnscaled ) && painter->transform().isScaling() ) { bool isCosmetic = painter->pen().isCosmetic(); if ( isCosmetic && painter->pen().widthF() == 0.0 ) { QPainter::RenderHints hints = painter->renderHints(); if ( hints.testFlag( QPainter::NonCosmeticDefaultPen ) ) isCosmetic = false; } doMap = !isCosmetic; } if ( doMap ) { const QTransform transform = painter->transform(); painter->resetTransform(); painter->drawPath( transform.map( *cmd.path() ) ); painter->setTransform( transform ); } else { painter->drawPath( *cmd.path() ); } break; } case QwtPainterCommand::Pixmap: { const QwtPainterCommand::PixmapData *data = cmd.pixmapData(); painter->drawPixmap( data->rect, data->pixmap, data->subRect ); break; } case QwtPainterCommand::Image: { const QwtPainterCommand::ImageData *data = cmd.imageData(); painter->drawImage( data->rect, data->image, data->subRect, data->flags ); break; } case QwtPainterCommand::State: { const QwtPainterCommand::StateData *data = cmd.stateData(); if ( data->flags & QPaintEngine::DirtyPen ) painter->setPen( data->pen ); if ( data->flags & QPaintEngine::DirtyBrush ) painter->setBrush( data->brush ); if ( data->flags & QPaintEngine::DirtyBrushOrigin ) painter->setBrushOrigin( data->brushOrigin ); if ( data->flags & QPaintEngine::DirtyFont ) painter->setFont( data->font ); if ( data->flags & QPaintEngine::DirtyBackground ) { painter->setBackgroundMode( data->backgroundMode ); painter->setBackground( data->backgroundBrush ); } if ( data->flags & QPaintEngine::DirtyTransform ) { painter->setTransform( data->transform * transform ); } if ( data->flags & QPaintEngine::DirtyClipEnabled ) painter->setClipping( data->isClipEnabled ); if ( data->flags & QPaintEngine::DirtyClipRegion) { painter->setClipRegion( data->clipRegion, data->clipOperation ); } if ( data->flags & QPaintEngine::DirtyClipPath ) { painter->setClipPath( data->clipPath, data->clipOperation ); } if ( data->flags & QPaintEngine::DirtyHints) { const QPainter::RenderHints hints = data->renderHints; painter->setRenderHint( QPainter::Antialiasing, hints.testFlag( QPainter::Antialiasing ) ); painter->setRenderHint( QPainter::TextAntialiasing, hints.testFlag( QPainter::TextAntialiasing ) ); painter->setRenderHint( QPainter::SmoothPixmapTransform, hints.testFlag( QPainter::SmoothPixmapTransform ) ); painter->setRenderHint( QPainter::HighQualityAntialiasing, hints.testFlag( QPainter::HighQualityAntialiasing ) ); painter->setRenderHint( QPainter::NonCosmeticDefaultPen, hints.testFlag( QPainter::NonCosmeticDefaultPen ) ); } if ( data->flags & QPaintEngine::DirtyCompositionMode) painter->setCompositionMode( data->compositionMode ); if ( data->flags & QPaintEngine::DirtyOpacity) painter->setOpacity( data->opacity ); break; } default: break; } }
void QtWebPageEventHandler::handleDoubleTapEvent(const QTouchEvent::TouchPoint& point) { deactivateTapHighlight(); QTransform fromItemTransform = m_webPage->transformFromItem(); m_webPageProxy->findZoomableAreaForPoint(fromItemTransform.map(point.pos()).toPoint(), IntSize(point.rect().size().toSize())); }
void AbstractDiagram::Private::addLabel( LabelPaintCache* cache, const QModelIndex& index, const CartesianDiagramDataCompressor::CachePosition* position, const PositionPoints& points, const Position& autoPositionPositive, const Position& autoPositionNegative, const qreal value, qreal favoriteAngle /* = 0.0 */ ) { CartesianDiagramDataCompressor::AggregatedDataValueAttributes allAttrs( aggregatedAttrs( index, position ) ); QMap<QModelIndex, DataValueAttributes>::const_iterator it; for ( it = allAttrs.constBegin(); it != allAttrs.constEnd(); ++it ) { DataValueAttributes dva = it.value(); if ( !dva.isVisible() ) { continue; } const bool isPositive = ( value >= 0.0 ); RelativePosition relPos( dva.position( isPositive ) ); relPos.setReferencePoints( points ); if ( relPos.referencePosition().isUnknown() ) { relPos.setReferencePosition( isPositive ? autoPositionPositive : autoPositionNegative ); } // Rotate the label position (not the label itself) if the diagram is rotated so that the defaults still work if ( isTransposed() ) { KChartEnums::PositionValue posValue = relPos.referencePosition().value(); if ( posValue >= KChartEnums::PositionNorthWest && posValue <= KChartEnums::PositionWest ) { // rotate 90 degrees clockwise posValue = static_cast< KChartEnums::PositionValue >( posValue + 2 ); if ( posValue > KChartEnums::PositionWest ) { // wraparound posValue = static_cast< KChartEnums::PositionValue >( posValue - ( KChartEnums::PositionWest - KChartEnums::PositionNorthWest ) ); } relPos.setReferencePosition( Position( posValue ) ); } } const QPointF referencePoint = relPos.referencePoint(); if ( !diagram->coordinatePlane()->isVisiblePoint( referencePoint ) ) { continue; } const qreal fontHeight = cachedFontMetrics( dva.textAttributes(). calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ), diagram )->height(); // Note: When printing data value texts and padding's Measure is using automatic reference area // detection, the font height is used as reference size for both horizontal and vertical // padding. QSizeF relativeMeasureSize( fontHeight, fontHeight ); if ( !dva.textAttributes().hasRotation() ) { TextAttributes ta = dva.textAttributes(); ta.setRotation( favoriteAngle ); dva.setTextAttributes( ta ); } // get the size of the label text using a subset of the information going into the final layout const QString text = formatDataValueText( dva, index, value ); QTextDocument doc; doc.setDocumentMargin( 0 ); if ( Qt::mightBeRichText( text ) ) { doc.setHtml( text ); } else { doc.setPlainText( text ); } const QFont calculatedFont( dva.textAttributes() .calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ) ); doc.setDefaultFont( calculatedFont ); const QRectF plainRect = doc.documentLayout()->frameBoundingRect( doc.rootFrame() ); /** * A few hints on how the positioning of the text frame is done: * * Let's assume we have a bar chart, a text for a positive value * to be drawn, and "North" as attrs.positivePosition(). * * The reference point (pos) is then set to the top center point * of a bar. The offset now depends on the alignment: * * Top: text is centered horizontally to the bar, bottom of * text frame starts at top of bar * * Bottom: text is centered horizontally to the bar, top of * text frame starts at top of bar * * Center: text is centered horizontally to the bar, center * line of text frame is same as top of bar * * TopLeft: right edge of text frame is horizontal center of * bar, bottom of text frame is top of bar. * * ... * * Positive and negative value labels are treated equally, "North" * also refers to the top of a negative bar, and *not* to the bottom. * * * "NorthEast" likewise refers to the top right edge of the bar, * "NorthWest" to the top left edge of the bar, and so on. * * In other words, attrs.positivePosition() always refers to a * position of the *bar*, and relPos.alignment() always refers * to an alignment of the text frame relative to this position. */ QTransform transform; { // move to the general area where the label should be QPointF calcPoint = relPos.calculatedPoint( relativeMeasureSize ); transform.translate( calcPoint.x(), calcPoint.y() ); // align the text rect; find out by how many half-widths / half-heights to move. int dx = -1; if ( relPos.alignment() & Qt::AlignLeft ) { dx -= 1; } else if ( relPos.alignment() & Qt::AlignRight ) { dx += 1; } int dy = -1; if ( relPos.alignment() & Qt::AlignTop ) { dy -= 1; } else if ( relPos.alignment() & Qt::AlignBottom ) { dy += 1; } transform.translate( qreal( dx ) * plainRect.width() * 0.5, qreal( dy ) * plainRect.height() * 0.5 ); // rotate the text rect around its center transform.translate( plainRect.center().x(), plainRect.center().y() ); int rotation = dva.textAttributes().rotation(); if ( !isPositive && dva.mirrorNegativeValueTextRotation() ) { rotation *= -1; } transform.rotate( rotation ); transform.translate( -plainRect.center().x(), -plainRect.center().y() ); } QPainterPath labelArea; //labelArea.addPolygon( transform.mapToPolygon( plainRect.toRect() ) ); //labelArea.closeSubpath(); // Not doing that because QTransform has a special case for 180° that gives a different than // usual ordering of the points in the polygon returned by mapToPolygon( const QRect & ). // We expect a particular ordering in paintDataValueTextsAndMarkers() by using elementAt( 0 ), // and similar things might happen elsewhere. labelArea.addPolygon( transform.map( QPolygon( plainRect.toRect(), true ) ) ); // store the label geometry and auxiliary data cache->paintReplay.append( LabelPaintInfo( it.key(), dva, labelArea, referencePoint, value >= 0.0, text ) ); } }
void QgsComposerMapOverview::draw( QPainter *painter ) { if ( !mEnabled || mFrameMapId == -1 || !mComposerMap || !mComposerMap->composition() ) { return; } if ( !painter ) { return; } const QgsComposerMap* overviewFrameMap = mComposerMap->composition()->getComposerMapById( mFrameMapId ); if ( !overviewFrameMap ) { return; } //get polygon for other overview frame map's extent (use visibleExtentPolygon as it accounts for map rotation) QPolygonF otherExtent = overviewFrameMap->visibleExtentPolygon(); //get current map's extent as a QPolygonF QPolygonF thisExtent = mComposerMap->visibleExtentPolygon(); //intersect the two QPolygonF intersectExtent = thisExtent.intersected( otherExtent ); //setup painter scaling to dots so that raster symbology is drawn to scale double dotsPerMM = painter->device()->logicalDpiX() / 25.4; //setup render context QgsMapSettings ms = mComposerMap->composition()->mapSettings(); //context units should be in dots ms.setOutputSize( QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ).toSize() ); ms.setExtent( *mComposerMap->currentMapExtent() ); ms.setOutputDpi( painter->device()->logicalDpiX() ); QgsRenderContext context = QgsRenderContext::fromMapSettings( ms ); context.setForceVectorOutput( true ); context.setPainter( painter ); QgsExpressionContext* expressionContext = createExpressionContext(); context.setExpressionContext( *expressionContext ); delete expressionContext; painter->save(); painter->setCompositionMode( mBlendMode ); painter->translate( mComposerMap->mXOffset, mComposerMap->mYOffset ); painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots painter->setRenderHint( QPainter::Antialiasing ); mFrameSymbol->startRender( context ); //construct a polygon corresponding to the intersecting map extent //need to scale line to dots, rather then mm, since the painter has been scaled to dots QTransform mapTransform; QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, dotsPerMM * mComposerMap->rect().width(), dotsPerMM * mComposerMap->rect().height() ) ); //workaround QT Bug #21329 thisRectPoly.pop_back(); thisExtent.pop_back(); //create transform from map coordinates to painter coordinates QTransform::quadToQuad( thisExtent, thisRectPoly, mapTransform ); QPolygonF intersectPolygon; intersectPolygon = mapTransform.map( intersectExtent ); QList<QPolygonF> rings; //empty list if ( !mInverted ) { //Render the intersecting map extent mFrameSymbol->renderPolygon( intersectPolygon, &rings, 0, context );; } else { //We are inverting the overview frame (ie, shading outside the intersecting extent) //Construct a polygon corresponding to the overview map extent QPolygonF outerPolygon; outerPolygon << QPointF( 0, 0 ) << QPointF( mComposerMap->rect().width() * dotsPerMM, 0 ) << QPointF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ) << QPointF( 0, mComposerMap->rect().height() * dotsPerMM ) << QPointF( 0, 0 ); //Intersecting extent is an inner ring for the shaded area rings.append( intersectPolygon ); mFrameSymbol->renderPolygon( outerPolygon, &rings, 0, context ); } mFrameSymbol->stopRender( context ); painter->restore(); }
void HairpinSegment::layout() { if (hairpin()->useTextLine()) { // layout as textline rather than true hairpin // use dynamics text style for position, so the text aligns with dynamics // TODO: new style setting specifically for vertical offset of textline hairpins? // or, use hairpinY but adjust by 0.5sp, which currently yields same vertical position as dynamics if (parent()) rypos() += score()->textStyle(TextStyleType::DYNAMICS).offset(spatium()).y(); TextLineSegment::layout(); return; } QTransform t; qreal _spatium = spatium(); qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5; qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5; qreal len; qreal x = pos2().x(); if (x < _spatium) // minimum size of hairpin x = _spatium; qreal y = pos2().y(); len = sqrt(x * x + y * y); t.rotateRadians(asin(y/len)); drawCircledTip = hairpin()->hairpinCircledTip(); circledTipRadius = 0; if( drawCircledTip ) circledTipRadius = 0.6 * _spatium * .5; if (hairpin()->hairpinType() == Hairpin::Type::CRESCENDO) { // crescendo switch (spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::BEGIN: l1.setLine(.0 + circledTipRadius*2, .0, len, h1); l2.setLine(.0 + circledTipRadius*2, .0, len, -h1); circledTip.setX( 0 + circledTipRadius ); circledTip.setY( 0 ); break; case SpannerSegmentType::MIDDLE: case SpannerSegmentType::END: drawCircledTip = false; l1.setLine(.0, h2, len, h1); l2.setLine(.0, -h2, len, -h1); break; } } else { // decrescendo switch(spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::END: l1.setLine(.0, h1, len - circledTipRadius*2, 0.0); l2.setLine(.0, -h1, len - circledTipRadius*2, 0.0); circledTip.setX( len - circledTipRadius ); circledTip.setY( 0 ); break; case SpannerSegmentType::BEGIN: case SpannerSegmentType::MIDDLE: drawCircledTip = false; l1.setLine(.0, h1, len, + h2); l2.setLine(.0, -h1, len, - h2); break; } } // Do Coord rotation l1 = t.map(l1); l2 = t.map(l2); if( drawCircledTip ) circledTip = t.map(circledTip); QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized(); qreal w = point(score()->styleS(StyleIdx::hairpinLineWidth)); setbbox(r.adjusted(-w*.5, -w*.5, w, w)); if (parent()) rypos() += score()->styleS(StyleIdx::hairpinY).val() * _spatium; adjustReadPos(); }
QPainterPath ArtisticTextToolSelection::outline() { if (!hasSelection()) return QPainterPath(); CharIndex charPos = m_currentShape->indexOfChar(m_selectionStart); if (charPos.first < 0) return QPainterPath(); QPainterPath outline; QPolygonF polygon; QList<ArtisticTextRange> ranges = m_currentShape->text(); int globalCharIndex = m_selectionStart; int remainingChars = m_selectionCount; while (remainingChars) { const ArtisticTextRange ¤tRange = ranges[charPos.first]; int currentTextLength = currentRange.text().length(); while (charPos.second < currentTextLength && remainingChars > 0) { const QPointF pos = m_currentShape->charPositionAt(globalCharIndex); const qreal angle = m_currentShape->charAngleAt(globalCharIndex); QTransform charTransform; charTransform.translate( pos.x() - 1, pos.y() ); charTransform.rotate( 360. - angle ); QFontMetricsF metrics(currentRange.font()); polygon.prepend(charTransform.map(QPointF(0.0, -metrics.ascent()))); polygon.append(charTransform.map(QPointF(0.0, metrics.descent()))); // advance to next character charPos.second++; globalCharIndex++; remainingChars--; // next character has y-offset or we are at the end of this text range const bool hasYOffset = currentRange.hasYOffset(charPos.second); const bool atRangeEnd = charPos.second == currentTextLength; const bool atSelectionEnd = remainingChars == 0; if (hasYOffset || atRangeEnd || atSelectionEnd) { if (hasYOffset || atRangeEnd) { const QChar c = currentRange.text().at(charPos.second-1); const qreal w = metrics.width(c); polygon.prepend(charTransform.map(QPointF(w, -metrics.ascent()))); polygon.append(charTransform.map(QPointF(w, metrics.descent()))); } else { const QPointF pos = m_currentShape->charPositionAt(globalCharIndex); const qreal angle = m_currentShape->charAngleAt(globalCharIndex); charTransform.reset(); charTransform.translate( pos.x() - 1, pos.y() ); charTransform.rotate( 360. - angle ); polygon.prepend(charTransform.map(QPointF(0.0, -metrics.ascent()))); polygon.append(charTransform.map(QPointF(0.0, metrics.descent()))); } QPainterPath p; p.addPolygon(polygon); outline = outline.united(p); polygon.clear(); } } // go to first character of next text range charPos.first++; charPos.second = 0; } // transform to document coordinates return m_currentShape->absoluteTransformation(0).map(outline); }
bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, const QgsSymbolV2RenderContext* context, const QgsFeature* f, const QPointF& shift ) const { //width double symbolWidth = mSymbolWidth; QgsExpression* widthExpression = expression( "width" ); if ( widthExpression ) //1. priority: data defined setting on symbol layer level { symbolWidth = widthExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble(); } else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level { symbolWidth = mSize; } if ( mSymbolWidthUnit == QgsSymbolV2::MM ) { symbolWidth *= mmMapUnitScaleFactor; } //height double symbolHeight = mSymbolHeight; QgsExpression* heightExpression = expression( "height" ); if ( heightExpression ) //1. priority: data defined setting on symbol layer level { symbolHeight = heightExpression->evaluate( const_cast<QgsFeature*>( f ) ).toDouble(); } else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level { symbolHeight = mSize; } if ( mSymbolHeightUnit == QgsSymbolV2::MM ) { symbolHeight *= mmMapUnitScaleFactor; } //outline width double outlineWidth = mOutlineWidth; QgsExpression* outlineWidthExpression = expression( "outline_width" ); if ( outlineWidthExpression ) { outlineWidth = outlineWidthExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble(); } if ( mOutlineWidthUnit == QgsSymbolV2::MM ) { outlineWidth *= outlineWidth; } //fill color QColor fc = mFillColor; QgsExpression* fillColorExpression = expression( "fill_color" ); if ( fillColorExpression ) { fc = QColor( fillColorExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toString() ); } int fillColorIndex = e.closestColorMatch( fc.rgb() ); //outline color QColor oc = mOutlineColor; QgsExpression* outlineColorExpression = expression( "outline_color" ); if ( outlineColorExpression ) { oc = QColor( outlineColorExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toString() ); } int outlineColorIndex = e.closestColorMatch( oc.rgb() ); //symbol name QString symbolName = mSymbolName; QgsExpression* symbolNameExpression = expression( "symbol_name" ); if ( symbolNameExpression ) { QgsExpression* symbolNameExpression = expression( "symbol_name" ); symbolName = symbolNameExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toString(); } //offset double offsetX = 0; double offsetY = 0; markerOffset( *context, offsetX, offsetY ); QPointF off( offsetX, offsetY ); //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle) double rotation = 0.0; QgsExpression* rotationExpression = expression( "rotation" ); if ( rotationExpression ) { rotation = rotationExpression->evaluate( const_cast<QgsFeature*>( context->feature() ) ).toDouble(); } else if ( !qgsDoubleNear( mAngle, 0.0 ) ) { rotation = mAngle; } rotation = -rotation; //rotation in Qt is counterclockwise if ( rotation ) off = _rotatedOffset( off, rotation ); QTransform t; t.translate( shift.x() + offsetX, shift.y() + offsetY ); if ( rotation != 0 ) t.rotate( rotation ); double halfWidth = symbolWidth / 2.0; double halfHeight = symbolHeight / 2.0; if ( symbolName == "circle" ) { if ( qgsDoubleNear( halfWidth, halfHeight ) ) { QPointF pt( t.map( QPointF( 0, 0 ) ) ); e.writeCircle( layerName, outlineColorIndex, QgsPoint( pt.x(), pt.y() ), halfWidth ); } else { QgsPolyline line; double stepsize = 2 * M_PI / 40; for ( int i = 0; i < 39; ++i ) { double angle = stepsize * i; double x = halfWidth * cos( angle ); double y = halfHeight * sin( angle ); QPointF pt( t.map( QPointF( x, y ) ) ); line.push_back( QgsPoint( pt.x(), pt.y() ) ); } //close ellipse with first point line.push_back( line.at( 0 ) ); e.writePolyline( line, layerName, "solid", outlineColorIndex, outlineWidth, true ); } } else if ( symbolName == "rectangle" ) { QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) ); QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) ); QPointF pt3( t.map( QPointF( -halfWidth, halfHeight ) ) ); QPointF pt4( t.map( QPointF( halfWidth, halfHeight ) ) ); e.writeSolid( layerName, fillColorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) ); return true; } else if ( symbolName == "cross" ) { QgsPolyline line1( 2 ); QPointF pt1( t.map( QPointF( -halfWidth, 0 ) ) ); QPointF pt2( t.map( QPointF( halfWidth, 0 ) ) ); line1[0] = QgsPoint( pt1.x(), pt1.y() ); line1[1] = QgsPoint( pt2.x(), pt2.y() ); e.writePolyline( line1, layerName, "CONTINUOUS", outlineColorIndex, outlineWidth, false ); QgsPolyline line2( 2 ); QPointF pt3( t.map( QPointF( 0, halfHeight ) ) ); QPointF pt4( t.map( QPointF( 0, -halfHeight ) ) ); line2[0] = QgsPoint( pt3.x(), pt3.y() ); line2[1] = QgsPoint( pt4.x(), pt4.y() ); e.writePolyline( line2, layerName, "CONTINUOUS", outlineColorIndex, outlineWidth, false ); return true; } else if ( symbolName == "triangle" ) { QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) ); QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) ); QPointF pt3( t.map( QPointF( 0, halfHeight ) ) ); QPointF pt4( t.map( QPointF( 0, halfHeight ) ) ); e.writeSolid( layerName, fillColorIndex, QgsPoint( pt1.x(), pt1.y() ), QgsPoint( pt2.x(), pt2.y() ), QgsPoint( pt3.x(), pt3.y() ), QgsPoint( pt4.x(), pt4.y() ) ); return true; } return false; //soon... }