Beispiel #1
0
    foreach ( SkyObject* obj, obs ) {
        bool visible = false;
        QPointF o = m_proj->toScreen( obj, true, &visible );
        if( !visible || !m_proj->onScreen(o) ) continue;

        float size = 20.;
        float x1 = o.x() - 0.5*size;
        float y1 = o.y() - 0.5*size;
        drawArc( QRectF(x1, y1, size, size), -60*16, 120*16 );
        drawArc( QRectF(x1, y1, size, size), 120*16, 120*16 );
    }
Beispiel #2
0
Adesk::Boolean SimpleDoubleGateDraw::subWorldDraw ( AcGiWorldDraw* mode )
{
    assertReadEnabled () ;

    drawArc( mode, m_insertPt, m_angle, m_gap, m_radius );
    drawLine( mode, m_insertPt, m_angle, m_gap, 0, m_length );

    drawArc( mode, m_insertPt, m_angle + PI, m_gap, m_radius );
    drawLine( mode, m_insertPt, m_angle + PI, m_gap, 0, m_length );

    return Adesk::kTrue;
}
Beispiel #3
0
// 円弧を描画(回転、拡大縮小つき)
// center_x, center_y  円の中心位置
// radius_x, radius_y  半径(横と縦)
// start_rad, end_rad  開始・終了角度
// division            円の分割数(数値が大きいと滑らかな円になる)
// line_width          線幅
// color               色
// angle_rad           回転角度(ラジアン)
// scaling             横、縦の拡大縮小率
// origin              矩形の原点位置
void drawArc(const float center_x, const float center_y,
             const float radius_x, const float radius_y,
             const float start_rad, const float end_rad,
             const int division,
             const float line_width,
             const Color& color,
             const float angle_rad,
             const Vec2f& scaling,
             const Vec2f& origin) {

  // 回転、拡大縮小の行列を生成
  auto matrix = transformMatrix2D(angle_rad,
                                  Vec3f(center_x, center_y, 0.0f),
                                  Vec3f(scaling.x(), scaling.y(), 1.0f));

  // 行列をOpenGLに設定
  glPushMatrix();
  glMultMatrixf(matrix.data());

  // 描画
  drawArc(-origin.x(), -origin.y(),
          radius_x, radius_y,
          start_rad, end_rad,
          division,
          line_width,
          color);

  // 行列を元に戻す
  glPopMatrix();
}
Beispiel #4
0
/**
 * Draws a circle.
 * @param cx center in x
 * @param cy center in y
 * @param radius Radius
 */
void RS_PainterQt::drawCircle(const RS_Vector& cp, double radius) {

// RVT_PORT    if (drawingMode==RS2::ModeXOR && radius<500) {
                if (radius<500) {
        // This is _very_ slow for large arcs:
        QPainter::drawEllipse(toScreenX(cp.x-radius),
                              toScreenY(cp.y-radius),
                              RS_Math::round(2.0*radius),
                              RS_Math::round(2.0*radius));
    } else {
#ifdef __APPLE1__
        drawArcMac(cp,
                radius,
                0.0, 2*M_PI,
                false);
#else
        drawArc(cp,
                radius,
                0.0, 2*M_PI,
                cp + RS_Vector(radius, 0.0),
                cp + RS_Vector(radius, 0.0),
                false);
#endif
        }
}
Beispiel #5
0
//-------------------------------------------------------------------------
//  draw the current shape
//-------------------------------------------------------------------------
void drawShape ()
{
	switch (currentShape)
	{
		case DRAW_OVAL:

			drawOval (0, 0, width[currentShape], height[currentShape], 
						segments[currentShape]);

			break;
		case FILL_OVAL:

			fillOval (0, 0, width[currentShape], height[currentShape], 
						segments[currentShape]);

			break;
		case DRAW_ARC:

			drawArc (0, 0, width[currentShape], height[currentShape], 
						startAngleW, arcAngleW, segments[currentShape]);

			break;
		case FILL_ARC:

			fillArc (0, 0, width[currentShape], height[currentShape], 
						startAngleF, arcAngleF, segments[currentShape]);

			break;
	}
}
Beispiel #6
0
Datei: 1-6.c Projekt: 2khc/UCL
int main(void)
{

  drawRect(20,20,100,100);

  drawArc(20,20,100,100,0,360);
}
Beispiel #7
0
int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
{
    BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
    DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
    BOARD_COMMIT commit( m_frame );

    SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ARC );

    m_frame->SetToolID( m_editModules ? ID_MODEDIT_ARC_TOOL : ID_PCB_ARC_BUTT,
            wxCURSOR_PENCIL, _( "Add graphic arc" ) );

    while( drawArc( arc ) )
    {
        if( arc )
        {
            commit.Add( arc );
            commit.Push( _( "Draw an arc" ) );
        }

        arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
    }

    m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );

    return 0;
}
Beispiel #8
0
/**
  * Aufforderung zur Neuzeichnung.
  * @param window     Verweis auf das Fenster, in dem die Figur
  *                   erscheinen soll.
  * @param cellWidth  Breite einer Zelle auf dem Spielfeld in Pixeln.
  * @param cellHeight Hoehe einer Zelle auf dem Spielfeld in Pixeln.
  */
