void BrushPreview::updatePreview() { #ifndef DESIGNER_PLUGIN if(!m_preview) { m_preview = new paintcore::LayerStack; m_previewCache = new paintcore::LayerStackPixmapCacheObserver(this); m_previewCache->attachToLayerStack(m_preview); } auto layerstack = m_preview->editor(0); if(m_preview->width() == 0) { const QSize size = contentsRect().size(); layerstack.resize(0, size.width(), size.height(), 0); layerstack.createLayer(0, 0, QColor(0,0,0), false, false, QString()); } else if(m_preview->width() != contentsRect().width() || m_preview->height() != contentsRect().height()) { layerstack.resize(0, contentsRect().width() - m_preview->width(), contentsRect().height() - m_preview->height(), 0); } QRectF previewRect( m_preview->width()/8, m_preview->height()/4, m_preview->width()-m_preview->width()/4, m_preview->height()-m_preview->height()/2 ); paintcore::PointVector pointvector; switch(_shape) { case Stroke: pointvector = brushes::shapes::sampleStroke(previewRect); break; case Line: pointvector << paintcore::Point(previewRect.left(), previewRect.top(), 1.0) << paintcore::Point(previewRect.right(), previewRect.bottom(), 1.0); break; case Rectangle: pointvector = brushes::shapes::rectangle(previewRect); break; case Ellipse: pointvector = brushes::shapes::ellipse(previewRect); break; case FloodFill: case FloodErase: pointvector = brushes::shapes::sampleBlob(previewRect); break; } QColor bgcolor = m_bg; brushes::ClassicBrush brush = m_brush; // Special handling for some blending modes // TODO this could be implemented in some less ad-hoc way if(brush.blendingMode() == paintcore::BlendMode::MODE_BEHIND) { // "behind" mode needs a transparent layer for anything to show up brush.setBlendingMode(paintcore::BlendMode::MODE_NORMAL); } else if(brush.blendingMode() == paintcore::BlendMode::MODE_COLORERASE) { // Color-erase mode: use fg color as background bgcolor = m_color; } if(_shape == FloodFill) { brush.setColor(bgcolor); } auto layer = layerstack.getEditableLayerByIndex(0); layer.putTile(0, 0, 99999, isTransparentBackground() ? paintcore::Tile() : paintcore::Tile(bgcolor)); brushes::BrushEngine brushengine; brushengine.setBrush(1, 1, brush); for(int i=0;i<pointvector.size();++i) brushengine.strokeTo(pointvector[i], layer.layer()); brushengine.endStroke(); const auto dabs = brushengine.takeDabs(); for(int i=0;i<dabs.size();++i) brushes::drawBrushDabsDirect(*dabs.at(i), layer); layer.mergeSublayer(1); if(_shape == FloodFill || _shape == FloodErase) { paintcore::FillResult fr = paintcore::floodfill(m_preview, previewRect.center().toPoint(), _shape == FloodFill ? m_color : QColor(), _fillTolerance, 0, false, 360000); if(_fillExpansion>0) fr = paintcore::expandFill(fr, _fillExpansion, m_color); if(!fr.image.isNull()) layer.putImage(fr.x, fr.y, fr.image, _shape == FloodFill ? (_underFill ? paintcore::BlendMode::MODE_BEHIND : paintcore::BlendMode::MODE_NORMAL) : paintcore::BlendMode::MODE_ERASE); } m_needupdate=false; #endif }
void BrushPreview::updatePreview() { if(!m_preview) { m_preview = new paintcore::LayerStack; QSize size = contentsRect().size(); m_preview->resize(0, size.width(), size.height(), 0); m_preview->createLayer(0, 0, QColor(0,0,0), false, false, QString()); } else if(m_preview->width() != contentsRect().width() || m_preview->height() != contentsRect().height()) { m_preview->resize(0, contentsRect().width() - m_preview->width(), contentsRect().height() - m_preview->height(), 0); } QRectF previewRect( m_preview->width()/8, m_preview->height()/4, m_preview->width()-m_preview->width()/4, m_preview->height()-m_preview->height()/2 ); paintcore::PointVector pointvector; switch(_shape) { case Stroke: pointvector = paintcore::shapes::sampleStroke(previewRect); break; case Line: pointvector << paintcore::Point(previewRect.left(), previewRect.top(), 1.0) << paintcore::Point(previewRect.right(), previewRect.bottom(), 1.0); break; case Rectangle: pointvector = paintcore::shapes::rectangle(previewRect); break; case Ellipse: pointvector = paintcore::shapes::ellipse(previewRect); break; case FloodFill: pointvector = paintcore::shapes::sampleBlob(previewRect); break; } QColor bgcolor = m_bg; paintcore::Brush brush = m_brush; // Special handling for some blending modes // TODO this could be implemented in some less ad-hoc way if(brush.blendingMode() == 11) { // "behind" mode needs a transparent layer for anything to show up brush.setBlendingMode(paintcore::BlendMode::MODE_NORMAL); } else if(brush.blendingMode() == 12) { // Color-erase mode: use fg color as background bgcolor = m_color; } if(_shape == FloodFill) { brush.setColor(bgcolor); } paintcore::Layer *layer = m_preview->getLayerByIndex(0); layer->fillRect(QRect(0, 0, layer->width(), layer->height()), isTransparentBackground() ? QColor(Qt::transparent) : bgcolor, paintcore::BlendMode::MODE_REPLACE); paintcore::StrokeState ss(brush); for(int i=1;i<pointvector.size();++i) layer->drawLine(0, brush, pointvector[i-1], pointvector[i], ss); layer->mergeSublayer(0); if(_shape == FloodFill) { paintcore::FillResult fr = paintcore::floodfill(m_preview, previewRect.center().toPoint(), m_color, _fillTolerance, 0, false); if(_fillExpansion>0) fr = paintcore::expandFill(fr, _fillExpansion, m_color); layer->putImage(fr.x, fr.y, fr.image, _underFill ? paintcore::BlendMode::MODE_BEHIND : paintcore::BlendMode::MODE_NORMAL); } m_needupdate=false; }