void QGIViewPart::dumpPath(const char* text,QPainterPath path) { QPainterPath::Element elem; Base::Console().Message(">>>%s has %d elements\n",text,path.elementCount()); char* typeName; for(int iElem = 0; iElem < path.elementCount(); iElem++) { elem = path.elementAt(iElem); if(elem.isMoveTo()) { typeName = "MoveTo"; } else if (elem.isLineTo()) { typeName = "LineTo"; } else if (elem.isCurveTo()) { typeName = "CurveTo"; } else { typeName = "Unknown"; } Base::Console().Message(">>>>> element %d: type:%d/%s pos(%.3f,%.3f) M:%d L:%d C:%d\n",iElem, elem.type,typeName,elem.x,elem.y,elem.isMoveTo(),elem.isLineTo(),elem.isCurveTo()); } }
GlyphToSVGHelper::GlyphToSVGHelper(QPainterPath path, QTransform tf) :m_path(path), m_transform(tf) { QStringList data; QPointF curPos; for (int i = 0; i < path.elementCount(); ++i) { QPainterPath::Element cur = path.elementAt(i); QPointF curPoint(tf.map(cur)); if(cur.isMoveTo()) { curPos = curPoint; data << QString("M %1 %2").arg(curPos.x()).arg(curPos.y()); } else if(cur.isLineTo()) { curPos = curPoint; data << QString("L %1 %2").arg(curPos.x()).arg(curPos.y()); } else if(cur.isCurveTo()) { QPointF c1 = tf.map(path.elementAt(i + 1)); QPointF c2 = tf.map(path.elementAt(i + 2)); data << QString("C %1 %2 %3 %4 %5 %6") .arg(curPoint.x()).arg(curPoint.y()) .arg(c1.x()).arg(c1.y()) .arg(c2.x()).arg(c2.y()); // qDebug(data.last().toUtf8()); i += 2; curPos = c2; } else qDebug("Unknown point type"); } m_svg += QString("<path d=\"%1\" fill=\"%2\" />").arg(data.join(" ")).arg("black"); }
void LineRenderable::render(QPainter &painter, const RenderConfig &config) const { QPen pen(painter.pen()); pen.setCapStyle(cap_style); pen.setJoinStyle(join_style); if (join_style == Qt::MiterJoin) { pen.setMiterLimit(LineSymbol::miterLimit()); fixPenForPdf(pen, painter); } painter.setPen(pen); // One-time adjustment for line width QRectF bounding_box = config.bounding_box.adjusted(-line_width, -line_width, line_width, line_width); const int count = path.elementCount(); if (count <= 2 || bounding_box.contains(path.controlPointRect())) { // path fully contained painter.drawPath(path); } else { // Manually clip the path with bounding_box, this seems to be faster. // The code splits up the painter path into new paths which intersect // the view rect and renders these only. // NOTE: this does not work correctly with miter joins, but this // should be a minor issue. QPainterPath::Element element = path.elementAt(0); QPainterPath::Element last_element = path.elementAt(count-1); bool path_closed = (element.x == last_element.x) && (element.y == last_element.y); QPainterPath part_path; QPainterPath first_path; bool path_started = false; bool part_finished = false; bool current_part_is_first = bounding_box.contains(element); QPainterPath::Element prev_element = element; for (int i = 1; i < count; ++i) { element = path.elementAt(i); if (element.isLineTo()) { qreal min_x, min_y, max_x, max_y; if (prev_element.x < element.x) { min_x = prev_element.x; max_x = element.x; } else { min_x = element.x; max_x = prev_element.x; } if (prev_element.y < element.y) { min_y = prev_element.y; max_y = element.y; } else { min_y = element.y; max_y = prev_element.y; } if ( min_x <= bounding_box.right() && max_x >= bounding_box.left() && min_y <= bounding_box.bottom() && max_y >= bounding_box.top() ) { if (!path_started) { part_path = QPainterPath(); part_path.moveTo(prev_element.x, prev_element.y); path_started = true; } part_path.lineTo(element.x, element.y); } else if (path_started) { part_finished = true; } else { current_part_is_first = false; } } else if (element.isCurveTo()) { Q_ASSERT(i < count - 2); QPainterPath::Element next_element = path.elementAt(i + 1); QPainterPath::Element end_element = path.elementAt(i + 2); qreal min_x = qMin(prev_element.x, qMin(element.x, qMin(next_element.x, end_element.x))); qreal min_y = qMin(prev_element.y, qMin(element.y, qMin(next_element.y, end_element.y))); qreal max_x = qMax(prev_element.x, qMax(element.x, qMax(next_element.x, end_element.x))); qreal max_y = qMax(prev_element.y, qMax(element.y, qMax(next_element.y, end_element.y))); if ( min_x <= bounding_box.right() && max_x >= bounding_box.left() && min_y <= bounding_box.bottom() && max_y >= bounding_box.top() ) { if (!path_started) { part_path = QPainterPath(); part_path.moveTo(prev_element.x, prev_element.y); path_started = true; } part_path.cubicTo(element.x, element.y, next_element.x, next_element.y, end_element.x, end_element.y); } else if (path_started) { part_finished = true; } else { current_part_is_first = false; } } else if (element.isMoveTo() && path_started) { part_path.moveTo(element.x, element.y); } if (part_finished) { if (current_part_is_first && path_closed) { current_part_is_first = false; first_path = part_path; } else { painter.drawPath(part_path); } path_started = false; part_finished = false; } prev_element = element; } if (path_started) { if (path_closed && !first_path.isEmpty()) part_path.connectPath(first_path); painter.drawPath(part_path); } } // DEBUG: show all control points /*QPen debugPen(QColor(Qt::red)); painter.setPen(debugPen); for (int i = 0; i < path.elementCount(); ++i) { const QPainterPath::Element& e = path.elementAt(i); painter.drawEllipse(QPointF(e.x, e.y), 0.2f, 0.2f); } painter.setPen(pen);*/ }