void Cherry::draw(Gosu::Graphics& graphics, int cellWidth, int cellHeight) {
	// die Stiele
	for (int i = 0; i < 2; i++) {
		drawArc(graphics, Gosu::Color(255, 128, 64), cellWidth, cellHeight, false, Descriptor.stalks[ i ], 90, 70);
	}

	// die Fruechte selbst
	for (int i = 0; i < 2; i++) {
		drawArc(graphics, Gosu::Color(204, 0, 0), cellWidth, cellHeight, true, Descriptor.cherries[ i ], 0, 360);
	}

	// die Reflektionen auf den Fruechten
	for (int i = 0; i < 4; i++) {
		drawArc(graphics, Gosu::Color(255, 255, 255), cellWidth, cellHeight, true, Descriptor.reflection[ i ], 0, 360);
	}
}
Beispiel #9
0
int main(void) {

    setSize(900, 700);
    drawImage(150,0,700,500,"file:background.png");
    //Text
    setColourGradient("white","yellow");
    drawString(200,470,"H a p p y...W i n t e r");
    //SnowMan Body
    setColourGradient("gray","white");
    fillOval(440.0,160.0,65.0,60.0);
    fillOval(430.0,220.0,90.0,80.0);
    fillOval(400.0,300.0,150.0,160.0);
    //Facial Features
    setColourGradient("black","green");
    fillOval(455.0,175.0,10.0,10.0);
    fillOval(480.0,175.0,10.0,10.0);
    drawArc(470,200,20,50,30,40);
    //Hands
    setColour(white);
    drawLine(440,240,395,200);
    drawLine(520,240,565,200);
    //Accessories
    drawOval(472,235,10,10);
    drawOval(472,255,10,10);
    drawOval(472,275,10,10);
    return 0;
}
Beispiel #10
0
void swcRectangle::drawOuterCornerX(bool en_multisample)
{
    (en_multisample) ?  glEnable(GL_MULTISAMPLE_ARB) : glDisable(GL_MULTISAMPLE_ARB);

    //outer-border-corner-top-left
    if (radius_top_left == 0)
        drawTriRect(true,
            -border_size_left, -border_size_top, border_size_left, border_size_top,
            &border_colors[0], &border_colors[48], opacity);
    else
        drawArc(radius_top_left.x, radius_top_left.y, 180, 90,
            radius_top_left.x + border_size_left, radius_top_left.y + border_size_top,
            &border_colors[0], opacity);

    //outer-border-corner-top-right
    if (radius_top_right == 0)
        drawTriRect(false,
            width, -border_size_top, border_size_right, border_size_top,
            &border_colors[0], &border_colors[16], opacity);
    else
        drawArc(width - radius_top_right.x, radius_top_right.y, 90, 0,
            radius_top_right.x + border_size_right, radius_top_right.y + border_size_top,
            &border_colors[4], opacity);

    //outer-border-corner-bottom-right
    if (radius_bottom_right == 0)
        drawTriRect(true,
            width, height, border_size_right, border_size_bottom,
            &border_colors[16], &border_colors[32], opacity);
    else
        drawArc(width - radius_bottom_right.x, height - radius_bottom_right.y, 270, 360,
            radius_bottom_right.x + border_size_right, radius_bottom_right.y + border_size_bottom,
            &border_colors[12],opacity);

    //outer-border-corner-bottom-left
    if (radius_bottom_left == 0)
    drawTriRect(false,
            -border_size_left, height, border_size_left, border_size_bottom,
            &border_colors[48], &border_colors[32],
            opacity);
    else
        drawArc(radius_bottom_left.x, height - radius_bottom_left.y, 180, 270,
            radius_bottom_left.x + border_size_left, radius_bottom_left.y + border_size_bottom,
            &border_colors[20], opacity);

    if (en_multisample) glDisable(GL_MULTISAMPLE_ARB);
}
Beispiel #11
0
int main(void)
{
  drawOval(30,30,100,150);
  drawOval(0,0,499,299);
  
  drawArc(100,100,90,120,0,180);
  return 0;
}
int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
{
    if( m_editModules )
    {
        m_frame->SetToolID( ID_MODEDIT_ARC_TOOL, wxCURSOR_PENCIL, _( "Add graphic arc" ) );

        EDGE_MODULE* arc = new EDGE_MODULE( m_board->m_Modules );

        while( drawArc( reinterpret_cast<DRAWSEGMENT*&>( arc ) ) )
        {
            if( arc )
            {
                m_frame->OnModify();
                m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
                arc->SetParent( m_board->m_Modules );
                arc->SetLocalCoord();
                m_board->m_Modules->GraphicalItems().PushFront( arc );
            }

            arc = new EDGE_MODULE( m_board->m_Modules );
        }
    }
    else // !m_editModules case
    {
        m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) );

        DRAWSEGMENT* arc = new DRAWSEGMENT;

        while( drawArc( arc ) )
        {
            if( arc )
            {
                m_board->Add( arc );
                m_frame->OnModify();
                m_frame->SaveCopyInUndoList( arc, UR_NEW );
            }

            arc = new DRAWSEGMENT;
        }
    }

    m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );

    return 0;
}
Beispiel #13
0
int main(void) {


  drawArc(30, 30, 100, 100, 0, 360);
  drawRect(45, 45, 70, 70);


  return 0;
}
Beispiel #14
0
void myDisplay()
{
	glClear(GL_COLOR_BUFFER_BIT);	//Clear the screen and set color
	glColor3f(1.0, 0.0, 0.0);
	Point p(200, 200);
	drawArc(p, 100, 0, 400);
	glFlush();	//Send to the screen

}
Beispiel #15
0
void myDisplay()
{
	glClear(GL_COLOR_BUFFER_BIT);	//Clear the screen
	glColor3f(1.0, 0.0, 0.0);
	Point2 p(200, 200);
	drawArc(p, 100, 0, 400);

	glFlush();	//Send to the output screen from buffer

}
Beispiel #16
0
bool GiGraphics::drawArc3P(const GiContext* ctx, const Point2d& startpt, 
                           const Point2d& midpt, const Point2d& endpt, 
                           bool modelUnit)
{
    Point2d center;
    float r, startAngle, sweepAngle;
    
    return (mgcurv::arc3P(startpt, midpt, endpt, center, r, &startAngle, &sweepAngle)
            && drawArc(ctx, center, r, r, startAngle, sweepAngle, modelUnit));
}
Beispiel #17
0
void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
{
	struct arc a;

	a.xCenter = xCenter;
	a.yCenter = yCenter;
	a.radius = radius;
	a.startAngle = startAngle;
	a.sweep = sweep;
	a.negative = negative;
	drawArc(p, &a, uiDrawPathLineTo);
}
Beispiel #18
0
void WgtSonar::paintEvent(QPaintEvent *event) {
	QPainter *p = new QPainter(this);
	p->setRenderHint(QPainter::Antialiasing, true);
	
	p->setPen(QColor(255, 0, 0));
	p->setBrush(QColor(255, 0, 0));
	for(int i = 0; i < 7; i++)
		drawArc(rand()%120 + 50, i, p);
	
	p->setPen(QColor(200, 200, 200));
	for(int i = 1; i < 4; i++)
		drawCircle(i*40 + 50, p);
}
Beispiel #19
0
void swcRectangle::drawInnerCornerCurves(bool en_multisample)
{

    (en_multisample) ? glEnable(GL_MULTISAMPLE_ARB) : glDisable(GL_MULTISAMPLE_ARB);

    //border-radius-top-left
    drawArc(radius_top_left.x, radius_top_left.y, 180, 90,
            radius_top_left.x, radius_top_left.y,
            &colors[0], opacity);
    //border-radius-top-right
    drawArc(width - radius_top_right.x, radius_top_right.y, 90, 0,
            radius_top_right.x, radius_top_right.y,
            &colors[4], opacity);
    //border-radius-bottom-right
    drawArc(width - radius_bottom_right.x, height - radius_bottom_right.y, 270, 360,
            radius_bottom_right.x, radius_bottom_right.y,
            &colors[12], opacity);
    //border-radius-bottom-left
    drawArc(radius_bottom_left.x, height - radius_bottom_left.y, 180, 270,
            radius_bottom_left.x, radius_bottom_left.y,
            &colors[20], opacity);
    if (en_multisample) glDisable(GL_MULTISAMPLE_ARB);
}
Beispiel #20
0
void UBGraphicsCompass::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Selector &&
        UBDrawingController::drawingController ()->stylusTool() != UBStylusTool::Play)
        return;

    if (!mResizing && !mRotating && !mDrawing)
    {
        QGraphicsRectItem::mouseMoveEvent(event);
        mDrewCenterCross = false;
    }
    else
    {
        if (mResizing)
        {
            QPointF delta = event->pos() - event->lastPos();
            if (rect().width() + delta.x() < sMinRadius)
                delta.setX(sMinRadius - rect().width());
            setRect(QRectF(rect().topLeft(), QSizeF(rect().width() + delta.x(), rect().height())));
        }
        else
        {
            QLineF currentLine(needlePosition(), event->pos());
            QLineF lastLine(needlePosition(), event->lastPos());
            qreal deltaAngle = currentLine.angleTo(lastLine);
            if (deltaAngle > 180)
                deltaAngle -= 360;
            else if (deltaAngle < -180)
                deltaAngle += 360;
            rotateAroundNeedle(deltaAngle);

            if (mDrawing)
            {
                mSpanAngleInDegrees += deltaAngle;
                if (mSpanAngleInDegrees >= 1080)
                    mSpanAngleInDegrees -= 360;
                else if (mSpanAngleInDegrees < -1080)
                    mSpanAngleInDegrees += 360;
                drawArc();
            }
        }
        event->accept();
    }
}
Beispiel #21
0
void arco::paintEvent(QPaintEvent *e){
  QPainter painter(this);
  QPen pointPen(Qt::black);
  pointPen.setWidth(2);
  painter.setPen(pointPen);

  if (drawArcArco){
    QString radioStr = ui->radioTxt->toPlainText();
    QString anguloStr = ui->angulosTxt->toPlainText();

    if (!radioStr.isEmpty() && !anguloStr.isEmpty()) {
      angulo = anguloStr.toInt();
      radio = radioStr.toInt();
      for(int i=0; i<transforms.size(); ++i){
        painter.setTransform(transforms[i],true);
        drawArc(angulo, radio,painter);
     }
    }
  }
}
Beispiel #22
0
/**
  * Aufforderung zur Neuzeichnung.
  * @param window     Verweis auf das Fenster, in dem die Figur
  *                   erscheinen soll.
  * @param cellWidth  Breite einer Zelle auf dem Spielfeld in Pixeln.
  * @param cellHeight Hoehe einer Zelle auf dem Spielfeld in Pixeln.
  */
