void PaintMethods::paintDebugDrawing(QPainter& painter, const DebugDrawing& debugDrawing, const QTransform& baseTrans)
{
  for(const DebugDrawing::Element* e = debugDrawing.getFirst(); e; e = debugDrawing.getNext(e))
    switch(e->type)
    {
      case DebugDrawing::Element::POLYGON:
      {
        paintPolygon(*static_cast<const DebugDrawing::Polygon*>(e), painter);
        break;
      }
      case DebugDrawing::Element::GRID_RGBA:
      {
        paintGridRGBA(*static_cast<const DebugDrawing::GridRGBA*>(e), painter);
        break;
      }
      case DebugDrawing::Element::GRID_MONO:
      {
        paintGridMono(*static_cast<const DebugDrawing::GridMono*>(e), painter);
        break;
      }
      case DebugDrawing::Element::ELLIPSE:
      {
        paintEllipse(*static_cast<const DebugDrawing::Ellipse*>(e), painter);
        break;
      }
      case DebugDrawing::Element::ARC:
      {
        paintArc(*static_cast<const DebugDrawing::Arc*>(e), painter);
        break;
      }
      case DebugDrawing::Element::RECTANGLE:
      {
        paintRectangle(*static_cast<const DebugDrawing::Rectangle*>(e), painter);
        break;
      }
      case DebugDrawing::Element::LINE:
      {
        paintLine(*static_cast<const DebugDrawing::Line*>(e), painter);
        break;
      }
      case DebugDrawing::Element::ORIGIN:
      {
        paintOrigin(*static_cast<const DebugDrawing::Origin*>(e), painter, baseTrans);
        break;
      }
      case DebugDrawing::Element::TEXT:
      {
        paintText(*static_cast<const DebugDrawing::Text*>(e), painter);
        break;
      }
      default:
        break;
    }
}
Exemple #2
0
void SprayBrush::paint(KisPaintDeviceSP dab, KisPaintDeviceSP source,
                       const KisPaintInformation& info, qreal rotation, qreal scale,
                       const KoColor &color, const KoColor &bgColor)
{
    // initializing painter
    if (!m_painter) {
        m_painter = new KisPainter(dab);
        m_painter->setFillStyle(KisPainter::FillStyleForegroundColor);
        m_painter->setMaskImageSize(m_shapeProperties->width, m_shapeProperties->height);
        m_dabPixelSize = dab->colorSpace()->pixelSize();
        if (m_colorProperties->useRandomHSV) {
            m_transfo = dab->colorSpace()->createColorTransformation("hsv_adjustment", QHash<QString, QVariant>());
        }

        m_brushQImage = m_shapeProperties->image;
        if (!m_brushQImage.isNull()) {
            m_brushQImage = m_brushQImage.scaled(m_shapeProperties->width, m_shapeProperties->height);
        }
        m_imageDevice = new KisPaintDevice(dab->colorSpace());
    }


    qreal x = info.pos().x();
    qreal y = info.pos().y();
    KisRandomAccessorSP accessor = dab->createRandomAccessorNG(qRound(x), qRound(y));

    Q_ASSERT(color.colorSpace()->pixelSize() == dab->pixelSize());
    m_inkColor = color;
    KisCrossDeviceColorPicker colorPicker(source, m_inkColor);

    // apply size sensor
    m_radius = m_properties->radius * scale;

    // jitter movement
    if (m_properties->jitterMovement) {
        x = x + ((2 * m_radius * drand48()) - m_radius) * m_properties->amount;
        y = y + ((2 * m_radius * drand48()) - m_radius) * m_properties->amount;
    }

    // this is wrong for every shape except pixel and anti-aliased pixel


    if (m_properties->useDensity) {
        m_particlesCount = (m_properties->coverage * (M_PI * m_radius * m_radius));
    }
    else {
        m_particlesCount = m_properties->particleCount;
    }

    QHash<QString, QVariant> params;
    qreal nx, ny;
    int ix, iy;

    qreal angle;
    qreal length;
    qreal rotationZ = 0.0;
    qreal particleScale = 1.0;

    bool shouldColor = true;
    if (m_colorProperties->fillBackground) {
        m_painter->setPaintColor(bgColor);
        paintCircle(m_painter, x, y, m_radius);
    }

    QTransform m;
    m.reset();
    m.rotateRadians(-rotation + deg2rad(m_properties->brushRotation));
    m.scale(m_properties->scale, m_properties->scale);

    for (quint32 i = 0; i < m_particlesCount; i++) {
        // generate random angle
        angle = drand48() * M_PI * 2;

        // generate random length
        if (m_properties->gaussian) {
            length = qBound<qreal>(0.0, m_rand->nextGaussian(0.0, 0.50) , 1.0);
        }
        else {
            length = drand48();
        }

        if (m_shapeDynamicsProperties->enabled) {
            // rotation
            rotationZ = rotationAngle();

            if (m_shapeDynamicsProperties->followCursor) {

                rotationZ = linearInterpolation(rotationZ, angle, m_shapeDynamicsProperties->followCursorWeigth);
            }


            if (m_shapeDynamicsProperties->followDrawingAngle) {

                rotationZ = linearInterpolation(rotationZ, info.drawingAngle(), m_shapeDynamicsProperties->followDrawingAngleWeight);
            }

            // random size - scale
            if (m_shapeDynamicsProperties->randomSize) {
                particleScale = drand48();
            }
        }
        // generate polar coordinate
        nx = (m_radius * cos(angle)  * length);
        ny = (m_radius * sin(angle)  * length);

        // compute the height of the ellipse
        ny *= m_properties->aspect;

        // transform
        m.map(nx, ny, &nx, &ny);

        // color transformation

        if (shouldColor) {
            if (m_colorProperties->sampleInputColor) {
                colorPicker.pickOldColor(nx + x, ny + y, m_inkColor.data());
            }

            // mix the color with background color
            if (m_colorProperties->mixBgColor) {
                KoMixColorsOp * mixOp = dab->colorSpace()->mixColorsOp();

                const quint8 *colors[2];
                colors[0] = m_inkColor.data();
                colors[1] = bgColor.data();

                qint16 colorWeights[2];
                int MAX_16BIT = 255;
                qreal blend = info.pressure();

                colorWeights[0] = static_cast<quint16>(blend * MAX_16BIT);
                colorWeights[1] = static_cast<quint16>((1.0 - blend) * MAX_16BIT);
                mixOp->mixColors(colors, colorWeights, 2, m_inkColor.data());
            }

            if (m_colorProperties->useRandomHSV && m_transfo) {
                params["h"] = (m_colorProperties->hue / 180.0) * drand48();
                params["s"] = (m_colorProperties->saturation / 100.0) * drand48();
                params["v"] = (m_colorProperties->value / 100.0) * drand48();
                m_transfo->setParameters(params);
                m_transfo->transform(m_inkColor.data(), m_inkColor.data() , 1);
            }

            if (m_colorProperties->useRandomOpacity) {
                quint8 alpha = qRound(drand48() * OPACITY_OPAQUE_U8);
                m_inkColor.setOpacity(alpha);
                m_painter->setOpacity(alpha);
            }

            if (!m_colorProperties->colorPerParticle) {
                shouldColor = false;
            }
            m_painter->setPaintColor(m_inkColor);
        }

        qreal jitteredWidth = qMax(qreal(1.0), m_shapeProperties->width * particleScale);
        qreal jitteredHeight = qMax(qreal(1.0), m_shapeProperties->height * particleScale);

        if (m_shapeProperties->enabled){
        switch (m_shapeProperties->shape){
            // ellipse
            case 0:
            {
                if (m_shapeProperties->width == m_shapeProperties->height){
                    paintCircle(m_painter, nx + x, ny + y, qRound(jitteredWidth * 0.5));
                }
                else {
                    paintEllipse(m_painter, nx + x, ny + y, qRound(jitteredWidth * 0.5) , qRound(jitteredHeight * 0.5), rotationZ);
                }
                break;
            }
            // rectangle
            case 1:
            {
                paintRectangle(m_painter, nx + x, ny + y, qRound(jitteredWidth) , qRound(jitteredHeight), rotationZ);
                break;
            }
            // wu-particle
            case 2: {
                paintParticle(accessor, m_inkColor, nx + x, ny + y);
                break;
            }
            // pixel
            case 3: {
                ix = qRound(nx + x);
                iy = qRound(ny + y);
                accessor->moveTo(ix, iy);
                memcpy(accessor->rawData(), m_inkColor.data(), m_dabPixelSize);
                break;
            }
            case 4: {
                if (!m_brushQImage.isNull()) {

                    QTransform m;
                    m.rotate(rad2deg(rotationZ));

                    if (m_shapeDynamicsProperties->randomSize) {
                        m.scale(particleScale, particleScale);
                    }
                    m_transformed = m_brushQImage.transformed(m, Qt::SmoothTransformation);
                    m_imageDevice->convertFromQImage(m_transformed, 0);
                    KisRandomAccessorSP ac = m_imageDevice->createRandomAccessorNG(0, 0);
                    QRect rc = m_transformed.rect();

                    if (m_colorProperties->useRandomHSV && m_transfo) {

                        for (int y = rc.y(); y < rc.y() + rc.height(); y++) {
                            for (int x = rc.x(); x < rc.x() + rc.width(); x++) {
                                ac->moveTo(x, y);
                                m_transfo->transform(ac->rawData(), ac->rawData() , 1);
                            }
                        }
                    }

                    ix = qRound(nx + x - rc.width() * 0.5);
                    iy = qRound(ny + y - rc.height() * 0.5);
                    m_painter->bitBlt(QPoint(ix, iy), m_imageDevice, rc);
                    m_imageDevice->clear();
                    break;
                }
            }
            }
            // Auto-brush
        }
        else {
            QPointF hotSpot = m_brush->hotSpot(particleScale, particleScale, -rotationZ, info);
            QPointF pos(nx + x, ny + y);
            QPointF pt = pos - hotSpot;

            qint32 ix;
            qreal xFraction;
            qint32 iy;
            qreal yFraction;

            KisPaintOp::splitCoordinate(pt.x(), &ix, &xFraction);
            KisPaintOp::splitCoordinate(pt.y(), &iy, &yFraction);

            //KisFixedPaintDeviceSP dab;
            if (m_brush->brushType() == IMAGE ||
                    m_brush->brushType() == PIPE_IMAGE) {
                m_fixedDab = m_brush->paintDevice(m_fixedDab->colorSpace(), particleScale, -rotationZ, info, xFraction, yFraction);

                if (m_colorProperties->useRandomHSV && m_transfo) {
                    quint8 * dabPointer = m_fixedDab->data();
                    int pixelCount = m_fixedDab->bounds().width() * m_fixedDab->bounds().height();
                    m_transfo->transform(dabPointer, dabPointer, pixelCount);
                }

            }
            else {
                m_brush->mask(m_fixedDab, m_inkColor, particleScale, particleScale, -rotationZ, info, xFraction, yFraction);
            }
            m_painter->bltFixed(QPoint(ix, iy), m_fixedDab, m_fixedDab->bounds());
        }
    }
    // recover from jittering of color,
    // m_inkColor.opacity is recovered with every paint
}
Exemple #3
0
// Utilizamos esta función sólo para pintar en pantalla. La lógica del programa debe ir en logic
void paint( const World& world ) 
{
	// La pantalla tiene unas dimensiones de 500x500
	changeColor(WHITE);
	plot(0, 0);		// Punto inferior izquierdo
	plot(500, 500); // Punto superior derecho
	plot(499, 0);	// Punto inferior derecho
	plot(0, 499);	// Punto superior izquierdo

	/*changeColor(RED);
	drawQuad(100, 100, 25, 50);

	changeColor(GREEN);
	drawCircle(200, 200, 25);*/

	// Cualquier número que se salga de este margen no se mostrará por pantalla

	//dibujar las estrellas
	changeColor(WHITE);

	paintStars(world.stars);

	//dibujar el cuadrado de informacion
	changeColor(world.infoBox.color);

	paintRectangle(world.infoBox);

	//dibujar el area del juego

	changeColor(world.gameBox.color);

	paintRectangle(world.gameBox);

	printText(10, 475, "TIME:", world.colorTime);
	printText(70, 475, world.time, world.colorTime);

	//string chivato = int2string(world.ship.position.x);

	string levelPlayer = int2string(world.numberLevel+1);
	string livesPlayer = int2string(world.lives);
	string scorePlayer = int2string(world.score);

	printText(170, 475, "LEVEL: ", world.colorTime);
	printText(240, 475, levelPlayer, world.colorTime);

	printText(270, 475, "Lives: ", world.colorTime);
	printText(325, 475, livesPlayer, world.colorTime);

	printText(370, 475, "Score: ", world.colorTime);
	printText(430, 475, scorePlayer, world.colorTime);

	//Pinto los bloques

	for(int i = 0; i < world.blocks.size(); i++) {
		if(world.blocks[i].numberOfImpacts > 0) {
		
			changeColor(world.blocks[i].form.color);

			paintShip(world.blocks[i].form);
		}
	}

	//pintar nave
	paintShip(world.ship);

	//paintShip(world.prueba);

	//plot(215 + world.ship.width, 40);
	//plot(0, 499);

	//pintar pelota
	paintBall(world.ball);

	//dump
	/*string coordenadaX = int2string(world.ship.position.x);
	string limitX = int2string(world.ship.position.x + world.ship.width);

	printText(150, 475, coordenadaX, world.colorTime);
	printText(200, 475, limitX, world.colorTime);*/

	plot(world.includesBall.position.x, world.includesBall.position.y);

	/*if(checkCollision2(world.includesBall, world.ship))
	{
		printText(300, 475, "colision!", world.colorTime);
	}*/


	if(world.states.gameStates == GAMEOVER) {
		printText(200, 250, "GAME OVER", world.colorTime);
		printText(155, 200, "Press space to continue", world.colorTime);

	}else if(world.states.gameStates == WIN) {
		printText(200, 250, "YOU WIN", world.colorTime);
		printText(110, 200, "Press space to continue next level", world.colorTime);
	}


}
Exemple #4
0
void t_libraryEditor::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QBrush polyBrush;
    polyBrush.setColor(g_color);
    QPen dotPen;
    uint8_t minThickness = 4;
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.scale(scale, scale);
    painter.translate(offsetx,offsety);
    painter.setBackgroundMode(Qt::OpaqueMode);
    painter.setBackground(QBrush(QColor(255,255,255)));
    painter.fillRect(-2000,-2000,4000,4000,QColor(255,255,255));

    dotPen.setStyle(Qt::DashLine);
    dotPen.setColor(QColor(200,200,200));
    dotPen.setWidth(0);
    painter.setPen(dotPen);
    for(int16_t x = -2000; x != 2000; x += 50)
    {
        painter.drawLine(x,-2000,x,2000);
        painter.drawLine(-2000,x,2000,x);
    }

    if(haveComp)
    {
        for(uint16_t t = 0; t != currentComponent->items.size(); ++t)
        {
            if(currentComponent->items.at(t)->thickness < minThickness)
                currentComponent->items.at(t)->thickness = minThickness;
            if(currentComponent->items.at(t)->type == 'P')
            {
                t_PolylineObject *ob = static_cast<t_PolylineObject*>(currentComponent->items.at(t));
                paintPolygon(painter, *ob);
            }
            else if(currentComponent->items.at(t)->type == 'C')
            {
                t_CircleObject *ob = static_cast<t_CircleObject*>(currentComponent->items.at(t));
                paintCircle(painter, *ob);
            }
            else if(currentComponent->items.at(t)->type == 'X')
            {
                t_PinObject *ob = static_cast<t_PinObject*>(currentComponent->items.at(t));
                paintPin(painter, *ob);
            }
            else if(currentComponent->items.at(t)->type == 'S')
            {
                t_RectangleObject *ob = static_cast<t_RectangleObject*>(currentComponent->items.at(t));
                paintRectangle(painter, *ob);
            }
            else if(currentComponent->items.at(t)->type == 'A')
            {
                t_ArcObject *ob = static_cast<t_ArcObject*>(currentComponent->items.at(t));
                paintArc(painter, *ob);
            }
        }
        for(uint8_t t = 0; t != currentComponent->fields.size(); ++t)
        {
            t_component_field tF = currentComponent->fields.at(t);
            if(tF.flags & (1 << VISIBLE))
            {
                paintText(painter, tF);
            }
        }
    }

