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);
        }
    }
}
Example #2
0
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);
}
Example #3
0
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();
}
Example #6
0
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;
}
Example #7
0
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();
}
Example #8
0
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();
}
Example #10
0
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;
}
Example #11
0
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);
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
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();
}
Example #17
0
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 ) );
  }
}
Example #18
0
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();
}
Example #20
0
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;
}
Example #21
0
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);
}
Example #22
0
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();
    }
}