void Pacman::draw(Gosu::Graphics& graphics, int cellWidth, int cellHeight) 
{
	Gosu::Color foo(255, 255, 0);

	//this->spriteset[mouthStatus]->draw(4 + xOffset + this->cellX * cellWidth, 4 + yOffset + this->cellY * cellHeight, 2);

	/*graphics.drawQuad(xOffset + this->cellX * cellWidth, yOffset + this->cellY * cellHeight, foo,
					  xOffset + this->cellX * cellWidth + cellWidth, yOffset + this->cellY * cellHeight, foo,
					  xOffset + this->cellX * cellWidth, yOffset + this->cellY * cellHeight + cellHeight, foo,
					  xOffset + this->cellX * cellWidth + cellWidth, yOffset + this->cellY * cellHeight + cellHeight, foo, 3);*/
	drawArc(graphics, foo, cellWidth, cellHeight, true, Descriptor.circle, (mouthOpenAngle / 2 + getAngleFromDirection() * 90), (360 - mouthOpenAngle));

/*
	QPainter painter(window);
	// Zeichenfarbe setzen
	painter.setPen(QColor(255, 255, 0));
	painter.setBrush(Qt::SolidPattern);
	painter.setRenderHint(QPainter::Antialiasing);
	// Kreissegment zeichnen
	drawArc(painter, cellWidth, cellHeight,
			true, Descriptor.circle, (mouthOpenAngle / 2 + getAngleFromDirection() * 90), 
			(360 - mouthOpenAngle)); */
}
Beispiel #23
0
void HexEdge::redrawedge()
{
    double pc0[3], pc1[3];
    globalVertices->GetPoint(vertIds->GetId(0),pc0);
    globalVertices->GetPoint(vertIds->GetId(1),pc1);
    myPoints->SetPoint(0,pc0);
    switch(edgeType)
    {
    case LINE:
        myPoints->SetPoint(1,pc1);
        drawLine();
        break;
    case ARC:
        double c[3],arcpnt[3];
        myPoints->GetPoint(cntrlPointsIds->GetId(0),arcpnt);
        myPoints->SetPoint(arcNpoints-1,pc1);
        vtkMath::Solve3PointCircle(pc0,arcpnt,pc1,c);
        drawArc(c);
        break;
    }
    data->Modified();
    tube->Modified();
}
//Draws the 3D scene
void drawScene() {
	int i;
	//Clear information from last draw
	glClear(GL_COLOR_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
	glLoadIdentity(); //Reset the drawing perspective
	
	glColor3f(0.0f,0.0f,0.0f);
	glBegin(GL_QUADS);
	glVertex3f(-2.0f,-2.0f,-5.0f);
	glVertex3f(-2.0f,2.0f,-5.0f);
	glVertex3f(2.0f,2.0f,-5.0f);
	glVertex3f(2.0f,-2.0f,-5.0f);
	glEnd();//outer black quad
	
	glColor3f(0.99f, 0.84f, 0.61f);
	glBegin(GL_QUADS);
	glVertex3f(-1.8f,-1.8f,-5.0f);
	glVertex3f(-1.8f,1.8f,-5.0f);
	glVertex3f(1.8f,1.8f,-5.0f);
	glVertex3f(1.8f,-1.8f,-5.0f);
	glEnd();//board 
	
	glColor3f(0.0f,0.0f,0.0f);
	drawDisc(0.0f,0.0f,0.42f,1000);
	glColor3f(0.99f, 0.84f, 0.61f);
	drawDisc(0.0f,0.0f,0.40f,1000);
	glColor3f(0.0f, 0.0f, 0.0f);
	drawDisc(0.0f,0.0f,0.38f,1000);
	glColor3f(0.99f, 0.84f, 0.61f);
	drawDisc(0.0f,0.0f,0.36f,1000);//central circle
	
	glColor3f(0.0f,0.0f,0.0f);
	drawDisc(0.0f,0.0f,0.08f,1000);
	glColor3f(1.0f,0.0f,0.0f);
	drawDisc(0.0f,0.0f,0.06f,1000);//central disc
	
	
	
	drawCircle(0.0f,0.0f,0.08f);
	drawTri();//for stars
	
	for(i=0;i<4;i++){
	//symmetric codes
	glColor3f(0.52f, 0.37f, 0.26f);
	drawDisc(1.69f, 1.69f, 0.11f,1000);//holes
	
	//drawArc(0.6f,0.6f,0.2121f);
	glColor3f(0.0f, 0.0f, 0.0f);
	//drawArc(0.6f,0.6f,0.2121f);
	glBegin(GL_LINE_STRIP);
	glVertex3f(0.45f,0.45f,-5.0f);//45 degree line
	glVertex3f(1.4f,1.4f,-5.0f);
	glBegin(GL_LINE_STRIP);
	glVertex3f(1.4f,1.4f,-5.0f);//arrows
	glVertex3f(1.36f,1.4f,-5.0f);
	glVertex3f(1.4f,1.4f,-5.0f);//arrows
	glVertex3f(1.4f,1.36f,-5.0f);
	glEnd();
	drawArc(0.6f,0.6f,0.2121f);
		
	glColor3f(0.0f,0.0f,0.0f);
	glBegin(GL_QUADS);//base line
	glVertex3f(1.1f, 1.2f, -5.0f);
	glVertex3f(1.1f, 1.21f, -5.0f);
	glVertex3f(-1.1f, 1.21f, -5.0f);
	glVertex3f(-1.1f, 1.2f, -5.0f);
	
	glVertex3f(1.1f, 1.35f, -5.0f);
	glVertex3f(1.1f, 1.33f, -5.0f);
	glVertex3f(-1.1f, 1.33f, -5.0f);
	glVertex3f(-1.1f, 1.35f, -5.0f);
	glEnd();
	
	glColor3f(1.0f, 0.0f, 0.0f);//base line circles
	drawDisc(1.1f, 1.275f, 0.075f,1000);
	drawDisc(-1.1f, 1.275f, 0.075f,1000);
	glColor3f(0.0f,0.0f,0.0f);
	drawCircle(1.1f, 1.275f, 0.075f);
	drawCircle(-1.1f, 1.275f, 0.075f);
	glRotatef(90.0f,0.0f,0.0f,1.0f);
	}
	reDraw();
	glutSwapBuffers(); //Send the 3D scene to the screen
}
Beispiel #25
0
void WPainter::drawArc(double x, double y, double width, double height,
                       int startAngle, int spanAngle)
{
    drawArc(WRectF(x, y, width, height), startAngle, spanAngle);
}
Beispiel #26
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    setupUi(this);
    setWindowTitle(tr("GD CAD"));
    newFile();

    qApp->installEventFilter(this);

<<<<<<< HEAD
    connect(ui->pointButton, SIGNAL(clicked()), this, SLOT(drawPoint()));
    connect(ui->lineButton, SIGNAL(clicked()), this, SLOT(drawLine()));
    connect(ui->circleButton, SIGNAL(clicked()), this, SLOT(drawCircle()));
    connect(ui->ellipseButton, SIGNAL(clicked()), this, SLOT(drawEllipse()));
    connect(ui->arcButton, SIGNAL(clicked()),this, SLOT(drawArc()));
    connect(ui->polylineButton, SIGNAL(clicked()),this, SLOT(drawPolyline()));


    connect(ui->actionPoints, SIGNAL(triggered()), this, SLOT(drawPoint()));
    connect(ui->actionLine, SIGNAL(triggered()), this, SLOT(drawLine()));
    connect(ui->actionCircle, SIGNAL(triggered()), this, SLOT(drawCircle()));
    connect(ui->actionEllipse, SIGNAL(triggered()), this, SLOT(drawEllipse()));

    connect(ui->actionArc, SIGNAL(triggered()), this, SLOT(drawArc()));
    connect(ui->actionPolyline, SIGNAL(triggered()), this, SLOT(drawPolyline()));

    addToolbars();

    connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(newFile()));
    connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(close()));
