void SvgParser::applyStrokeStyle(KoShape *shape) { SvgGraphicsContext *gc = m_context.currentGC(); if (! gc) return; if (gc->strokeType == SvgGraphicsContext::None) { shape->setStroke(0); } else if (gc->strokeType == SvgGraphicsContext::Solid) { double lineWidth = gc->stroke.lineWidth(); QVector<qreal> dashes = gc->stroke.lineDashes(); KoShapeStroke *stroke = new KoShapeStroke(gc->stroke); // apply line width to dashes and dash offset if (dashes.count() && lineWidth > 0.0) { QVector<qreal> dashes = stroke->lineDashes(); for (int i = 0; i < dashes.count(); ++i) dashes[i] /= lineWidth; double dashOffset = stroke->dashOffset(); stroke->setLineStyle(Qt::CustomDashLine, dashes); stroke->setDashOffset(dashOffset / lineWidth); } else { stroke->setLineStyle(Qt::SolidLine, QVector<qreal>()); } shape->setStroke(stroke); } else if (gc->strokeType == SvgGraphicsContext::Complex) { // try to find referenced gradient SvgGradientHelper *gradient = findGradient(gc->strokeId); if (gradient) { // great, we have a gradient stroke QBrush brush; if (gradient->gradientUnits() == SvgGradientHelper::ObjectBoundingBox) { brush = *gradient->gradient(); brush.setTransform(gradient->transform()); } else { QGradient *convertedGradient(SvgGradientHelper::convertGradient(gradient->gradient(), shape->size())); brush = *convertedGradient; delete convertedGradient; brush.setTransform(gradient->transform() * gc->matrix * shape->transformation().inverted()); } KoShapeStroke *stroke = new KoShapeStroke(gc->stroke); stroke->setLineBrush(brush); stroke->setLineStyle(Qt::SolidLine, QVector<qreal>()); shape->setStroke(stroke); } else { // no referenced stroke found, use fallback color KoShapeStroke *stroke = new KoShapeStroke(gc->stroke); stroke->setLineStyle(Qt::SolidLine, QVector<qreal>()); shape->setStroke(stroke); } } }
void TextureViewWidget::drawPixelWasteDecoration(QPainter *p) const { //Draw Warning if more than 30% or 1KB are wasted const auto hasTextureWasteProblem = (m_pixelWasteInPercent > transparencyWasteLimitInPercent || m_pixelWasteInBytes > transparencyWasteLimitInBytes); if (!hasTextureWasteProblem) return; p->save(); auto scaleTransform = QTransform::fromScale(zoom(), zoom()); p->setTransform(scaleTransform, true); //Draw Wasted Area QPen pen(Qt::red); pen.setCosmetic(true); p->setPen(pen); QBrush brush = QBrush(Qt::red, Qt::FDiagPattern); brush.setTransform(scaleTransform.inverted()); p->setBrush(brush); auto outerRect = m_analyzedRect; auto wasteArea = QPainterPath(); wasteArea.addRect(outerRect); auto innerRect = QPainterPath(); auto translatedBoundingRect = m_opaqueBoundingRect.translated(m_analyzedRect.topLeft()); innerRect.addRect(translatedBoundingRect); wasteArea = wasteArea.subtracted(innerRect); p->drawPath(wasteArea); p->restore(); }
void EDATool::layerToPenBrush(int layer, QPen &pen, QBrush &brush) { struct LayerDefinition { LayerDefinition(QString s, QColor c, Qt::BrushStyle bs){ this->name = s; this->color = c; this->brushStyle = bs; } QString name; QColor color; enum Qt::BrushStyle brushStyle; int zorder; }; LayerDefinition *ld[52]; ld[0] = new LayerDefinition("Undefined", QColor(0,0,0,255), Qt::CrossPattern); ld[1] = new LayerDefinition("Top", QColor(255,0,0,127), Qt::SolidPattern); ld[16] = new LayerDefinition("Bottom", QColor(0,0,255,127), Qt::SolidPattern); ld[21] = new LayerDefinition("tPlace", QColor(255,255,255,127), Qt::SolidPattern); ld[29] = new LayerDefinition("tStop", QColor(0,255,0,127), Qt::BDiagPattern); ld[31] = new LayerDefinition("tCream", QColor(255,255,255,127), Qt::BDiagPattern); ld[51] = new LayerDefinition("tDocu", QColor(200,200,200,127), Qt::SolidPattern); if (!ld[layer]) { layer = 0; // default style } brush.setColor(ld[layer]->color); brush.setStyle(ld[layer]->brushStyle); brush.setTransform(QTransform::fromScale(0.005, 0.005)); pen.setColor(ld[layer]->color); pen.setStyle(Qt::SolidLine); }
void QEmulationPaintEngine::stroke(const QVectorPath &path, const QPen &pen) { QPainterState *s = state(); if (s->bgMode == Qt::OpaqueMode && pen.style() > Qt::SolidLine) { QPen bgPen = pen; bgPen.setBrush(s->bgBrush); bgPen.setStyle(Qt::SolidLine); real_engine->stroke(path, bgPen); } QBrush brush = pen.brush(); QPen copy = pen; Qt::BrushStyle style = qbrush_style(brush); if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { const QGradient *g = brush.gradient(); if (g->coordinateMode() > QGradient::LogicalMode) { if (g->coordinateMode() == QGradient::StretchToDeviceMode) { QTransform mat = brush.transform(); mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height()); brush.setTransform(mat); copy.setBrush(brush); real_engine->stroke(path, copy); return; } else if (g->coordinateMode() == QGradient::ObjectBoundingMode) { QTransform mat = brush.transform(); QRectF r = path.controlPointRect(); mat.translate(r.x(), r.y()); mat.scale(r.width(), r.height()); brush.setTransform(mat); copy.setBrush(brush); real_engine->stroke(path, copy); return; } } } real_engine->stroke(path, pen); }
void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { QPainterState *s = state(); if (s->bgMode == Qt::OpaqueMode) { Qt::BrushStyle style = brush.style(); if (style >= Qt::Dense1Pattern && style <= Qt::DiagCrossPattern) real_engine->fill(path, s->bgBrush); } Qt::BrushStyle style = qbrush_style(brush); if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { const QGradient *g = brush.gradient(); if (g->coordinateMode() > QGradient::LogicalMode) { if (g->coordinateMode() == QGradient::StretchToDeviceMode) { QBrush copy = brush; QTransform mat = copy.transform(); mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height()); copy.setTransform(mat); real_engine->fill(path, copy); return; } else if (g->coordinateMode() == QGradient::ObjectBoundingMode) { QBrush copy = brush; QTransform mat = copy.transform(); QRectF r = path.controlPointRect(); mat.translate(r.x(), r.y()); mat.scale(r.width(), r.height()); copy.setTransform(mat); real_engine->fill(path, copy); return; } } } real_engine->fill(path, brush); }
static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, QRectF gradientRect = QRectF())//copy from QPlainTextEditor from 4.8.1 { p->save(); if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) { if (!gradientRect.isNull()) { QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top()); m.scale(gradientRect.width(), gradientRect.height()); brush.setTransform(m); const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); } } else { p->setBrushOrigin(rect.topLeft()); } p->fillRect(rect, brush); p->restore(); }
void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context ) { QPainter* p = context.renderContext().painter(); if ( !p ) { return; } p->setPen( QPen( Qt::NoPen ) ); if ( context.selected() ) { QColor selColor = context.selectionColor(); // Alister - this doesn't seem to work here //if ( ! selectionIsOpaque ) // selColor.setAlphaF( context.alpha() ); p->setBrush( QBrush( selColor ) ); _renderPolygon( p, points, rings ); } if ( doubleNear( mAngle, 0.0 ) ) { p->setBrush( mBrush ); } else { QTransform t = mBrush.transform(); t.rotate( mAngle ); QBrush rotatedBrush = mBrush; rotatedBrush.setTransform( t ); p->setBrush( rotatedBrush ); } _renderPolygon( p, points, rings ); if ( mOutline ) { mOutline->renderPolyline( points, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() ); if ( rings ) { QList<QPolygonF>::const_iterator ringIt = rings->constBegin(); for ( ; ringIt != rings->constEnd(); ++ringIt ) { mOutline->renderPolyline( *ringIt, context.feature(), context.renderContext(), -1, selectFillBorder && context.selected() ); } } } }
void TextureViewWidget::drawBorderImageCutouts(QPainter *p) const { p->save(); auto scaleTransform = QTransform::fromScale(zoom(), zoom()); p->setTransform(scaleTransform, true); QPen pen(Qt::white); pen.setCosmetic(true); p->setPen(pen); QBrush brush = QBrush(Qt::white, Qt::FDiagPattern); brush.setTransform(scaleTransform.inverted()); p->setBrush(brush); if (m_horizontalBorderImageSavingsInPercent > minimumBorderImageSavingsPercent) { auto horizontalCutout = m_horizontalBorderRectMidCut.translated(m_analyzedRect.topLeft()); p->drawRect(horizontalCutout); } if (m_verticalBorderImageSavings > minimumBorderImageSavingsPercent) { auto verticalCutout = m_verticalBorderRectMidCut.translated(m_analyzedRect.topLeft()); p->drawRect(verticalCutout); } p->restore(); }
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 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(); } }