예제 #1
0
static QPainterPath getPathStroke(const QPainterPath &path, const RenderObject* object, const RenderStyle* style)
{ 
    QPainterPathStroker s;
    s.setWidth(KSVGPainterFactory::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0));

    if (style->svgStyle()->capStyle() == ButtCap)
        s.setCapStyle(Qt::FlatCap);
    else if (style->svgStyle()->capStyle() == RoundCap)
        s.setCapStyle(Qt::RoundCap);

    if (style->svgStyle()->joinStyle() == MiterJoin) {
        s.setJoinStyle(Qt::MiterJoin);
        s.setMiterLimit((qreal) style->svgStyle()->strokeMiterLimit());
    } else if(style->svgStyle()->joinStyle() == RoundJoin)
        s.setJoinStyle(Qt::RoundJoin);

    const KCDashArray& dashes = KSVGPainterFactory::dashArrayFromRenderingStyle(style);
    double dashOffset = KSVGPainterFactory::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0);

    unsigned int dashLength = !dashes.isEmpty() ? dashes.size() : 0;
    if(dashLength) {
        QVector<qreal> pattern;
        unsigned int count = (dashLength % 2) == 0 ? dashLength : dashLength * 2;

        for(unsigned int i = 0; i < count; i++)
            pattern.append(dashes[i % dashLength] / (float)s.width());

        s.setDashPattern(pattern);
    
        Q_UNUSED(dashOffset);
        // TODO: dash-offset, does/will qt4 API allow it? (Rob)
    }

    return s.createStroke(path);
}
예제 #2
0
void LayoutBreak::draw(QPainter* painter) const
      {
      if (score()->printing() || !score()->showUnprintable())
            return;

      QPainterPathStroker stroker;
      stroker.setWidth(lw/2);
      stroker.setJoinStyle(Qt::MiterJoin);
      stroker.setCapStyle(Qt::SquareCap);

      QVector<qreal> dashes ;
      dashes.append(1);
      dashes.append(3);
      stroker.setDashPattern(dashes);
      QPainterPath stroke = stroker.createStroke(path);

      painter->fillPath(stroke, selected() ? MScore::selectColor[0] : MScore::layoutBreakColor);


      painter->setPen(QPen(selected() ? MScore::selectColor[0] : MScore::layoutBreakColor,
         lw, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
      painter->setBrush(Qt::NoBrush);
      painter->drawPath(path2);

      }
예제 #3
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();
}
예제 #4
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);
}
예제 #5
0
void tst_QPainterPath::testStroker()
{
    QFETCH(QPainterPath, path);
    QFETCH(QPen, pen);
    QFETCH(QPainterPath, stroke);

    QPainterPathStroker stroker;
    stroker.setWidth(pen.widthF());
    stroker.setCapStyle(pen.capStyle());
    stroker.setJoinStyle(pen.joinStyle());
    stroker.setMiterLimit(pen.miterLimit());
    stroker.setDashPattern(pen.style());
    stroker.setDashOffset(pen.dashOffset());

    QPainterPath result = stroker.createStroke(path);

    // check if stroke == result
    QVERIFY(result.subtracted(stroke).isEmpty());
    QVERIFY(stroke.subtracted(result).isEmpty());
}
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();
}
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);
}
예제 #8
0
void Box::draw(QPainter* painter) const
      {
      if (score() && score()->printing())
            return;
      if (selected() || editMode || dropTarget() || score()->showFrames()) {
            qreal w = spatium() * .15;
            QPainterPathStroker stroker;
            stroker.setWidth(w);
            stroker.setJoinStyle(Qt::MiterJoin);
            stroker.setCapStyle(Qt::SquareCap);

            QVector<qreal> dashes ;
            dashes.append(1);
            dashes.append(3);
            stroker.setDashPattern(dashes);
            QPainterPath path;
            w *= .5;
            path.addRect(bbox().adjusted(w, w, -w, -w));
            QPainterPath stroke = stroker.createStroke(path);
            painter->setBrush(Qt::NoBrush);
            painter->fillPath(stroke, (selected() || editMode || dropTarget()) ? MScore::selectColor[0] : MScore::frameMarginColor);
            }
      }