Beispiel #27
0
void KivioShapePainter::drawShape( KivioShape *pShape, float x, float y, float w, float h )
{
    KivioShapeData *pShapeData;

    m_x = x;
    m_y = y;
    m_w = w;
    m_h = h;

    m_pShape = pShape;

    pShapeData = pShape->shapeData();

    switch( pShapeData->shapeType() )
    {
    case KivioShapeData::kstArc:
        drawArc();
        break;

    case KivioShapeData::kstPie:
        drawPie();
        break;

    case KivioShapeData::kstLineArray:
        drawLineArray();
        break;

    case KivioShapeData::kstPolyline:
        drawPolyline();
        break;

    case KivioShapeData::kstPolygon:
        drawPolygon();
        break;

    case KivioShapeData::kstBezier:
        drawBezier();
        break;

    case KivioShapeData::kstRectangle:
        drawRectangle();
        break;

    case KivioShapeData::kstRoundRectangle:
        drawRoundRectangle();
        break;

    case KivioShapeData::kstEllipse:
        drawEllipse();
        break;

    case KivioShapeData::kstOpenPath:
        drawOpenPath();
        break;

    case KivioShapeData::kstClosedPath:
        drawClosedPath();
        break;

    case KivioShapeData::kstTextBox:
        drawTextBox();
        break;


    case KivioShapeData::kstNone:
    default:
        break;
    }
}
Beispiel #28
0
static void drawArc(uiDrawPath *p, struct arc *a, void (*startFunction)(uiDrawPath *, double, double))
{
	double sinx, cosx;
	double startX, startY;
	double endX, endY;
	D2D1_ARC_SEGMENT as;
	BOOL fullCircle;
	double absSweep;

	// as above, we can't do a full circle with one arc
	// simulate it with two half-circles
	// of course, we have a dragon: equality on floating-point values!
	// I've chosen to do the AlmostEqualRelative() technique in https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
	fullCircle = FALSE;
	// use the absolute value to tackle both ≥2π and ≤-2π at the same time
	absSweep = fabs(a->sweep);
	if (absSweep > (2 * M_PI))		// this part is easy
		fullCircle = TRUE;
	else {
		double aerDiff;

		aerDiff = fabs(absSweep - (2 * M_PI));
		// if we got here then we know a->sweep is larger (or the same!)
		fullCircle = aerDiff <= absSweep * aerMax;
	}
	// TODO make sure this works right for the negative direction
	if (fullCircle) {
		a->sweep = M_PI;
		drawArc(p, a, startFunction);
		a->startAngle += M_PI;
		drawArc(p, a, NULL);
		return;
	}

	// first, figure out the arc's endpoints
	// unfortunately D2D1SinCos() is only defined on Windows 8 and newer
	// the MSDN page doesn't say this, but says it requires d2d1_1.h, which is listed as only supported on Windows 8 and newer elsewhere on MSDN
	// so we must use sin() and cos() and hope it's right...
	sinx = sin(a->startAngle);
	cosx = cos(a->startAngle);
	startX = a->xCenter + a->radius * cosx;
	startY = a->yCenter + a->radius * sinx;
	sinx = sin(a->startAngle + a->sweep);
	cosx = cos(a->startAngle + a->sweep);
	endX = a->xCenter + a->radius * cosx;
	endY = a->yCenter + a->radius * sinx;

	// now do the initial step to get the current point to be the start point
	// this is either creating a new figure, drawing a line, or (in the case of our full circle code above) doing nothing
	if (startFunction != NULL)
		(*startFunction)(p, startX, startY);

	// now we can draw the arc
	as.point.x = endX;
	as.point.y = endY;
	as.size.width = a->radius;
	as.size.height = a->radius;
	as.rotationAngle = 0;		// as above, not relevant for circles
	if (a->negative)
		as.sweepDirection = D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE;
	else
		as.sweepDirection = D2D1_SWEEP_DIRECTION_CLOCKWISE;
	// TODO explain the outer if
	if (!a->negative)
		if (a->sweep > M_PI)
			as.arcSize = D2D1_ARC_SIZE_LARGE;
		else
			as.arcSize = D2D1_ARC_SIZE_SMALL;
	else
		// TODO especially this part
		if (a->sweep > M_PI)
			as.arcSize = D2D1_ARC_SIZE_SMALL;
		else
			as.arcSize = D2D1_ARC_SIZE_LARGE;
	ID2D1GeometrySink_AddArc(p->sink, &as);
}
Beispiel #29
0
namespace SkRecords {

// NoOps draw nothing.
template <> void Draw::draw(const NoOp&) {}

#define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; }
DRAW(Restore, restore());
DRAW(Save, save());
DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds,
                                                 r.paint,
                                                 r.backdrop.get(),
                                                 r.saveLayerFlags)));
DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
DRAW(Concat, concat(r.matrix));
DRAW(Translate, translate(r.dx, r.dy));

DRAW(ClipPath, clipPath(r.path, r.opAA.op, r.opAA.aa));
DRAW(ClipRRect, clipRRect(r.rrect, r.opAA.op, r.opAA.aa));
DRAW(ClipRect, clipRect(r.rect, r.opAA.op, r.opAA.aa));
DRAW(ClipRegion, clipRegion(r.region, r.op));

#ifdef SK_EXPERIMENTAL_SHADOWING
DRAW(TranslateZ, SkCanvas::translateZ(r.z));
#else
template <> void Draw::draw(const TranslateZ& r) { }
#endif

DRAW(DrawArc, drawArc(r.oval, r.startAngle, r.sweepAngle, r.useCenter, r.paint));
DRAW(DrawDRRect, drawDRRect(r.outer, r.inner, r.paint));
DRAW(DrawImage, drawImage(r.image.get(), r.left, r.top, r.paint));

template <> void Draw::draw(const DrawImageLattice& r) {
    SkCanvas::Lattice lattice;
    lattice.fXCount = r.xCount;
    lattice.fXDivs = r.xDivs;
    lattice.fYCount = r.yCount;
    lattice.fYDivs = r.yDivs;
    lattice.fFlags = (0 == r.flagCount) ? nullptr : r.flags;
    lattice.fBounds = &r.src;
    fCanvas->drawImageLattice(r.image.get(), lattice, r.dst, r.paint);
}

DRAW(DrawImageRect, legacy_drawImageRect(r.image.get(), r.src, r.dst, r.paint, r.constraint));
DRAW(DrawImageNine, drawImageNine(r.image.get(), r.center, r.dst, r.paint));
DRAW(DrawOval, drawOval(r.oval, r.paint));
DRAW(DrawPaint, drawPaint(r.paint));
DRAW(DrawPath, drawPath(r.path, r.paint));
DRAW(DrawPatch, drawPatch(r.cubics, r.colors, r.texCoords, r.xmode, r.paint));
DRAW(DrawPicture, drawPicture(r.picture.get(), &r.matrix, r.paint));

#ifdef SK_EXPERIMENTAL_SHADOWING
DRAW(DrawShadowedPicture, drawShadowedPicture(r.picture.get(), &r.matrix, r.paint, r.params));
#else
template <> void Draw::draw(const DrawShadowedPicture& r) { }
#endif

DRAW(DrawPoints, drawPoints(r.mode, r.count, r.pts, r.paint));
DRAW(DrawPosText, drawPosText(r.text, r.byteLength, r.pos, r.paint));
DRAW(DrawPosTextH, drawPosTextH(r.text, r.byteLength, r.xpos, r.y, r.paint));
DRAW(DrawRRect, drawRRect(r.rrect, r.paint));
DRAW(DrawRect, drawRect(r.rect, r.paint));
DRAW(DrawRegion, drawRegion(r.region, r.paint));
DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint));
DRAW(DrawTextBlob, drawTextBlob(r.blob.get(), r.x, r.y, r.paint));
DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, &r.matrix, r.paint));
DRAW(DrawTextRSXform, drawTextRSXform(r.text, r.byteLength, r.xforms, r.cull, r.paint));
DRAW(DrawAtlas, drawAtlas(r.atlas.get(),
                          r.xforms, r.texs, r.colors, r.count, r.mode, r.cull, r.paint));
DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors,
                                r.xmode, r.indices, r.indexCount, r.paint));
DRAW(DrawAnnotation, drawAnnotation(r.rect, r.key.c_str(), r.value.get()));
#undef DRAW

template <> void Draw::draw(const DrawDrawable& r) {
    SkASSERT(r.index >= 0);
    SkASSERT(r.index < fDrawableCount);
    if (fDrawables) {
        SkASSERT(nullptr == fDrawablePicts);
        fCanvas->drawDrawable(fDrawables[r.index], r.matrix);
    } else {
        fCanvas->drawPicture(fDrawablePicts[r.index], r.matrix, nullptr);
    }
}

// This is an SkRecord visitor that fills an SkBBoxHierarchy.
//
// The interesting part here is how to calculate bounds for ops which don't
// have intrinsic bounds.  What is the bounds of a Save or a Translate?
//
// We answer this by thinking about a particular definition of bounds: if I
// don't execute this op, pixels in this rectangle might draw incorrectly.  So
// the bounds of a Save, a Translate, a Restore, etc. are the union of the
// bounds of Draw* ops that they might have an effect on.  For any given
// Save/Restore block, the bounds of the Save, the Restore, and any other
// non-drawing ("control") ops inside are exactly the union of the bounds of
// the drawing ops inside that block.
//
// To implement this, we keep a stack of active Save blocks.  As we consume ops
// inside the Save/Restore block, drawing ops are unioned with the bounds of
// the block, and control ops are stashed away for later.  When we finish the
// block with a Restore, our bounds are complete, and we go back and fill them
// in for all the control ops we stashed away.
class FillBounds : SkNoncopyable {
public:
    FillBounds(const SkRect& cullRect, const SkRecord& record, SkRect bounds[])
        : fNumRecords(record.count())
        , fCullRect(cullRect)
        , fBounds(bounds) {
        fCTM = SkMatrix::I();
        fCurrentClipBounds = fCullRect;
    }

    void cleanUp() {
        // If we have any lingering unpaired Saves, simulate restores to make
        // sure all ops in those Save blocks have their bounds calculated.
        while (!fSaveStack.isEmpty()) {
            this->popSaveBlock();
        }

        // Any control ops not part of any Save/Restore block draw everywhere.
        while (!fControlIndices.isEmpty()) {
            this->popControl(fCullRect);
        }
    }

    void setCurrentOp(int currentOp) { fCurrentOp = currentOp; }


    template <typename T> void operator()(const T& op) {
        this->updateCTM(op);
        this->updateClipBounds(op);
        this->trackBounds(op);
    }

    // In this file, SkRect are in local coordinates, Bounds are translated back to identity space.
    typedef SkRect Bounds;

    int currentOp() const { return fCurrentOp; }
    const SkMatrix& ctm() const { return fCTM; }
    const Bounds& getBounds(int index) const { return fBounds[index]; }

    // Adjust rect for all paints that may affect its geometry, then map it to identity space.
    Bounds adjustAndMap(SkRect rect, const SkPaint* paint) const {
        // Inverted rectangles really confuse our BBHs.
        rect.sort();

        // Adjust the rect for its own paint.
        if (!AdjustForPaint(paint, &rect)) {
            // The paint could do anything to our bounds.  The only safe answer is the current clip.
            return fCurrentClipBounds;
        }

        // Adjust rect for all the paints from the SaveLayers we're inside.
        if (!this->adjustForSaveLayerPaints(&rect)) {
            // Same deal as above.
            return fCurrentClipBounds;
        }

        // Map the rect back to identity space.
        fCTM.mapRect(&rect);

        // Nothing can draw outside the current clip.
        if (!rect.intersect(fCurrentClipBounds)) {
            return Bounds::MakeEmpty();
        }

        return rect;
    }

private:
    struct SaveBounds {
        int controlOps;        // Number of control ops in this Save block, including the Save.
        Bounds bounds;         // Bounds of everything in the block.
        const SkPaint* paint;  // Unowned.  If set, adjusts the bounds of all ops in this block.
        SkMatrix ctm;
    };

    // Only Restore, SetMatrix, Concat, and Translate change the CTM.
    template <typename T> void updateCTM(const T&) {}
    void updateCTM(const Restore& op)   { fCTM = op.matrix; }
    void updateCTM(const SetMatrix& op) { fCTM = op.matrix; }
    void updateCTM(const Concat& op)    { fCTM.preConcat(op.matrix); }
    void updateCTM(const Translate& op) { fCTM.preTranslate(op.dx, op.dy); }

    // Most ops don't change the clip.
    template <typename T> void updateClipBounds(const T&) {}

    // Clip{Path,RRect,Rect,Region} obviously change the clip.  They all know their bounds already.
    void updateClipBounds(const ClipPath&   op) { this->updateClipBoundsForClipOp(op.devBounds); }
    void updateClipBounds(const ClipRRect&  op) { this->updateClipBoundsForClipOp(op.devBounds); }
    void updateClipBounds(const ClipRect&   op) { this->updateClipBoundsForClipOp(op.devBounds); }
    void updateClipBounds(const ClipRegion& op) { this->updateClipBoundsForClipOp(op.devBounds); }

    // The bounds of clip ops need to be adjusted for the paints of saveLayers they're inside.
    void updateClipBoundsForClipOp(const SkIRect& devBounds) {
        Bounds clip = SkRect::Make(devBounds);
        // We don't call adjustAndMap() because as its last step it would intersect the adjusted
        // clip bounds with the previous clip, exactly what we can't do when the clip grows.
        if (this->adjustForSaveLayerPaints(&clip)) {
            fCurrentClipBounds = clip.intersect(fCullRect) ? clip : Bounds::MakeEmpty();
        } else {
            fCurrentClipBounds = fCullRect;
        }
    }

    // Restore holds the devBounds for the clip after the {save,saveLayer}/restore block completes.
    void updateClipBounds(const Restore& op) {
        // This is just like the clip ops above, but we need to skip the effects (if any) of our
        // paired saveLayer (if it is one); it has not yet been popped off the save stack.  Our
        // devBounds reflect the state of the world after the saveLayer/restore block is done,
        // so they are not affected by the saveLayer's paint.
        const int kSavesToIgnore = 1;
        Bounds clip = SkRect::Make(op.devBounds);
        if (this->adjustForSaveLayerPaints(&clip, kSavesToIgnore)) {
            fCurrentClipBounds = clip.intersect(fCullRect) ? clip : Bounds::MakeEmpty();
        } else {
            fCurrentClipBounds = fCullRect;
        }
    }

    // We also take advantage of SaveLayer bounds when present to further cut the clip down.
    void updateClipBounds(const SaveLayer& op)  {
        if (op.bounds) {
            // adjustAndMap() intersects these layer bounds with the previous clip for us.
            fCurrentClipBounds = this->adjustAndMap(*op.bounds, op.paint);
        }
    }

    // The bounds of these ops must be calculated when we hit the Restore
    // from the bounds of the ops in the same Save block.
    void trackBounds(const Save&)          { this->pushSaveBlock(nullptr); }
    void trackBounds(const SaveLayer& op)  { this->pushSaveBlock(op.paint); }
    void trackBounds(const Restore&) { fBounds[fCurrentOp] = this->popSaveBlock(); }

    void trackBounds(const SetMatrix&)         { this->pushControl(); }
    void trackBounds(const Concat&)            { this->pushControl(); }
    void trackBounds(const Translate&)         { this->pushControl(); }
    void trackBounds(const TranslateZ&)        { this->pushControl(); }
    void trackBounds(const ClipRect&)          { this->pushControl(); }
    void trackBounds(const ClipRRect&)         { this->pushControl(); }
    void trackBounds(const ClipPath&)          { this->pushControl(); }
    void trackBounds(const ClipRegion&)        { this->pushControl(); }


