143QQuickBorderImage::QQuickBorderImage(QQuickItem *parent)
144: QQuickImageBase(*(
new QQuickBorderImagePrivate), parent)
146 connect(
this, &QQuickImageBase::sourceSizeChanged,
this, &QQuickBorderImage::sourceSizeChanged);
270void QQuickBorderImage::load()
272 Q_D(QQuickBorderImage);
274 if (d->url.isEmpty()) {
277 if (d->url.path().endsWith(QLatin1String(
"sci"))) {
278 const QQmlContext *context = qmlContext(
this);
279 QString lf = QQmlFile::urlToLocalFileOrQrc(context ? context->resolvedUrl(d->url)
283 if (!file.open(QIODevice::ReadOnly))
286 setGridScaledImage(QQuickGridScaledImage(&file));
288#if QT_CONFIG(qml_network)
290 d->setStatus(Loading);
292 QNetworkRequest req(d->url);
293 d->sciReply = qmlEngine(
this)->networkAccessManager()->get(req);
294 qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
295 this, QQuickBorderImage, SLOT(sciRequestFinished()));
299 loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
403void QQuickBorderImage::requestFinished()
405 Q_D(QQuickBorderImage);
407 if (d->pendingPix != d->currentPix) {
408 std::swap(d->pendingPix, d->currentPix);
409 d->pendingPix->clear(
this);
412 const QSize impsize = d->currentPix->implicitSize();
413 setImplicitSize(impsize.width() / d->devicePixelRatio, impsize.height() / d->devicePixelRatio);
415 if (d->currentPix->isError()) {
416 qmlWarning(
this) << d->currentPix->error();
424 if (sourceSize() != d->oldSourceSize) {
425 d->oldSourceSize = sourceSize();
426 emit sourceSizeChanged();
428 if (d->frameCount != d->currentPix->frameCount()) {
429 d->frameCount = d->currentPix->frameCount();
430 emit frameCountChanged();
460 const QSize &sourceSize,
461 const QSizeF &targetSize,
462 int horizontalTileMode,
463 int verticalTileMode,
464 qreal devicePixelRatio,
466 QRectF *innerTargetRect,
467 QRectF *innerSourceRect,
468 QRectF *subSourceRect)
470 *innerSourceRect = QRectF(0, 0, 1, 1);
471 *targetRect = QRectF(0, 0, targetSize.width(), targetSize.height());
472 *innerTargetRect = *targetRect;
475 qreal borderLeft = border->left() * devicePixelRatio;
476 qreal borderRight = border->right() * devicePixelRatio;
477 qreal borderTop = border->top() * devicePixelRatio;
478 qreal borderBottom = border->bottom() * devicePixelRatio;
479 if (borderLeft + borderRight > sourceSize.width() && borderLeft < sourceSize.width())
480 borderRight = sourceSize.width() - borderLeft;
481 if (borderTop + borderBottom > sourceSize.height() && borderTop < sourceSize.height())
482 borderBottom = sourceSize.height() - borderTop;
483 *innerSourceRect = QRectF(QPointF(borderLeft / qreal(sourceSize.width()),
484 borderTop / qreal(sourceSize.height())),
485 QPointF((sourceSize.width() - borderRight) / qreal(sourceSize.width()),
486 (sourceSize.height() - borderBottom) / qreal(sourceSize.height()))),
487 *innerTargetRect = QRectF(border->left(),
489 qMax<qreal>(0, targetSize.width() - (border->right() + border->left())),
490 qMax<qreal>(0, targetSize.height() - (border->bottom() + border->top())));
495 const QSizeF innerTargetSize = innerTargetRect->size() * devicePixelRatio;
496 if (innerSourceRect->width() <= 0)
498 else if (horizontalTileMode != QQuickBorderImage::Stretch) {
499 hTiles = innerTargetSize.width() / qreal(innerSourceRect->width() * sourceSize.width());
500 if (horizontalTileMode == QQuickBorderImage::Round)
501 hTiles = qCeil(hTiles);
503 if (innerSourceRect->height() <= 0)
505 else if (verticalTileMode != QQuickBorderImage::Stretch) {
506 vTiles = innerTargetSize.height() / qreal(innerSourceRect->height() * sourceSize.height());
507 if (verticalTileMode == QQuickBorderImage::Round)
508 vTiles = qCeil(vTiles);
511 *subSourceRect = QRectF(0, 0, hTiles, vTiles);
515QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
517 Q_D(QQuickBorderImage);
519 QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window());
521 if (!texture || width() <= 0 || height() <= 0) {
526 QSGInternalImageNode *node =
static_cast<QSGInternalImageNode *>(oldNode);
528 bool updatePixmap = d->pixmapChanged;
529 d->pixmapChanged =
false;
531 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
536 node->setTexture(texture);
540 QRectF innerTargetRect;
541 QRectF innerSourceRect;
542 QRectF subSourceRect;
543 d->calculateRects(d->border,
544 QSize(d->currentPix->width(), d->currentPix->height()), QSizeF(width(), height()),
545 d->horizontalTileMode, d->verticalTileMode, d->devicePixelRatio,
546 &targetRect, &innerTargetRect,
547 &innerSourceRect, &subSourceRect);
549 node->setTargetRect(targetRect);
550 node->setInnerSourceRect(innerSourceRect);
551 node->setInnerTargetRect(innerTargetRect);
552 node->setSubSourceRect(subSourceRect);
553 node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
555 node->setMipmapFiltering(QSGTexture::None);
556 node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
557 if (innerSourceRect == QRectF(0, 0, 1, 1) && (subSourceRect.width() > 1 || subSourceRect.height() > 1)) {
558 node->setHorizontalWrapMode(QSGTexture::Repeat);
559 node->setVerticalWrapMode(QSGTexture::Repeat);
561 node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
562 node->setVerticalWrapMode(QSGTexture::ClampToEdge);
564 node->setAntialiasing(d->antialiasing);