14#include <klocalizedstring.h>
57 const QString &filterId,
64 m_updatesFacade(updatesFacade),
67 m_forceReset(forceReset),
68 m_selection(selection)
94 gc.
bitBlt(srcRect.topLeft(), dev, srcRect);
119 warnKrita <<
"WARNING: Transform Stroke: the device is absent in cache!";
152 if (processedNodes.size() > 1) {
160 "transformed_image");
169 Q_FOREACH(
KisNodeSP node, processedNodes) {
171 if (!node->inherits(
"KisMask")) {
199 const QRect
bounds = group->image()->bounds();
200 const int desiredAnimTime = group->image()->animationInterface()->currentTime();
206 "transformed_image");
223 QQueue<KisNodeSP> linearizedSrcNodes;
225 linearizedSrcNodes.enqueue(node);
229 KisNodeSP srcNode = linearizedSrcNodes.dequeue();
231 if (!processedNodes.contains(srcNode)) {
232 node->setVisible(false);
250 rootNode->
projectionLeaf()->explicitlyRegeneratePassThroughProjection();
278 const qreal coeff = 1.0 / 255.0;
279 const qreal baseOpacity = 0.5;
285 pixel.
setOpacity(quint8(gray * alpha * baseOpacity * coeff));
290 previewDevice = cacheDevice;
305 Q_ASSERT(cachedPortion);
323 extLayer->supportsPerspectiveTransform())) {
325 QRect oldDirtyRect = oldExtent | extLayer->theoreticalBoundingRect();
328 QTransform t = w.transform();
339 const QRect theoreticalNewDirtyRect =
394 externalLayer->projectionLeaf()->setTemporaryHiddenFromRendering(
true);
400 params->setHidden(
true);
412 if (!hull.isEmpty()) {
456 int numContributions = 0;
458 if (node->inherits(
"KisGroupLayer"))
continue;
465 device = extLayer->projection();
483 const bool isConvertedSelection =
488 QPolygon polygon = isConvertedSelection ?
493 numContributions += 1;
501 if (numContributions > 1) {
505 return QPolygon(points);
522 if (overlaySelectionMask) {
532 if (rootNode->inherits(
"KisTransformMask") && rootNode->
projectionLeaf()->isDroppedNode()) {
543 bool isExternalSourcePresent =
false;
546 bool argsAreInitialized =
false;
555 &lastCommandUndoJobs,
557 argsAreInitialized =
true;
559 argsAreInitialized =
true;
566 extraInitJobs << lastCommandUndoJobs;
583 if (autoKeyframeCommand) {
632 if (node->inherits(
"KisGroupLayer"))
continue;
635 srcRect |= mask->sourceDataBounds();
637 srcRect |= mask->selection()->selectedExactRect();
639 srcRect |= mask->selection()->selectedExactRect();
645 if (mask->paintDevice()) {
646 srcRect |= mask->paintDevice()->nonDefaultPixelArea();
657 if (!argsAreInitialized) {
676 Q_FOREACH (
KisNodeSP root, filteredRoots) {
677 sharedData->addUpdate(root, root->
projectionPlane()->tightUserVisibleBounds());
699 if (!lastCommandUndoJobs.isEmpty()) {
702 for (
auto it = extraInitJobs.begin(); it != extraInitJobs.end(); ++it) {
703 (*it)->setCancellable(
false);
727 auto restoreTemporaryHiddenNodes = [
this] () {
731 delayedNode->forceUpdateTimedNode();
738 if (applyTransform) {
778 deactivatedOverlaySelectionMask->
setDirty();
781 if (applyTransform) {
788 for (
auto it = mutatedJobs.begin(); it != mutatedJobs.end(); ++it) {
789 (*it)->setCancellable(
false);
KisDeleteLaterWrapper< T > * makeKisDeleteLaterWrapper(T value)
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID AlphaColorModelID("A", ki18n("Alpha mask"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
virtual bool decorationsVisible() const =0
virtual void setDecorationsVisible(bool value, bool update)=0
The KisDelayedUpdateNodeInterface class is an interface for nodes that delay their real updates with ...
void explicitlySetCurrentTime(int frameId)
QColor selectionOverlayMaskColor(bool defaultValue=false) const
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
KisGroupLayerSP rootLayer() const
const KoColorSpace * colorSpace() const
KisImageAnimationInterface * animationInterface() const
KisPaintDeviceSP projection() const
QRect bounds() const override
void setRootLayer(KisGroupLayerSP rootLayer)
void setDefaultBounds(KisDefaultBoundsBaseSP bounds)
KisPaintDeviceSP createCompositionSourceDevice() const
virtual const KoColorSpace * compositionSourceColorSpace() const
QRect exactBounds() const
const KoColorSpace * colorSpace() const
void clearSelection(KisSelectionSP selection)
KisDefaultBoundsBaseSP defaultBounds() const
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
void setSelection(KisSelectionSP selection)
void bitBlt(qint32 dstX, qint32 dstY, const KisPaintDeviceSP srcDev, qint32 srcX, qint32 srcY, qint32 srcWidth, qint32 srcHeight)
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE const quint8 * rawDataConst() const
virtual void postProcessToplevelCommand(KUndo2Command *command)
Applies some modifications (e.g. assigning extra data) to the toplevel command.
void setMacroId(int value)
void cancelStrokeCallback() override
void initStrokeCallback() override
void runAndSaveCommand(KUndo2CommandSP command, KisStrokeJobData::Sequentiality sequentiality, KisStrokeJobData::Exclusivity exclusivity)
void finishStrokeCallback() override
void doStrokeCallback(KisStrokeJobData *data) override
KisStrokeUndoFacade * undoFacade() const
void addMutatedJobs(const QVector< KisStrokeJobData * > list)
KUndo2Command * endAndTake()
virtual void enableDirtyRequests()=0
virtual void disableDirtyRequests()=0
virtual quint32 pixelSize() const =0
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
void setOpacity(quint8 alpha)
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
T kisGrowRect(const T &rect, U offset)
QSharedPointer< T > toQShared(T *ptr)
QSharedPointer< KUndo2Command > KUndo2CommandSP
KisSharedPtr< KisNode > KisNodeSP
KUndo2MagicString kundo2_i18n(const char *text)
KUndo2Command * tryAutoCreateDuplicatedFrame(KisPaintDeviceSP device, AutoCreateKeyframeFlags flags)
create a new duplicated keyframe if auto-keyframe mode is on
QPolygon findConvexHullSelectionLike(KisPaintDeviceSP device)
QPolygon findConvexHull(const QVector< QPoint > &points)
KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks)
void recursiveApplyNodes(NodePointer node, Functor func)
void forceAllHiddenOriginalsUpdate(KisNodeSP root)
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea)
void forceAllDelayedNodesUpdate(KisNodeSP root)
void addJobSequential(QVector< Job * > &jobs, Func func)
void addJobBarrier(QVector< Job * > &jobs, Func func)
virtual KisPaintDeviceSP projection() const =0
virtual QRect exactBounds() const
virtual QRect extent() const
virtual KisPaintDeviceSP paintDevice() const =0
bool hasEditablePaintDevice() const
void setPassThroughMode(bool value)
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
virtual KisNode * graphOverlayNode() const
virtual KisAbstractProjectionPlaneSP projectionPlane() const
KisProjectionLeafSP projectionLeaf
virtual KisNodeSP clone() const =0
quint32 childCount() const
KisNodeGraphListener * graphListener
void setDirty(const QVector< QRect > &rects) override
void setDecorationsVisible(bool value, bool update) override
KisPixelSelectionSP projection() const
KisPixelSelectionSP pixelSelection
void setVisible(bool visible)
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
static KoColorSpaceRegistry * instance()