331QList<QSize> QAppleIconEngine::availableIconSizes(
double aspectRatio)
333 const qreal devicePixelRatio = qGuiApp->devicePixelRatio();
334 const QList<QSize> sizes = {
335 {qRound(16 * devicePixelRatio), qRound(16. * devicePixelRatio / aspectRatio)},
336 {qRound(32 * devicePixelRatio), qRound(32. * devicePixelRatio / aspectRatio)},
337 {qRound(64 * devicePixelRatio), qRound(64. * devicePixelRatio / aspectRatio)},
338 {qRound(128 * devicePixelRatio), qRound(128. * devicePixelRatio / aspectRatio)},
339 {qRound(256 * devicePixelRatio), qRound(256. * devicePixelRatio / aspectRatio)},
350QSize QAppleIconEngine::actualSize(
const QSize &size, QIcon::Mode , QIcon::State )
352 const double inputAspectRatio = isNull() ? 1.0 : m_image.size.width / m_image.size.height;
353 const double outputAspectRatio = size.width() / size.height();
355 if (outputAspectRatio > inputAspectRatio)
356 result.rwidth() = result.height() * inputAspectRatio;
358 result.rheight() = result.width() / inputAspectRatio;
362QPixmap QAppleIconEngine::pixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state)
364 return scaledPixmap(size, mode, state, 1.0);
406QPixmap QAppleIconEngine::scaledPixmap(
const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale)
408 const CacheKey key(mode, state, size, scale);
409 QPixmap pixmap = m_cache.value(key);
410 if (pixmap.isNull()) {
411 const QSize paintSize = actualSize(size, mode, state);
412 const QSize paintOffset = paintSize != size
413 ? (QSizeF(size - paintSize) * 0.5).toSize()
416 pixmap = QPixmap(size * scale);
417 pixmap.setDevicePixelRatio(scale);
418 pixmap.fill(Qt::transparent);
420 if (!pixmap.isNull()) {
421 QPainter painter(&pixmap);
422 paint(&painter, QRect(paintOffset.width(), paintOffset.height(),
423 paintSize.width(), paintSize.height()), mode, state);
424 m_cache.insert(key, pixmap);
430void QAppleIconEngine::paint(QPainter *painter,
const QRect &rect, QIcon::Mode mode, QIcon::State state)
435 const QPalette palette;
438 color = palette.color(QPalette::Inactive, QPalette::Text);
440 case QIcon::Disabled:
441 color = palette.color(QPalette::Disabled, QPalette::Text);
444 color = palette.color(QPalette::Active, QPalette::Text);
446 case QIcon::Selected:
447 color = palette.color(QPalette::Active, QPalette::HighlightedText);
450 const auto *image = configuredImage(m_image, color);
452 QMacCGContext ctx(painter);
454#if defined(Q_OS_MACOS)
455 NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:YES];
456 [NSGraphicsContext saveGraphicsState];
457 [NSGraphicsContext setCurrentContext:gc];
459 const NSSize pixmapSize = NSMakeSize(rect.width(), rect.height());
460 [image setSize:pixmapSize];
461 const NSRect sourceRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
462 const NSRect iconRect = NSMakeRect(rect.x(), rect.y(), pixmapSize.width, pixmapSize.height);
464 [image drawInRect:iconRect fromRect:sourceRect operation:NSCompositingOperationSourceOver
465 fraction:1.0 respectFlipped:YES hints:@{
466 NSImageHintUserInterfaceLayoutDirection: painter->layoutDirection() == Qt::RightToLeft ?
467 @(NSUserInterfaceLayoutDirectionRightToLeft) : @(NSUserInterfaceLayoutDirectionLeftToRight)
469 [NSGraphicsContext restoreGraphicsState];
470#elif defined(QT_PLATFORM_UIKIT)
471 auto *layoutDirectionTrait = [UITraitCollection traitCollectionWithLayoutDirection:
472 painter->layoutDirection() == Qt::RightToLeft ?
473 UITraitEnvironmentLayoutDirectionRightToLeft :
474 UITraitEnvironmentLayoutDirectionLeftToRight];
476 image = [image imageWithConfiguration:layoutDirectionTrait.imageConfiguration];
478 UIGraphicsPushContext(ctx);
479 const CGRect cgrect = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
480 [image drawInRect:cgrect];
481 UIGraphicsPopContext();
485void QAppleIconEngine::virtual_hook(
int hookIdentifier,
void *data)
489 if (hookIdentifier == QIconPrivate::PlatformIconHook)
490 *
static_cast<
decltype(m_image)*>(data) = m_image;
492 QIconEngine::virtual_hook(hookIdentifier, data);