/*    if(incompleteStage)
    {
        dotPen.setWidth(5);
        dotPen.setStyle(Qt::SolidLine);
        dotPen.setColor(QColor(200,100,100));
        painter.setPen(dotPen);
        painter.drawLine(incompleteLine);
    }
    else if(pinPlacement)
    {
        dotPen.setWidth(1);
        dotPen.setColor(QColor(100,200,100));
        painter.setPen(dotPen);
        painter.drawEllipse(incompleteLine.p2(), 10, 10);
    }
    */
    dotPen.setColor(QColor(100,100,100));
    dotPen.setWidth(1);
    painter.setPen(dotPen);
    painter.drawLine(0,-10,0,10);
    painter.drawLine(-10,0,10,0);
    event->accept();
}
Exemple #5
0
void detectFace(bit_image_t *faceMask, image_t *rawImage)
{
  int *histX;
  int *histY;
  int x, y;
  int pIndex;
  rgb_color_t c;
  int i, j;
  int width, height;
  int maxHistX, maxHistY;
  int faceX, faceY;

  int histXLen, histYLen;
  int *aboveThresholdX;
  int *aboveThresholdY;
  int aboveThresholdXLen;
  int aboveThresholdYLen;

  rect_t resultRect = {0, 0, 0, 0};
  int maxArea;

  // compute histogramm
  histXLen = faceMask->width;
  histYLen = faceMask->height;
  histX = (int *)malloc(histXLen*sizeof(int));
  histY = (int *)malloc(histYLen*sizeof(int));

  memset(histX, 0, faceMask->width*sizeof(int));
  memset(histY, 0, faceMask->height*sizeof(int));

  uint16_t bpIndex=0;
  uint8_t byteIndex=0;
  for (y = 0; y < faceMask->height; y++) {
    for (x = 0; x < faceMask->width; x++) {

      if(faceMask->data[bpIndex]>>byteIndex){
	histX[x]++;
	histY[y]++;
      }
      
      byteIndex++;
      if(byteIndex>=8){
        byteIndex=0;
        bpIndex++;
      }
    }
  }

  // find maximum histgram value and related xy-coordinate
  maxHistX = 0;
  for (i = 0; i < faceMask->width; i++) {
    if (histX[i] > maxHistX) {
      maxHistX = histX[i];
      faceX = i;
    }
  }
  maxHistY = 0;
  for (i = 0; i < faceMask->height; i++) {
    if (histY[i] > maxHistY) {
      maxHistY = histY[i];
      faceY = i;
    }
  }

  // select coordinates where histogram value is above half 
  // of max hist value
  aboveThresholdX = (int *)malloc(histXLen*sizeof(int));
  aboveThresholdY = (int *)malloc(histYLen*sizeof(int));
  j = 0;
  for (i=0; i < histXLen; i+=STEP_SIZE) {
    if (histX[i] > maxHistX/2) {
      aboveThresholdX[j] = i;
      j++;
    }
  }
  aboveThresholdXLen = j;

  j = 0;
  for (i=0; i < histYLen; i+=STEP_SIZE) {
    if (histY[i] > maxHistY/2) {
      aboveThresholdY[j] = i;
      j++;
    }
  }
  aboveThresholdYLen = j;

  // compute candidate face regions and pick the
  // one with the largest area
  maxArea=0;
  for (i=0; i<aboveThresholdYLen; i++) {
    for (j=0; j<aboveThresholdXLen; j++) {
      rect_t r;
      int area;      

      r.topLeftX = getIndexBelowThreshold(histX, histXLen, aboveThresholdX[j], -1, maxHistX/6);
      r.bottomRightX = getIndexBelowThreshold(histX, histXLen, aboveThresholdX[j], 1, maxHistX/6);
      r.topLeftY = getIndexBelowThreshold(histY, histYLen, aboveThresholdY[i], -1, maxHistY/9);
      r.bottomRightY = getIndexBelowThreshold(histY, histYLen, aboveThresholdY[i], 1, maxHistY/9);

      width = r.bottomRightX-r.topLeftX;
      height = r.bottomRightY-r.topLeftY;
      area = width*height;

      if (area > maxArea) {
	resultRect = r;	
	maxArea = area;
      }
    }
  }

  free(aboveThresholdX);
  free(aboveThresholdY);
  free(histX);
  free(histY);

  if (maxArea > 0) {
    // adjust face proportions, assume upright faces
    // typical face proportions: width:height = 2:3
    width = resultRect.bottomRightX-resultRect.topLeftX;
    height = resultRect.bottomRightY-resultRect.topLeftY;
    if (width < height) {
      if (height > width/2*3) {
	resultRect.bottomRightY = resultRect.topLeftY + width/2*3;
      }
    }

    printf("selected rect: topLeft=(%d, %d), bottomRight=(%d, %d)\n", resultRect.topLeftX, resultRect.topLeftY, resultRect.bottomRightX, resultRect.bottomRightY);
    
    paintRectangle(rawImage, resultRect);
  }
}
Exemple #6
0
void SprayBrush::paint(KisPaintDeviceSP dev, const KisPaintInformation& info, const KoColor &color)
{
    qreal x = info.pos().x();
    qreal y = info.pos().y();

    // initializing painter
    KisPainter drawer(dev);
    drawer.setPaintColor(color);

    // jitter radius
    int tmpRadius = m_radius;
    if (m_jitterSize){
        m_radius = m_radius * drand48();
    }

    // jitter movement
    if (m_jitterMovement){
        x = x + (( 2 * m_radius * drand48() ) - m_radius) * m_amount;
        y = y + (( 2 * m_radius * drand48() ) - m_radius) * m_amount;
    }

    KisRandomAccessor accessor = dev->createRandomAccessor( qRound(x), qRound(y) );
    m_pixelSize = dev->colorSpace()->pixelSize();
    m_inkColor = color;
    m_counter++;

    // coverage: adaptively select how many objects are sprayed per paint
    if (m_useDensity){
        m_particlesCount = (m_coverage * (M_PI * m_radius * m_radius) );
    }

    // Metaballs are rendered little differently
    if (m_shape == 2 && m_object == 0){
        paintMetaballs(dev, info, color);
    }

    qreal nx, ny;
    int ix, iy;

    qreal angle;
    qreal lengthX;
    qreal lengthY;
    
    
    for (int i = 0; i < m_particlesCount; i++){
        // generate random angle
        angle = drand48() * M_PI * 2;
        // different X and Y length??
        lengthY = lengthX = drand48();
        // I hope we live the era where sin and cos is not slow for spray
        nx = (sin(angle) * m_radius * lengthX);
        ny = (cos(angle) * m_radius * lengthY);

        // transform
        nx *= m_scale;
        ny *= m_scale;

        // it is some shape (circle, ellipse, rectangle)
        if (m_object == 0)
        {
            // steps for single step in circle and ellipse
            int steps = 36;
            qreal random = drand48();       

            drawer.setFillColor(m_inkColor);
            drawer.setBackgroundColor(m_inkColor);
            drawer.setPaintColor(m_inkColor);
            // it is ellipse
            if (m_shape == 0){
                //  
                qreal ellipseA = m_width / 2.0;
                qreal ellipseB = m_height / 2.0;

                if (m_width == m_height)
                {
                    if (m_jitterShapeSize){
                        paintCircle(drawer, nx + x, ny + y, int((random * ellipseA) + 1.5) , steps);
                    } else{
                        paintCircle(drawer, nx + x, ny + y, qRound(ellipseA)  , steps);
                    }
                } else 
                {
                    if (m_jitterShapeSize){
                        paintEllipse(drawer, nx + x, ny + y,int((random * ellipseA) + 1.5) ,int((random * ellipseB) + 1.5), angle , steps);
                    } else{
                        paintEllipse(drawer, nx + x, ny + y, qRound(ellipseA), qRound(ellipseB), angle , steps);
                    }
                }
            } else if (m_shape == 1)
            {
                if (m_jitterShapeSize){
                    paintRectangle(drawer, nx + x, ny + y,int((random * m_width) + 1.5) ,int((random * m_height) + 1.5), angle , steps);
                } else{
                    paintRectangle(drawer, nx + x, ny + y, qRound(m_width), qRound(m_height), angle , steps);
                }
            }    
        // it is pixel particle
        }else if (m_object == 1){
            paintParticle(accessor,m_inkColor,nx + x, ny + y);
        }
        // it is pixel
        else if (m_object == 2)
        {
            ix = qRound(nx + x);
            iy = qRound(ny + y);
            accessor.moveTo(ix, iy);
            memcpy(accessor.rawData(), m_inkColor.data(), m_pixelSize);
        }
    }

    

    // hidden code for outline detection
    //m_inkColor.setOpacity(128);
    //paintOutline(dev,m_inkColor,x, y, m_radius * 2);

    // recover from jittering of color
    m_radius = tmpRadius;
}