332QList<QSize> QAppleIconEngine::availableIconSizes(
double aspectRatio)
334 const qreal devicePixelRatio = qGuiApp->devicePixelRatio();
335 const QList<QSize> sizes = {
336 {qRound(16 * devicePixelRatio), qRound(16. * devicePixelRatio / aspectRatio)},
337 {qRound(32 * devicePixelRatio), qRound(32. * devicePixelRatio / aspectRatio)},
338 {qRound(64 * devicePixelRatio), qRound(64. * devicePixelRatio / aspectRatio)},
339 {qRound(128 * devicePixelRatio), qRound(128. * devicePixelRatio / aspectRatio)},
340 {qRound(256 * devicePixelRatio), qRound(256. * devicePixelRatio / aspectRatio)},
351QSize QAppleIconEngine::actualSize(
const QSize &size, QIcon::Mode , QIcon::State )
353 const double inputAspectRatio = isNull() ? 1.0 : m_image.size.width / m_image.size.height;
354 const double outputAspectRatio = size.width() / size.height();
356 if (outputAspectRatio > inputAspectRatio)
357 result.rwidth() = result.height() * inputAspectRatio;
359 result.rheight() = result.width() / inputAspectRatio;
363QPixmap QAppleIconEngine::pixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state)
365 return scaledPixmap(size, mode, state, 1.0);
407QPixmap QAppleIconEngine::scaledPixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale)
409 const CacheKey key(mode, state, size, scale);
410 QPixmap pixmap = m_cache.value(key);
411 if (pixmap.isNull()) {
412 const QSize paintSize = actualSize(size, mode, state);
413 const QSize paintOffset = paintSize != size
414 ? (QSizeF(size - paintSize) * 0.5).toSize()
417 pixmap = QPixmap(size * scale);
418 pixmap.setDevicePixelRatio(scale);
419 pixmap.fill(Qt::transparent);
421 if (!pixmap.isNull()) {
422 QPainter painter(&pixmap);
423 paint(&painter, QRect(paintOffset.width(), paintOffset.height(),
424 paintSize.width(), paintSize.height()), mode, state);
425 m_cache.insert(key, pixmap);
431void QAppleIconEngine::paint(QPainter *painter,
const QRect &rect, QIcon::Mode mode, QIcon::State state)
436 const QPalette palette;
439 color = palette.color(QPalette::Inactive, QPalette::Text);
441 case QIcon::Disabled:
442 color = palette.color(QPalette::Disabled, QPalette::Text);
445 color = palette.color(QPalette::Active, QPalette::Text);
447 case QIcon::Selected:
448 color = palette.color(QPalette::Active, QPalette::HighlightedText);
451 const auto *image = configuredImage(m_image, color);
453 QMacCGContext ctx(painter);
455#if defined(Q_OS_MACOS)
456 NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:YES];
457 [NSGraphicsContext saveGraphicsState];
458 [NSGraphicsContext setCurrentContext:gc];
460 const NSSize pixmapSize = NSMakeSize(rect.width(), rect.height());
461 [image setSize:pixmapSize];
462 const NSRect sourceRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
463 const NSRect iconRect = NSMakeRect(rect.x(), rect.y(), pixmapSize.width, pixmapSize.height);
465 [image drawInRect:iconRect fromRect:sourceRect operation:NSCompositingOperationSourceOver
466 fraction:1.0 respectFlipped:YES hints:@{
467 NSImageHintUserInterfaceLayoutDirection: painter->layoutDirection() == Qt::RightToLeft ?
468 @(NSUserInterfaceLayoutDirectionRightToLeft) : @(NSUserInterfaceLayoutDirectionLeftToRight)
470 [NSGraphicsContext restoreGraphicsState];
471#elif defined(QT_PLATFORM_UIKIT)
472 auto *layoutDirectionTrait = [UITraitCollection traitCollectionWithLayoutDirection:
473 painter->layoutDirection() == Qt::RightToLeft ?
474 UITraitEnvironmentLayoutDirectionRightToLeft :
475 UITraitEnvironmentLayoutDirectionLeftToRight];
477 image = [image imageWithConfiguration:layoutDirectionTrait.imageConfiguration];
479 UIGraphicsPushContext(ctx);
480 const CGRect cgrect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
481 [image drawInRect:cgrect];
482 UIGraphicsPopContext();
486void QAppleIconEngine::virtual_hook(
int hookIdentifier,
void *data)
490 if (hookIdentifier == QIconPrivate::PlatformIconHook)
491 *
static_cast<
decltype(m_image)*>(data) = m_image;
493 QIconEngine::virtual_hook(hookIdentifier, data);