21#include <klocalizedstring.h>
109#define SANITY_CHECK_LOCKED(name) \
110 if (!locked()) warnKrita() << "Locking policy failed:" << name \
111 << "has been called without the image" \
114#define SANITY_CHECK_LOCKED(name)
118 qRegisterMetaType<KisImageSP>(
"KisImageSP");
152 [=](
bool forgettable) {
167 return std::make_pair(suspend, resume);
180 bool addedUIUpdateRequestSuccessfully =
false;
191 addedUIUpdateRequestSuccessfully =
true;
203 connect(
undoStore.data(), SIGNAL(historyStateChanged()), &
signalRouter, SLOT(emitImageModifiedNotification()));
293 const QRect &cropRect,
294 KisProjectionUpdateFlags flags);
303 KoColorConversionTransformation::ConversionFlags conversionFlags);
320 struct SetImageProjectionColorSpace;
342 colorSpace, undoStore,
346 moveToThread(qApp->thread());
368 switch (image.format()) {
369 case QImage::Format_Invalid:
370 case QImage::Format_Mono:
371 case QImage::Format_MonoLSB:
374 case QImage::Format_Indexed8:
375 case QImage::Format_RGB32:
376 case QImage::Format_ARGB32:
377 case QImage::Format_ARGB32_Premultiplied:
380 case QImage::Format_RGB16:
383 case QImage::Format_ARGB8565_Premultiplied:
384 case QImage::Format_RGB666:
385 case QImage::Format_ARGB6666_Premultiplied:
386 case QImage::Format_RGB555:
387 case QImage::Format_ARGB8555_Premultiplied:
388 case QImage::Format_RGB888:
389 case QImage::Format_RGB444:
390 case QImage::Format_ARGB4444_Premultiplied:
391 case QImage::Format_RGBX8888:
392 case QImage::Format_RGBA8888:
393 case QImage::Format_RGBA8888_Premultiplied:
396 case QImage::Format_BGR30:
397 case QImage::Format_A2BGR30_Premultiplied:
398 case QImage::Format_RGB30:
399 case QImage::Format_A2RGB30_Premultiplied:
402 case QImage::Format_Alpha8:
405 case QImage::Format_Grayscale8:
408 case QImage::Format_Grayscale16:
411 case QImage::Format_RGBX64:
412 case QImage::Format_RGBA64:
413 case QImage::Format_RGBA64_Premultiplied:
430 return new KisImage(*
this, 0, exactCopy);
464 if (colorSpaceChanged) {
468 if (resolutionChanged) {
474 setObjectName(rhs.objectName());
487 oldRoot->disconnect();
491#define EMIT_IF_NEEDED if (!(policy & REPLACE)) {} else emit
496 if (colorSpaceChanged) {
499 if (resolutionChanged) {
524 QQueue<KisNodeSP> linearizedNodes;
527 linearizedNodes.enqueue(node);
530 [&linearizedNodes, exactCopy, &rhs,
this](
KisNodeSP node) {
531 KisNodeSP refNode = linearizedNodes.dequeue();
555 using KeyframeChannelContainer = QMap<QString, KisKeyframeChannel*>;
557 for (KeyframeChannelContainer::iterator i = keyframeChannels.begin();
558 i != keyframeChannels.end(); i++) {
559 keyframeChannels[i.key()]->setNode(node);
597 rhs.width(), rhs.height(),
603 moveToThread(qApp->thread());
633 KisNodeSP deletedNode = parent->at(index);
671 UpdateOverlaySelectionStroke(
KisImageSP image)
676 setClearsRedoOnStart(
false);
679 void initStrokeCallback()
override {
682 if (oldMask == newMask)
return;
686 m_image->m_d->overlaySelectionMask = newMask;
688 if (oldMask || newMask) {
689 m_image->
m_d->rootLayer->notifyChildMaskChanged();
693 const QRect oldMaskRect = oldMask->
graphListener() ? oldMask->
extent() : m_image->bounds();
694 m_image->m_d->rootLayer->setDirtyDontResetAnimationCache(oldMaskRect);
701 m_image->undoAdapter()->emitSelectionChanged();
744 QString baseName = _baseName;
747 int maxLayerIndex = 0;
748 QRegularExpression numberedLayerRegexp(
".* (\\d+)$");
750 [&numLayers, &maxLayerIndex, &numberedLayerRegexp] (
KisNodeSP node) {
751 if (node->inherits(
"KisLayer")) {
752 QRegularExpressionMatch match = numberedLayerRegexp.match(node->name());
754 if (match.hasMatch()) {
755 maxLayerIndex = qMax(maxLayerIndex, match.captured(1).toInt());
762 if (numLayers == 1) {
763 return i18nc(
"Name for the bottom-most layer in the layerstack",
"Background");
766 if (baseName.isEmpty()) {
767 baseName = i18n(
"Paint Layer");
770 return QString(
"%1 %2").arg(baseName).arg(maxLayerIndex + 1);
863 if (newRect ==
bounds() && !cropLayers)
return;
881 emitSignals, actionName, extraData);
883 if (cropLayers || !newRect.topLeft().isNull()) {
911 PurgeUnusedDataStroke(
KisImageSP image,
bool isCancellable)
919 this->enableJob(JOB_DOSTROKE,
true);
922 setClearsRedoOnStart(!isCancellable);
923 setRequestsOtherStrokesToEnd(!isCancellable);
924 setCanForgetAboutMe(isCancellable);
927 void initStrokeCallback()
override
934 [&paintDevicesList, &projectionsList,
this](
KisNodeSP node) {
935 KisPaintDeviceList deviceList = node->getLodCapableDevices();
937 Q_FOREACH (KisPaintDeviceSP dev, deviceList) {
942 if (dev == node->paintDevice() && !canForgetAboutMe()) {
943 paintDevicesList << dev;
945 projectionsList << dev;
956 projectionsList.removeAll(dev);
964 paintDevicesList << projectionsList;
965 projectionsList.clear();
974 addMutatedJobs(jobsData);
977 void finishStrokeCallback()
override {
978 for (
auto it = m_transactions.begin(); it != m_transactions.end(); ++it) {
979 std::unique_ptr<KUndo2Command> cmd(it->endAndTake());
989 m_transactions.clear();
991 m_finalCommand->redo();
992 m_image->postExecutionUndoAdapter()->addCommand(
toQShared(m_finalCommand.release()));
997 if (node->preferredThumbnailBoundsMode() != KisThumbnailBoundsMode::Precise) {
998 node->setPreferredThumbnailBoundsMode(KisThumbnailBoundsMode::Precise);
1005 std::unique_ptr<KUndo2Command> m_finalCommand;
1006 std::vector<KisTransaction> m_transactions;
1009 KisStrokeId id = startStroke(
new PurgeUnusedDataStroke(
this, isCancellable));
1015 const bool isLayer = qobject_cast<KisLayer*>(node.
data());
1028 emitSignals, actionName, extraData);
1046 bool sizeChanged =
size != this->
size();
1048 if (!resolutionChanged && !sizeChanged)
return;
1058 KisProcessingApplicator::ProcessingFlags signalFlags =
1059 (resolutionChanged || sizeChanged) ?
1065 emitSignals, actionName);
1067 qreal sx = qreal(
size.width()) / this->
size().width();
1068 qreal sy = qreal(
size.height()) / this->
size().height();
1070 QTransform shapesCorrection;
1072 if (resolutionChanged) {
1073 shapesCorrection = QTransform::fromScale(
xRes() / xres,
yRes() / yres);
1086 if (resolutionChanged) {
1116 QTransform transform = worker.
transform();
1118 offset = center - transform.map(center);
1123 emitSignals, actionName);
1129 offset.x(), offset.y(),
1167 else if (selection) {
1172 baseBounds = baseBounds.united(node->
exactBounds());
1185 QTransform transform = worker.
transform();
1188 QRect newRect = transform.mapRect(baseBounds);
1189 newSize = newRect.size();
1190 offset = -newRect.topLeft();
1193 QPointF origin = QRectF(baseBounds).center();
1196 offset = -(transform.map(origin) - origin);
1201 (newSize.width() != baseBounds.width() ||
1202 newSize.height() != baseBounds.height());
1209 KisProcessingApplicator::ProcessingFlags signalFlags =
1217 emitSignals, actionName);
1224 offset.x(), offset.y(),
1254 if (nodes.size() == 1 && nodes[0]->inherits(
"KisMask")) {
1258 rotateImpl(
kundo2_i18np(
"Rotate Layer",
"Rotate %1 Layers", nodes.size()), nodes, radians,
false, selection);
1265 double angleX,
double angleY,
1273 double angleX,
double angleY,
1280 else if (selection) {
1285 baseBounds = baseBounds.united(node->
exactBounds());
1288 const QPointF origin = QRectF(baseBounds).center();
1291 const qreal pi = 3.1415926535897932385;
1292 const qreal deg2rad = pi / 180.0;
1294 qreal tanX = tan(angleX * deg2rad);
1295 qreal tanY = tan(angleY * deg2rad);
1307 QRect newRect = worker.
transform().mapRect(baseBounds);
1308 newSize = newRect.size();
1310 else offset = origin - worker.
transform().map(origin);
1313 if (newSize == baseBounds.size())
return;
1318 KisProcessingApplicator::ProcessingFlags signalFlags =
1324 emitSignals, actionName);
1332 offset.x(), offset.y(),
1358 if (nodes.size() == 1 && nodes[0]->inherits(
"KisMask")) {
1360 angleX, angleY, selection);
1364 angleX, angleY, selection);
1377 KoColorConversionTransformation::ConversionFlags conversionFlags)
1385 if (!dstColorSpace || *srcColorSpace == *dstColorSpace)
return;
1394 emitSignals, actionName);
1398 srcColorSpace, dstColorSpace,
1399 renderingIntent, conversionFlags),
1431 KoColorConversionTransformation::ConversionFlags conversionFlags)
1435 if (!dstColorSpace || *srcColorSpace == *dstColorSpace)
return;
1446 if (convertLayers) {
1452 emitSignals, actionName);
1462 srcColorSpace, dstColorSpace,
1463 renderingIntent, conversionFlags),
1478 KoColorConversionTransformation::ConversionFlags conversionFlags)
1496 KisProcessingApplicator::ProcessingFlags flags =
1501 emitSignals, actionName);
1527 if (!dstColorSpace)
return false;
1532 emitSignals, actionName);
1536 srcColorSpace, dstColorSpace),
1552 imageProfileIsSame &=
1555 return *node->colorSpace()->profile() != *profile;
1558 if (imageProfileIsSame) {
1569 if (!dstColorSpace)
return false;
1576 emitSignals, actionName);
1586 srcColorSpace, dstColorSpace),
1632 qWarning() <<
"WARNING: Ignoring attempt to set image x resolution <= 0 (" << xres <<
")!";
1638 qWarning() <<
"WARNING: Ignoring attempt to set image y resolution <= 0 (" << yres <<
")!";
1644 return QPointF(documentCoord.x() *
xRes(), documentCoord.y() *
yRes());
1650 return QPoint(qFloor(pixelCoord.x()), qFloor(pixelCoord.y()));
1660 return QPointF(pixelCoord.x() /
xRes(), pixelCoord.y() /
yRes());
1665 return QPointF((pixelCoord.x() + 0.5) /
xRes(), (pixelCoord.y() + 0.5) /
yRes());
1708 return visitor.
count();
1720 return visitor.
count();
1731 childNode->accept(visitor);
1733 return visitor.
count();
1769 imageRect.getRect(&x, &y, &w, &h);
1780 if (!dev)
return QImage();
1792 if (scaledImageSize.isEmpty()) {
1800 double scaleX = qreal(scaledImageSize.width()) /
width();
1801 double scaleY = qreal(scaledImageSize.height()) /
height();
1804 if (scaleX < 1.0/256 || scaleY < 1.0/256) {
1832 QRect boundRect =
bounds();
1837 boundRect = t.
map(boundRect);
1937 if ((*it) && (*it)->type() == type) {
1941 qWarning() <<
"Skipping deleted annotation";
1952 if ((*it)->type() == type) {
2011 for (
int y = 0; y < rc.height(); y += patchHeight) {
2012 for (
int x = 0; x < rc.width(); x += patchWidth) {
2013 QRect patchRect(x, y, patchWidth, patchHeight);
2025 if ((isolateLayer || isolateGroup) ==
false)
return false;
2034 StartIsolatedModeStroke(
KisNodeSP node,
KisImageSP image,
bool isolateLayer,
bool isolateGroup)
2039 m_isolateLayer(isolateLayer),
2040 m_isolateGroup(isolateGroup)
2043 this->enableJob(JOB_DOSTROKE,
true);
2045 setClearsRedoOnStart(
false);
2048 void initStrokeCallback()
override {
2049 if (m_isolateLayer ==
false && m_isolateGroup ==
true) {
2051 m_newRoot = m_newRoot->parent() ? m_newRoot->parent() : m_newRoot;
2055 m_newRoot->projectionLeaf()->explicitlyRegeneratePassThroughProjection();
2056 m_prevRoot = m_image->m_d->isolationRootNode;
2058 const bool beforeVisibility = m_newRoot->projectionLeaf()->visible();
2059 const bool prevRootBeforeVisibility = m_prevRoot ? m_prevRoot->projectionLeaf()->visible() :
false;
2061 m_image->m_d->isolationRootNode = m_newRoot;
2062 Q_EMIT m_image->sigIsolatedModeChanged();
2064 const bool afterVisibility = m_newRoot->projectionLeaf()->visible();
2065 const bool prevRootAfterVisibility = m_prevRoot ? m_prevRoot->projectionLeaf()->visible() :
false;
2067 m_newRootNeedsFullRefresh = beforeVisibility != afterVisibility;
2068 m_prevRootNeedsFullRefresh = prevRootBeforeVisibility != prevRootAfterVisibility;
2071 void finishStrokeCallback()
override {
2075 if (m_prevRoot && m_prevRootNeedsFullRefresh) {
2076 m_image->refreshGraphAsync(m_prevRoot);
2079 if (m_newRootNeedsFullRefresh) {
2080 m_image->refreshGraphAsync(m_newRoot);
2083 if (!m_prevRootNeedsFullRefresh && !m_newRootNeedsFullRefresh) {
2085 m_image->m_d->notifyProjectionUpdatedInPatches(m_image->bounds(), jobs);
2086 this->runnableJobsInterface()->addRunnableJobs(jobs);
2089 m_image->invalidateAllFrames();
2096 bool m_newRootNeedsFullRefresh =
false;
2097 bool m_prevRootNeedsFullRefresh =
false;
2099 bool m_isolateLayer;
2100 bool m_isolateGroup;
2137 qWarning() <<
"Cannot set the diffuse white metadata on the image: profile provides a different inconsistent value";
2152 m_oldRootNode(
nullptr),
2153 m_oldNodeNeedsRefresh(
false)
2155 this->enableJob(JOB_INIT);
2156 this->enableJob(JOB_DOSTROKE,
true);
2158 setClearsRedoOnStart(
false);
2161 void initStrokeCallback()
override {
2162 if (!m_image->m_d->isolationRootNode)
return;
2164 m_oldRootNode = m_image->m_d->isolationRootNode;
2166 const bool beforeVisibility = m_oldRootNode->projectionLeaf()->visible();
2167 m_image->m_d->isolationRootNode = 0;
2168 m_image->m_d->isolateLayer =
false;
2169 m_image->m_d->isolateGroup =
false;
2170 Q_EMIT m_image->sigIsolatedModeChanged();
2171 const bool afterVisibility = m_oldRootNode->projectionLeaf()->visible();
2173 m_oldNodeNeedsRefresh = (beforeVisibility != afterVisibility);
2176 void finishStrokeCallback()
override {
2178 m_image->invalidateAllFrames();
2180 if (m_oldNodeNeedsRefresh){
2181 m_oldRootNode->setDirty(m_image->bounds());
2190 m_image->m_d->notifyProjectionUpdatedInPatches(m_image->bounds(), jobs);
2191 this->runnableJobsInterface()->addRunnableJobs(jobs);
2198 bool m_oldNodeNeedsRefresh;
2237 return scheduler.tryCancelCurrentStrokeAsync();
2305 if (leaf->shouldBeRendered()) {
2306 for (
auto it = changeRects.begin(); it != changeRects.end(); ++it) {
2311 leaf = leaf->nextSibling();
2314 std::swap(requestedRects, changeRects);
2330 if ((*it)->filterRefreshGraph(
this,
root.
data(), requestedRects, cropRect, flags)) {
2423 postponedUpdates.append(rect);
2426 return postponedUpdates;
2437 if (dirtyRect.isEmpty())
return;
2479 const QRect &cropRect,
2480 KisProjectionUpdateFlags flags)
2482 if (rects.isEmpty())
return;
2484 scheduler.updateProjection(node, rects, cropRect, flags);
2499 if ((*it)->filter(
this, node, rects, flags)) {
2520 Q_FOREACH (
const QRect &rc, rects) {
2522 allSplitRects.append(splitRect);
float value(const T *src, size_t ch)
QVector< KisImageSignalType > KisImageSignalVector
@ ColorSpaceChangedSignal
@ ModifiedWithoutUndoSignal
@ ResolutionChangedSignal
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
const quint8 OPACITY_OPAQUE_U8
PythonPluginManager * instance
void notifyWaitOnImageStarted(KisImage *image)
void notifyWaitOnImageEnded(KisImage *image)
static KisBusyWaitBroker * instance()
The KisDumbUndoStore class doesn't actually save commands, so you cannot undo or redo!
static KisFilterStrategyRegistry * instance()
void invalidateFrames(const KisTimeSpan &range, const QRect &rect)
void notifyNodeChanged(const KisNode *node, const QRect &rect, bool recursive)
void requestTimeSwitchNonGUI(int time, bool useUndo=false)
int updatePatchWidth() const
int updatePatchHeight() const
bool enableProgressReporting(bool requestDefault=false) const
KisSelectionMaskSP deselectedGlobalSelection() const
void setDeselectedGlobalSelection(KisSelectionMaskSP selectionMask)
KisImageGlobalSelectionManagementInterface(KisImage *image)
void emitNotifyBatchUpdateStarted()
void emitNotifyBatchUpdateEnded()
void emitNotification(KisImageSignalType type)
void emitNodeHasBeenAdded(KisNode *parent, int index, KisNodeAdditionFlags flags)
void emitAboutToRemoveANode(KisNode *parent, int index)
void emitNodeChanged(KisNodeSP node)
KisCompositeProgressProxy compositeProgressProxy
std::optional< KisRelativeContentLightLevelInformation > relativeContentLightLevelInformation
KisLocklessStack< QRect > savedDisabledUIUpdates
KisNodeSP isolationRootNode
vKisAnnotationSP annotations
KisSelectionMaskSP deselectedGlobalSelectionMask
void notifyProjectionUpdatedInPatches(const QRect &rc, QVector< KisRunnableStrokeJobData * > &jobs)
KisImageAnimationInterface * animationInterface
bool wrapAroundModePermitted
KisUpdateScheduler scheduler
KisProofingConfigurationSP proofingConfig
KisSelectionMaskSP targetOverlaySelectionMask
KisImageGlobalSelectionManagementInterface globalSelectionInterface
KisSelectionMaskSP overlaySelectionMask
void requestProjectionUpdateImpl(KisNode *node, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags)
void updateHDRMetadataOnColorSpaceChange(const KoColorSpace *newColorSpace)
bool tryCancelCurrentStrokeAsync()
KisPostExecutionUndoAdapter postExecutionUndoAdapter
std::optional< double > diffuseWhiteLightLevel
KisLegacyUndoAdapter legacyUndoAdapter
std::optional< KisColorVolumeInformation > colorVolumeInformation
QAtomicInt disableUIUpdateSignals
QScopedPointer< KisUndoStore > undoStore
WrapAroundAxis wrapAroundModeAxis
const KoColorSpace * colorSpace
QAtomicInt disableDirtyRequests
QVector< KisProjectionUpdatesFilterSP > projectionUpdatesFilters
KisImageSignalRouter signalRouter
QStack< KisProjectionUpdatesFilterCookie > disabledUpdatesCookies
void convertImageColorSpaceImpl(const KoColorSpace *dstColorSpace, bool convertLayers, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
QList< KisLayerCompositionSP > compositions
bool allowMasksOnRootNode
KisGroupLayerSP rootLayer
KisImagePrivate(KisImage *_q, qint32 w, qint32 h, const KoColorSpace *c, KisUndoStore *undo, KisImageAnimationInterface *_animationInterface)
std::optional< KisRelativeContentLightLevelInformation > relativeContentLightLevelInformation() const
relativeContentLightLevelInformation This returns (optionally) a KisRelativeContentLightLevelInformat...
void resizeImage(const QRect &newRect)
start asynchronous operation on resizing the image
KisUndoAdapter * undoAdapter() const
void shearNodes(KisNodeList nodes, double angleX, double angleY, KisSelectionSP selection)
vKisAnnotationSP_it endAnnotations()
void requestStrokeEndActiveNode()
QImage convertToQImage(qint32 x1, qint32 y1, qint32 width, qint32 height, const KoColorProfile *profile)
void sigLayersChangedAsync()
int workingThreadsLimit() const
void setColorVolumeInformation(const std::optional< KisColorVolumeInformation > cvi)
Set the color volume information.
void invalidateAllFrames() override
void addAnnotation(KisAnnotationSP annotation)
bool wrapAroundModeActive() const
void sigNodeCollapsedChanged()
bool canReselectGlobalSelection()
KisImageGlobalSelectionManagementInterface * globalSelectionManagementInterface() const
void scaleNode(KisNodeSP node, const QPointF ¢er, qreal scaleX, qreal scaleY, KisFilterStrategy *filterStrategy, KisSelectionSP selection)
start asynchronous operation on scaling a subtree of nodes starting at node
void nodeChanged(KisNode *node) override
bool isIsolatingLayer() const
void setLodPreferences(const KisLodPreferences &value)
bool startIsolatedMode(KisNodeSP node, bool isolateLayer, bool isolateGroup)
bool hasUpdatesRunning() const override
void disableUIUpdates() override
void setWorkingThreadsLimit(int value)
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
void setHdrReferenceWhiteLightLevel(const std::optional< double > value)
Set the diffuse white light level, in cd/m²
void nodeHasBeenAdded(KisNode *parent, int index, KisNodeAdditionFlags flags) override
void keyframeChannelAboutToBeRemoved(KisNode *node, KisKeyframeChannel *channel) override
bool cancelStroke(KisStrokeId id) override
KisGroupLayerSP rootLayer() const
void disableDirtyRequests() override
void setWrapAroundModeAxis(WrapAroundAxis value)
void shearImpl(const KUndo2MagicString &actionName, KisNodeSP rootNode, bool resizeImage, double angleX, double angleY, KisSelectionSP selection)
void cropNode(KisNodeSP node, const QRect &newRect, const bool activeFrameOnly=false)
start asynchronous operation on cropping a subtree of nodes starting at node
void enableDirtyRequests() override
QPointF documentToPixel(const QPointF &documentCoord) const
void keyframeChannelHasBeenAdded(KisNode *node, KisKeyframeChannel *channel) override
UndoResult tryUndoUnfinishedLod0Stroke()
void aboutToRemoveANode(KisNode *parent, int index) override
qint32 nChildLayers() const
void shear(double angleX, double angleY)
start asynchronous operation on shearing the image
const KoColorSpace * colorSpace() const
QPointF mirrorAxesCenter() const
KisImageAnimationInterface * animationInterface() const
void shearNode(KisNodeSP node, double angleX, double angleY, KisSelectionSP selection)
start asynchronous operation on shearing a subtree of nodes starting at node
void purgeUnusedData(bool isCancellable)
purge all pixels that have default pixel to free up memory
KisCompositeProgressProxy * compositeProgressProxy()
void requestUndoDuringStroke()
void removeComposition(KisLayerCompositionSP composition)
void setProjectionColorSpace(const KoColorSpace *colorSpace)
void setAllowMasksOnRootNode(bool value)
void copyFromImageImpl(const KisImage &rhs, int policy)
void rotateImpl(const KUndo2MagicString &actionName, KisNodeSP rootNode, double radians, bool resizeImage, KisSelectionSP selection)
void sigStrokeCancellationRequested()
void blockUpdates() override
blockUpdates block updating the image projection
void sigRedoDuringStrokeRequested()
QString nextLayerName(const QString &baseName="") const
KisAnnotationSP annotation(const QString &type)
void flattenLayer(KisLayerSP layer)
KisProjectionUpdatesFilterSP removeProjectionUpdatesFilter(KisProjectionUpdatesFilterCookie cookie) override
removes already installed filter from the stack of updates filers
void sigInternalStopIsolatedModeRequested()
void unifyLayersColorSpace()
bool assignImageProfile(const KoColorProfile *profile, bool blockAllUpdates=false)
QRect effectiveLodBounds() const
bool isIdle(bool allowLocked=false)
void copyFromImage(const KisImage &rhs)
KisProjectionUpdatesFilterCookie currentProjectionUpdatesFilter() const override
QPointF pixelToDocument(const QPointF &pixelCoord) const
void scaleNodes(KisNodeList nodes, const QPointF ¢er, qreal scaleX, qreal scaleY, KisFilterStrategy *filterStrategy, KisSelectionSP selection)
void convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
KisSelectionMaskSP overlaySelectionMask() const
void sigResolutionChanged(double xRes, double yRes)
void barrierLock(bool readOnly=false)
Wait until all the queued background jobs are completed and lock the image.
KisImage * clone(bool exactCopy=false)
void flatten(KisNodeSP activeNode)
void rotateImage(double radians)
start asynchronous operation on rotating the image
WrapAroundAxis wrapAroundModeAxis() const
void sigColorSpaceChanged(const KoColorSpace *cs)
KisPaintDeviceSP projection() const
@ REPLACE
we are replacing the current KisImage with another
@ CONSTRUCT
we are copy-constructing a new KisImage
void scaleImage(const QSize &size, qreal xres, qreal yres, KisFilterStrategy *filterStrategy)
start asynchronous operation on scaling the image
void resizeImageImpl(const QRect &newRect, bool cropLayers)
void immediateLockForReadOnly()
void aboutToAddANode(KisNode *parent, int index) override
void setDefaultProjectionColor(const KoColor &color)
void setProofingConfiguration(KisProofingConfigurationSP proofingConfig)
setProofingConfiguration, this sets the image's proofing configuration, and signals the proofingConfi...
void explicitRegenerateLevelOfDetail()
void notifyBatchUpdateEnded() override
void notifyBatchUpdateStarted() override
std::optional< double > hdrReferenceWhiteLightLevel() const
HDR Reference White livel.
bool allowMasksOnRootNode() const
void addComposition(KisLayerCompositionSP composition)
KisPostExecutionUndoAdapter * postExecutionUndoAdapter() const override
qint32 nHiddenLayers() const
void requestStrokeCancellation()
KisNode * graphOverlayNode() const override
void moveCompositionUp(KisLayerCompositionSP composition)
void requestTimeSwitch(int time) override
QPoint documentToImagePixelFloored(const QPointF &documentCoord) const
void addJob(KisStrokeId id, KisStrokeJobData *data) override
void setOverlaySelectionMask(KisSelectionMaskSP mask)
KisImage(KisUndoStore *undoStore, qint32 width, qint32 height, const KoColorSpace *colorSpace, const QString &name)
colorSpace can be null. In that case, it will be initialised to a default color space.
void cropImage(const QRect &newRect)
start asynchronous operation on cropping the image
void setMirrorAxesCenter(const QPointF &value) const
bool assignLayerProfile(KisNodeSP node, const KoColorProfile *profile)
void initialRefreshGraph()
void sigStrokeEndRequested()
void sigUndoDuringStrokeRequested()
void setSize(const QSize &size)
QVector< QRect > enableUIUpdates() override
void nodeCollapsedChanged(KisNode *node) override
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void notifySelectionChanged() override
bool isIsolatingGroup() const
void notifyAboutToBeDeleted()
KisLodPreferences lodPreferences() const
void sigAboutToBeDeleted()
void invalidateFrames(const KisTimeSpan &range, const QRect &rect) override
void mergeMultipleLayers(QList< KisNodeSP > mergedLayers, KisNodeSP putAfter)
int currentLevelOfDetail() const
KisSelectionSP globalSelection() const
void sigStrokeEndRequestedActiveNodeFiltered()
KisNodeSP isolationRootNode() const
QList< KisLayerCompositionSP > compositions()
void sigProofingConfigChanged()
void mergeDown(KisLayerSP l, const KisMetaData::MergeStrategy *strategy)
const KUndo2Command * lastExecutedCommand() const override
void removeAnnotation(const QString &type)
KisImageSignalRouter * signalRouter()
QRect bounds() const override
KoColor defaultProjectionColor() const
void convertLayerColorSpace(KisNodeSP node, const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
void notifyLayersChanged()
use if the layers have changed completely (eg. when flattening)
friend class KisImageResizeCommand
bool tryBarrierLock(bool readOnly=false)
Tries to lock the image without waiting for the jobs to finish.
KisUndoStore * undoStore()
void unblockUpdates() override
unblockUpdates unblock updating the image project. This only restarts the scheduler and does not sche...
void setModifiedWithoutUndo()
bool hasOverlaySelectionMask() const
KisProjectionUpdatesFilterCookie addProjectionUpdatesFilter(KisProjectionUpdatesFilterSP filter) override
void moveCompositionDown(KisLayerCompositionSP composition)
bool wrapAroundModePermitted() const
void notifyProjectionUpdated(const QRect &rc) override
void sigImageUpdated(const QRect &)
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
void rotateNodes(KisNodeList nodes, double radians, KisSelectionSP selection)
void endStroke(KisStrokeId id) override
std::optional< KisColorVolumeInformation > colorVolumeInformation() const
colorVolumeInformation
void notifyUIUpdateCompleted(const QRect &rc) override
const KoColorProfile * profile() const
void setRelativeContentLightLevelInformation(const std::optional< KisRelativeContentLightLevelInformation > clli)
vKisAnnotationSP_it beginAnnotations()
void requestRedoDuringStroke()
void sigSizeChanged(const QPointF &oldStillPoint, const QPointF &newStillPoint)
void setResolution(double xres, double yres)
void setRootLayer(KisGroupLayerSP rootLayer)
static KisImageSP fromQImage(const QImage &image, KisUndoStore *undoStore)
void convertImageProjectionColorSpace(const KoColorSpace *dstColorSpace)
void setWrapAroundModePermitted(bool value)
void requestProjectionUpdate(KisNode *node, const QVector< QRect > &rects, KisProjectionUpdateFlags flags) override
void setUndoStore(KisUndoStore *undoStore)
KisProofingConfigurationSP proofingConfiguration() const
proofingConfiguration
void rotateNode(KisNodeSP node, double radians, KisSelectionSP selection)
start asynchronous operation on rotating a subtree of nodes starting at node
KisKeyframeChannel stores and manages KisKeyframes. Maps units of time to virtual keyframe values....
void setNode(KisNodeWSP node)
QRect exactBounds() const
void purgeDefaultPixels()
KoColor defaultPixel() const
QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags()) const
void convertFromQImage(const QImage &image, const KoColorProfile *profile, qint32 offsetX=0, qint32 offsetY=0)
static void copyAreaOptimized(const QPoint &dstPt, KisPaintDeviceSP src, KisPaintDeviceSP dst, const QRect &originalSrcRect)
void setUndoStore(KisUndoStore *undoStore)
void applyVisitor(KisProcessingVisitorSP visitor, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
void applyVisitorAllFrames(KisProcessingVisitorSP visitor, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
The KisProofingConfiguration struct Little struct that stores the proofing configuration for a given ...
bool requestsOtherStrokesToEnd() const
static SharedDataSP createSharedData()
static QList< KisStrokeJobData * > createSuspendJobsData(KisImageWSP image)
static QList< KisStrokeJobData * > createResumeJobsData(KisImageWSP image)
static QList< KisStrokeJobData * > createJobsData(KisImageWSP image)
static KisTimeSpan infinite(int start)
void emitSelectionChanged()
void setUndoStore(KisUndoStore *undoStore)
virtual bool hasHighDynamicRange() const =0
virtual const KoColorProfile * profile() const =0
static KoColor createTransparent(const KoColorSpace *cs)
A holder for an updater that does nothing.
const T value(const QString &id) const
void setProperty(const QString &name, const QVariant &value)
static bool qFuzzyCompare(half p1, half p2)
This file is part of the Krita application in calligra.
#define KIS_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_NOOP(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
#define SANITY_CHECK_LOCKED(name)
KIS_DECLARE_STATIC_INITIALIZER
bool checkMasksNeedConversion(KisNodeSP root, const QRect &bounds)
static bool isLayer(KisNodeSP node)
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
QSharedPointer< T > toQShared(T *ptr)
std::pair< KisStrokeStrategy *, QList< KisStrokeJobData * > > KisSuspendResumePair
std::pair< KisStrokeStrategy *, QList< KisStrokeJobData * > > KisLodSyncPair
KisSharedPtr< KisAnnotation > KisAnnotationSP
KisWeakSharedPtr< KisImage > KisImageWSP
QSharedPointer< KisProofingConfiguration > KisProofingConfigurationSP
vKisAnnotationSP::iterator vKisAnnotationSP_it
void * KisProjectionUpdatesFilterCookie
KUndo2MagicString kundo2_i18n(const char *text)
KUndo2MagicString kundo2_noi18n(const QString &text)
KUndo2MagicString kundo2_i18np(const char *sing, const char *plur, const A1 &a1)
void flattenImage(KisImageSP image, KisNodeSP activeNode, MergeFlags flags)
KisNodeSP recursiveFindNode(KisNodeSP node, std::function< bool(KisNodeSP)> func)
void flattenLayer(KisImageSP image, KisLayerSP layer, MergeFlags flags)
void recursiveApplyNodes(NodePointer node, Functor func)
void mergeDown(KisImageSP image, KisLayerSP layer, const KisMetaData::MergeStrategy *strategy, MergeFlags flags)
void mergeMultipleNodes(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter, MergeFlags flags)
void addJobConcurrent(QVector< Job * > &jobs, Func func)
void makeContainerUnique(C &container)
QMap< QString, KisKeyframeChannel * > keyframeChannels
virtual KisPaintDeviceSP projection() const =0
virtual QRect exactBounds() const
void setUuid(const QUuid &id)
virtual const KoColorSpace * colorSpace() const =0
FlipFlopCommand(State initialState, KUndo2Command *parent=0)
void setDefaultProjectionColor(KoColor color)
bool accept(KisNodeVisitor &v) override
void setImage(KisImageWSP image) override
KisPaintDeviceSP original() const override
KoColor defaultProjectionColor() const
const KoColorSpace * m_cs
SetImageProjectionColorSpace(const KoColorSpace *cs, KisImageWSP image, State initialState, KUndo2Command *parent=0)
KisPaintDeviceSP projection() const override
virtual KisSelectionMaskSP selectionMask() const
void notifyChildMaskChanged()
bool lodSupported() const
bool lodPreferred() const
KisPaintDeviceSP paintDevice() const override
static KisMemoryStatisticsServer * instance()
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
void setRoot(KisNodeSP root)
virtual void aboutToRemoveANode(KisNode *parent, int index)
virtual void aboutToAddANode(KisNode *parent, int index)
virtual void requestProjectionUpdate(KisNode *node, const QVector< QRect > &rects, KisProjectionUpdateFlags flags)
virtual void nodeHasBeenAdded(KisNode *parent, int index, KisNodeAdditionFlags flags)
virtual void nodeChanged(KisNode *node)
KisNodeSP firstChild() const
QList< KisNodeSP > childNodes(const QStringList &nodeTypes, const KoProperties &properties) const
void setImage(KisImageWSP newImage) override
KisProjectionLeafSP projectionLeaf
virtual KisNodeSP clone() const =0
void setGraphListener(KisNodeGraphListener *graphListener)
KisNodeSP nextSibling() const
KisNodeGraphListener * graphListener
KisPaintDeviceSP paintDevice
QRect extent() const override
void setDirty(const QVector< QRect > &rects) override
bool hasShapeSelection() const
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.
virtual void addExplicitUIUpdateRect(const QRect &rc)=0
UndoResult tryUndoLastStrokeAsync()
void unlock(bool resetLodLevels=true)
void addJob(KisStrokeId id, KisStrokeJobData *data) override
void setPostSyncLod0GUIPlaneRequestForResumeCallback(const std::function< void()> &callback)
void setProgressProxy(KoProgressProxy *progressProxy)
void setSuspendResumeUpdatesStrokeStrategyFactory(const KisSuspendResumeStrategyPairFactory &factory)
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void immediateLockForReadOnly()
void setLodPreferences(const KisLodPreferences &value)
int currentLevelOfDetail() const
bool hasUpdatesRunning() const
void setLod0ToNStrokeStrategyFactory(const KisLodSyncStrokeStrategyFactory &factory)
void endStroke(KisStrokeId id) override
void explicitRegenerateLevelOfDetail()
KisLodPreferences lodPreferences() const
bool wrapAroundModeSupported() const
void setThreadsLimit(int value)
KisPostExecutionUndoAdapter * lodNPostExecutionUndoAdapter() const
void setPurgeRedoStateCallback(const std::function< void()> &callback)
bool cancelStroke(KisStrokeId id) override
void fullRefreshAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags)
void reportJobStarted(void *key)
static KisUpdateTimeMonitor * instance()
void reportUpdateFinished(const QRect &rect)
virtual std::optional< double > hdrReferenceWhite() const =0
hdrReferenceWhite HDR reference white is only available for Perceptual Quantizer profiles that save t...
virtual TransferCharacteristics getTransferCharacteristics() const
getTransferCharacteristics This function should be subclassed at some point so we can get the value f...
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorSpace * graya8(const QString &profile=QString())
const KoColorSpace * graya16(const QString &profile=QString())
const KoColorSpace * rgb8(const QString &profileName=QString())
const KoColorSpace * rgb16(const QString &profileName=QString())
const KoColorSpace * alpha8()