void KisVisualColorSelectorShape::setColor(KoColor c) { //qDebug() << this << "KisVisualColorSelectorShape::setColor"; if (c.colorSpace() != m_d->colorSpace) { c.convertTo(m_d->colorSpace); } m_d->currentColor = c; updateCursor(); m_d->imagesNeedUpdate = true; update(); }
void KisOcioDisplayFilterTest::test() { KisExposureGammaCorrectionInterface *egInterface = new KisDumbExposureGammaCorrectionInterface(); OcioDisplayFilter filter(egInterface); QString configFile = TestUtil::fetchDataFileLazy("./psyfiTestingConfig-master/config.ocio"); dbgKrita << ppVar(configFile); Q_ASSERT(QFile::exists(configFile)); OCIO::ConstConfigRcPtr ocioConfig = OCIO::Config::CreateFromFile(configFile.toUtf8()); filter.config = ocioConfig; filter.inputColorSpaceName = ocioConfig->getColorSpaceNameByIndex(0); filter.displayDevice = ocioConfig->getDisplay(1); filter.view = ocioConfig->getView(filter.displayDevice, 0); filter.gamma = 1.0; filter.exposure = 0.0; filter.swizzle = RGBA; filter.blackPoint = 0.0; filter.whitePoint = 1.0; filter.forceInternalColorManagement = false; filter.setLockCurrentColorVisualRepresentation(false); filter.updateProcessor(); dbgKrita << ppVar(filter.inputColorSpaceName); dbgKrita << ppVar(filter.displayDevice); dbgKrita << ppVar(filter.view); dbgKrita << ppVar(filter.gamma); dbgKrita << ppVar(filter.exposure); const KoColorSpace *paintingCS = KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), Float32BitsColorDepthID.id(), 0); KisImageSP image = utils::createImage(0, QSize(100, 100)); image->convertImageColorSpace(paintingCS, KoColorConversionTransformation::InternalRenderingIntent, KoColorConversionTransformation::InternalConversionFlags); image->waitForDone(); dbgKrita << ppVar(paintingCS) << ppVar(image->root()->firstChild()->colorSpace()); KoCanvasResourceManager *resourceManager = utils::createResourceManager(image, image->root(), ""); KisDisplayColorConverter converter(resourceManager, 0); dbgKrita << ppVar(image->root()->firstChild()); QVariant v; v.setValue(KisNodeWSP(image->root()->firstChild())); resourceManager->setResource(KisCanvasResourceProvider::CurrentKritaNode, v); converter.setDisplayFilter(&filter); dbgKrita << ppVar(converter.paintingColorSpace()); { QColor refColor(255, 128, 0); KoColor realColor = converter.approximateFromRenderedQColor(refColor); QColor roundTripColor = converter.toQColor(realColor); dbgKrita << ppVar(refColor); dbgKrita << ppVar(realColor.colorSpace()) << ppVar(KoColor::toQString(realColor)); dbgKrita << ppVar(roundTripColor); } { KoColor realColor(Qt::red, paintingCS); QColor roundTripColor = converter.toQColor(realColor); dbgKrita << ppVar(realColor.colorSpace()) << ppVar(KoColor::toQString(realColor)); dbgKrita << ppVar(roundTripColor); } }
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 }
void setFillColor(const KoColor &sourceColor) { m_sourceColor = sourceColor; m_pixelSize = sourceColor.colorSpace()->pixelSize(); m_data = m_sourceColor.data(); }
void KoColor::fromKoColor(const KoColor& src) { src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace(), 1); }
bool KoColor::operator==(const KoColor &other) const { if (!(*colorSpace() == *other.colorSpace())) return false; return memcmp(d->data, other.d->data, d->colorSpace->pixelSize()) == 0; }
QPointF KisVisualColorSelectorShape::convertKoColorToShapeCoordinate(KoColor c) { ////qDebug() << this << ">>>>>>>>> convertKoColorToShapeCoordinate()"; if (c.colorSpace() != m_d->colorSpace) { c.convertTo(m_d->colorSpace); } QVector <float> channelValues (m_d->currentColor.colorSpace()->channelCount()); channelValues.fill(1.0); m_d->colorSpace->normalisedChannelsValue(c.data(), channelValues); QVector <float> channelValuesDisplay = channelValues; QVector <qreal> maxvalue(c.colorSpace()->channelCount()); maxvalue.fill(1.0); if (m_d->displayRenderer && (m_d->colorSpace->colorDepthId() == Float16BitsColorDepthID || m_d->colorSpace->colorDepthId() == Float32BitsColorDepthID || m_d->colorSpace->colorDepthId() == Float64BitsColorDepthID) && m_d->colorSpace->colorModelId() != LABAColorModelID && m_d->colorSpace->colorModelId() != CMYKAColorModelID) { for (int ch = 0; ch<maxvalue.size(); ch++) { KoChannelInfo *channel = m_d->colorSpace->channels()[ch]; maxvalue[ch] = m_d->displayRenderer->maxVisibleFloatValue(channel); channelValues[ch] = channelValues[ch]/(maxvalue[ch]); channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(ch, m_d->colorSpace->channels())] = channelValues[ch]; } } else { for (int i =0; i<channelValues.size();i++) { channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(i, m_d->colorSpace->channels())] = qBound((float)0.0,channelValues[i], (float)1.0); } } QPointF coordinates(0.0,0.0); qreal huedivider = 1.0; qreal huedivider2 = 1.0; if (m_d->channel1==0) { huedivider = 360.0; } if (m_d->channel2==0) { huedivider2 = 360.0; } if (m_d->model != ColorModel::Channel && c.colorSpace()->colorModelId().id() == "RGBA") { if (c.colorSpace()->colorModelId().id() == "RGBA") { if (m_d->model == ColorModel::HSV){ QVector <float> inbetween(3); RGBToHSV(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); coordinates.setX(inbetween[m_d->channel1]/huedivider); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]/huedivider2); } } else if (m_d->model == ColorModel::HSL) { QVector <float> inbetween(3); RGBToHSL(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); coordinates.setX(inbetween[m_d->channel1]/huedivider); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]/huedivider2); } } else if (m_d->model == ColorModel::HSI) { QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay); QVector <qreal> inbetween(3); RGBToHSI(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = getHSX(inbetween); coordinates.setX(inbetween[m_d->channel1]); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]); } } else if (m_d->model == ColorModel::HSY) { QVector <qreal> luma = m_d->colorSpace->lumaCoefficients(); QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay); QVector <qreal> inbetween(3); RGBToHSY(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2], luma[0], luma[1], luma[2]); inbetween = getHSX(inbetween); coordinates.setX(inbetween[m_d->channel1]); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(inbetween[m_d->channel2]); } } } } else { coordinates.setX(qBound((float)0.0, channelValuesDisplay[m_d->channel1], (float)1.0)); if (m_d->dimension == Dimensions::twodimensional) { coordinates.setY(qBound((float)0.0, channelValuesDisplay[m_d->channel2], (float)1.0)); } } return coordinates; }
KoColor KisVisualColorSelectorShape::convertShapeCoordinateToKoColor(QPointF coordinates, bool cursor) { //qDebug() << this << ">>>>>>>>> convertShapeCoordinateToKoColor()" << coordinates; KoColor c = m_d->currentColor; QVector <float> channelValues (c.colorSpace()->channelCount()); channelValues.fill(1.0); c.colorSpace()->normalisedChannelsValue(c.data(), channelValues); QVector <float> channelValuesDisplay = channelValues; QVector <qreal> maxvalue(c.colorSpace()->channelCount()); maxvalue.fill(1.0); if (m_d->displayRenderer && (m_d->colorSpace->colorDepthId() == Float16BitsColorDepthID || m_d->colorSpace->colorDepthId() == Float32BitsColorDepthID || m_d->colorSpace->colorDepthId() == Float64BitsColorDepthID) && m_d->colorSpace->colorModelId() != LABAColorModelID && m_d->colorSpace->colorModelId() != CMYKAColorModelID) { for (int ch = 0; ch < maxvalue.size(); ch++) { KoChannelInfo *channel = m_d->colorSpace->channels()[ch]; maxvalue[ch] = m_d->displayRenderer->maxVisibleFloatValue(channel); channelValues[ch] = channelValues[ch]/(maxvalue[ch]); channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(ch, m_d->colorSpace->channels())] = channelValues[ch]; } } else { for (int i =0; i < channelValues.size();i++) { channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(i, m_d->colorSpace->channels())] = qBound((float)0.0,channelValues[i], (float)1.0); } } qreal huedivider = 1.0; qreal huedivider2 = 1.0; if (m_d->channel1 == 0) { huedivider = 360.0; } if (m_d->channel2 == 0) { huedivider2 = 360.0; } if (m_d->model != ColorModel::Channel && c.colorSpace()->colorModelId().id() == "RGBA") { if (m_d->model == ColorModel::HSV) { /* * RGBToHSV has a undefined hue possibility. This means that hue will be -1. * This can be annoying for dealing with a selector, but I understand it is being * used for the KoColorSelector... For now implement a qMax here. */ QVector <float> inbetween(3); RGBToHSV(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); inbetween[m_d->channel1] = coordinates.x()*huedivider; if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y()*huedivider2; } if (cursor) { setHSX(convertvectorfloatToqreal(inbetween)); Q_EMIT sigHSXchange(); } HSVToRGB(qMax(inbetween[0],(float)0.0), inbetween[1], inbetween[2], &channelValuesDisplay[0], &channelValuesDisplay[1], &channelValuesDisplay[2]); } else if (m_d->model == ColorModel::HSL) { /* * HSLToRGB can give negative values on the grey. I fixed the fromNormalisedChannel function to clamp, * but you might want to manually clamp for floating point values. */ QVector <float> inbetween(3); RGBToHSL(channelValuesDisplay[0],channelValuesDisplay[1], channelValuesDisplay[2], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = convertvectorqrealTofloat(getHSX(convertvectorfloatToqreal(inbetween))); inbetween[m_d->channel1] = fmod(coordinates.x()*huedivider, 360.0); if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y()*huedivider2; } if (cursor) { setHSX(convertvectorfloatToqreal(inbetween)); Q_EMIT sigHSXchange(); } HSLToRGB(qMax(inbetween[0], (float)0.0), inbetween[1], inbetween[2], &channelValuesDisplay[0], &channelValuesDisplay[1], &channelValuesDisplay[2]); } else if (m_d->model == ColorModel::HSI) { /* * HSI is a modified HSY function. */ QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay); QVector <qreal> inbetween(3); RGBToHSI(chan2[0],chan2[1], chan2[2], &inbetween[0], &inbetween[1], &inbetween[2]); inbetween = getHSX(inbetween); inbetween[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y(); } if (cursor) { setHSX(inbetween); Q_EMIT sigHSXchange(); } HSIToRGB(inbetween[0], inbetween[1], inbetween[2],&chan2[0],&chan2[1], &chan2[2]); channelValuesDisplay = convertvectorqrealTofloat(chan2); } else /*if (m_d->model == ColorModel::HSY)*/ { /* * HSY is pretty slow to render due being a pretty over-the-top function. * Might be worth investigating whether HCY can be used instead, but I have had * some weird results with that. */ QVector <qreal> luma= m_d->colorSpace->lumaCoefficients(); QVector <qreal> chan2 = convertvectorfloatToqreal(channelValuesDisplay); QVector <qreal> inbetween(3); RGBToHSY(chan2[0],chan2[1], chan2[2], &inbetween[0], &inbetween[1], &inbetween[2], luma[0], luma[1], luma[2]); inbetween = getHSX(inbetween); inbetween[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { inbetween[m_d->channel2] = coordinates.y(); } if (cursor) { setHSX(inbetween); Q_EMIT sigHSXchange(); } HSYToRGB(inbetween[0], inbetween[1], inbetween[2],&chan2[0],&chan2[1], &chan2[2], luma[0], luma[1], luma[2]); channelValuesDisplay = convertvectorqrealTofloat(chan2); } } else { channelValuesDisplay[m_d->channel1] = coordinates.x(); if (m_d->dimension == Dimensions::twodimensional) { channelValuesDisplay[m_d->channel2] = coordinates.y(); } } for (int i=0; i<channelValues.size();i++) { channelValues[i] = channelValuesDisplay[KoChannelInfo::displayPositionToChannelIndex(i, m_d->colorSpace->channels())]*(maxvalue[i]); } c.colorSpace()->fromNormalisedChannelsValue(c.data(), channelValues); return c; }
void KoColor::fromKoColor(const KoColor& src) { src.colorSpace()->convertPixelsTo(src.d->data, d->data, colorSpace(), 1, KoColorConversionTransformation::InternalRenderingIntent, KoColorConversionTransformation::InternalConversionFlags); }
void cutOneWay(const KoColor &color, KisPaintDeviceSP src, KisPaintDeviceSP colorScribble, KisPaintDeviceSP backgroundScribble, KisPaintDeviceSP resultDevice, KisPaintDeviceSP maskDevice, const QRect &boundingRect) { using namespace boost; KIS_ASSERT_RECOVER_RETURN(src->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(colorScribble->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(backgroundScribble->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(maskDevice->pixelSize() == 1); KIS_ASSERT_RECOVER_RETURN(*resultDevice->colorSpace() == *color.colorSpace()); KisLazyFillCapacityMap capacityMap(src, colorScribble, backgroundScribble, maskDevice, boundingRect); KisLazyFillGraph &graph = capacityMap.graph(); std::vector<default_color_type> groups(num_vertices(graph)); std::vector<int> residual_capacity(num_edges(graph), 0); std::vector<typename graph_traits<KisLazyFillGraph>::vertices_size_type> distance_vec(num_vertices(graph), 0); std::vector<typename graph_traits<KisLazyFillGraph>::edge_descriptor> predecessor_vec(num_vertices(graph)); auto vertexIndexMap = get(boost::vertex_index, graph); typedef KisLazyFillGraph::vertex_descriptor Vertex; Vertex s(Vertex::LABEL_A); Vertex t(Vertex::LABEL_B); float maxFlow = boykov_kolmogorov_max_flow(graph, capacityMap, make_iterator_property_map(&residual_capacity[0], get(boost::edge_index, graph)), get(boost::edge_reverse, graph), make_iterator_property_map(&predecessor_vec[0], vertexIndexMap), make_iterator_property_map(&groups[0], vertexIndexMap), make_iterator_property_map(&distance_vec[0], vertexIndexMap), vertexIndexMap, s, t); Q_UNUSED(maxFlow); KisSequentialIterator dstIt(resultDevice, graph.rect()); KisSequentialIterator mskIt(maskDevice, graph.rect()); const int pixelSize = resultDevice->pixelSize(); do { KisLazyFillGraph::vertex_descriptor v(dstIt.x(), dstIt.y()); long vertex_idx = get(boost::vertex_index, graph, v); default_color_type label = groups[vertex_idx]; if (label == black_color) { memcpy(dstIt.rawData(), color.data(), pixelSize); *mskIt.rawData() = 10 + (int(label) << 4); } } while (dstIt.nextPixel() && mskIt.nextPixel()); }
void KoColorSlider::drawContents( QPainter *painter ) { QPixmap checker(8, 8); QPainter p(&checker); p.fillRect(0, 0, 4, 4, Qt::lightGray); p.fillRect(4, 0, 4, 4, Qt::darkGray); p.fillRect(0, 4, 4, 4, Qt::darkGray); p.fillRect(4, 4, 4, 4, Qt::lightGray); p.end(); QRect contentsRect_(contentsRect()); painter->fillRect(contentsRect_, QBrush(checker)); if( !d->upToDate || d->pixmap.isNull() || d->pixmap.width() != contentsRect_.width() || d->pixmap.height() != contentsRect_.height() ) { KoColor c = d->minColor; // smart way to fetch colorspace QColor color; const quint8 *colors[2]; colors[0] = d->minColor.data(); colors[1] = d->maxColor.data(); KoMixColorsOp * mixOp = c.colorSpace()->mixColorsOp(); QImage image(contentsRect_.width(), contentsRect_.height(), QImage::Format_ARGB32 ); if( orientation() == Qt::Horizontal ) { for (int x = 0; x < contentsRect_.width(); x++) { qreal t = static_cast<qreal>(x) / (contentsRect_.width() - 1); qint16 colorWeights[2]; colorWeights[0] = static_cast<quint8>((1.0 - t) * 255 + 0.5); colorWeights[1] = 255 - colorWeights[0]; mixOp->mixColors(colors, colorWeights, 2, c.data()); c.toQColor(&color); for (int y = 0; y < contentsRect_.height(); y++) image.setPixel(x, y, color.rgba()); } } else { for (int y = 0; y < contentsRect_.height(); y++) { qreal t = static_cast<qreal>(y) / (contentsRect_.height() - 1); qint16 colorWeights[2]; colorWeights[0] = static_cast<quint8>((t) * 255 + 0.5); colorWeights[1] = 255 - colorWeights[0]; mixOp->mixColors(colors, colorWeights, 2, c.data()); c.toQColor(&color); for (int x = 0; x < contentsRect_.width(); x++) image.setPixel(x, y, color.rgba()); } } d->pixmap = QPixmap::fromImage(image); d->upToDate = true; } painter->drawPixmap( contentsRect_, d->pixmap, QRect( 0, 0, d->pixmap.width(), d->pixmap.height()) ); }
void KoUniColorChooser::updateValues() { KoColor tmpColor; m_HIn->blockSignals(true); m_SIn->blockSignals(true); m_VIn->blockSignals(true); m_RIn->blockSignals(true); m_GIn->blockSignals(true); m_BIn->blockSignals(true); if (cmykColorSpace()) { m_CIn->blockSignals(true); m_MIn->blockSignals(true); m_YIn->blockSignals(true); m_KIn->blockSignals(true); } m_LIn->blockSignals(true); m_aIn->blockSignals(true); m_bIn->blockSignals(true); /* KoOldColor color = m_fgColor; int h = color.H(); int s = color.S(); int v = color.V(); m_HIn->setValue(h); m_SIn->setValue(s); m_VIn->setValue(v); */ tmpColor = m_currentColor; tmpColor.convertTo(rgbColorSpace()); m_RIn->setValue(tmpColor.data()[2]); m_GIn->setValue(tmpColor.data()[1]); m_BIn->setValue(tmpColor.data()[0]); if(m_showOpacitySlider) { m_opacitySlider->blockSignals(true); m_opacityIn->blockSignals(true); KoColor minColor = tmpColor; tmpColor.colorSpace()->setOpacity(minColor.data(), OPACITY_TRANSPARENT_U8, 1); KoColor maxColor = tmpColor; tmpColor.colorSpace()->setOpacity(maxColor.data(), OPACITY_OPAQUE_U8, 1); m_opacitySlider->setColors(minColor, maxColor); m_opacitySlider->setValue(tmpColor.opacityF() * 100 ); m_opacityIn->setValue(tmpColor.opacityF() * 100 ); m_opacityIn->blockSignals(false); m_opacitySlider->blockSignals(false); } tmpColor = m_currentColor; tmpColor.convertTo(labColorSpace()); m_LIn->setValue(((quint16 *)tmpColor.data())[0]/(256*256/100)); m_aIn->setValue(((quint16 *)tmpColor.data())[1]/256); m_bIn->setValue(((quint16 *)tmpColor.data())[2]/256); if ( cmykColorSpace() ) { tmpColor = m_currentColor; tmpColor.convertTo(cmykColorSpace()); m_CIn->setValue((tmpColor.data()[0]*100)/255); m_MIn->setValue((tmpColor.data()[1]*100/255)); m_YIn->setValue((tmpColor.data()[2]*100)/255); m_KIn->setValue((tmpColor.data()[3]*100)/255); } m_HIn->blockSignals(false); m_SIn->blockSignals(false); m_VIn->blockSignals(false); m_RIn->blockSignals(false); m_GIn->blockSignals(false); m_BIn->blockSignals(false); if (cmykColorSpace()) { m_CIn->blockSignals(false); m_MIn->blockSignals(false); m_YIn->blockSignals(false); m_KIn->blockSignals(false); } m_LIn->blockSignals(false); m_aIn->blockSignals(false); m_bIn->blockSignals(false); }
KisSpacingInformation KisColorSmudgeOp::paintAt(const KisPaintInformation& info) { KisBrushSP brush = m_brush; // Simple error catching if (!painter()->device() || !brush || !brush->canPaintFor(info)) { return KisSpacingInformation(1.0); } if (m_smudgeRateOption.getMode() == KisSmudgeOption::SMEARING_MODE) { /** * Disable handling of the subpixel precision. In the smudge op we * should read from the aligned areas of the image, so having * additional internal offsets, created by the subpixel precision, * will worsen the quality (at least because * QRectF(m_dstDabRect).center() will not point to the real center * of the brush anymore). * Of course, this only really matters with smearing_mode (bug:327235), * and you only notice the lack of subpixel precision in the dulling methods. */ m_dabCache->disableSubpixelPrecision(); } //if precision KoColor colorSpaceChanger = painter()->paintColor(); const KoColorSpace* preciseColorSpace = colorSpaceChanger.colorSpace(); /*if (colorSpaceChanger.colorSpace()->colorDepthId().id() == "U8") { preciseColorSpace = KoColorSpaceRegistry::instance()->colorSpace(colorSpaceChanger.colorSpace()->colorModelId().id(), "U16", colorSpaceChanger.profile() ); colorSpaceChanger.convertTo(preciseColorSpace); } painter()->setPaintColor(colorSpaceChanger);*/ // get the scaling factor calculated by the size option qreal scale = m_sizeOption.apply(info); scale *= KisLodTransform::lodToScale(painter()->device()); qreal rotation = m_rotationOption.apply(info); if (checkSizeTooSmall(scale)) return KisSpacingInformation(); setCurrentScale(scale); setCurrentRotation(rotation); QPointF scatteredPos = m_scatterOption.apply(info, brush->maskWidth(scale, rotation, 0, 0, info), brush->maskHeight(scale, rotation, 0, 0, info)); QPointF hotSpot = brush->hotSpot(scale, scale, rotation, info); /** * Update the brush mask. * * Upon leaving the function: * o m_maskDab stores the new mask * o m_maskBounds stores the extents of the mask paint device * o m_dstDabRect stores the destination rect where the mask is going * to be written to */ updateMask(info, scale, rotation, scatteredPos); QPointF newCenterPos = QRectF(m_dstDabRect).center(); /** * Save the center of the current dab to know where to read the * data during the next pass. We do not save scatteredPos here, * because it may differ slightly from the real center of the * brush (due to rounding effects), which will result in a * really weird quality. */ QRect srcDabRect = m_dstDabRect.translated((m_lastPaintPos - newCenterPos).toPoint()); m_lastPaintPos = newCenterPos; KisSpacingInformation spacingInfo = effectiveSpacing(scale, rotation, m_spacingOption, info); if (m_firstRun) { m_firstRun = false; return spacingInfo; } // save the old opacity value and composite mode quint8 oldOpacity = painter()->opacity(); QString oldCompositeOpId = painter()->compositeOp()->id(); qreal fpOpacity = (qreal(oldOpacity) / 255.0) * m_opacityOption.getOpacityf(info); if (m_image && m_overlayModeOption.isChecked()) { m_image->blockUpdates(); m_backgroundPainter->bitBlt(QPoint(), m_image->projection(), srcDabRect); m_image->unblockUpdates(); } else { // IMPORTANT: clear the temporary painting device to color black with zero opacity: // it will only clear the extents of the brush. m_tempDev->clear(QRect(QPoint(), m_dstDabRect.size())); } if (m_smudgeRateOption.getMode() == KisSmudgeOption::SMEARING_MODE) { m_smudgePainter->bitBlt(QPoint(), painter()->device(), srcDabRect); } else { QPoint pt = (srcDabRect.topLeft() + hotSpot).toPoint(); if (m_smudgeRadiusOption.isChecked()) { qreal effectiveSize = 0.5 * (m_dstDabRect.width() + m_dstDabRect.height()); m_smudgeRadiusOption.apply(*m_smudgePainter, info, effectiveSize, pt.x(), pt.y(), painter()->device()); KoColor color2 = m_smudgePainter->paintColor(); m_smudgePainter->fill(0, 0, m_dstDabRect.width(), m_dstDabRect.height(), color2); } else { KoColor color = painter()->paintColor(); // get the pixel on the canvas that lies beneath the hot spot // of the dab and fill the temporary paint device with that color KisCrossDeviceColorPickerInt colorPicker(painter()->device(), color); colorPicker.pickColor(pt.x(), pt.y(), color.data()); m_smudgePainter->fill(0, 0, m_dstDabRect.width(), m_dstDabRect.height(), color); } } // if the user selected the color smudge option, // we will mix some color into the temporary painting device (m_tempDev) if (m_colorRateOption.isChecked()) { // this will apply the opacity (selected by the user) to copyPainter // (but fit the rate inbetween the range 0.0 to (1.0-SmudgeRate)) qreal maxColorRate = qMax<qreal>(1.0 - m_smudgeRateOption.getRate(), 0.2); m_colorRateOption.apply(*m_colorRatePainter, info, 0.0, maxColorRate, fpOpacity); // paint a rectangle with the current color (foreground color) // or a gradient color (if enabled) // into the temporary painting device and use the user selected // composite mode KoColor color = painter()->paintColor(); m_gradientOption.apply(color, m_gradient, info); m_colorRatePainter->fill(0, 0, m_dstDabRect.width(), m_dstDabRect.height(), color); } // if color is disabled (only smudge) and "overlay mode" is enabled // then first blit the region under the brush from the image projection // to the painting device to prevent a rapid build up of alpha value // if the color to be smudged is semi transparent. if (m_image && m_overlayModeOption.isChecked() && !m_colorRateOption.isChecked()) { painter()->setCompositeOp(COMPOSITE_COPY); painter()->setOpacity(OPACITY_OPAQUE_U8); m_image->blockUpdates(); painter()->bitBlt(m_dstDabRect.topLeft(), m_image->projection(), m_dstDabRect); m_image->unblockUpdates(); } // set opacity calculated by the rate option m_smudgeRateOption.apply(*painter(), info, 0.0, 1.0, fpOpacity); // then blit the temporary painting device on the canvas at the current brush position // the alpha mask (maskDab) will be used here to only blit the pixels that are in the area (shape) of the brush painter()->setCompositeOp(COMPOSITE_COPY); painter()->bitBltWithFixedSelection(m_dstDabRect.x(), m_dstDabRect.y(), m_tempDev, m_maskDab, m_dstDabRect.width(), m_dstDabRect.height()); painter()->renderMirrorMaskSafe(m_dstDabRect, m_tempDev, 0, 0, m_maskDab, !m_dabCache->needSeparateOriginal()); // restore orginal opacy and composite mode values painter()->setOpacity(oldOpacity); painter()->setCompositeOp(oldCompositeOpId); return spacingInfo; }