148QQuickBorderImage::QQuickBorderImage(QQuickItem *parent)
149: QQuickImageBase(*(
new QQuickBorderImagePrivate), parent)
151 connect(
this, &QQuickImageBase::sourceSizeChanged,
this, &QQuickBorderImage::sourceSizeChanged);
275void QQuickBorderImage::load()
277 Q_D(QQuickBorderImage);
279 if (d->url.isEmpty()) {
282 if (d->url.path().endsWith(QLatin1String(
"sci"))) {
283 const QQmlContext *context = qmlContext(
this);
284 QString lf = QQmlFile::urlToLocalFileOrQrc(context ? context->resolvedUrl(d->url)
288 if (!file.open(QIODevice::ReadOnly))
291 setGridScaledImage(QQuickGridScaledImage(&file));
293#if QT_CONFIG(qml_network)
295 d->setStatus(Loading);
297 QNetworkRequest req(d->url);
298 d->sciReply = qmlEngine(
this)->networkAccessManager()->get(req);
299 qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
300 this, QQuickBorderImage, SLOT(sciRequestFinished()));
304 loadPixmap(d->url, LoadPixmapOptions(HandleDPR | UseProviderOptions));
409void QQuickBorderImage::requestFinished()
411 Q_D(QQuickBorderImage);
413 if (d->pendingPix != d->currentPix) {
414 std::swap(d->pendingPix, d->currentPix);
415 d->pendingPix->clear(
this);
418 const QSize impsize = d->currentPix->implicitSize();
419 setImplicitSize(impsize.width() / d->devicePixelRatio, impsize.height() / d->devicePixelRatio);
421 if (d->currentPix->isError()) {
422 qmlWarning(
this) << d->currentPix->error();
430 if (sourceSize() != d->oldSourceSize) {
431 d->oldSourceSize = sourceSize();
432 emit sourceSizeChanged();
434 if (d->frameCount != d->currentPix->frameCount()) {
435 d->frameCount = d->currentPix->frameCount();
436 emit frameCountChanged();
466 const QSize &sourceSize,
467 const QSizeF &targetSize,
468 int horizontalTileMode,
469 int verticalTileMode,
470 qreal devicePixelRatio,
472 QRectF *innerTargetRect,
473 QRectF *innerSourceRect,
474 QRectF *subSourceRect)
476 *innerSourceRect = QRectF(0, 0, 1, 1);
477 *targetRect = QRectF(0, 0, targetSize.width(), targetSize.height());
478 *innerTargetRect = *targetRect;
481 qreal borderLeft = border->left() * devicePixelRatio;
482 qreal borderRight = border->right() * devicePixelRatio;
483 qreal borderTop = border->top() * devicePixelRatio;
484 qreal borderBottom = border->bottom() * devicePixelRatio;
485 if (borderLeft + borderRight > sourceSize.width() && borderLeft < sourceSize.width())
486 borderRight = sourceSize.width() - borderLeft;
487 if (borderTop + borderBottom > sourceSize.height() && borderTop < sourceSize.height())
488 borderBottom = sourceSize.height() - borderTop;
489 *innerSourceRect = QRectF(QPointF(borderLeft / qreal(sourceSize.width()),
490 borderTop / qreal(sourceSize.height())),
491 QPointF((sourceSize.width() - borderRight) / qreal(sourceSize.width()),
492 (sourceSize.height() - borderBottom) / qreal(sourceSize.height()))),
493 *innerTargetRect = QRectF(border->left(),
495 qMax<qreal>(0, targetSize.width() - (border->right() + border->left())),
496 qMax<qreal>(0, targetSize.height() - (border->bottom() + border->top())));
501 const QSizeF innerTargetSize = innerTargetRect->size() * devicePixelRatio;
502 if (innerSourceRect->width() <= 0)
504 else if (horizontalTileMode != QQuickBorderImage::Stretch) {
505 hTiles = innerTargetSize.width() / qreal(innerSourceRect->width() * sourceSize.width());
506 if (horizontalTileMode == QQuickBorderImage::Round)
507 hTiles = qCeil(hTiles);
509 if (innerSourceRect->height() <= 0)
511 else if (verticalTileMode != QQuickBorderImage::Stretch) {
512 vTiles = innerTargetSize.height() / qreal(innerSourceRect->height() * sourceSize.height());
513 if (verticalTileMode == QQuickBorderImage::Round)
514 vTiles = qCeil(vTiles);
517 *subSourceRect = QRectF(0, 0, hTiles, vTiles);
521QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
523 Q_D(QQuickBorderImage);
525 QSGTexture *texture = d->sceneGraphRenderContext()->textureForFactory(d->currentPix->textureFactory(), window());
527 if (!texture || width() <= 0 || height() <= 0) {
532 QSGInternalImageNode *node =
static_cast<QSGInternalImageNode *>(oldNode);
534 bool updatePixmap = d->pixmapChanged;
535 d->pixmapChanged =
false;
537 node = d->sceneGraphContext()->createInternalImageNode(d->sceneGraphRenderContext());
542 node->setTexture(texture);
546 QRectF innerTargetRect;
547 QRectF innerSourceRect;
548 QRectF subSourceRect;
549 d->calculateRects(d->border,
550 QSize(d->currentPix->width(), d->currentPix->height()), QSizeF(width(), height()),
551 d->horizontalTileMode, d->verticalTileMode, d->devicePixelRatio,
552 &targetRect, &innerTargetRect,
553 &innerSourceRect, &subSourceRect);
555 node->setTargetRect(targetRect);
556 node->setInnerSourceRect(innerSourceRect);
557 node->setInnerTargetRect(innerTargetRect);
558 node->setSubSourceRect(subSourceRect);
559 node->setMirror(d->mirrorHorizontally, d->mirrorVertically);
561 node->setMipmapFiltering(QSGTexture::None);
562 node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
563 if (innerSourceRect == QRectF(0, 0, 1, 1) && (subSourceRect.width() > 1 || subSourceRect.height() > 1)) {
564 node->setHorizontalWrapMode(QSGTexture::Repeat);
565 node->setVerticalWrapMode(QSGTexture::Repeat);
567 node->setHorizontalWrapMode(QSGTexture::ClampToEdge);
568 node->setVerticalWrapMode(QSGTexture::ClampToEdge);
570 node->setAntialiasing(d->antialiasing);