9#include "private/framesvg_p.h"
15#include <QCryptographicHash>
19#include <QStringBuilder>
26#include "private/framesvg_helpers.h"
27#include "private/imageset_p.h"
28#include "private/svg_p.h"
32QHash<ImageSetPrivate *, QHash<uint, QWeakPointer<FrameData>>> FrameSvgPrivate::s_sharedFrames;
36static const int MAX_FRAME_SIZE = 100000;
38FrameData::~FrameData()
40 FrameSvgPrivate::s_sharedFrames[imageSet].
remove(cacheId);
45 , d(new FrameSvgPrivate(this))
57 if (path == imagePath()) {
64 Svg::d->setImagePath(path);
65 if (!d->repaintBlocked) {
66 d->updateFrameData(Svg::d->lastModified);
72 if (borders == d->enabledBorders) {
76 d->enabledBorders = borders;
78 if (!d->repaintBlocked) {
79 d->updateFrameData(Svg::d->lastModified);
83FrameSvg::EnabledBorders FrameSvg::enabledBorders()
const
85 return d->enabledBorders;
108 d->location = location;
117 if (!d->prefix.isEmpty()) {
121 d->requestedPrefix =
prefix;
125 if (!d->repaintBlocked) {
126 d->updateFrameData(Svg::d->lastModified);
162 return d->requestedPrefix;
167 if (imagePath().isEmpty()) {
171 if (size.isEmpty()) {
178 if (d->frame && size.toSize() == d->frame->frameSize) {
181 d->pendingFrameSize = size.toSize();
183 if (!d->repaintBlocked) {
184 d->updateFrameData(Svg::d->lastModified, FrameSvgPrivate::UpdateFrame);
193 return d->frameSize(d->frame.data());
203 if (d->frame->noBorderPadding) {
209 return d->frame->topMargin;
212 return d->frame->leftMargin;
215 return d->frame->rightMargin;
219 return d->frame->bottomMargin;
229 if (d->frame->noBorderPadding) {
235 return d->frame->insetTopMargin;
238 return d->frame->insetLeftMargin;
241 return d->frame->insetRightMargin;
245 return d->frame->insetBottomMargin;
255 if (d->frame->noBorderPadding) {
261 return d->frame->fixedTopMargin;
264 return d->frame->fixedLeftMargin;
267 return d->frame->fixedRightMargin;
271 return d->frame->fixedBottomMargin;
277 if (!d->frame || d->frame->noBorderPadding) {
278 left = top = right = bottom = 0;
282 top = d->frame->topMargin;
283 left = d->frame->leftMargin;
284 right = d->frame->rightMargin;
285 bottom = d->frame->bottomMargin;
290 if (!d->frame || d->frame->noBorderPadding) {
291 left = top = right = bottom = 0;
295 top = d->frame->fixedTopMargin;
296 left = d->frame->fixedLeftMargin;
297 right = d->frame->fixedRightMargin;
298 bottom = d->frame->fixedBottomMargin;
303 if (!d->frame || d->frame->noBorderPadding) {
304 left = top = right = bottom = 0;
308 top = d->frame->insetTopMargin;
309 left = d->frame->insetLeftMargin;
310 right = d->frame->insetRightMargin;
311 bottom = d->frame->insetBottomMargin;
318 return rect.
adjusted(d->frame->leftMargin, d->frame->topMargin, -d->frame->rightMargin, -d->frame->bottomMargin);
327 return d->alphaMask();
337 size_t id = qHash(d->cacheId(d->frame.data(),
QString()), SvgRectsCache::s_seed);
339 QRegion *obj = d->frame->cachedMasks.object(
id);
343 const qreal dpr =
alphaMask.devicePixelRatio();
346 if (
alphaMask.devicePixelRatio() != 1.0) {
359 d->frame->cachedMasks.insert(
id, obj);
368 if (d->cacheAll && !cache) {
383 d->frame->cachedBackground =
QPixmap();
384 d->frame->cachedMasks.clear();
387 d->maskFrame->cachedBackground =
QPixmap();
388 d->maskFrame->cachedMasks.clear();
394 if (d->frame->cachedBackground.isNull()) {
395 d->generateBackground(d->frame);
398 return d->frame->cachedBackground;
403 if (d->frame->cachedBackground.isNull()) {
404 d->generateBackground(d->frame);
405 if (d->frame->cachedBackground.isNull()) {
410 painter->
drawPixmap(target, d->frame->cachedBackground, source.
isValid() ? source : target);
415 if (d->frame->cachedBackground.isNull()) {
416 d->generateBackground(d->frame);
417 if (d->frame->cachedBackground.isNull()) {
422 painter->
drawPixmap(pos, d->frame->cachedBackground);
428 return d->frame->fixedTopHeight + d->frame->fixedBottomHeight;
436 return d->frame->fixedRightWidth + d->frame->fixedLeftWidth;
442FrameSvgPrivate::~FrameSvgPrivate() =
default;
444QPixmap FrameSvgPrivate::alphaMask()
449 maskPrefix = QStringLiteral(
"mask-");
452 if (maskPrefix.
isNull()) {
453 if (frame->cachedBackground.isNull()) {
454 generateBackground(frame);
456 return frame->cachedBackground;
461 const QString maskRequestedPrefix = requestedPrefix.
isEmpty() ? QStringLiteral(
"mask") : maskPrefix % requestedPrefix;
462 maskPrefix = maskPrefix % prefix;
465 maskFrame = lookupOrCreateMaskFrame(frame, maskPrefix, maskRequestedPrefix);
466 if (!maskFrame->cachedBackground.isNull()) {
467 return maskFrame->cachedBackground;
469 updateSizes(maskFrame);
470 generateBackground(maskFrame);
471 return maskFrame->cachedBackground;
474 const bool shouldUpdate = (maskFrame->enabledBorders != frame->enabledBorders
475 || maskFrame->frameSize != frameSize(frame.data())
476 || maskFrame->imagePath != frame->imagePath);
478 maskFrame = lookupOrCreateMaskFrame(frame, maskPrefix, maskRequestedPrefix);
479 if (!maskFrame->cachedBackground.isNull()) {
480 return maskFrame->cachedBackground;
482 updateSizes(maskFrame);
485 if (maskFrame->cachedBackground.isNull()) {
486 generateBackground(maskFrame);
489 return maskFrame->cachedBackground;
492QSharedPointer<FrameData>
493FrameSvgPrivate::lookupOrCreateMaskFrame(
const QSharedPointer<FrameData> &frame,
const QString &maskPrefix,
const QString &maskRequestedPrefix)
495 const size_t key =
qHash(cacheId(frame.
data(), maskPrefix));
496 QSharedPointer<FrameData> mask = s_sharedFrames[q->imageSet()->d].value(key);
504 mask.
reset(
new FrameData(*frame.
data()));
505 mask->prefix = maskPrefix;
506 mask->requestedPrefix = maskRequestedPrefix;
507 mask->imageSet = q->imageSet()->d;
508 mask->imagePath = frame->imagePath;
509 mask->enabledBorders = frame->enabledBorders;
510 mask->frameSize = frameSize(frame).toSize();
512 mask->lastModified = frame->lastModified;
513 s_sharedFrames[q->imageSet()->d].insert(key, mask);
518void FrameSvgPrivate::generateBackground(
const QSharedPointer<FrameData> &frame)
520 if (!frame->cachedBackground.isNull() || !q->hasElementPrefix(frame->prefix)) {
524 const size_t id =
qHash(cacheId(frame.
data(), frame->prefix));
526 bool frameCached = !frame->cachedBackground.isNull();
527 bool overlayCached =
false;
529 const bool overlayAvailable = !frame->prefix.startsWith(QLatin1String(
"mask-")) && q->hasElement(frame->prefix % QLatin1String(
"overlay"));
531 if (q->isUsingRenderingCache()) {
532 frameCached = q->imageSet()->d->findInCache(
QString::number(
id), frame->cachedBackground, frame->lastModified) && !frame->cachedBackground.isNull();
534 frame->cachedBackground.setDevicePixelRatio(q->devicePixelRatio());
537 if (overlayAvailable) {
538 const size_t overlayId =
qHash(cacheId(frame.
data(), frame->prefix % QLatin1String(
"overlay")));
539 overlayCached = q->imageSet()->d->findInCache(
QString::number(overlayId), overlay, frame->lastModified) && !overlay.
isNull();
547 generateFrameBackground(frame);
552 QPointF actualOverlayPos = QPointF(0, 0);
553 if (overlayAvailable && !overlayCached) {
554 overlaySize = q->elementSize(frame->prefix % QLatin1String(
"overlay")).
toSize();
556 if (q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-pos-right"))) {
557 actualOverlayPos.
setX(frame->frameSize.width() - overlaySize.
width());
558 }
else if (q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-pos-bottom"))) {
559 actualOverlayPos.
setY(frame->frameSize.height() - overlaySize.
height());
561 }
else if (q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-stretch"))) {
562 overlaySize = frameSize(frame).
toSize();
564 if (q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-tile-horizontal"))) {
565 overlaySize.
setWidth(frameSize(frame).width());
567 if (q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-tile-vertical"))) {
568 overlaySize.
setHeight(frameSize(frame).height());
572 overlay = alphaMask();
573 QPainter overlayPainter(&overlay);
576 if (q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-tile-horizontal"))
577 || q->hasElement(frame->prefix % QLatin1String(
"hint-overlay-tile-vertical"))) {
578 QSizeF s = q->size().toSize();
579 q->resize(q->elementSize(frame->prefix % QLatin1String(
"overlay")));
581 overlayPainter.drawTiledPixmap(QRectF(QPointF(0, 0), overlaySize), q->pixmap(frame->prefix % QLatin1String(
"overlay")));
584 q->paint(&overlayPainter, QRectF(actualOverlayPos, overlaySize), frame->prefix % QLatin1String(
"overlay"));
587 overlayPainter.end();
591 cacheFrame(frame->prefix, frame->cachedBackground, overlayCached ? overlay : QPixmap());
595 QPainter p(&frame->cachedBackground);
597 p.drawPixmap(actualOverlayPos, overlay, QRectF(actualOverlayPos, overlaySize));
601void FrameSvgPrivate::generateFrameBackground(
const QSharedPointer<FrameData> &frame)
604 const QSizeF size = frameSize(frame) * q->devicePixelRatio();
612 if (size.
width() >= MAX_FRAME_SIZE || size.
height() >= MAX_FRAME_SIZE) {
613 qCWarning(LOG_KSVG) <<
"Not generating frame background for a size whose width or height is more than" << MAX_FRAME_SIZE << size;
618 frame->cachedBackground = QPixmap(QSize(std::ceil(size.
width()), std::ceil(size.
height())));
620 QPainter p(&frame->cachedBackground);
624 QRectF contentRect = contentGeometry(frame, size);
625 paintCenter(p, frame, contentRect, size);
627 paintCorner(p, frame, FrameSvg::LeftBorder | FrameSvg::TopBorder, contentRect);
628 paintCorner(p, frame, FrameSvg::RightBorder | FrameSvg::TopBorder, contentRect);
629 paintCorner(p, frame, FrameSvg::LeftBorder | FrameSvg::BottomBorder, contentRect);
630 paintCorner(p, frame, FrameSvg::RightBorder | FrameSvg::BottomBorder, contentRect);
633 const qreal leftHeight = q->elementSize(frame->prefix % QLatin1String(
"left")).height();
634 paintBorder(p, frame, FrameSvg::LeftBorder, QSizeF(frame->leftWidth, leftHeight) * q->devicePixelRatio(), contentRect);
635 const qreal rightHeight = q->elementSize(frame->prefix % QLatin1String(
"right")).height();
636 paintBorder(p, frame, FrameSvg::RightBorder, QSizeF(frame->rightWidth, rightHeight) * q->devicePixelRatio(), contentRect);
638 const qreal topWidth = q->elementSize(frame->prefix % QLatin1String(
"top")).width();
639 paintBorder(p, frame, FrameSvg::TopBorder, QSizeF(topWidth, frame->topHeight) * q->devicePixelRatio(), contentRect);
640 const qreal bottomWidth = q->elementSize(frame->prefix % QLatin1String(
"bottom")).width();
641 paintBorder(p, frame, FrameSvg::BottomBorder, QSizeF(bottomWidth, frame->bottomHeight) * q->devicePixelRatio(), contentRect);
645 frame->cachedBackground.setDevicePixelRatio(q->devicePixelRatio());
648QRectF FrameSvgPrivate::contentGeometry(
const QSharedPointer<FrameData> &frame,
const QSizeF &size)
const
650 const QSizeF contentSize(size.
width() - frame->leftWidth * q->devicePixelRatio() - frame->rightWidth * q->devicePixelRatio(),
651 size.
height() - frame->topHeight * q->devicePixelRatio() - frame->bottomHeight * q->devicePixelRatio());
652 QRectF contentRect(QPointF(0, 0), contentSize);
653 if (frame->enabledBorders & FrameSvg::LeftBorder && q->hasElement(frame->prefix % QLatin1String(
"left"))) {
654 contentRect.
translate(frame->leftWidth * q->devicePixelRatio(), 0);
658 if (frame->enabledBorders & FrameSvg::TopBorder && q->hasElement(frame->prefix % QLatin1String(
"top"))) {
659 contentRect.
translate(0, frame->topHeight * q->devicePixelRatio());
664void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType)
670 const uint oldKey = fd->cacheId;
672 const QString oldPath = fd->imagePath;
673 const FrameSvg::EnabledBorders oldBorders = fd->enabledBorders;
674 const QSizeF currentSize = fd->frameSize;
676 fd->enabledBorders = enabledBorders;
677 fd->frameSize = pendingFrameSize;
678 fd->imagePath = q->imagePath();
680 newKey =
qHash(cacheId(fd.data(), prefix));
683 fd->enabledBorders = oldBorders;
684 fd->frameSize = currentSize;
685 fd->imagePath = oldPath;
688 if (oldKey == newKey) {
693 auto newFd = FrameSvgPrivate::s_sharedFrames[q->imageSet()->d].
value(newKey);
697 Q_ASSERT(newKey == newFd.lock()->cacheId);
702 fd.reset(
new FrameData(*fd));
704 fd.reset(
new FrameData(q, QString()));
709 fd->requestedPrefix = requestedPrefix;
711 fd->enabledBorders = enabledBorders;
712 fd->frameSize = pendingFrameSize;
713 fd->imagePath = q->imagePath();
714 fd->lastModified = lastModified;
717 newKey =
qHash(cacheId(fd.data(), prefix));
721 FrameSvgPrivate::s_sharedFrames[q->imageSet()->d].
insert(newKey, fd);
722 fd->cacheId = newKey;
723 fd->imageSet = q->imageSet()->d;
724 if (updateType == UpdateFrameAndMargins) {
725 updateAndSignalSizes();
731void FrameSvgPrivate::paintCenter(QPainter &p,
const QSharedPointer<FrameData> &frame,
const QRectF &contentRect,
const QSizeF &fullSize)
735 const QString centerElementId = frame->prefix % QLatin1String(
"center");
736 if (frame->tileCenter) {
737 QSizeF centerTileSize = q->elementSize(centerElementId);
741 QPainter centerPainter(¢er);
743 q->paint(¢erPainter, QRectF(QPointF(0, 0), centerTileSize), centerElementId);
745 if (frame->composeOverBorder) {
748 p.
drawTiledPixmap(FrameSvgHelpers::sectionRect(FrameSvg::NoBorder, contentRect, fullSize * q->devicePixelRatio()), center);
751 if (frame->composeOverBorder) {
752 q->paint(&p, QRectF(QPointF(0, 0), fullSize), centerElementId);
754 q->paint(&p, FrameSvgHelpers::sectionRect(FrameSvg::NoBorder, contentRect, fullSize * q->devicePixelRatio()), centerElementId);
759 if (frame->composeOverBorder) {
761 p.
drawPixmap(QRectF(QPointF(0, 0), fullSize), alphaMask(), QRectF(QPointF(0, 0), alphaMask().size()));
766void FrameSvgPrivate::paintBorder(QPainter &p,
767 const QSharedPointer<FrameData> &frame,
768 const FrameSvg::EnabledBorders borders,
770 const QRectF &contentRect)
const
773 QString side = frame->prefix % FrameSvgHelpers::borderToElementId(borders);
774 if (frame->enabledBorders & borders && q->hasElement(side) && !size.
isEmpty()) {
775 if (frame->stretchBorders) {
776 q->paint(&p, FrameSvgHelpers::sectionRect(borders, contentRect, frame->frameSize * q->devicePixelRatio()), side);
778 QSize grownSize(std::ceil(size.
width()), std::ceil(size.
height()));
779 QPixmap px(grownSize);
783 QPainter sidePainter(&px);
786 q->paint(&sidePainter, QRect(QPoint(0, 0), grownSize), side);
790 auto r = FrameSvgHelpers::sectionRect(borders, contentRect, frame->frameSize * q->devicePixelRatio());
791 r.setTopLeft(r.topLeft().toPoint());
792 r.setSize(QSizeF(std::ceil(r.size().width()), std::ceil(r.size().height())));
799void FrameSvgPrivate::paintCorner(QPainter &p,
const QSharedPointer<FrameData> &frame, KSvg::FrameSvg::EnabledBorders border,
const QRectF &contentRect)
const
803 if ((frame->enabledBorders & border) != border) {
806 const QString corner = frame->prefix % FrameSvgHelpers::borderToElementId(border);
807 if (q->hasElement(corner)) {
808 auto r = FrameSvgHelpers::sectionRect(border, contentRect, frame->frameSize * q->devicePixelRatio());
811 r.setTopLeft(r.topLeft().toPoint());
812 r.setSize(QSizeF(std::ceil(r.size().width()), std::ceil(r.size().height())));
813 q->paint(&p, r.toRect(), corner);
817SvgPrivate::CacheId FrameSvgPrivate::cacheId(FrameData *frame,
const QString &prefixToSave)
const
819 const QSize size = frameSize(frame).
toSize();
820 return SvgPrivate::CacheId{double(size.
width()),
825 q->devicePixelRatio(),
827 (uint)frame->enabledBorders,
829 q->Svg::d->lastModified};
832void FrameSvgPrivate::cacheFrame(
const QString &prefixToSave,
const QPixmap &background,
const QPixmap &overlay)
834 if (!q->isUsingRenderingCache()) {
843 const size_t id =
qHash(cacheId(frame.data(), prefixToSave));
851 const size_t overlayId =
qHash(cacheId(frame.data(), frame->prefix % QLatin1String(
"overlay")));
856void FrameSvgPrivate::updateSizes(FrameData *frame)
const
861 QSizeF s = q->size();
863 if (!frame->cachedBackground.isNull()) {
864 frame->cachedBackground = QPixmap();
873 const auto offset = frame->prefix.length();
874 nameBuffer.
reserve(offset + 30);
875 nameBuffer.
append(frame->prefix);
881 auto createName = [&nameBuffer, offset]<std::size_t length>(
const char16_t(&name)[length]) {
882 nameBuffer.
replace(offset, length - 1,
reinterpret_cast<const QChar *
>(name), length);
883 return QStringView(nameBuffer).
mid(0, offset + length - 1);
887 frame->fixedTopHeight = q->elementSize(createName(u
"top")).height();
889 if (
auto topMargin = q->elementRect(createName(u
"hint-top-margin")); topMargin.isValid()) {
890 frame->fixedTopMargin = topMargin.height();
892 frame->fixedTopMargin = frame->fixedTopHeight;
896 if (frame->enabledBorders & FrameSvg::TopBorder) {
897 frame->topMargin = frame->fixedTopMargin;
898 frame->topHeight = frame->fixedTopHeight;
900 frame->topMargin = frame->topHeight = 0;
903 if (
auto topInset = q->elementRect(createName(u
"hint-top-inset")); topInset.isValid()) {
904 frame->insetTopMargin = topInset.height();
906 frame->insetTopMargin = -1;
909 frame->fixedLeftWidth = q->elementSize(createName(u
"left")).width();
911 if (
auto leftMargin = q->elementRect(createName(u
"hint-left-margin")); leftMargin.isValid()) {
912 frame->fixedLeftMargin = leftMargin.width();
914 frame->fixedLeftMargin = frame->fixedLeftWidth;
917 if (frame->enabledBorders & FrameSvg::LeftBorder) {
918 frame->leftMargin = frame->fixedLeftMargin;
919 frame->leftWidth = frame->fixedLeftWidth;
921 frame->leftMargin = frame->leftWidth = 0;
924 if (
auto leftInset = q->elementRect(createName(u
"hint-left-inset")); leftInset.isValid()) {
925 frame->insetLeftMargin = leftInset.width();
927 frame->insetLeftMargin = -1;
930 frame->fixedRightWidth = q->elementSize(createName(u
"right")).width();
932 if (
auto rightMargin = q->elementRect(createName(u
"hint-right-margin")); rightMargin.isValid()) {
933 frame->fixedRightMargin = rightMargin.width();
935 frame->fixedRightMargin = frame->fixedRightWidth;
938 if (frame->enabledBorders & FrameSvg::RightBorder) {
939 frame->rightMargin = frame->fixedRightMargin;
940 frame->rightWidth = frame->fixedRightWidth;
942 frame->rightMargin = frame->rightWidth = 0;
945 if (
auto rightInset = q->elementRect(createName(u
"hint-right-inset")); rightInset.isValid()) {
946 frame->insetRightMargin = rightInset.width();
948 frame->insetRightMargin = -1;
951 frame->fixedBottomHeight = q->elementSize(createName(u
"bottom")).height();
953 if (
auto bottomMargin = q->elementRect(createName(u
"hint-bottom-margin")); bottomMargin.isValid()) {
954 frame->fixedBottomMargin = bottomMargin.height();
956 frame->fixedBottomMargin = frame->fixedBottomHeight;
959 if (frame->enabledBorders & FrameSvg::BottomBorder) {
960 frame->bottomMargin = frame->fixedBottomMargin;
961 frame->bottomHeight = frame->fixedBottomHeight;
963 frame->bottomMargin = frame->bottomHeight = 0;
966 if (
auto bottomInset = q->elementRect(createName(u
"hint-bottom-inset")); bottomInset.isValid()) {
967 frame->insetBottomMargin = bottomInset.height();
969 frame->insetBottomMargin = -1;
972 static const QString maskPrefix = QStringLiteral(
"mask-");
973 static const QString hintTileCenter = QStringLiteral(
"hint-tile-center");
974 static const QString hintNoBorderPadding = QStringLiteral(
"hint-no-border-padding");
975 static const QString hintStretchBorders = QStringLiteral(
"hint-stretch-borders");
977 frame->composeOverBorder = (q->hasElement(createName(u
"hint-compose-over-border")) && q->hasElement(maskPrefix % createName(u
"center")));
981 frame->tileCenter = (q->hasElement(hintTileCenter) || q->hasElement(createName(u
"hint-tile-center")));
982 frame->noBorderPadding = (q->hasElement(hintNoBorderPadding) || q->hasElement(createName(u
"hint-no-border-padding")));
983 frame->stretchBorders = (q->hasElement(hintStretchBorders) || q->hasElement(createName(u
"hint-stretch-borders")));
987void FrameSvgPrivate::updateNeeded()
989 q->setElementPrefix(requestedPrefix);
998void FrameSvgPrivate::updateAndSignalSizes()
1005 Q_EMIT q->repaintNeeded();
1008QSizeF FrameSvgPrivate::frameSize(FrameData *frame)
const
1014 if (!frame->frameSize.isValid()) {
1016 frame->frameSize = q->size().toSize();
1019 return frame->frameSize;
1029 return d->repaintBlocked;
1034 d->repaintBlocked = blocked;
1037 d->updateFrameData(Svg::d->lastModified);
1043#include "moc_framesvg.cpp"
Q_INVOKABLE bool hasElementPrefix(const QString &prefix) const
This method returns whether the SVG has the necessary elements with the given prefix to draw a frame.
Q_INVOKABLE QRectF contentsRect() const
This method returns the rectangle of the center element, taking the margins into account.
Q_INVOKABLE QSizeF frameSize() const
bool isRepaintBlocked() const
This method returns whether we are in a transaction of many changes at once.
Q_INVOKABLE void paintFrame(QPainter *painter, const QRectF &target, const QRectF &source=QRectF())
This method paints the loaded SVG with the elements that represents the border.
Q_INVOKABLE void clearCache()
This method deletes the internal cache.
@ RightMargin
The right margin.
@ LeftMargin
The left margin.
@ TopMargin
The top margin.
Q_INVOKABLE int minimumDrawingHeight()
This method returns the minimum height required to correctly draw this SVG.
Q_INVOKABLE void setCacheAllRenderedFrames(bool cache)
This method sets whether saving all the rendered prefixes in a cache or not.
Q_INVOKABLE int minimumDrawingWidth()
This method returns the minimum width required to correctly draw this SVG.
Q_INVOKABLE qreal marginSize(const FrameSvg::MarginEdge edge) const
This method returns the margin size for the given edge.
QString actualPrefix() const
This method returns the prefix that is actually being used (including a '-' at the end if not empty).
void setRepaintBlocked(bool blocked)
This method sets whether we should block rebuilding generated graphics for each change made.
Q_INVOKABLE QRegion mask() const
This method returns a mask that tightly contains the fully opaque areas of the SVG.
Q_INVOKABLE void getInset(qreal &left, qreal &top, qreal &right, qreal &bottom) const
This is a convenience method that extracts the size of the four inset margins and saves their size in...
void setEnabledBorders(const EnabledBorders borders)
This method sets which borders should be painted.
Q_INVOKABLE qreal insetSize(const FrameSvg::MarginEdge edge) const
This method returns the insets margin size for the specified edge.
Q_INVOKABLE void getMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const
This is a convenience method that extracts the size of the four margins and saves their size into the...
@ LeftEdge
Along the left side of the screen.
@ RightEdge
Along the right side of the screen.
@ BottomEdge
Along the bottom of the screen.
@ TopEdge
Along the top of the screen.
Q_INVOKABLE QString prefix()
This method returns the prefix for SVG elements of the FrameSvg (including a '-' at the end if not em...
Q_INVOKABLE void setElementPrefix(KSvg::FrameSvg::LocationPrefix location)
This method sets the prefix (.
Q_INVOKABLE void setImagePath(const QString &path) override
Loads a new Svg.
Q_INVOKABLE QPixmap framePixmap()
This method returns a pixmap of the SVG represented by this object.
Q_INVOKABLE void getFixedMargins(qreal &left, qreal &top, qreal &right, qreal &bottom) const
This is a convenience method that extracts the size of the four margins and saves their size into the...
QPixmap alphaMask() const
This method returns a pixmap whose alpha channel is the opacity of the frame.
Q_INVOKABLE void resizeFrame(const QSizeF &size)
This method resizes the frame, maintaining the same border size.
Q_INVOKABLE qreal fixedMarginSize(const FrameSvg::MarginEdge edge) const
This method returns the margin size for the specified edge.
FrameSvg(QObject *parent=nullptr)
Constructs a new FrameSvg that paints the proper named subelements as borders.
Q_INVOKABLE bool cacheAllRenderedFrames() const
This method returns whether all the different prefixes should be kept in a cache when rendered.
void setContainsMultipleImages(bool multiple)
This method sets whether the SVG contains a single image or multiple ones.
Svg(QObject *parent=nullptr)
This method constructs an SVG object that implicitly shares and caches rendering.
void repaintNeeded()
This signal is emitted whenever the SVG data has changed in such a way that a repaint is required.
Q_INVOKABLE bool hasElement(const QString &elementId) const
This method checks whether an element exists in the loaded SVG.
KTEXTEDITOR_EXPORT size_t qHash(KTextEditor::Cursor cursor, size_t seed=0) noexcept
iterator insert(const Key &key, const T &value)
bool remove(const Key &key)
T value(const Key &key) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void drawTiledPixmap(const QRect &rectangle, const QPixmap &pixmap, const QPoint &position)
void setCompositionMode(CompositionMode mode)
bool isNull() const const
void setDevicePixelRatio(qreal scaleFactor)
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const const
bool isEmpty() const const
bool isValid() const const
void translate(const QPointF &offset)
qreal height() const const
bool isEmpty() const const
bool isValid() const const
void setHeight(qreal height)
void setWidth(qreal width)
QSize toSize() const const
qreal width() const const
QString & append(QChar ch)
bool isEmpty() const const
bool isNull() const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
void reserve(qsizetype size)
QTextStream & center(QTextStream &stream)