예제 #9
0
QImage BitmapHelper::drawSelection(const QImage *source, const QPainterPath &selectedPath, int scale)
{
  QImage image = *source;
  QPixmap pixmap = QPixmap::fromImage(image);
  QPainter painter(&pixmap);

  QColor selectionBorderColor = QColor(0, 0, 248, 128);
  QBrush selectionFillBrush(QColor(64, 128, 248, 128));

  QTransform transform;
  transform = transform.scale((float)scale, (float)scale);
  painter.setTransform(transform);

  painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
  painter.setRenderHint(QPainter::Antialiasing, false);
  painter.setRenderHint(QPainter::HighQualityAntialiasing, false);
  painter.setPen(selectionBorderColor);
  painter.setBrush(selectionFillBrush);

  painter.fillPath(selectedPath, selectionFillBrush);

  if (scale > 5) {
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::HighQualityAntialiasing, true);

    QPainterPathStroker stroker;
    float offset = 1.0f / (float)scale;
    stroker.setWidth(offset * 2.0f);
    stroker.setJoinStyle(Qt::RoundJoin);
    stroker.setDashPattern(Qt::DashLine);

    QPainterPath strokedPath = stroker.createStroke(selectedPath);
    painter.fillPath(strokedPath, QBrush(selectionBorderColor));
  }

  return pixmap.toImage();
}
void PathStrokeRenderer::paint(QPainter *painter)
{
    if (m_points.isEmpty())
        initializePoints();

    painter->setRenderHint(QPainter::Antialiasing);

    QPalette pal = palette();
    painter->setPen(Qt::NoPen);

    // Construct the path
    QPainterPath path;
    path.moveTo(m_points.at(0));

    if (m_pathMode == LineMode) {
        for (int i=1; i<m_points.size(); ++i)
            path.lineTo(m_points.at(i));
    } else {
        int i=1;
        while (i + 2 < m_points.size()) {
            path.cubicTo(m_points.at(i), m_points.at(i+1), m_points.at(i+2));
            i += 3;
        }
        while (i < m_points.size()) {
            path.lineTo(m_points.at(i));
            ++i;
        }
    }

    // Draw the path
    {
        QColor lg = Qt::red;

        // The "custom" pen
        if (m_penStyle == Qt::NoPen) {
            QPainterPathStroker stroker;
            stroker.setWidth(m_penWidth);
            stroker.setJoinStyle(m_joinStyle);
            stroker.setCapStyle(m_capStyle);

            QVector<qreal> dashes;
            qreal space = 4;
            dashes << 1 << space
                   << 3 << space
                   << 9 << space
                   << 27 << space
                   << 9 << space
                   << 3 << space;
            stroker.setDashPattern(dashes);
            QPainterPath stroke = stroker.createStroke(path);
            painter->fillPath(stroke, lg);

        } else {
            QPen pen(lg, m_penWidth, m_penStyle, m_capStyle, m_joinStyle);
            painter->strokePath(path, pen);
        }
    }

    if (1) {
        // Draw the control points
        painter->setPen(QColor(50, 100, 120, 200));
        painter->setBrush(QColor(200, 200, 210, 120));
        for (int i=0; i<m_points.size(); ++i) {
            QPointF pos = m_points.at(i);
            painter->drawEllipse(QRectF(pos.x() - m_pointSize,
                                       pos.y() - m_pointSize,
                                       m_pointSize*2, m_pointSize*2));
        }
        painter->setPen(QPen(Qt::lightGray, 0, Qt::SolidLine));
        painter->setBrush(Qt::NoBrush);
        painter->drawPolyline(m_points);
    }

}
예제 #11
0
bool PathStrokerPlugin::run(ScribusDoc* doc, QString)
{
	ScribusDoc* currDoc = doc;
	if (currDoc == 0)
		currDoc = ScCore->primaryMainWindow()->doc;
	if (currDoc->m_Selection->count() > 0)
	{
		QVector<double> m_array;
		PageItem *currItem = currDoc->m_Selection->itemAt(0);
		FPointArray path = currItem->PoLine;
		QPainterPath pp;
		if (currItem->itemType() == PageItem::PolyLine)
			pp = path.toQPainterPath(false);
		else
			pp = path.toQPainterPath(true);
		if (currItem->NamedLStyle.isEmpty())
		{
			QPainterPathStroker stroke;
			stroke.setCapStyle(currItem->lineEnd());
			stroke.setJoinStyle(currItem->lineJoin());
			if (currItem->lineStyle() == Qt::SolidLine)
				stroke.setDashPattern(currItem->lineStyle());
			else
			{
				getDashArray(currItem->lineStyle(), 1, m_array);
				stroke.setDashPattern(m_array);
			}
			stroke.setWidth(currItem->lineWidth());
			QPainterPath result = stroke.createStroke(pp).simplified();
			if (currItem->startArrowIndex() != 0)
			{
				FPoint Start = currItem->PoLine.point(0);
				for (uint xx = 1; xx < currItem->PoLine.size(); xx += 2)
				{
					FPoint Vector = currItem->PoLine.point(xx);
					if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
					{
						double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
						QMatrix arrowTrans;
						FPointArray arrow = currDoc->arrowStyles.at(currItem->startArrowIndex()-1).points.copy();
						arrowTrans.translate(Start.x(), Start.y());
						arrowTrans.rotate(r);
						arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
						arrow.map(arrowTrans);
						result.addPath(arrow.toQPainterPath(true));
						break;
					}
				}
			}
			if (currItem->endArrowIndex() != 0)
			{
				FPoint End = currItem->PoLine.point(currItem->PoLine.size()-2);
				for (uint xx = currItem->PoLine.size()-1; xx > 0; xx -= 2)
				{
					FPoint Vector = currItem->PoLine.point(xx);
					if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
					{
						double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
						QMatrix arrowTrans;
						FPointArray arrow = currDoc->arrowStyles.at(currItem->endArrowIndex()-1).points.copy();
						arrowTrans.translate(End.x(), End.y());
						arrowTrans.rotate(r);
						arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
						arrow.map(arrowTrans);
						result.addPath(arrow.toQPainterPath(true));
						break;
					}
				}
			}
			currDoc->m_Selection->clear();
			PageItem* newItem = currDoc->convertItemTo(currItem, PageItem::Polygon);
			newItem->setLineWidth(0);
			newItem->setLineStyle(Qt::SolidLine);
			newItem->setFillColor(newItem->lineColor());
			newItem->setFillShade(newItem->lineShade());
			newItem->setFillTransparency(newItem->lineTransparency());
			newItem->setFillBlendmode(newItem->lineBlendmode());
			FPointArray points;
			points.fromQPainterPath(result);
			newItem->PoLine = points;
			newItem->Frame = false;
			newItem->ClipEdited = true;
			newItem->FrameType = 3;
			currDoc->AdjustItemSize(newItem);
			newItem->OldB2 = newItem->width();
			newItem->OldH2 = newItem->height();
			newItem->updateClip();
			newItem->ContourLine = newItem->PoLine.copy();
			newItem->setFillEvenOdd(true);
			currDoc->m_Selection->addItem(newItem);
		}
		else
		{
			currDoc->m_Selection->clear();
			multiLine ml = currDoc->MLineStyles[currItem->NamedLStyle];
			bool first = true;
			for (int it = ml.size()-1; it > -1; it--)
			{
				if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
				{
					QPainterPathStroker stroke;
					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[it].LineEnd));
					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[it].LineJoin));
					if (static_cast<Qt::PenStyle>(ml[it].Dash) == Qt::SolidLine)
						stroke.setDashPattern(static_cast<Qt::PenStyle>(ml[it].Dash));
					else
					{
						getDashArray(static_cast<Qt::PenStyle>(ml[it].Dash), 1, m_array);
						stroke.setDashPattern(m_array);
					}
					stroke.setWidth(ml[it].Width);
					QPainterPath result = stroke.createStroke(pp).simplified();
					PageItem* newItem;
					if (first)
					{
						newItem = currDoc->convertItemTo(currItem, PageItem::Polygon);
					}
					else
					{
						newItem = new PageItem_Polygon(*currItem);
						newItem->convertTo(PageItem::Polygon);
						currDoc->Items->append(newItem);
					}
					first = false;
					newItem->ItemNr = currDoc->Items->count()-1;
					newItem->setLineStyle(Qt::SolidLine);
					newItem->setFillColor(ml[it].Color);
					newItem->setFillShade(ml[it].Shade);
					newItem->setFillTransparency(newItem->lineTransparency());
					newItem->setFillBlendmode(newItem->lineBlendmode());
					newItem->setLineColor(CommonStrings::None);
					newItem->setCustomLineStyle("");
					FPointArray points;
					points.fromQPainterPath(result);
					newItem->PoLine = points;
					newItem->Frame = false;
					newItem->ClipEdited = true;
					newItem->FrameType = 3;
					currDoc->AdjustItemSize(newItem);
					newItem->OldB2 = newItem->width();
					newItem->OldH2 = newItem->height();
					newItem->updateClip();
					newItem->ContourLine = newItem->PoLine.copy();
					newItem->setFillEvenOdd(true);
					currDoc->m_Selection->addItem(newItem);
				}
			}
			if (currItem->startArrowIndex() != 0)
			{
				FPoint Start = currItem->PoLine.point(0);
				for (uint xx = 1; xx < currItem->PoLine.size(); xx += 2)
				{
					FPoint Vector = currItem->PoLine.point(xx);
					if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
					{
						double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
						QMatrix arrowTrans;
						FPointArray arrow = currDoc->arrowStyles.at(currItem->startArrowIndex()-1).points.copy();
						arrowTrans.translate(Start.x(), Start.y());
						arrowTrans.rotate(r);
						arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
						arrow.map(arrowTrans);
						PageItem* newItem = new PageItem_Polygon(*currItem);
						currDoc->Items->append(newItem);
						newItem->ItemNr = currDoc->Items->count()-1;
						newItem->setLineWidth(0);
						newItem->setLineStyle(Qt::SolidLine);
						newItem->setCustomLineStyle("");
						newItem->setFillColor(newItem->lineColor());
						newItem->setFillShade(newItem->lineShade());
						newItem->setFillTransparency(newItem->lineTransparency());
						newItem->setFillBlendmode(newItem->lineBlendmode());
						newItem->PoLine = arrow;
						newItem->Frame = false;
						newItem->ClipEdited = true;
						newItem->FrameType = 3;
						currDoc->AdjustItemSize(newItem);
						newItem->OldB2 = newItem->width();
						newItem->OldH2 = newItem->height();
						newItem->updateClip();
						newItem->ContourLine = newItem->PoLine.copy();
						newItem->setFillEvenOdd(true);
						currDoc->m_Selection->addItem(newItem);
						break;
					}
				}
			}
			if (currItem->endArrowIndex() != 0)
			{
				FPoint End = currItem->PoLine.point(currItem->PoLine.size()-2);
				for (uint xx = currItem->PoLine.size()-1; xx > 0; xx -= 2)
				{
					FPoint Vector = currItem->PoLine.point(xx);
					if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
					{
						double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
						QMatrix arrowTrans;
						FPointArray arrow = currDoc->arrowStyles.at(currItem->endArrowIndex()-1).points.copy();
						arrowTrans.translate(End.x(), End.y());
						arrowTrans.rotate(r);
						arrowTrans.scale(currItem->lineWidth(), currItem->lineWidth());
						arrow.map(arrowTrans);
						PageItem* newItem = new PageItem_Polygon(*currItem);
						currDoc->Items->append(newItem);
						newItem->ItemNr = currDoc->Items->count()-1;
						newItem->setLineWidth(0);
						newItem->setLineStyle(Qt::SolidLine);
						newItem->setCustomLineStyle("");
						newItem->setFillColor(newItem->lineColor());
						newItem->setFillShade(newItem->lineShade());
						newItem->setFillTransparency(newItem->lineTransparency());
						newItem->setFillBlendmode(newItem->lineBlendmode());
						newItem->PoLine = arrow;
						newItem->Frame = false;
						newItem->ClipEdited = true;
						newItem->FrameType = 3;
						currDoc->AdjustItemSize(newItem);
						newItem->OldB2 = newItem->width();
						newItem->OldH2 = newItem->height();
						newItem->updateClip();
						newItem->ContourLine = newItem->PoLine.copy();
						newItem->setFillEvenOdd(true);
						currDoc->m_Selection->addItem(newItem);
						break;
					}
				}
			}
			if (currDoc->m_Selection->count() > 1)
				currDoc->itemSelection_GroupObjects(false, false);
			currDoc->m_Selection->itemAt(0)->emitAllToGUI();
		}
		currDoc->changed();
	}
	return true;
}