/** * Inserts a point at the given index. */ bool LinePath::insertPoint( int pointIndex, const QPoint &point ) { int count = m_LineList.count(); if( count == 0 ) return false; const bool bLoading = UMLApp::app()->document()->loading(); if( count == 1 || pointIndex == 1) { Q3CanvasLine * first = m_LineList.first(); QPoint sp = first -> startPoint(); QPoint ep = first -> endPoint(); first -> setPoints( sp.x(), sp.y(), point.x(), point.y() ); Q3CanvasLine * line = new Q3CanvasLine( getScene() ); line -> setZ( -2 ); line -> setPoints( point.x(), point.y(), ep.x(), ep.y() ); line -> setPen( getPen() ); line -> setVisible( true ); m_LineList.insert( 1, line ); if (!bLoading) setupSelected(); return true; } if( count + 1 == pointIndex ) { Q3CanvasLine * before = m_LineList.last(); QPoint sp = before -> startPoint(); QPoint ep = before -> endPoint(); before -> setPoints( sp.x(), sp.y(), point.x(), point.y() ); Q3CanvasLine * line = new Q3CanvasLine( getScene() ); line -> setPoints( point.x(), point.y(), ep.x(), ep.y() ); line -> setZ( -2 ); line -> setPen( getPen() ); line -> setVisible( true ); m_LineList.append( line ); if (!bLoading) setupSelected(); return true; } Q3CanvasLine * before = m_LineList.at( pointIndex - 1 ); QPoint sp = before -> startPoint(); QPoint ep = before -> endPoint(); before -> setPoints( sp.x(), sp.y(), point.x(), point.y() ); Q3CanvasLine * line = new Q3CanvasLine(getScene() ); line -> setPoints( point.x(), point.y(), ep.x(), ep.y() ); line -> setZ( -2 ); line -> setPen( getPen() ); line -> setVisible( true ); m_LineList.insert( pointIndex, line ); if (!bLoading) setupSelected(); return true; }
//----------------------------------------------------------------------------- void GdiplusDrawContext::drawGraphicsPath (CGraphicsPath* _path, PathDrawMode mode, CGraphicsTransform* t) { GdiplusGraphicsPath* gdiPlusPath = dynamic_cast<GdiplusGraphicsPath*> (_path); if (gdiPlusPath && pGraphics) { GdiplusDrawScope drawScope (pGraphics, currentState.clipRect, getCurrentTransform ()); Gdiplus::GraphicsPath* path = gdiPlusPath->getGraphicsPath (); if (t) { Gdiplus::Matrix matrix; convert (matrix, *t); path = path->Clone (); path->Transform (&matrix); } if (mode == kPathStroked) { pGraphics->DrawPath (getPen (), path); } else { path->SetFillMode (mode == kPathFilledEvenOdd ? Gdiplus::FillModeAlternate : Gdiplus::FillModeWinding); pGraphics->FillPath (getBrush (), path); } if (path != gdiPlusPath->getGraphicsPath ()) delete path; } }
void RGraphicsSceneQt::exportPainterPaths(const QList<RPainterPath>& paths) { if (getEntity() == NULL && !exportToPreview) { qWarning("RGraphicsSceneQt::exportPainterPaths: entity is NULL"); return; } RPainterPath path; for (int i=0; i<paths.size(); i++) { path = paths.at(i); path.setZLevel(0); path.setBrush(getBrush(path)); if (path.getInheritPen()) { path.setPen(currentPainterPath.getPen()); } else { path.setPen(getPen(path)); } if (!exportToPreview) { // export into current path (used for complex linetypes): if (currentPainterPath.isValid()) { currentPainterPath.addPath(path); } else { addPath(getBlockRefOrEntity()->getId(), path, draftMode); } } else { addToPreview(path); } } }
void QRenderConverter::applyStyle(QGraphicsPathItem* item, const CLBoundingBox* bounds, const CLGroup *group, const CLRenderResolver* resolver, QGraphicsItemGroup* itemGroup) { if (resolver == NULL || group == NULL || bounds == NULL || item == NULL) return; QPen *pen = getPen(NULL, group, resolver, bounds); item->setPen(*pen); delete pen; if (item->path().elementCount() < 2) return; QPointF start = item->path().elementAt(0); QPointF second = item->path().elementAt(1); QPointF end = item->path().elementAt(item->path().elementCount() - 1); QPointF secondLast = item->path().elementAt(item->path().elementCount() - 2); if (group -> isSetStartHead()) { const CLLineEnding *line = resolver->getLineEnding(group->getStartHead()); addLineEndingToItem(item, line, group, resolver, start, second, itemGroup); } if (group->isSetEndHead()) { const CLLineEnding *line = resolver->getLineEnding(group->getEndHead()); addLineEndingToItem(item, line, group, resolver, end, secondLast, itemGroup); } }
void IntervalProgressDisplay::EllipticalPaintStrategy::drawCircles(QPainter &p, const QRectF &rect, const PaintContext &context, const PaintColors &colors, int beatsToDraw, int beatsToDrawOffset, bool drawPath) { if (drawPath) { paintEllipticalPath(p, rect, colors, context.currentBeat, beatsToDraw); } qreal angleIncrement = (2 * -PI) / beatsToDraw; double angle = -PI/2 + angleIncrement; qreal hRadius = rect.width()/2; qreal vRadius = rect.height()/2; qreal centerX = rect.center().x(); qreal centerY = rect.center().y(); for (int beat = beatsToDraw-1; beat >= 0; --beat) { // draw the current beat if (beat + beatsToDrawOffset >= context.currentBeat) { qreal x = centerX + ((hRadius) * std::cos(angle)); qreal y = centerY + ((vRadius) * std::sin(angle)); p.setBrush(getBrush(beat, beatsToDrawOffset, context, colors)); p.setPen(getPen(beat, beatsToDrawOffset, context)); qreal size = getCircleSize(beat, beatsToDrawOffset, context); p.drawEllipse(QPointF(x, y), size, size); } angle += angleIncrement; } }
void fillItemFromCurve(QGraphicsItemGroup *item, const CLBoundingBox *pBB, const CLCurve* pCurve, const CLGroup *group, const CLRenderResolver* resolver) { QPainterPath path; if (!pCurve->isContinuous()) { for (size_t i = 0; i < pCurve->getNumCurveSegments(); ++i) { const CLLineSegment* current = pCurve->getSegmentAt(i); path.moveTo(current->getStart().getX(), current->getStart().getY()); if (current->isBezier()) { path.cubicTo( current->getBase1().getX(), current->getBase1().getY(), current->getBase2().getX(), current->getBase2().getY(), current->getEnd().getX(), current->getEnd().getY()); } else { path.lineTo( current->getEnd().getX(), current->getEnd().getY()); } } } else if (pCurve->getListOfPoints().size() > 0) { for (size_t i = 0; i < pCurve->getNumCurveSegments(); ++i) { const CLLineSegment* current = pCurve->getSegmentAt(i); if (i == 0) path.moveTo(current->getStart().getX(), current->getStart().getY()); if (current->isBezier()) { path.cubicTo( current->getBase1().getX(), current->getBase1().getY(), current->getBase2().getX(), current->getBase2().getY(), current->getEnd().getX(), current->getEnd().getY()); } else { path.lineTo( current->getEnd().getX(), current->getEnd().getY()); } } } else return; QGraphicsPathItem *pathItem = new QGraphicsPathItem(path); QPen *pen = getPen(NULL, group, resolver, pBB); pathItem->setPen(*pen); delete pen; //QBrush *brush = getBrush(NULL, group, resolver, pBB); //pathItem->setBrush(*brush); //delete brush; item->addToGroup(pathItem); }
/** * Draws a line from (x1, y1) to (x2, y2). */ void RS_PainterQt::drawLine(const RS_Vector& p1, const RS_Vector& p2) { #ifdef __APPLE1__ int w2 = (int)getPen().getScreenWidth()/2; QPainter::drawLine(toScreenX(p1.x-w2), toScreenY(p1.y-w2), toScreenX(p2.x-w2), toScreenY(p2.y-w2)); #else QPainter::drawLine(toScreenX(p1.x), toScreenY(p1.y), toScreenX(p2.x), toScreenY(p2.y)); #endif }
/** * @return Factor for scaling the line styles considering the current * paper scaling and the fact that styles are stored in Millimeter. */ double RS_Entity::getStyleFactor(RS_GraphicView* view) { double styleFactor = 1.0; if (view!=NULL) { if (view->isPrinting()==false && view->isDraftMode()) { styleFactor = 1.0/view->getFactor().x; } else { //styleFactor = getStyleFactor(); // the factor caused by the unit: RS2::Unit unit = RS2::None; RS_Graphic* g = getGraphic(); if (g!=NULL) { unit = g->getUnit(); //double scale = g->getPaperScale(); styleFactor = RS_Units::convert(1.0, RS2::Millimeter, unit); // / scale; } // the factor caused by the line width: if (((int)getPen(true).getWidth())>0) { styleFactor *= ((double)getPen(true).getWidth()/100.0); } else if (((int)getPen(true).getWidth())==0) { styleFactor *= 0.01; } } if (view->isPrinting() || view->isPrintPreview() || view->isDraftMode()==false) { RS_Graphic* graphic = getGraphic(); if (graphic!=NULL && graphic->getPaperScale()>1.0e-6) { styleFactor /= graphic->getPaperScale(); } } } //RS_DEBUG->print("stylefactor: %f", styleFactor); //RS_DEBUG->print("viewfactor: %f", view->getFactor().x); if (styleFactor*view->getFactor().x<0.2) { styleFactor = -1.0; } return styleFactor; }
void ObjectFlatten::close () { if (!penDown) return; Vec2 t0 = transform( getPen() ); Vec2 t1 = transform( getStart() ); getObject()->lines.push_back( Line( t0.x,t0.y, t1.x,t1.y )); penDown = false; }
void ObjectFlatten::lineTo (const Vec2 &p1, int space) { if (!penDown) return; Vec2 t0 = transform( getPen() ); Vec2 t1 = transform( p1 ); getObject()->lines.push_back( Line( t0.x,t0.y, t1.x,t1.y )); getObject()->contourPoints.push_back( t1 ); getObject()->contours.back().length++; }
void LC_PenWizard::selectByColor(QColor color) { auto graphic = mdi_win->getGraphic(); foreach (auto e, graphic->getEntityList()) { if (e->getPen().getColor().name() == color.name()) { e->setSelected(true); } } mdi_win->getGraphicView()->redraw(RS2::RedrawDrawing); }
void ObjectFlatten::quadTo (const Vec2 &p1, const Vec2 &p2, int space) { if (!penDown) return; Vec2 t0 = transform( getPen() ); Vec2 t1 = transform( p1 ); Vec2 t2 = transform( p2 ); getObject()->quads.push_back( Quad( t0.x,t0.y, t1.x,t1.y, t2.x,t2.y )); getObject()->contourPoints.push_back( t2 ); getObject()->contours.back().length++; }
void ObjectFlatten::cubicTo (const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, int space) { if (!penDown) return; Vec2 t0 = transform( getPen() ); Vec2 t1 = transform( p1 ); Vec2 t2 = transform( p2 ); Vec2 t3 = transform( p3 ); getObject()->cubics.push_back( Cubic( t0.x,t0.y, t1.x,t1.y, t2.x,t2.y, t3.x,t3.y )); getObject()->contourPoints.push_back( t2 ); getObject()->contours.back().length++; }
void LinePath::activate() { int count = m_LineList.count(); if (count == 0) return; QCanvas * canvas = getCanvas(); if (canvas == NULL) return; for (int i = 0; i < count ; i++) { QCanvasLine *line = m_LineList.at(i); line -> setCanvas( canvas ); line -> setPen( getPen() ); } }
void CubicsToQuads::cubicTo (const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, int space) { Cubic cubic; cubic.p0 = getPen(); cubic.p1 = p1; cubic.p2 = p2; cubic.p3 = p3; quads.clear(); cubicToQuads( cubic, quads ); for (Uint32 q=0; q<quads.size(); ++q) { Quad quad = quads[q]; ObjectClone::quadTo( quad.p1, quad.p2, space ); } }
void Drawing::onDraw(HDC &hdc) { HPEN hPenOld; // Draw a red line HPEN hLinePen; hLinePen = getPen(); hPenOld = (HPEN)SelectObject(hdc, hLinePen); SelectObject(hdc, CreateSolidBrush(this->penColor)); draw(hdc); SelectObject(hdc, hPenOld); DeleteObject(hLinePen); }
/** * Sets the start and end points. */ bool LinePath::setStartEndPoints( const QPoint &start, const QPoint &end ) { int count = m_LineList.count(); if( count == 0 ) { Q3CanvasLine * line = new Q3CanvasLine(getScene() ); line -> setPoints( start.x(), start.y(),end.x(),end.y() ); line -> setZ( -2 ); line -> setPen( getPen() ); line -> setVisible( true ); m_LineList.append( line ); return true; } bool status = setPoint( 0, start ); if( status) return setPoint(count,end); return false; }
void fillItemFromPolygon(QGraphicsItemGroup *item, const CLBoundingBox *pBB, const CLPolygon* pPoly, const CLGroup *group, const CLRenderResolver* resolver) { QPainterPath& path = *getPath(pPoly, pBB); path.setFillRule(Qt::WindingFill); if (pPoly->isSetFillRule()) { switch (pPoly->getFillRule()) { case CLGraphicalPrimitive2D::EVENODD: path.setFillRule(Qt::OddEvenFill); break; case CLGraphicalPrimitive2D::NONZERO: default: path.setFillRule(Qt::WindingFill); break; } } if (group->isSetFillRule()) { switch (group->getFillRule()) { case CLGraphicalPrimitive2D::EVENODD: path.setFillRule(Qt::OddEvenFill); break; case CLGraphicalPrimitive2D::NONZERO: default: path.setFillRule(Qt::WindingFill); break; } } QGraphicsPathItem *pathItem = new QGraphicsPathItem(path); QPen *pen = getPen(pPoly, group, resolver, pBB); pathItem->setPen(*pen); delete pen; QBrush *brush = getBrush(pPoly, group, resolver, pBB); pathItem->setBrush(*brush); delete brush; transform(pathItem, pPoly, group); item->addToGroup(pathItem); }
void LinePath::setAssocType( Uml::Association_Type type ) { LineListIt it( m_LineList ); QCanvasLine * line = 0; while( ( line = it.current() ) ) { line -> setPen( getPen() ); ++it; } if( m_pClearPoly ) { delete m_pClearPoly; m_pClearPoly = 0; } if( type == Uml::at_Coll_Message ) setupParallelLine(); else createHeadLines(); update(); }
void fillItemFromEllipse(QGraphicsItemGroup *item, const CLBoundingBox *pBB, const CLEllipse *pEllipse, const CLGroup *group, const CLRenderResolver* resolver) { double x = pBB->getPosition().getX() + pEllipse->getCX().getAbsoluteValue() + pEllipse->getCX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth(); double y = pBB->getPosition().getY() + pEllipse->getCY().getAbsoluteValue() + pEllipse->getCY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight(); double rx = pEllipse->getRX().getAbsoluteValue() + pEllipse->getRX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth(); double ry = pEllipse->getRY().getAbsoluteValue() + pEllipse->getRY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight(); QGraphicsEllipseItem* ellipseItem = new QGraphicsEllipseItem( x - rx, y - ry, rx * 2, ry * 2); QPen *pen = getPen(pEllipse, group, resolver, pBB); ellipseItem->setPen(*pen); delete pen; QBrush *brush = getBrush(pEllipse, group, resolver, pBB); ellipseItem->setBrush(*brush); delete brush; transform(ellipseItem, pEllipse, group); item->addToGroup(ellipseItem); }
/** * Sets the Association type. */ void LinePath::setAssocType( Uml::Association_Type type ) { QList<Q3CanvasLine*>::Iterator it = m_LineList.begin(); QList<Q3CanvasLine*>::Iterator end = m_LineList.end(); for( ; it != end; ++it ) (*it) -> setPen( getPen() ); delete m_pClearPoly; m_pClearPoly = 0; if( type == Uml::at_Coll_Message ) { setupParallelLine(); } else { createHeadLines(); createSubsetSymbol(); } update(); }
void fillItemFromRectangle(QGraphicsItemGroup *item, const CLBoundingBox *pBB, const CLRectangle *pRect, const CLGroup *group, const CLRenderResolver* resolver) { double x = pBB->getPosition().getX() + pRect->getX().getAbsoluteValue() + pRect->getX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth(); double y = pBB->getPosition().getY() + pRect->getY().getAbsoluteValue() + pRect->getY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight(); double w = pRect->getWidth().getAbsoluteValue() + pRect->getWidth().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth(); double h = pRect->getHeight().getAbsoluteValue() + pRect->getHeight().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight(); double rx = pRect->getRadiusX().getAbsoluteValue() + pRect->getRadiusX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth(); double ry = pRect->getRadiusY().getAbsoluteValue() + pRect->getRadiusY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight(); QGraphicsRectItem* result = new QRoundedRect( x, y, w, h, rx, ry); QPen *pen = getPen(pRect, group, resolver, pBB); result->setPen(*pen); delete pen; QBrush *brush = getBrush(pRect, group, resolver, pBB); result->setBrush(*brush); delete brush; transform(result, pRect, group); item->addToGroup(result); }
void fillItemFromRenderCurve(QGraphicsItemGroup *item, const CLBoundingBox *pBB, const CLRenderCurve* pCurve, const CLGroup *group, const CLRenderResolver* resolver) { QPainterPath& path = *getPath(pCurve, pBB); QGraphicsPathItem *pathItem = new QGraphicsPathItem(path); QPen *pen = getPen(pCurve, group, resolver, pBB); pathItem->setPen(*pen); delete pen; item->addToGroup(pathItem); //QBrush *brush = getBrush(NULL, group, resolver, pBB); //pathItem->setBrush(*brush); //delete brush; if (path.elementCount() > 1) { if (group -> isSetStartHead()) { const CLLineEnding *line = resolver->getLineEnding(group->getStartHead()); addLineEndingToItem(pathItem, line, group, resolver, path.elementAt(0), path.elementAt(1), item); } else if (pCurve->isSetStartHead()) { const CLLineEnding *line = resolver->getLineEnding(pCurve->getStartHead()); addLineEndingToItem(pathItem, line, line->getGroup(), resolver, path.elementAt(0), path.elementAt(1), item); } if (group->isSetEndHead()) { const CLLineEnding *line = resolver->getLineEnding(group->getEndHead()); addLineEndingToItem(pathItem, line, group, resolver, path.elementAt(path.elementCount() - 1), path.elementAt(path.elementCount() - 2), item); } else if (pCurve->isSetEndHead()) { const CLLineEnding *line = resolver->getLineEnding(pCurve->getEndHead()); addLineEndingToItem(pathItem, line, line->getGroup(), resolver, path.elementAt(path.elementCount() - 1), path.elementAt(path.elementCount() - 2), item); } } transform(pathItem, pCurve, group); }
/** * Updates the entity buffer of this insert entity. This method * needs to be called whenever the block this insert is based on changes. */ void RS_Insert::update() { RS_DEBUG->print("RS_Insert::update"); RS_DEBUG->print("RS_Insert::update: name: %s", data.name.toLatin1().data()); // RS_DEBUG->print("RS_Insert::update: insertionPoint: %f/%f", // data.insertionPoint.x, data.insertionPoint.y); if (updateEnabled==false) { return; } clear(); RS_Block* blk = getBlockForInsert(); if (blk==nullptr) { //return nullptr; RS_DEBUG->print("RS_Insert::update: Block is nullptr"); return; } if (isUndone()) { RS_DEBUG->print("RS_Insert::update: Insert is in undo list"); return; } if (fabs(data.scaleFactor.x)<1.0e-6 || fabs(data.scaleFactor.y)<1.0e-6) { RS_DEBUG->print("RS_Insert::update: scale factor is 0"); return; } RS_Pen tmpPen; /*QListIterator<RS_Entity> it = createIterator(); RS_Entity* e; while ( (e = it.current()) != nullptr ) { ++it;*/ RS_DEBUG->print("RS_Insert::update: cols: %d, rows: %d", data.cols, data.rows); RS_DEBUG->print("RS_Insert::update: block has %d entities", blk->count()); //int i_en_counts=0; for(auto e: *blk){ for (int c=0; c<data.cols; ++c) { // RS_DEBUG->print("RS_Insert::update: col %d", c); for (int r=0; r<data.rows; ++r) { // i_en_counts++; // RS_DEBUG->print("RS_Insert::update: row %d", r); if (e->rtti()==RS2::EntityInsert && data.updateMode!=RS2::PreviewUpdate) { // RS_DEBUG->print("RS_Insert::update: updating sub-insert"); ((RS_Insert*)e)->update(); } // RS_DEBUG->print("RS_Insert::update: cloning entity"); RS_Entity* ne; if ( (data.scaleFactor.x - data.scaleFactor.y)>1.0e-6) { if (e->rtti()== RS2::EntityArc) { RS_Arc* a= (RS_Arc*)e; ne = new RS_Ellipse(this, RS_EllipseData(a->getCenter(), RS_Vector(a->getRadius(), 0), 1, a->getAngle1(), a->getAngle2(), a->isReversed() )); ne->setLayer(e->getLayer()); ne->setPen(e->getPen(false)); } else if (e->rtti()== RS2::EntityCircle) { RS_Circle* a= (RS_Circle*)e; ne = new RS_Ellipse(this, RS_EllipseData(a->getCenter(), RS_Vector(a->getRadius(), 0), 1, 0.0,2.0*M_PI, false)); ne->setLayer(e->getLayer()); ne->setPen(e->getPen(false)); } else ne = e->clone(); } else ne = e->clone(); ne->initId(); ne->setUpdateEnabled(false); // if entity layer are 0 set to insert layer to allow "1 layer control" bug ID #3602152 RS_Layer *l= ne->getLayer();//special fontchar block don't have if (l != nullptr && ne->getLayer()->getName() == "0") ne->setLayer(this->getLayer()); ne->setParent(this); ne->setVisible(getFlag(RS2::FlagVisible)); // RS_DEBUG->print("RS_Insert::update: transforming entity"); // Move: // RS_DEBUG->print("RS_Insert::update: move 1"); if (fabs(data.scaleFactor.x)>1.0e-6 && fabs(data.scaleFactor.y)>1.0e-6) { ne->move(data.insertionPoint + RS_Vector(data.spacing.x/data.scaleFactor.x*c, data.spacing.y/data.scaleFactor.y*r)); } else { ne->move(data.insertionPoint); } // Move because of block base point: // RS_DEBUG->print("RS_Insert::update: move 2"); ne->move(blk->getBasePoint()*-1); // Scale: // RS_DEBUG->print("RS_Insert::update: scale"); ne->scale(data.insertionPoint, data.scaleFactor); // Rotate: // RS_DEBUG->print("RS_Insert::update: rotate"); ne->rotate(data.insertionPoint, data.angle); // Select: ne->setSelected(isSelected()); // individual entities can be on indiv. layers tmpPen = ne->getPen(false); // color from block (free floating): if (tmpPen.getColor()==RS_Color(RS2::FlagByBlock)) { tmpPen.setColor(getPen().getColor()); } // line width from block (free floating): if (tmpPen.getWidth()==RS2::WidthByBlock) { tmpPen.setWidth(getPen().getWidth()); } // line type from block (free floating): if (tmpPen.getLineType()==RS2::LineByBlock) { tmpPen.setLineType(getPen().getLineType()); } // now that we've evaluated all flags, let's strip them: // TODO: strip all flags (width, line type) //tmpPen.setColor(tmpPen.getColor().stripFlags()); ne->setPen(tmpPen); ne->setUpdateEnabled(true); if (data.updateMode!=RS2::PreviewUpdate) { // RS_DEBUG->print("RS_Insert::update: updating new entity"); ne->update(); } // RS_DEBUG->print("RS_Insert::update: adding new entity"); appendEntity(ne); // std::cout<<"done # of entity: "<<i_en_counts<<std::endl; } } } calculateBorders(); RS_DEBUG->print("RS_Insert::update: OK"); }
void RS_Ellipse::draw(RS_Painter* painter, RS_GraphicView* view, double patternOffset) { if (painter==NULL || view==NULL) { return; } if (getPen().getLineType()==RS2::SolidLine || isSelected() || view->getDrawingMode()==RS2::ModePreview) { painter->drawEllipse(view->toGui(getCenter()), getMajorRadius() * view->getFactor().x, getMinorRadius() * view->getFactor().x, getAngle(), getAngle1(), getAngle2(), isReversed()); } else { double styleFactor = getStyleFactor(view); if (styleFactor<0.0) { painter->drawEllipse(view->toGui(getCenter()), getMajorRadius() * view->getFactor().x, getMinorRadius() * view->getFactor().x, getAngle(), getAngle1(), getAngle2(), isReversed()); return; } // Pattern: RS_LineTypePattern* pat; if (isSelected()) { pat = &patternSelected; } else { pat = view->getPattern(getPen().getLineType()); } if (pat==NULL) { return; } // Pen to draw pattern is always solid: RS_Pen pen = painter->getPen(); pen.setLineType(RS2::SolidLine); painter->setPen(pen); double* da; // array of distances in x. int i; // index counter double length = getAngleLength(); // create pattern: da = new double[pat->num]; double tot=0.0; i=0; bool done = false; double curA = getAngle1(); double curR; RS_Vector cp = view->toGui(getCenter()); double r1 = getMajorRadius() * view->getFactor().x; double r2 = getMinorRadius() * view->getFactor().x; do { curR = sqrt(RS_Math::pow(getMinorRadius()*cos(curA), 2.0) + RS_Math::pow(getMajorRadius()*sin(curA), 2.0)); if (curR>1.0e-6) { da[i] = fabs(pat->pattern[i] * styleFactor) / curR; if (pat->pattern[i] * styleFactor > 0.0) { if (tot+fabs(da[i])<length) { painter->drawEllipse(cp, r1, r2, getAngle(), curA, curA + da[i], false); } else { painter->drawEllipse(cp, r1, r2, getAngle(), curA, getAngle2(), false); } } } curA+=da[i]; tot+=fabs(da[i]); done=tot>length; i++; if (i>=pat->num) { i=0; } } while(!done); delete[] da; } }
SDL_Texture * Painter::textToTexture(std::string text) { SDL_Surface *surface = getFont()->toSurface(text, getPen()); return SDL_CreateTextureFromSurface(renderer, surface); }
void RS_Line::draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) { if (painter==NULL || view==NULL) { return; } //only draw the visible portion of line QVector<RS_Vector> endPoints(0); RS_Vector vpMin(view->toGraph(0,view->getHeight())); RS_Vector vpMax(view->toGraph(view->getWidth(),0)); QPolygonF visualBox(QRectF(vpMin.x,vpMin.y,vpMax.x-vpMin.x, vpMax.y-vpMin.y)); if( getStartpoint().isInWindowOrdered(vpMin, vpMax) ) endPoints<<getStartpoint(); if( getEndpoint().isInWindowOrdered(vpMin, vpMax) ) endPoints<<getEndpoint(); if(endPoints.size()<2){ QVector<RS_Vector> vertex; for(unsigned short i=0;i<4;i++){ const QPointF& vp(visualBox.at(i)); vertex<<RS_Vector(vp.x(),vp.y()); } for(unsigned short i=0;i<4;i++){ RS_Line line(NULL,RS_LineData(vertex.at(i),vertex.at((i+1)%4))); auto&& vpIts=RS_Information::getIntersection(static_cast<RS_Entity*>(this), &line, true); if( vpIts.size()==0) continue; endPoints<<vpIts.get(0); } } if(endPoints.size()<2) return; if( (endPoints[0] - getStartpoint()).squared() > (endPoints[1] - getStartpoint()).squared() ) std::swap(endPoints[0],endPoints[1]); RS_Vector pStart(view->toGui(endPoints.at(0))); RS_Vector pEnd(view->toGui(endPoints.at(1))); // std::cout<<"draw line: "<<pStart<<" to "<<pEnd<<std::endl; RS_Vector direction=pEnd-pStart; if(isHelpLayer(true) && direction.squared() > RS_TOLERANCE){ //extend line on a help layer to fill the whole view RS_Vector lb(0,0); RS_Vector rt(view->getWidth(),view->getHeight()); QList<RS_Vector> rect; rect<<lb<<RS_Vector(rt.x,lb.y); rect<<rt<<RS_Vector(lb.x,rt.y); rect<<lb; RS_VectorSolutions sol; RS_Line dLine(pStart,pEnd); for(int i=0;i<4;i++){ RS_Line bLine(rect.at(i),rect.at(i+1)); RS_VectorSolutions sol2=RS_Information::getIntersection(&bLine, &dLine); if( sol2.getNumber()>0 && bLine.isPointOnEntity(sol2.get(0),RS_TOLERANCE)) { sol.push_back(sol2.get(0)); } } switch(sol.getNumber()){ case 2: pStart=sol.get(0); pEnd=sol.get(1); break; case 3: case 4: pStart=sol.get(0); pEnd=sol.get(2); break; default: return; } direction=pEnd-pStart; } double length=direction.magnitude(); patternOffset -= length; if (( !isSelected() && ( getPen().getLineType()==RS2::SolidLine || view->getDrawingMode()==RS2::ModePreview)) ) { //if length is too small, attempt to draw the line, could be a potential bug painter->drawLine(pStart,pEnd); return; } // double styleFactor = getStyleFactor(view); // Pattern: RS_LineTypePattern* pat; if (isSelected()) { // styleFactor=1.; pat = &patternSelected; } else { pat = view->getPattern(getPen().getLineType()); } if (pat==NULL) { // patternOffset -= length; RS_DEBUG->print(RS_Debug::D_WARNING, "RS_Line::draw: Invalid line pattern"); painter->drawLine(pStart,pEnd); return; } // patternOffset = remainder(patternOffset - length-0.5*pat->totalLength,pat->totalLength)+0.5*pat->totalLength; if(length<=RS_TOLERANCE){ painter->drawLine(pStart,pEnd); return; //avoid division by zero } direction/=length; //cos(angle), sin(angle) // Pen to draw pattern is always solid: RS_Pen pen = painter->getPen(); pen.setLineType(RS2::SolidLine); painter->setPen(pen); // index counter int i; // pattern segment length: double patternSegmentLength = pat->totalLength; // create pattern: RS_Vector* dp=new RS_Vector[pat->num > 0?pat->num:0]; double* ds=new double[pat->num > 0?pat->num:0]; if (pat->num >0 ){ double dpmm=static_cast<RS_PainterQt*>(painter)->getDpmm(); for (i=0; i<pat->num; ++i) { // ds[j]=pat->pattern[i] * styleFactor; //fixme, styleFactor support needed ds[i]=dpmm*pat->pattern[i]; if( fabs(ds[i]) < 1. ) ds[i] = (ds[i]>=0.)?1.:-1.; dp[i] = direction*fabs(ds[i]); } }else { delete[] dp; delete[] ds; RS_DEBUG->print(RS_Debug::D_WARNING,"invalid line pattern for line, draw solid line instread"); painter->drawLine(view->toGui(getStartpoint()), view->toGui(getEndpoint())); return; } double total= remainder(patternOffset-0.5*patternSegmentLength,patternSegmentLength) -0.5*patternSegmentLength; // double total= patternOffset-patternSegmentLength; RS_Vector p1,p2,p3; RS_Vector curP(pStart+direction*total); double t2; for(int j=0;total<length;j=(j+1)%i) { // line segment (otherwise space segment) t2=total+fabs(ds[j]); p3=curP+dp[j]; if (ds[j]>0.0 && t2 > 0.0) { // drop the whole pattern segment line, for ds[i]<0: // trim end points of pattern segment line to line p1 =(total > -0.5)? curP:pStart; p2 =(t2<length+0.5)?p3:pEnd; painter->drawLine(p1,p2); } total=t2; curP=p3; } delete[] dp; delete[] ds; }
/** draw circle as a 2 pi arc */ void RS_Circle::draw(RS_Painter* painter, RS_GraphicView* view, double& patternOffset) { RS_Arc arc(getParent(), RS_ArcData(getCenter(),getRadius(),0.,2.*M_PI, false)); arc.setSelected(isSelected()); arc.setPen(getPen()); arc.draw(painter,view,patternOffset); }
void addLineEndingToItem(QGraphicsPathItem* item, const CLLineEnding* ending, const CLGroup* group, const CLRenderResolver* resolver, QPointF point, QPointF second, QGraphicsItemGroup* itemGroup) { const CLGroup* lineGroup = ending->getGroup(); for (size_t i = 0; i < lineGroup->getNumElements(); ++i) { const CLPolygon* poly = dynamic_cast<const CLPolygon*>(lineGroup->getElement(i)); const CLRenderCurve* rcurve = dynamic_cast<const CLRenderCurve*>(lineGroup->getElement(i)); const CLEllipse* ellipse = dynamic_cast<const CLEllipse*>(lineGroup->getElement(i)); const CLRectangle* rect = dynamic_cast<const CLRectangle*>(lineGroup->getElement(i)); if (rcurve != NULL) { QPainterPath path = item->path(); QPainterPath& linePath = *getPath(rcurve, ending->getBoundingBox()); applyRotationalMapping(linePath, ending, point, second); linePath.translate(point); path.addPath(linePath); item->setPath(path); } else if (poly != NULL) { QPainterPath path = item->path(); QPainterPath& linePath = *getPath(poly, ending->getBoundingBox()); applyRotationalMapping(linePath, ending, point, second); linePath.translate(point); path.addPath(linePath); item->setPath(path); if (poly->isSetFill() || group->isSetFill()) { QBrush* brush = getBrush(poly, ending->getGroup(), resolver, ending->getBoundingBox()); QPen* pen = getPen(poly, ending->getGroup(), resolver, ending->getBoundingBox()); linePath.setFillRule(Qt::WindingFill); if (poly->isSetFillRule()) { switch (poly->getFillRule()) { case CLGraphicalPrimitive2D::EVENODD: linePath.setFillRule(Qt::OddEvenFill); break; case CLGraphicalPrimitive2D::NONZERO: default: linePath.setFillRule(Qt::WindingFill); break; } } if (group->isSetFillRule()) { switch (group->getFillRule()) { case CLGraphicalPrimitive2D::EVENODD: linePath.setFillRule(Qt::OddEvenFill); break; case CLGraphicalPrimitive2D::NONZERO: default: linePath.setFillRule(Qt::WindingFill); break; } } QGraphicsPathItem* outline = new QGraphicsPathItem(linePath); outline->setPen(*pen); outline->setBrush(*brush); itemGroup->addToGroup(outline); } } else if (ellipse != NULL) { QPainterPath path = item->path(); QPainterPath& linePath = *getPath(ellipse, ending->getBoundingBox()); applyRotationalMapping(linePath, ending, point, second); linePath.translate(point); path.addPath(linePath); item->setPath(path); if (ellipse->isSetFill() || group->isSetFill()) { QBrush* brush = getBrush(ellipse, ending->getGroup(), resolver, ending->getBoundingBox()); QPen* pen = getPen(ellipse, ending->getGroup(), resolver, ending->getBoundingBox()); QGraphicsPathItem* outline = new QGraphicsPathItem(linePath); outline->setPen(*pen); outline->setBrush(*brush); itemGroup->addToGroup(outline); } } else if (rect != NULL) { QPainterPath path = item->path(); QPainterPath& linePath = *getPath(rect, ending->getBoundingBox()); applyRotationalMapping(linePath, ending, point, second); linePath.translate(point); path.addPath(linePath); item->setPath(path); if (rect->isSetFill() || group->isSetFill()) { QBrush* brush = getBrush(rect, ending->getGroup(), resolver, ending->getBoundingBox()); QPen* pen = getPen(rect, ending->getGroup(), resolver, ending->getBoundingBox()); QGraphicsPathItem* outline = new QGraphicsPathItem(linePath); outline->setPen(*pen); outline->setBrush(*brush); itemGroup->addToGroup(outline); } } } }
void RS_Arc::draw(RS_Painter* painter, RS_GraphicView* view, double /*patternOffset*/) { if (painter==NULL || view==NULL) { return; } //double styleFactor = getStyleFactor(); // simple style-less lines if (getPen().getLineType()==RS2::SolidLine || isSelected() || view->getDrawingMode()==RS2::ModePreview) { painter->drawArc(view->toGui(getCenter()), getRadius() * view->getFactor().x, getAngle1(), getAngle2(), isReversed()); } else { double styleFactor = getStyleFactor(view); if (styleFactor<0.0) { painter->drawArc(view->toGui(getCenter()), getRadius() * view->getFactor().x, getAngle1(), getAngle2(), isReversed()); return; } // Pattern: RS_LineTypePattern* pat; if (isSelected()) { pat = &patternSelected; } else { pat = view->getPattern(getPen().getLineType()); } if (pat==NULL) { return; } if (getRadius()<1.0e-6) { return; } // Pen to draw pattern is always solid: RS_Pen pen = painter->getPen(); pen.setLineType(RS2::SolidLine); painter->setPen(pen); double a1; double a2; if (data.reversed) { a2 = getAngle1(); a1 = getAngle2(); } else { a1 = getAngle1(); a2 = getAngle2(); } double* da; // array of distances in x. int i; // index counter double length = getAngleLength(); // create scaled pattern: da = new double[pat->num]; for (i=0; i<pat->num; ++i) { da[i] = fabs(pat->pattern[i] * styleFactor) / getRadius(); } double tot=0.0; i=0; bool done = false; double curA = a1; //double cx = getCenter().x * factor.x + offsetX; //double cy = - a->getCenter().y * factor.y + getHeight() - offsetY; RS_Vector cp = view->toGui(getCenter()); double r = getRadius() * view->getFactor().x; do { if (pat->pattern[i] > 0.0) { if (tot+da[i]<length) { painter->drawArc(cp, r, curA, curA + da[i], false); } else { painter->drawArc(cp, r, curA, a2, false); } } curA+=da[i]; tot+=da[i]; done=tot>length; i++; if (i>=pat->num) { i=0; } } while(!done); delete[] da; } }