void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount) { QPen pen = state()->pen; if (pen.capStyle() == Qt::FlatCap) pen.setCapStyle(Qt::SquareCap); if (pen.brush().isOpaque()) { while (pointCount > 0) { int count = qMin(pointCount, 16); qreal pts[64]; int oset = -1; for (int i=0; i<count; ++i) { pts[++oset] = points[i].x(); pts[++oset] = points[i].y(); pts[++oset] = points[i].x() + 1/63.; pts[++oset] = points[i].y(); } QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, pen); pointCount -= 16; points += 16; } } else { for (int i=0; i<pointCount; ++i) { qreal pts[] = { qreal(points[i].x()), qreal(points[i].y()), qreal(points[i].x() +1/63.), qreal(points[i].y()) }; QVectorPath path(pts, 2, 0); stroke(path, pen); } } }
void tst_QPen::stream() { QFETCH(QPen, pen); QByteArray bytes; { QDataStream stream(&bytes, QIODevice::WriteOnly); stream << pen; } QPen cmp; { QDataStream stream(&bytes, QIODevice::ReadOnly); stream >> cmp; } QCOMPARE(pen.widthF(), cmp.widthF()); QCOMPARE(pen.style(), cmp.style()); QCOMPARE(pen.capStyle(), cmp.capStyle()); QCOMPARE(pen.joinStyle(), cmp.joinStyle()); QCOMPARE(pen.brush(), cmp.brush()); QCOMPARE(pen, cmp); }
QPainterPath GraphicsUtils::shapeFromPath(const QPainterPath &path, const QPen &pen, double shapeStrokeWidth, bool includeOriginalPath) { // this function mostly copied from QGraphicsItem::qt_graphicsItem_shapeFromPath // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0 // if we pass a value of 0.0 to QPainterPathStroker::setWidth() static const double penWidthZero = double(0.00000001); if (path == QPainterPath()) return path; QPainterPathStroker ps; ps.setCapStyle(pen.capStyle()); //ps.setCapStyle(Qt::FlatCap); if (shapeStrokeWidth <= 0.0) ps.setWidth(penWidthZero); else ps.setWidth(shapeStrokeWidth); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); QPainterPath p = ps.createStroke(path); if (includeOriginalPath) { p.addPath(path); } return p; }
void DrawingPolyItem::setPen(const QPen& pen) { setPenColor(pen.brush().color()); setPenWidth(pen.widthF()); setPenStyle(pen.style()); setPenCapStyle(pen.capStyle()); setPenJoinStyle(pen.joinStyle()); }
void GeoLineStringGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport ) { if ( !style() ) { painter->save(); painter->setPen( QPen() ); painter->drawPolyline( *m_lineString ); painter->restore(); return; } if(style()->lineStyle().paintedColor() == Qt::transparent) return; painter->save(); QPen currentPen = painter->pen(); if ( currentPen.color() != style()->lineStyle().paintedColor() ) currentPen.setColor( style()->lineStyle().paintedColor() ); if ( currentPen.widthF() != style()->lineStyle().width() || style()->lineStyle().physicalWidth() != 0.0 ) { if ( float( viewport->radius() ) / EARTH_RADIUS * style()->lineStyle().physicalWidth() < style()->lineStyle().width() ) currentPen.setWidthF( style()->lineStyle().width() ); else currentPen.setWidthF( float( viewport->radius() ) / EARTH_RADIUS * style()->lineStyle().physicalWidth() ); } if ( currentPen.capStyle() != style()->lineStyle().capStyle() ) currentPen.setCapStyle( style()->lineStyle().capStyle() ); if ( currentPen.style() != style()->lineStyle().penStyle() ) currentPen.setStyle( style()->lineStyle().penStyle() ); if ( style()->lineStyle().penStyle() == Qt::CustomDashLine ) currentPen.setDashPattern( style()->lineStyle().dashPattern() ); if ( painter->mapQuality() != Marble::HighQuality && painter->mapQuality() != Marble::PrintQuality ) { QColor penColor = currentPen.color(); penColor.setAlpha( 255 ); currentPen.setColor( penColor ); } if ( painter->pen() != currentPen ) painter->setPen( currentPen ); if ( style()->lineStyle().background() ) { QBrush brush = painter->background(); brush.setColor( style()->polyStyle().paintedColor() ); painter->setBackground( brush ); painter->setBackgroundMode( Qt::OpaqueMode ); } painter->drawPolyline( *m_lineString ); painter->restore(); }
int QLineItem::getEndPointShape() { QPen pen = this->pen(); Qt::PenCapStyle style ; style = pen.capStyle(); if(style == Qt::FlatCap) nEndPointShape = 0; else if(style == Qt::SquareCap) nEndPointShape = 1; else if(style == Qt::RoundCap) nEndPointShape = 2; else nEndPointShape = 0; return nEndPointShape; }
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) { GraphicsContext* gc = scratchContext(); QPainterPathStroker stroke; if (applier) { applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); } return stroke.createStroke(m_path).boundingRect(); }
bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const { ASSERT(applier); QPainterPathStroker stroke; GraphicsContext* gc = scratchContext(); applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); return stroke.createStroke(m_path).contains(point); }
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) { // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer // on each call. OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1)); GraphicsContext* gc = scratchImage->context(); QPainterPathStroker stroke; if (applier) { applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); } return stroke.createStroke(m_path).boundingRect(); }
QPainterPath ArrowItem::shape() const { QPainterPath path; path.setFillRule(Qt::WindingFill); if (m_shaftItem &&m_shaftItem->path() != QPainterPath()) { QPainterPathStroker ps; QPen pen = m_shaftItem->pen(); ps.setCapStyle(pen.capStyle()); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); // overwrite pen width to make selection more lazy ps.setWidth(16.0); QPainterPath p = ps.createStroke(m_shaftItem->path()); path.addPath(p); } if (m_startHeadItem) path.addRect(mapRectFromItem(m_startHeadItem, m_startHeadItem->boundingRect())); if (m_endHeadItem) path.addRect(mapRectFromItem(m_endHeadItem, m_endHeadItem->boundingRect())); return path; }
QPainterPath Toolbox::shapeFromPath(const QPainterPath& path, const QPen& pen, const QBrush& brush, const UnsignedLength& minWidth) noexcept { // http://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/graphicsview/qgraphicsitem.cpp // Function: qt_graphicsItem_shapeFromPath() if (path == QPainterPath() || pen == Qt::NoPen) { return path; } else { QPainterPathStroker ps; ps.setCapStyle(pen.capStyle()); ps.setWidth(qMax(qMax(pen.widthF(), qreal(0.00000001)), minWidth->toPx())); ps.setJoinStyle(pen.joinStyle()); ps.setMiterLimit(pen.miterLimit()); QPainterPath p = ps.createStroke(path); if (brush != Qt::NoBrush) { p.addPath(path); } return p; } }
bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const { ASSERT(applier); // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer // on each call. OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1)); GraphicsContext* gc = scratchImage->context(); QPainterPathStroker stroke; applier->strokeStyle(gc); QPen pen = gc->pen(); stroke.setWidth(pen.widthF()); stroke.setCapStyle(pen.capStyle()); stroke.setJoinStyle(pen.joinStyle()); stroke.setMiterLimit(pen.miterLimit()); stroke.setDashPattern(pen.dashPattern()); stroke.setDashOffset(pen.dashOffset()); return stroke.createStroke(m_path).contains(point); }
QString TextBoxContent::cacheKey(AbstractVisualItem *abstract_model) { TextBoxItem * model = dynamic_cast<TextBoxItem*>(abstract_model); if(!model) return ""; QString key = model->property("$tb.cacheKey").toString(); QVariant var = model->property("$tb.cacheKeyRev"); int keyRev = var.isValid() ? var.toInt() : -1; if(key.isEmpty() || (uint)keyRev != (uint)model->revision()) { QByteArray array; QDataStream list(&array, QIODevice::WriteOnly); list << model->text(); if(model && model->outlineEnabled()) { QPen p = model->outlinePen(); list << (int)p.color().rgba(); list << p.miterLimit(); list << p.widthF(); list << (int)p.style(); list << (int)p.capStyle(); list << (int)p.joinStyle(); } list << model->shadowBlurRadius(); list << (int)model->shadowBrush().color().rgba(); list << model->shadowOffsetX(); list << model->shadowOffsetY(); list << (int)model->fillType(); list << (int)model->fillBrush().color().rgba(); list << (int)model->zoomEffectEnabled(); QString md5key = MD5::md5sum(array); QDir path(QString("%1/%2").arg(AppSettings::cachePath()).arg(TEXT_RENDER_CACHE_DIR)); if(!path.exists()) QDir(AppSettings::cachePath()).mkdir(TEXT_RENDER_CACHE_DIR); QSizeF shadowSize = model->shadowEnabled() ? QSizeF(model->shadowOffsetX(),model->shadowOffsetY()) : QSizeF(0,0); QSize renderSize = (model->contentsRect().size()+shadowSize).toSize(); key = QString("%1/%2/%3-%4x%5") .arg(AppSettings::cachePath()) .arg(TEXT_RENDER_CACHE_DIR) .arg(md5key) .arg(renderSize.width()) .arg(renderSize.height()); model->setProperty("$tb.cacheKey",key); model->setProperty("$tb.cacheKeyRev",model->revision()); //qDebug() << "TextBoxContent::cacheKey(): "<<model->itemName()<<": model rev:"<<model->revision()<<", key: "<<key; } return key; }
bool DomConvenience::variantToElement(const QVariant& v, QDomElement& e) { bool ok = true; clearAttributes(e); switch (v.type()) { case QVariant::String: e.setTagName("string"); e.setAttribute("value", v.toString()); break; #if 0 case QVariant::CString: e.setTagName("string"); e.setAttribute("value", v.toString()); break; #endif case QVariant::Int: e.setTagName("int"); e.setAttribute("value", v.toInt()); break; case QVariant::UInt: e.setTagName("uint"); e.setAttribute("value", v.toUInt()); break; case QVariant::Double: e.setTagName("double"); e.setAttribute("value", v.toDouble()); break; case QVariant::Bool: e.setTagName("bool"); e.setAttribute("value", boolString(v.toBool())); break; case QVariant::Color: { e.setTagName("color"); QColor color = v.value<QColor>(); e.setAttribute("red", color.red()); e.setAttribute("green", color.green()); e.setAttribute("blue", color.blue()); } break; case QVariant::Pen: { e.setTagName("pen"); QPen pen = v.value<QPen>(); e.setAttribute("red", pen.color().red()); e.setAttribute("green", pen.color().green()); e.setAttribute("blue", pen.color().blue()); e.setAttribute("style", pen.style()); e.setAttribute("cap", pen.capStyle()); e.setAttribute("join", pen.joinStyle()); } break; case QVariant::Brush: { e.setTagName("brush"); QBrush brush = v.value<QBrush>(); e.setAttribute("red", brush.color().red()); e.setAttribute("green", brush.color().green()); e.setAttribute("blue", brush.color().blue()); e.setAttribute("style", brush.style()); } break; case QVariant::Point: { e.setTagName("point"); QPoint point = v.toPoint(); e.setAttribute("x", point.x()); e.setAttribute("y", point.y()); } break; case QVariant::Rect: { e.setTagName("rect"); QRect rect = v.toRect(); e.setAttribute("x", rect.x()); e.setAttribute("y", rect.y()); e.setAttribute("width", rect.width()); e.setAttribute("height", rect.height()); } break; case QVariant::Size: { e.setTagName("size"); QSize qsize = v.toSize(); e.setAttribute("width", qsize.width()); e.setAttribute("height", qsize.height()); } break; case QVariant::Font: { e.setTagName("font"); QFont f(v.value<QFont>()); e.setAttribute("family", f.family()); e.setAttribute("pointsize", f.pointSize()); e.setAttribute("bold", boolString(f.bold())); e.setAttribute("italic", boolString(f.italic())); e.setAttribute("underline", boolString(f.underline())); e.setAttribute("strikeout", boolString(f.strikeOut())); } break; case QVariant::SizePolicy: { e.setTagName("sizepolicy"); QSizePolicy sp(v.value<QSizePolicy>()); e.setAttribute("hsizetype", sp.horData()); e.setAttribute("vsizetype", sp.verData()); e.setAttribute("horstretch", sp.horStretch()); e.setAttribute("verstretch", sp.verStretch()); } break; case QVariant::Cursor: e.setTagName("cursor"); e.setAttribute("shape", v.value<QCursor>().shape()); break; case QVariant::StringList: { e.setTagName("stringlist"); int32_t j; QDomNode n; QDomNodeList stringNodeList = e.elementsByTagName("string"); QDomElement stringElem; QStringList stringList = v.toStringList(); QStringList::Iterator it = stringList.begin(); for (j = 0; ((j < (int32_t)stringNodeList.length()) && (it != stringList.end())); j++) { // get the current string element stringElem = stringNodeList.item(j).toElement(); // set it to the current string variantToElement(QVariant(*it), stringElem); // iterate to the next string ++it; } // more nodes in previous stringlist then current, remove excess nodes if (stringNodeList.count() > stringList.count()) { while (j < (int32_t)stringNodeList.count()) e.removeChild(stringNodeList.item(j).toElement()); } else if (j < (int32_t)stringList.count()) { while (it != stringList.end()) { // create a new element stringElem = m_doc.createElement("string"); // set it to the currentstring variantToElement(QVariant(*it), stringElem); // append it to the current element e.appendChild(stringElem); // iterate to the next string ++it; } } } break; case QVariant::KeySequence: e.setTagName("key"); e.setAttribute("sequence", (QString)v.value<QKeySequence>().toString()); break; case QVariant::ByteArray: // this is only for [u]int64_t { e.setTagName("data"); // set the value e.setAttribute("value", getStringFromByteArray(v.toByteArray())); } break; default: qWarning("Don't know how to persist variant of type: %s (%d)!", v.typeName(), v.type()); ok = false; break; } return ok; }
void KoOdfGraphicStyles::saveOdfStrokeStyle(KoGenStyle &styleStroke, KoGenStyles &mainStyles, const QPen &pen) { // TODO implement all possibilities switch (pen.style()) { case Qt::NoPen: styleStroke.addProperty("draw:stroke", "none", KoGenStyle::GraphicType); return; case Qt::SolidLine: styleStroke.addProperty("draw:stroke", "solid", KoGenStyle::GraphicType); break; default: { // must be a dashed line styleStroke.addProperty("draw:stroke", "dash", KoGenStyle::GraphicType); // save stroke dash (14.14.7) which is severly limited, but still KoGenStyle dashStyle(KoGenStyle::StrokeDashStyle); dashStyle.addAttribute("draw:style", "rect"); QVector<qreal> dashes = pen.dashPattern(); dashStyle.addAttribute("draw:dots1", static_cast<int>(1)); dashStyle.addAttributePt("draw:dots1-length", dashes[0]*pen.widthF()); dashStyle.addAttributePt("draw:distance", dashes[1]*pen.widthF()); if (dashes.size() > 2) { dashStyle.addAttribute("draw:dots2", static_cast<int>(1)); dashStyle.addAttributePt("draw:dots2-length", dashes[2]*pen.widthF()); } QString dashStyleName = mainStyles.insert(dashStyle, "dash"); styleStroke.addProperty("draw:stroke-dash", dashStyleName, KoGenStyle::GraphicType); break; } } if (pen.brush().gradient()) { styleStroke.addProperty("calligra:stroke-gradient", saveOdfGradientStyle(mainStyles, pen.brush()), KoGenStyle::GraphicType); } else { styleStroke.addProperty("svg:stroke-color", pen.color().name(), KoGenStyle::GraphicType); styleStroke.addProperty("svg:stroke-opacity", QString("%1").arg(pen.color().alphaF()), KoGenStyle::GraphicType); } styleStroke.addPropertyPt("svg:stroke-width", pen.widthF(), KoGenStyle::GraphicType); switch (pen.joinStyle()) { case Qt::MiterJoin: styleStroke.addProperty("draw:stroke-linejoin", "miter", KoGenStyle::GraphicType); break; case Qt::BevelJoin: styleStroke.addProperty("draw:stroke-linejoin", "bevel", KoGenStyle::GraphicType); break; case Qt::RoundJoin: styleStroke.addProperty("draw:stroke-linejoin", "round", KoGenStyle::GraphicType); break; default: styleStroke.addProperty("draw:stroke-linejoin", "miter", KoGenStyle::GraphicType); styleStroke.addProperty("calligra:stroke-miterlimit", QString("%1").arg(pen.miterLimit()), KoGenStyle::GraphicType); break; } switch (pen.capStyle()) { case Qt::RoundCap: styleStroke.addProperty("svg:stroke-linecap", "round", KoGenStyle::GraphicType); break; case Qt::SquareCap: styleStroke.addProperty("svg:stroke-linecap", "square", KoGenStyle::GraphicType); break; default: styleStroke.addProperty("svg:stroke-linecap", "butt", KoGenStyle::GraphicType); break; } }
void GeoPolygonGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport ) { Q_UNUSED( viewport ); if ( !style() ) { painter->save(); painter->setPen( QPen() ); if ( m_polygon ) { painter->drawPolygon( *m_polygon ); } else if ( m_ring ) { painter->drawPolygon( *m_ring ); } painter->restore(); return; } painter->save(); QPen currentPen = painter->pen(); if ( !style()->polyStyle().outline() ) { currentPen.setColor( Qt::transparent ); } else { if ( currentPen.color() != style()->lineStyle().color() || currentPen.widthF() != style()->lineStyle().width() ) { currentPen.setColor( style()->lineStyle().color() ); currentPen.setWidthF( style()->lineStyle().width() ); } if ( currentPen.capStyle() != style()->lineStyle().capStyle() ) currentPen.setCapStyle( style()->lineStyle().capStyle() ); if ( currentPen.style() != style()->lineStyle().penStyle() ) currentPen.setStyle( style()->lineStyle().penStyle() ); if ( painter->mapQuality() != Marble::HighQuality && painter->mapQuality() != Marble::PrintQuality ) { QColor penColor = currentPen.color(); penColor.setAlpha( 255 ); currentPen.setColor( penColor ); } } if ( painter->pen() != currentPen ) painter->setPen( currentPen ); if ( !style()->polyStyle().fill() ) { if ( painter->brush().color() != Qt::transparent ) painter->setBrush( QColor( Qt::transparent ) ); } else { if ( painter->brush().color() != style()->polyStyle().color() ) { painter->setBrush( style()->polyStyle().color() ); } } if ( m_polygon ) { painter->drawPolygon( *m_polygon ); } else if ( m_ring ) { painter->drawPolygon( *m_ring ); } painter->restore(); }
void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QPen& pen, QPen& selPen, double& offset ) { if ( !hasDataDefinedProperties() ) return; // shortcut //data defined properties bool hasStrokeWidthExpression = false; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH ) ) { context.setOriginalValueVariable( mWidth ); double scaledWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH, context, mWidth ).toDouble(), mWidthUnit, mWidthMapUnitScale ); pen.setWidthF( scaledWidth ); selPen.setWidthF( scaledWidth ); hasStrokeWidthExpression = true; } //color bool ok; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_COLOR ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( pen.color() ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_COLOR, context, QVariant(), &ok ).toString(); if ( ok ) pen.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ); } //offset if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET ) ) { context.setOriginalValueVariable( mOffset ); offset = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET, context, offset ).toDouble(); } //dash dot vector if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_CUSTOMDASH ) ) { double scaledWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), mWidth, mWidthUnit, mWidthMapUnitScale ); double dashWidthDiv = mPen.widthF(); if ( hasStrokeWidthExpression ) { dashWidthDiv = pen.widthF(); scaledWidth = pen.widthF(); } //fix dash pattern width in Qt 4.8 QStringList versionSplit = QString( qVersion() ).split( '.' ); if ( versionSplit.size() > 1 && versionSplit.at( 1 ).toInt() >= 8 && ( scaledWidth * context.renderContext().rasterScaleFactor() ) < 1.0 ) { dashWidthDiv = 1.0; } QVector<qreal> dashVector; QStringList dashList = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_CUSTOMDASH, context, QVariant(), &ok ).toString().split( ';' ); if ( ok ) { QStringList::const_iterator dashIt = dashList.constBegin(); for ( ; dashIt != dashList.constEnd(); ++dashIt ) { dashVector.push_back( QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), dashIt->toDouble(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv ); } pen.setDashPattern( dashVector ); } } //line style if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_LINE_STYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenStyle( pen.style() ) ); QString lineStyleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_LINE_STYLE, context, QVariant(), &ok ).toString(); if ( ok ) pen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( lineStyleString ) ); } //join style if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOINSTYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenJoinStyle( pen.joinStyle() ) ); QString joinStyleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOINSTYLE, context, QVariant(), &ok ).toString(); if ( ok ) pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) ); } //cap style if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_CAPSTYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenCapStyle( pen.capStyle() ) ); QString capStyleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_CAPSTYLE, context, QVariant(), &ok ).toString(); if ( ok ) pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) ); } }
void GeoPolygonGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport ) { painter->save(); bool const isBuildingFrame = isDecoration(); bool const isBuildingRoof = !isDecoration() && !decorations().isEmpty(); QPen currentPen = painter->pen(); if ( !style() ) { painter->setPen( QPen() ); } else { if ( !style()->polyStyle().outline() || isBuildingFrame ) { currentPen.setColor( Qt::transparent ); } else { if ( currentPen.color() != style()->lineStyle().paintedColor() || currentPen.widthF() != style()->lineStyle().width() ) { currentPen.setColor( style()->lineStyle().paintedColor() ); currentPen.setWidthF( style()->lineStyle().width() ); } if ( currentPen.capStyle() != style()->lineStyle().capStyle() ) currentPen.setCapStyle( style()->lineStyle().capStyle() ); if ( currentPen.style() != style()->lineStyle().penStyle() ) currentPen.setStyle( style()->lineStyle().penStyle() ); } if ( painter->pen() != currentPen ) painter->setPen( currentPen ); if ( !style()->polyStyle().fill() ) { if ( painter->brush().color() != Qt::transparent ) painter->setBrush( QColor( Qt::transparent ) ); } else { if ( isBuildingFrame ) { painter->setBrush( style()->polyStyle().paintedColor().darker(150) ); } else if ( painter->brush().color() != style()->polyStyle().paintedColor() ) { QImage textureImage = style()->polyStyle().textureImage(); if( !textureImage.isNull()){ GeoDataCoordinates coords = latLonAltBox().center(); qreal x, y; viewport->screenCoordinates(coords, x, y); if (m_cachedTexturePath != style()->polyStyle().texturePath() || m_cachedTextureColor != style()->polyStyle().paintedColor() ) { m_cachedTexture = QImage ( textureImage.size(), QImage::Format_ARGB32_Premultiplied ); m_cachedTexture.fill(style()->polyStyle().paintedColor()); QPainter imagePainter(&m_cachedTexture ); imagePainter.drawImage(0, 0, textureImage); imagePainter.end(); m_cachedTexturePath = style()->polyStyle().texturePath(); m_cachedTextureColor = style()->polyStyle().paintedColor(); } QBrush brush; brush.setTextureImage(m_cachedTexture); QTransform transform; brush.setTransform(transform.translate(x,y)); painter->setBrush(brush); } else { painter->setBrush( style()->polyStyle().paintedColor() ); } } } } if ( isBuildingFrame || isBuildingRoof ) { bool drawAccurate3D = false; bool isCameraAboveBuilding = false; QPointF offsetAtCorner = buildingOffset(QPointF(0, 0), viewport, &isCameraAboveBuilding); qreal maxOffset = qMax( qAbs( offsetAtCorner.x() ), qAbs( offsetAtCorner.y() ) ); drawAccurate3D = painter->mapQuality() == HighQuality ? maxOffset > 5.0 : maxOffset > 8.0; // Since subtracting one fully contained polygon from another results in a single // polygon with a "connecting line" between the inner and outer part we need // to first paint the inner area with no pen and then the outlines with the correct pen. QVector<QPolygonF*> outlines; QVector<QPolygonF*> innerPolygons; QVector<QPolygonF*> polygons; bool const hasInnerBoundaries = m_polygon ? !m_polygon->innerBoundaries().isEmpty() : false; if (m_polygon) { if (hasInnerBoundaries) { screenPolygons(viewport, m_polygon, innerPolygons, outlines); } viewport->screenCoordinates(m_polygon->outerBoundary(), polygons); } else if (m_ring) { viewport->screenCoordinates(*m_ring, polygons); } if ( isBuildingFrame ) { QVector<QPolygonF*> sides = (hasInnerBoundaries && drawAccurate3D && isCameraAboveBuilding) ? outlines : polygons; foreach(QPolygonF* polygon, sides) { if (polygon->isEmpty()) { continue; } if ( drawAccurate3D && isCameraAboveBuilding ) { // draw the building sides int const size = polygon->size(); QPointF & a = (*polygon)[0]; QPointF shiftA = a + buildingOffset(a, viewport); for (int i=1; i<size; ++i) { QPointF const & b = (*polygon)[i]; QPointF const shiftB = b + buildingOffset(b, viewport); QPolygonF buildingSide = QPolygonF() << a << shiftA << shiftB << b; if (hasInnerBoundaries) { //smoothen away our loss of antialiasing due to the QRegion Qt-bug workaround painter->setPen(QPen(painter->brush().color(), 1.5)); } painter->drawPolygon(buildingSide); a = b; shiftA = shiftB; } } else { // don't draw the building sides - just draw the base frame instead if (hasInnerBoundaries) { QRegion clip(polygon->toPolygon()); foreach(QPolygonF* clipPolygon, innerPolygons) { clip-=QRegion(clipPolygon->toPolygon()); } painter->setClipRegion(clip); } painter->drawPolygon(*polygon); } } } else if (isBuildingRoof) {
void GeoLineStringGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport ) { LabelPositionFlags labelPositionFlags = NoLabel; painter->save(); QPen currentPen = painter->pen(); if ( !style() ) { painter->setPen( QPen() ); } else { if ( currentPen.color() != style()->lineStyle().paintedColor() ) currentPen.setColor( style()->lineStyle().paintedColor() ); if ( currentPen.widthF() != style()->lineStyle().width() || style()->lineStyle().physicalWidth() != 0.0 ) { if ( float( viewport->radius() ) / EARTH_RADIUS * style()->lineStyle().physicalWidth() < style()->lineStyle().width() ) currentPen.setWidthF( style()->lineStyle().width() ); else currentPen.setWidthF( float( viewport->radius() ) / EARTH_RADIUS * style()->lineStyle().physicalWidth() ); } else if ( style()->lineStyle().width() != 0.0 ) { currentPen.setWidthF( style()->lineStyle().width() ); } if ( currentPen.capStyle() != style()->lineStyle().capStyle() ) currentPen.setCapStyle( style()->lineStyle().capStyle() ); if ( currentPen.style() != style()->lineStyle().penStyle() ) currentPen.setStyle( style()->lineStyle().penStyle() ); if ( style()->lineStyle().penStyle() == Qt::CustomDashLine ) currentPen.setDashPattern( style()->lineStyle().dashPattern() ); if ( painter->mapQuality() != Marble::HighQuality && painter->mapQuality() != Marble::PrintQuality ) { QColor penColor = currentPen.color(); penColor.setAlpha( 255 ); currentPen.setColor( penColor ); } if ( painter->pen() != currentPen ) painter->setPen( currentPen ); if ( style()->lineStyle().background() ) { QBrush brush = painter->background(); brush.setColor( style()->polyStyle().paintedColor() ); painter->setBackground( brush ); painter->setBackgroundMode( Qt::OpaqueMode ); } // label styles painter->setFont( style()->labelStyle().font() ); switch ( style()->labelStyle().alignment() ) { case GeoDataLabelStyle::Corner: case GeoDataLabelStyle::Right: labelPositionFlags |= LineStart; break; case GeoDataLabelStyle::Center: labelPositionFlags |= LineCenter; break; } } if ( ! ( isDecoration() && currentPen.widthF() < 2.5f ) ) { if( style()->lineStyle().cosmeticOutline() && style()->lineStyle().penStyle() == Qt::SolidLine ) { if ( isDecoration() ) { painter->drawPolyline( *m_lineString, "", NoLabel ); } else { if ( currentPen.widthF() > 2.5f ) { currentPen.setWidthF( currentPen.widthF() - 2.0f ); } currentPen.setColor( style()->polyStyle().paintedColor() ); painter->setPen( currentPen ); painter->drawPolyline( *m_lineString, feature()->name(), FollowLine, style()->labelStyle().paintedColor(), style()->labelStyle().font()); } } else { painter->drawPolyline( *m_lineString, feature()->name(), labelPositionFlags ); } } painter->restore(); }
bool DomConvenience::variantToElement(const QVariant& v, QDomElement& e) { bool ok = true; clearAttributes(e); switch (v.type()) { case QVariant::String: e.setTagName("string"); e.setAttribute("value", v.toString().utf8()); break; case QVariant::CString: e.setTagName("string"); e.setAttribute("value", v.toCString()); break; case QVariant::Int: e.setTagName("int"); e.setAttribute("value", v.toInt()); break; case QVariant::UInt: e.setTagName("uint"); e.setAttribute("value", v.toUInt()); break; case QVariant::Double: e.setTagName("double"); e.setAttribute("value", v.toDouble()); break; case QVariant::Bool: e.setTagName("bool"); e.setAttribute("value", boolString(v.toBool())); break; case QVariant::Color: { e.setTagName("color"); QColor color = v.toColor(); e.setAttribute("red", color.red()); e.setAttribute("green", color.green()); e.setAttribute("blue", color.blue()); } break; case QVariant::Pen: { e.setTagName("pen"); QPen pen = v.toPen(); e.setAttribute("red", pen.color().red()); e.setAttribute("green", pen.color().green()); e.setAttribute("blue", pen.color().blue()); e.setAttribute("style", pen.style()); e.setAttribute("cap", pen.capStyle()); e.setAttribute("join", pen.joinStyle()); } break; case QVariant::Brush: { e.setTagName("brush"); QBrush brush = v.toBrush(); e.setAttribute("red", brush.color().red()); e.setAttribute("green", brush.color().green()); e.setAttribute("blue", brush.color().blue()); e.setAttribute("style", brush.style()); } break; case QVariant::Point: { e.setTagName("point"); QPoint point = v.toPoint(); e.setAttribute("x", point.x()); e.setAttribute("y", point.y()); } break; case QVariant::Rect: { e.setTagName("rect"); QRect rect = v.toRect(); e.setAttribute("x", rect.x()); e.setAttribute("y", rect.y()); e.setAttribute("width", rect.width()); e.setAttribute("height", rect.height()); } break; case QVariant::Size: { e.setTagName("size"); QSize qsize = v.toSize(); e.setAttribute("width", qsize.width()); e.setAttribute("height", qsize.height()); } break; case QVariant::Font: { e.setTagName("font"); QFont f(v.toFont()); e.setAttribute("family", f.family()); e.setAttribute("pointsize", f.pointSize()); e.setAttribute("bold", boolString(f.bold())); e.setAttribute("italic", boolString(f.italic())); e.setAttribute("underline", boolString(f.underline())); e.setAttribute("strikeout", boolString(f.strikeOut())); } break; case QVariant::SizePolicy: { e.setTagName("sizepolicy"); QSizePolicy sp(v.toSizePolicy()); e.setAttribute("hsizetype", sp.horData()); e.setAttribute("vsizetype", sp.verData()); #if (QT_VERSION >= 300) e.setAttribute("horstretch", sp.horStretch()); e.setAttribute("verstretch", sp.verStretch()); #endif } break; case QVariant::Cursor: e.setTagName("cursor"); e.setAttribute("shape", v.toCursor().shape()); break; case QVariant::StringList: { e.setTagName("stringlist"); uint j; QDomNode n; QDomNodeList stringNodeList = e.elementsByTagName("string"); QDomElement stringElem; QStringList stringList = v.toStringList(); QStringList::Iterator it = stringList.begin(); for (j = 0; ((j < stringNodeList.length()) && (it != stringList.end())); j++) { // get the current string element stringElem = stringNodeList.item(j).toElement(); // set it to the current string variantToElement(QVariant(*it), stringElem); // iterate to the next string ++it; } // more nodes in previous stringlist then current, remove excess nodes if (stringNodeList.count() > stringList.count()) { while (j < stringNodeList.count()) e.removeChild(stringNodeList.item(j).toElement()); } else if (j <stringList.count()) { while (it != stringList.end()) { // create a new element stringElem = m_doc.createElement("string"); // set it to the currentstring variantToElement(QVariant(*it), stringElem); // append it to the current element e.appendChild(stringElem); // iterate to the next string ++it; } } } break; #if QT_VERSION >= 300 case QVariant::KeySequence: e.setTagName("key"); e.setAttribute("sequence", (QString)v.toKeySequence()); break; #endif case QVariant::ByteArray: // this is only for [u]int64_t { e.setTagName("uint64"); QByteArray ba = v.toByteArray(); // make sure this only handles [u]int64_t's if (ba.size() != sizeof(uint64_t)) { qWarning("Don't know how to persist variant of type: %s (%d) (size=%d)!", v.typeName(), v.type(), ba.size()); ok = false; break; } // convert the data back into a uint64_t uint64_t num = *(uint64_t*)ba.data(); QChar buff[33]; QChar* p = &buff[32]; const char* digitSet = "0123456789abcdef"; int len = 0; // construct the string do { *--p = digitSet[((int)(num%16))]; num = num >> 4; // divide by 16 len++; } while ( num ); // store it in a QString QString storage; storage.setUnicode(p, len); // set the value e.setAttribute("value", storage); } break; #if 0 case QVariant::List: case QVaraint::Map: #endif default: qWarning("Don't know how to persist variant of type: %s (%d)!", v.typeName(), v.type()); ok = false; break; } return ok; }
HPEN EmfPaintEngine::convertPen(const QPen& pen) { INT style = PS_NULL; switch (pen.style()){ case Qt::SolidLine: style = PS_SOLID; break; case Qt::DashLine: style = PS_DASH; break; case Qt::DotLine: style = PS_DOT; break; case Qt::DashDotLine: style = PS_DASHDOT; break; case Qt::DashDotDotLine: style = PS_DASHDOTDOT; break; default: break; } INT capStyle = PS_ENDCAP_FLAT; switch (pen.capStyle()){ case Qt::FlatCap: break; case Qt::SquareCap: capStyle = PS_ENDCAP_SQUARE; break; case Qt::RoundCap: capStyle = PS_ENDCAP_ROUND; break; default: break; } INT joinStyle = PS_JOIN_MITER; switch (pen.joinStyle()){ case Qt::MiterJoin: break; case Qt::BevelJoin: joinStyle = PS_JOIN_BEVEL; break; case Qt::RoundJoin: joinStyle = PS_JOIN_ROUND; break; case Qt::SvgMiterJoin: joinStyle = PS_JOIN_MITER; break; default: break; } LOGBRUSH lbrush = {BS_SOLID, RGB(pen.color().red(),pen.color().green(),pen.color().blue()), 0}; return ExtCreatePen(PS_GEOMETRIC | style | capStyle | joinStyle, pen.width(), &lbrush, 0, NULL); }
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) { #ifdef QT_DEBUG_DRAW qDebug() << "QPaintEngineEx::stroke()" << pen; #endif Q_D(QPaintEngineEx); if (path.isEmpty()) return; if (!d->strokeHandler) { d->strokeHandler = new StrokeHandler(path.elementCount()+4); d->stroker.setMoveToHook(qpaintengineex_moveTo); d->stroker.setLineToHook(qpaintengineex_lineTo); d->stroker.setCubicToHook(qpaintengineex_cubicTo); } if (!qpen_fast_equals(pen, d->strokerPen)) { d->strokerPen = pen; d->stroker.setJoinStyle(pen.joinStyle()); d->stroker.setCapStyle(pen.capStyle()); d->stroker.setMiterLimit(pen.miterLimit()); qreal penWidth = pen.widthF(); if (penWidth == 0) d->stroker.setStrokeWidth(1); else d->stroker.setStrokeWidth(penWidth); Qt::PenStyle style = pen.style(); if (style == Qt::SolidLine) { d->activeStroker = &d->stroker; } else if (style == Qt::NoPen) { d->activeStroker = 0; } else { d->dasher.setDashPattern(pen.dashPattern()); d->dasher.setDashOffset(pen.dashOffset()); d->activeStroker = &d->dasher; } } if (!d->activeStroker) { return; } if (pen.style() > Qt::SolidLine) { if (pen.isCosmetic()) { d->activeStroker->setClipRect(d->exDeviceRect); } else { QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect)); d->activeStroker->setClipRect(clipRect); } } const QPainterPath::ElementType *types = path.elements(); const qreal *points = path.points(); int pointCount = path.elementCount(); const qreal *lastPoint = points + (pointCount<<1); d->strokeHandler->types.reset(); d->strokeHandler->pts.reset(); // Some engines might decide to optimize for the non-shape hint later on... uint flags = QVectorPath::WindingFill; if (path.elementCount() > 2) flags |= QVectorPath::NonConvexShapeMask; if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin) flags |= QVectorPath::CurvedShapeMask; // ### Perspective Xforms are currently not supported... if (!pen.isCosmetic()) { // We include cosmetic pens in this case to avoid having to // change the current transform. Normal transformed, // non-cosmetic pens will be transformed as part of fill // later, so they are also covered here.. d->activeStroker->setCurveThresholdFromTransform(state()->matrix); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { switch (*types) { case QPainterPath::MoveToElement: d->activeStroker->moveTo(points[0], points[1]); points += 2; ++types; break; case QPainterPath::LineToElement: d->activeStroker->lineTo(points[0], points[1]); points += 2; ++types; break; case QPainterPath::CurveToElement: d->activeStroker->cubicTo(points[0], points[1], points[2], points[3], points[4], points[5]); points += 6; types += 3; flags |= QVectorPath::CurvedShapeMask; break; default: break; } } if (path.hasImplicitClose()) d->activeStroker->lineTo(path.points()[0], path.points()[1]); } else { d->activeStroker->moveTo(points[0], points[1]); points += 2; while (points < lastPoint) { d->activeStroker->lineTo(points[0], points[1]); points += 2; } if (path.hasImplicitClose()) d->activeStroker->lineTo(path.points()[0], path.points()[1]); } d->activeStroker->end(); if (!d->strokeHandler->types.size()) // an empty path... return; QVectorPath strokePath(d->strokeHandler->pts.data(), d->strokeHandler->types.size(), d->strokeHandler->types.data(), flags); fill(strokePath, pen.brush()); } else { // For cosmetic pens we need a bit of trickery... We to process xform the input points if (state()->matrix.type() >= QTransform::TxProject) { QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); } else { d->activeStroker->setCurveThresholdFromTransform(QTransform()); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { switch (*types) { case QPainterPath::MoveToElement: { QPointF pt = (*(QPointF *) points) * state()->matrix; d->activeStroker->moveTo(pt.x(), pt.y()); points += 2; ++types; break; } case QPainterPath::LineToElement: { QPointF pt = (*(QPointF *) points) * state()->matrix; d->activeStroker->lineTo(pt.x(), pt.y()); points += 2; ++types; break; } case QPainterPath::CurveToElement: { QPointF c1 = ((QPointF *) points)[0] * state()->matrix; QPointF c2 = ((QPointF *) points)[1] * state()->matrix; QPointF e = ((QPointF *) points)[2] * state()->matrix; d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); points += 6; types += 3; flags |= QVectorPath::CurvedShapeMask; break; } default: break; } } if (path.hasImplicitClose()) { QPointF pt = * ((QPointF *) path.points()) * state()->matrix; d->activeStroker->lineTo(pt.x(), pt.y()); } } else { QPointF p = ((QPointF *)points)[0] * state()->matrix; d->activeStroker->moveTo(p.x(), p.y()); points += 2; while (points < lastPoint) { QPointF p = ((QPointF *)points)[0] * state()->matrix; d->activeStroker->lineTo(p.x(), p.y()); points += 2; } if (path.hasImplicitClose()) d->activeStroker->lineTo(p.x(), p.y()); } d->activeStroker->end(); } QVectorPath strokePath(d->strokeHandler->pts.data(), d->strokeHandler->types.size(), d->strokeHandler->types.data(), flags); QTransform xform = state()->matrix; state()->matrix = QTransform(); transformChanged(); QBrush brush = pen.brush(); if (qbrush_style(brush) != Qt::SolidPattern) brush.setTransform(brush.transform() * xform); fill(strokePath, brush); state()->matrix = xform; transformChanged(); } }