| /* |
| * Copyright 2022 Rive |
| */ |
| |
| #include "rive/core/type_conversions.hpp" |
| #include <vector> |
| |
| #ifdef RIVE_BUILD_FOR_APPLE |
| |
| #include "cg_skia_factory.hpp" |
| #include "mac_utils.hpp" |
| |
| #if defined(RIVE_BUILD_FOR_OSX) |
| #include <ApplicationServices/ApplicationServices.h> |
| #elif defined(RIVE_BUILD_FOR_IOS) |
| #include <CoreGraphics/CoreGraphics.h> |
| #include <ImageIO/ImageIO.h> |
| #endif |
| |
| using namespace rive; |
| |
| std::vector<uint8_t> CGSkiaFactory::platformDecode(Span<const uint8_t> span, |
| SkiaFactory::ImageInfo* info) |
| { |
| std::vector<uint8_t> pixels; |
| |
| AutoCF image = DecodeToCGImage(span); |
| if (!image) |
| { |
| return pixels; |
| } |
| |
| bool isOpaque = false; |
| switch (CGImageGetAlphaInfo(image.get())) |
| { |
| case kCGImageAlphaNone: |
| case kCGImageAlphaNoneSkipFirst: |
| case kCGImageAlphaNoneSkipLast: |
| isOpaque = true; |
| break; |
| default: |
| break; |
| } |
| |
| // Now create a drawing context to produce RGBA pixels |
| |
| const size_t bitsPerComponent = 8; |
| CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba |
| if (isOpaque) |
| { |
| cgInfo |= kCGImageAlphaNoneSkipLast; |
| } |
| else |
| { |
| cgInfo |= kCGImageAlphaPremultipliedLast; // premul |
| } |
| const size_t width = CGImageGetWidth(image); |
| const size_t height = CGImageGetHeight(image); |
| const size_t rowBytes = width * 4; // 4 bytes per pixel |
| const size_t size = rowBytes * height; |
| |
| pixels.resize(size); |
| |
| AutoCF cs = CGColorSpaceCreateDeviceRGB(); |
| AutoCF cg = |
| CGBitmapContextCreate(pixels.data(), width, height, bitsPerComponent, rowBytes, cs, cgInfo); |
| if (!cg) |
| { |
| pixels.clear(); |
| return pixels; |
| } |
| |
| CGContextSetBlendMode(cg, kCGBlendModeCopy); |
| CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image); |
| |
| info->alphaType = isOpaque ? AlphaType::opaque : AlphaType::premul; |
| info->colorType = ColorType::rgba; |
| info->width = castTo<uint32_t>(width); |
| info->height = castTo<uint32_t>(height); |
| info->rowBytes = rowBytes; |
| return pixels; |
| }; |
| |
| #endif // RIVE_BUILD_FOR_APPLE |