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, QPalette(), 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)
439 const QPalette palette;
442 color = palette.color(QPalette::Inactive, QPalette::Text);
444 case QIcon::Disabled:
445 color = palette.color(QPalette::Disabled, QPalette::Text);
448 color = palette.color(QPalette::Active, QPalette::Text);
450 case QIcon::Selected:
451 color = palette.color(QPalette::Active, QPalette::HighlightedText);
454 const auto *image = configuredImage(m_image, color);
456 QMacCGContext ctx(painter);
458#if defined(Q_OS_MACOS)
459 NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:YES];
460 [NSGraphicsContext saveGraphicsState];
461 [NSGraphicsContext setCurrentContext:gc];
463 const NSSize pixmapSize = NSMakeSize(rect.width(), rect.height());
464 [image setSize:pixmapSize];
465 const NSRect sourceRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
466 const NSRect iconRect = NSMakeRect(rect.x(), rect.y(), pixmapSize.width, pixmapSize.height);
468 [image drawInRect:iconRect fromRect:sourceRect operation:NSCompositingOperationSourceOver
469 fraction:1.0 respectFlipped:YES hints:@{
470 NSImageHintUserInterfaceLayoutDirection: painter->layoutDirection() == Qt::RightToLeft ?
471 @(NSUserInterfaceLayoutDirectionRightToLeft) : @(NSUserInterfaceLayoutDirectionLeftToRight)
473 [NSGraphicsContext restoreGraphicsState];
474#elif defined(QT_PLATFORM_UIKIT)
475 auto *layoutDirectionTrait = [UITraitCollection traitCollectionWithLayoutDirection:
476 painter->layoutDirection() == Qt::RightToLeft ?
477 UITraitEnvironmentLayoutDirectionRightToLeft :
478 UITraitEnvironmentLayoutDirectionLeftToRight];
480 image = [image imageWithConfiguration:layoutDirectionTrait.imageConfiguration];
482 UIGraphicsPushContext(ctx);
483 const CGRect cgrect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
484 [image drawInRect:cgrect];
485 UIGraphicsPopContext();
489void QAppleIconEngine::virtual_hook(
int hookIdentifier,
void *data)
493 if (hookIdentifier == QIconPrivate::PlatformIconHook)
494 *
static_cast<
decltype(m_image)*>(data) = m_image;
496 QIconEngine::virtual_hook(hookIdentifier, data);