    // For all other ops, we can calculate and store the bounds directly now.
    template <typename T> void trackBounds(const T& op) {
        fBounds[fCurrentOp] = this->bounds(op);
        this->updateSaveBounds(fBounds[fCurrentOp]);
    }

    void pushSaveBlock(const SkPaint* paint) {
        // Starting a new Save block.  Push a new entry to represent that.
        SaveBounds sb;
        sb.controlOps = 0;
        // If the paint affects transparent black, the bound shouldn't be smaller
        // than the current clip bounds.
        sb.bounds =
            PaintMayAffectTransparentBlack(paint) ? fCurrentClipBounds : Bounds::MakeEmpty();
        sb.paint = paint;
        sb.ctm = this->fCTM;

        fSaveStack.push(sb);
        this->pushControl();
    }

    static bool PaintMayAffectTransparentBlack(const SkPaint* paint) {
        if (paint) {
            // FIXME: this is very conservative
            if (paint->getImageFilter() || paint->getColorFilter()) {
                return true;
            }

            // Unusual blendmodes require us to process a saved layer
            // even with operations outisde the clip.
            // For example, DstIn is used by masking layers.
            // https://code.google.com/p/skia/issues/detail?id=1291
            // https://crbug.com/401593
            switch (paint->getBlendMode()) {
                // For each of the following transfer modes, if the source
                // alpha is zero (our transparent black), the resulting
                // blended alpha is not necessarily equal to the original
                // destination alpha.
                case SkBlendMode::kClear:
                case SkBlendMode::kSrc:
                case SkBlendMode::kSrcIn:
                case SkBlendMode::kDstIn:
                case SkBlendMode::kSrcOut:
                case SkBlendMode::kDstATop:
                case SkBlendMode::kModulate:
                    return true;
                    break;
                default:
                    break;
            }
        }
        return false;
    }

    Bounds popSaveBlock() {
        // We're done the Save block.  Apply the block's bounds to all control ops inside it.
        SaveBounds sb;
        fSaveStack.pop(&sb);

        while (sb.controlOps --> 0) {
            this->popControl(sb.bounds);
        }

        // This whole Save block may be part another Save block.
        this->updateSaveBounds(sb.bounds);

        // If called from a real Restore (not a phony one for balance), it'll need the bounds.
        return sb.bounds;
    }

    void pushControl() {
        fControlIndices.push(fCurrentOp);
        if (!fSaveStack.isEmpty()) {
            fSaveStack.top().controlOps++;
        }
    }

    void popControl(const Bounds& bounds) {
        fBounds[fControlIndices.top()] = bounds;
        fControlIndices.pop();
    }

    void updateSaveBounds(const Bounds& bounds) {
        // If we're in a Save block, expand its bounds to cover these bounds too.
        if (!fSaveStack.isEmpty()) {
            fSaveStack.top().bounds.join(bounds);
        }
    }

    // FIXME: this method could use better bounds
    Bounds bounds(const DrawText&) const { return fCurrentClipBounds; }

    Bounds bounds(const DrawPaint&) const { return fCurrentClipBounds; }
    Bounds bounds(const NoOp&)  const { return Bounds::MakeEmpty(); }    // NoOps don't draw.

    Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
    Bounds bounds(const DrawRegion& op) const {
        SkRect rect = SkRect::Make(op.region.getBounds());
        return this->adjustAndMap(rect, &op.paint);
    }
    Bounds bounds(const DrawOval& op) const { return this->adjustAndMap(op.oval, &op.paint); }
    // Tighter arc bounds?
    Bounds bounds(const DrawArc& op) const { return this->adjustAndMap(op.oval, &op.paint); }
    Bounds bounds(const DrawRRect& op) const {
        return this->adjustAndMap(op.rrect.rect(), &op.paint);
    }
    Bounds bounds(const DrawDRRect& op) const {
        return this->adjustAndMap(op.outer.rect(), &op.paint);
    }
    Bounds bounds(const DrawImage& op) const {
        const SkImage* image = op.image.get();
        SkRect rect = SkRect::MakeXYWH(op.left, op.top, image->width(), image->height());

        return this->adjustAndMap(rect, op.paint);
    }
    Bounds bounds(const DrawImageLattice& op) const {
        return this->adjustAndMap(op.dst, op.paint);
    }
    Bounds bounds(const DrawImageRect& op) const {
        return this->adjustAndMap(op.dst, op.paint);
    }
    Bounds bounds(const DrawImageNine& op) const {
        return this->adjustAndMap(op.dst, op.paint);
    }
    Bounds bounds(const DrawPath& op) const {
        return op.path.isInverseFillType() ? fCurrentClipBounds
                                           : this->adjustAndMap(op.path.getBounds(), &op.paint);
    }
    Bounds bounds(const DrawPoints& op) const {
        SkRect dst;
        dst.set(op.pts, op.count);

        // Pad the bounding box a little to make sure hairline points' bounds aren't empty.
        SkScalar stroke = SkMaxScalar(op.paint.getStrokeWidth(), 0.01f);
        dst.outset(stroke/2, stroke/2);

        return this->adjustAndMap(dst, &op.paint);
    }
    Bounds bounds(const DrawPatch& op) const {
        SkRect dst;
        dst.set(op.cubics, SkPatchUtils::kNumCtrlPts);
        return this->adjustAndMap(dst, &op.paint);
    }
    Bounds bounds(const DrawVertices& op) const {
        SkRect dst;
        dst.set(op.vertices, op.vertexCount);
        return this->adjustAndMap(dst, &op.paint);
    }

    Bounds bounds(const DrawAtlas& op) const {
        if (op.cull) {
            // TODO: <reed> can we pass nullptr for the paint? Isn't cull already "correct"
            // for the paint (by the caller)?
            return this->adjustAndMap(*op.cull, op.paint);
        } else {
            return fCurrentClipBounds;
        }
    }

    Bounds bounds(const DrawPicture& op) const {
        SkRect dst = op.picture->cullRect();
        op.matrix.mapRect(&dst);
        return this->adjustAndMap(dst, op.paint);
    }

    Bounds bounds(const DrawShadowedPicture& op) const {
        SkRect dst = op.picture->cullRect();
        op.matrix.mapRect(&dst);
        return this->adjustAndMap(dst, op.paint);
    }

    Bounds bounds(const DrawPosText& op) const {
        const int N = op.paint.countText(op.text, op.byteLength);
        if (N == 0) {
            return Bounds::MakeEmpty();
        }

        SkRect dst;
        dst.set(op.pos, N);
        AdjustTextForFontMetrics(&dst, op.paint);
        return this->adjustAndMap(dst, &op.paint);
    }
    Bounds bounds(const DrawPosTextH& op) const {
        const int N = op.paint.countText(op.text, op.byteLength);
        if (N == 0) {
            return Bounds::MakeEmpty();
        }

        SkScalar left = op.xpos[0], right = op.xpos[0];
        for (int i = 1; i < N; i++) {
            left  = SkMinScalar(left,  op.xpos[i]);
            right = SkMaxScalar(right, op.xpos[i]);
        }
        SkRect dst = { left, op.y, right, op.y };
        AdjustTextForFontMetrics(&dst, op.paint);
        return this->adjustAndMap(dst, &op.paint);
    }
    Bounds bounds(const DrawTextOnPath& op) const {
        SkRect dst = op.path.getBounds();

        // Pad all sides by the maximum padding in any direction we'd normally apply.
        SkRect pad = { 0, 0, 0, 0};
        AdjustTextForFontMetrics(&pad, op.paint);

        // That maximum padding happens to always be the right pad today.
        SkASSERT(pad.fLeft == -pad.fRight);
        SkASSERT(pad.fTop  == -pad.fBottom);
        SkASSERT(pad.fRight > pad.fBottom);
        dst.outset(pad.fRight, pad.fRight);

        return this->adjustAndMap(dst, &op.paint);
    }

    Bounds bounds(const DrawTextRSXform& op) const {
        if (op.cull) {
            return this->adjustAndMap(*op.cull, nullptr);
        } else {
            return fCurrentClipBounds;
        }
    }

    Bounds bounds(const DrawTextBlob& op) const {
        SkRect dst = op.blob->bounds();
        dst.offset(op.x, op.y);
        return this->adjustAndMap(dst, &op.paint);
    }

    Bounds bounds(const DrawDrawable& op) const {
        return this->adjustAndMap(op.worstCaseBounds, nullptr);
    }

    Bounds bounds(const DrawAnnotation& op) const {
        return this->adjustAndMap(op.rect, nullptr);
    }

    static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) {
#ifdef SK_DEBUG
        SkRect correct = *rect;
#endif
        // crbug.com/373785 ~~> xPad = 4x yPad
        // crbug.com/424824 ~~> bump yPad from 2x text size to 2.5x
        const SkScalar yPad = 2.5f * paint.getTextSize(),
                       xPad = 4.0f * yPad;
        rect->outset(xPad, yPad);
#ifdef SK_DEBUG
        SkPaint::FontMetrics metrics;
        paint.getFontMetrics(&metrics);
        correct.fLeft   += metrics.fXMin;
        correct.fTop    += metrics.fTop;
        correct.fRight  += metrics.fXMax;
        correct.fBottom += metrics.fBottom;
        // See skia:2862 for why we ignore small text sizes.
        SkASSERTF(paint.getTextSize() < 0.001f || rect->contains(correct),
                  "%f %f %f %f vs. %f %f %f %f\n",
                  -xPad, -yPad, +xPad, +yPad,
                  metrics.fXMin, metrics.fTop, metrics.fXMax, metrics.fBottom);
#endif
    }

    // Returns true if rect was meaningfully adjusted for the effects of paint,
    // false if the paint could affect the rect in unknown ways.
    static bool AdjustForPaint(const SkPaint* paint, SkRect* rect) {
        if (paint) {
            if (paint->canComputeFastBounds()) {
                *rect = paint->computeFastBounds(*rect, rect);
                return true;
            }
            return false;
        }
        return true;
    }

    bool adjustForSaveLayerPaints(SkRect* rect, int savesToIgnore = 0) const {
        for (int i = fSaveStack.count() - 1 - savesToIgnore; i >= 0; i--) {
            SkMatrix inverse;
            if (!fSaveStack[i].ctm.invert(&inverse)) {
                return false;
            }
            inverse.mapRect(rect);
            if (!AdjustForPaint(fSaveStack[i].paint, rect)) {
                return false;
            }
            fSaveStack[i].ctm.mapRect(rect);
        }
        return true;
    }

    const int fNumRecords;

    // We do not guarantee anything for operations outside of the cull rect
    const SkRect fCullRect;

    // Conservative identity-space bounds for each op in the SkRecord.
    Bounds* fBounds;

    // We walk fCurrentOp through the SkRecord, as we go using updateCTM()
    // and updateClipBounds() to maintain the exact CTM (fCTM) and conservative
    // identity-space bounds of the current clip (fCurrentClipBounds).
    int fCurrentOp;
    SkMatrix fCTM;
    Bounds fCurrentClipBounds;

    // Used to track the bounds of Save/Restore blocks and the control ops inside them.
    SkTDArray<SaveBounds> fSaveStack;
    SkTDArray<int>   fControlIndices;
};

}  // namespace SkRecords
Beispiel #30
0
void execute_commands(char instruction[])
{
	bool axisSelected;
        
	// Do we have lineNr and checksums in this gcode?
	if((bool)(gc.seen[GCODE_CHECKSUM]) | (bool)(gc.seen[GCODE_N]))
	{
		// Check that if recieved a L code, we also got a C code. If not, one of them has been lost, and we have to reset queue
		if( (bool)(gc.seen[GCODE_CHECKSUM]) != (bool)(gc.seen[GCODE_N]) )
		{
           if(SendDebug & DEBUG_ERRORS)
           {
              if(gc.seen[GCODE_CHECKSUM])
                sprintf(talkToHost.string(), "Serial Error: checksum without line number. Checksum: %d, line received: %s", gc.Checksum, instruction);
              else
                sprintf(talkToHost.string(), "Serial Error: line number without checksum. Linenumber: %ld, line received: %s", gc.N, instruction);
           }
           talkToHost.setResend(gc.LastLineNrRecieved+1);
           return;
		}
		// Check checksum of this string. Flush buffers and re-request line of error is found
		if(gc.seen[GCODE_CHECKSUM])  // if we recieved a line nr, we know we also recieved a Checksum, so check it
		{
            // Calc checksum.
            byte checksum = 0;
            byte count=0;
            while(instruction[count] != '*')
              checksum = checksum^instruction[count++];
            // Check checksum.
            if(gc.Checksum != (int)checksum)
            {
              if(SendDebug & DEBUG_ERRORS)
                sprintf(talkToHost.string(), "Serial Error: checksum mismatch.  Remote (%d) not equal to local (%d), line received: %s", 
                			gc.Checksum, (int)checksum, instruction);
              talkToHost.setResend(gc.LastLineNrRecieved+1);
              return;
            }
			// Check that this lineNr is LastLineNrRecieved+1. If not, flush
			if(!( (bool)(gc.seen[GCODE_M]) && gc.M == 110)) // unless this is a reset-lineNr command
				if(gc.N != gc.LastLineNrRecieved+1)
				{
					if(SendDebug & DEBUG_ERRORS)
						sprintf(talkToHost.string(), "Serial Error: Linenumber (%ld) is not last + 1 (%ld), line received: %s", gc.N, gc.LastLineNrRecieved+1, instruction);
					talkToHost.setResend(gc.LastLineNrRecieved+1);
					return;
				}
			//If we reach this point, communication is a succes, update our "last good line nr" and continue
			gc.LastLineNrRecieved = gc.N;
		}
	}


	/* if no command was seen, but parameters were, then use the last G code as 
	* the current command
	*/
	if ((!(gc.seen[GCODE_G] | gc.seen[GCODE_M] | gc.seen[GCODE_T])) && (seenAnything() && (last_gcode_g >= 0)))
	{
		/* yes - so use the previous command with the new parameters */
		gc.G[0] = last_gcode_g;
		gc.GIndex=1;
		gc.seen[GCODE_G]=true;
	}

	// Deal with emergency stop as No 1 priority
	if ((gc.seen[GCODE_M]) && (gc.M == 112))
		sharedMachineModel.shutdown();
	
	//did we get a gcode?
	if (gc.seen[GCODE_G])
	{		   
		// Handle all GCodes in this line
		for(int gIndex=0; gIndex<gc.GIndex; gIndex++)
		{
			last_gcode_g = gc.G[gIndex];	/* remember this for future instructions */

		    unsigned long endTime; // For Dwell
		    
			// Process the buffered move commands first
			bool gCodeHandled=false;
			switch (gc.G[gIndex])
			{
				////////////////////////
				// Buffered commands
				////////////////////////
				
				case 0:		//Rapid move
							fetchCartesianParameters();
							rapidMove(fp);
							break;
							
				case 1:		// Controlled move;
							fetchCartesianParameters();
							sharedMachineModel.qMove(fp);
							break;
															  
				case 2:		// G2, Clockwise arc
				case 3: 	// G3, Counterclockwise arc
							fetchCartesianParameters();
							if(gc.seen[GCODE_R])
							{
							  //drawRadius(tempX, tempY, rVal, (gc.G[gIndex]==2));
								if(SendDebug & DEBUG_ERRORS)
									sprintf(talkToHost.string(), "Dud G code: G%d with R param not yet implemented", gc.G[gIndex]);
								talkToHost.setResend(gc.LastLineNrRecieved+1);
							}
							else if(gc.seen[GCODE_I] || gc.seen[GCODE_J])
							{
								drawArc(fp.x+gc.I, fp.y+gc.J, fp.x, fp.y, (gc.G[gIndex]==2));
							}
							else
							{
								if(SendDebug & DEBUG_ERRORS)
									sprintf(talkToHost.string(), "Dud G code: G%d without I or J params", gc.G[gIndex]);
								talkToHost.setResend(gc.LastLineNrRecieved+1);
							}
							break;
				
							
				case 28:	//go home.  If we send coordinates (regardless of their value) only zero those axes
							fetchCartesianParameters();
							axisSelected = false;
							if(gc.seen[GCODE_Z])
							{
							  sharedMachineModel.zeroZ();
							  axisSelected = true;
							}
							if(gc.seen[GCODE_X])
							{
							  sharedMachineModel.zeroX();
							  axisSelected = true;
							}
							if(gc.seen[GCODE_Y])
							{
							  sharedMachineModel.zeroY();
							  axisSelected = true;
							}                                
							if(!axisSelected)
							{
							  sharedMachineModel.zeroZ();
							  sharedMachineModel.zeroX();
							  sharedMachineModel.zeroY();
							  sharedMachineModel.absolutePositionValid=true;
							}
							sharedMachineModel.localPosition.f = SLOW_FEEDRATE;     // Most sensible feedrate to leave it in                    

							break;							

				////////////////////////
				// Non-Buffered commands
				////////////////////////
							
				case 4: 	//Dwell
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							endTime = millis() + (int)(gc.P + 0.5);
							while(millis() < endTime) 
								sharedMachineModel.manage(true);
							break;
		
				case 20:	//Inches for Units
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							sharedMachineModel.setUnits(false);
							break;
		
				case 21:	//mm for Units
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							sharedMachineModel.setUnits(true);
							break;
							
				case 54:
				case 55:
				case 56:
				case 57:
				case 58:
				case 59:	// Switch to Workin Coordinate System
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							if(!sharedMachineModel.switchToWCS(gc.G[gIndex]-54))
							{
								if(SendDebug & DEBUG_ERRORS)
									sprintf(talkToHost.string(), "Dud G code: G%d not possible, probably machine not homed", gc.G[gIndex]);
								talkToHost.setResend(gc.LastLineNrRecieved+1);
							}
							break;
		
				case 73:	// Peck drilling cycle for milling - high-speed
				case 81:	// Drill Cycle
				case 82:	// Drill Cycle with dwell
				case 83:	// Drill Cycle peck drilling
				case 85:	// Drill Cycle, slow retract
				case 89:	// Drill Cycle with dwell and slow reredract
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							fetchCartesianParameters();
							doDrillCycle(gc.G[gIndex], fp);
							break;
																					
				case 90: 	//Absolute Positioning
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							sharedMachineModel.setAbsMode(true);
							break;

				case 91: 	//Incremental Positioning
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							sharedMachineModel.setAbsMode(false);
							break;

				case 92:	//Set position as fp
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							fetchCartesianParameters();
							sharedMachineModel.setLocalZero(fp);
							break;

				case 98:	// Return to initial Z level in canned cycle
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							sharedMachineModel.setRetractMode(true);
							break;

				case 99:	// Return to R level in canned cycle
							sharedMachineModel.waitFor_qEmpty(); // Non-buffered G command. Wait till the buffer q is empty first
							sharedMachineModel.setRetractMode(false);
							break;

				default:
							if(SendDebug & DEBUG_ERRORS)
								sprintf(talkToHost.string(), "Dud G code: G%d", gc.G[gIndex]);
							talkToHost.setResend(gc.LastLineNrRecieved+1);
			}	// switch
		}		// for
	}			// Gcode
	
	// Get feedrate if supplied and queue is empty
	if ( gc.seen[GCODE_F] && sharedMachineModel.qEmpty())
		sharedMachineModel.localPosition.f=MIN(gc.F, FAST_XY_FEEDRATE);
		
	//find us an m code.
	if (gc.seen[GCODE_M])
	{
		// Wait till the q is empty first
		sharedMachineModel.waitFor_qEmpty();
		switch (gc.M)
		{
			case 0:
				sharedMachineModel.shutdown();
				break;
		    case 1:
				 //todo: optional stop
				 break;
			case 2:
				 //todo: program end
				 break;
				 
			case 6:
				 // Tool change
				 if(gc.seen[GCODE_T])
				 	sharedMachineModel.manualToolChange(gc.T);
				 else
				 	sharedMachineModel.manualToolChange(-1);
				 break;

			//custom code for temperature control
//			case 104:
//				if (gc.seen[GCODE_S])
//				{
//					ex[extruder_in_use]->setTemperature((int)gc.S);
//				}
//				break;

			//custom code for temperature reading
//			case 105:
//				talkToHost.setETemp(ex[extruder_in_use]->getTemperature());
//				talkToHost.setBTemp(heatedBed.getTemperature());
//				break;
//
//			//turn fan on
//			case 106:
//				ex[extruder_in_use]->setCooler(255);
//				break;
//
//			//turn fan off
//			case 107:
//				ex[extruder_in_use]->setCooler(0);
//				break;
//
//
//			// Set the temperature and wait for it to get there
//			case 109:
//				ex[extruder_in_use]->setTemperature((int)gc.S);
//				ex[extruder_in_use]->waitForTemperature();
//				break;
			// Starting a new print, reset the gc.LastLineNrRecieved counter
			case 110:
				if (gc.seen[GCODE_N])
					gc.LastLineNrRecieved = gc.N;
				break;
			case 111:
				SendDebug = gc.S;
				break;
			case 112:	// STOP! (priority commnand)
				sharedMachineModel.shutdown();
				break;

			//custom code for returning current coordinates
			case 114:
				talkToHost.setCoords(sharedMachineModel.localPosition);
				break;

			//Reserved for returning machine capabilities in keyword:value pairs
			//custom code for returning Firmware Version and Capabilities 
			case 115:
				talkToHost.capabilities();
				break;

//			// TODO: make this work properly
//			case 116:
//				ex[extruder_in_use]->waitForTemperature();
//				break;

			//custom code for returning zero-hit coordinates
//			case 117:
//				talkToHost.setCoords(zeroHit);
//				break;

			// The valve (real, or virtual...) is now the way to control any extruder (such as
			// a pressurised paste extruder) that cannot move using E codes.

//			// Open the valve
//			case 126:
//				ex[extruder_in_use]->valveSet(true, (int)(gc.P + 0.5));
//				break;
//                                
//			// Close the valve
//			case 127:
//				ex[extruder_in_use]->valveSet(false, (int)(gc.P + 0.5));
//				break;
                                                                
//			case 140:
//				if (gc.seen[GCODE_S])
//				{
//					heatedBed.setTemperature((int)gc.S);
//				}
//				break;

			case 141: //TODO: set chamber temperature
				break;
                                
			case 142: //TODO: set holding pressure
				break;                                


			// Pleasant Mill priority commands
			// These commands are executed, even if the machine isn't in "armed for data" mode
			
			case 900:	// Machine-Identification
				sprintf(talkToHost.string(), "Pleasant Mill[%s]", FW_VERSION);
				break;
				
			case 901:	// Get Device Name
				sprintf(talkToHost.string(), EEPROM_ReadString(EEPROM_ADR_DEVICENAME, strBuffer));
				break;
				
			case 902:	// Set Device Name: The string argument is found in the commen
				if(strlen(strArgBuffer)>0)
				{
					strBuffer[16]=0x0;
					EEPROM_WriteString(EEPROM_ADR_DEVICENAME, strArgBuffer);
				}
				else
				{
					if(SendDebug & DEBUG_ERRORS)
						sprintf(talkToHost.string(), "Error: M902 not possible, bad device name argument: %s", strArgBuffer);
					talkToHost.setResend(gc.LastLineNrRecieved+1);
				}
				break;
				
				
			default:
				if(SendDebug & DEBUG_ERRORS)
					sprintf(talkToHost.string(), "Dud M code: M%d", gc.M);
				talkToHost.setResend(gc.LastLineNrRecieved+1);
		}
	}

	// Tool (i.e. extruder) change?
	if (gc.seen[GCODE_T])
	{
		sharedMachineModel.waitFor_qEmpty(); 
//		newExtruder(gc.T);
	}
}