Skip to content

Add a CoreGraphics cross-import overlay with support for attaching CGImages. #827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 10, 2024

Conversation

grynspan
Copy link
Contributor

@grynspan grynspan commented Nov 16, 2024

This PR adds a new cross-import overlay target with Apple's Core Graphics framework that allows attaching a CGImage as an attachment in an arbitrary image format (PNG, JPEG, etc.)

Because CGImage is imported into Swift as a non-final class, it cannot conform directly to Attachable, so an AttachableContainer type acts as a proxy. This type is not meant to be used directly, so its name is underscored. Initializers on Attachment are provided so that this abstraction is almost entirely transparent to test authors.

A new protocol, AttachableAsCGImage, is introduced that abstracts away the relationship between the attached image and Core Graphics; in the future, I intend to make additional image types like NSImage and UIImage conform to this protocol too.

Example usage:

let sparklyDiamonds: CGImage = ...
let attachment = Attachment(image, named: "sparkly-diamonds", as: .tiff, encodingQuality: 0.75)
...
attachment.attach()

The code in this PR is, by definition, specific to Apple's platforms. In the future, I'd be interested in adding Windows/Linux equivalents (HBITMAP? Whatever Gnome/KDE/Qt use?) but that's beyond the scope of this PR.

Checklist:

  • Code and documentation should follow the style of the Style Guide.
  • If public symbols are renamed or modified, DocC references should be updated.

@grynspan grynspan added enhancement New feature or request darwin 🍎 macOS, iOS, watchOS, tvOS, and visionOS support public-api Affects public API attachments/activities 🖇️ Work related to attachments and/or activities labels Nov 16, 2024
@grynspan grynspan self-assigned this Nov 16, 2024
@grynspan
Copy link
Contributor Author

@swift-ci test

@grynspan grynspan force-pushed the jgrynspan/coregraphics-overlay branch from 753920d to 0e9b551 Compare November 16, 2024 19:06
…GImage`s.

This PR adds a new cross-import overlay target with Apple's Core Graphics
framework that allows attaching a `CGImage` as an attachment in an arbitrary
image format (PNG, JPEG, etc.)

Because `CGImage` is imported into Swift as a non-final class, it cannot conform
directly to `Attachable`, so an `AttachableContainer` type acts as a proxy. This
type is not meant to be used directly, so its name is underscored. Initializers
on `Attachment` are provided so that this abstraction is almost entirely
transparent to test authors.

A new protocol, `AttachableAsCGImage`, is introduced that abstracts away the
relationship between the attached image and Core Graphics; in the future, I
intend to make additional image types like `NSImage and `UIImage` conform to
this protocol too.

The code in this PR is, by definition, specific to Apple's platforms. In the
future, I'd be interested in adding Windows/Linux equivalents (`HBITMAP`?
Whatever Gnome/KDE/Qt use?) but that's beyond the scope of this PR.
@grynspan grynspan force-pushed the jgrynspan/coregraphics-overlay branch from 0e9b551 to d11f84e Compare December 6, 2024 00:41
@grynspan
Copy link
Contributor Author

grynspan commented Dec 6, 2024

@swift-ci test

@grynspan grynspan requested a review from stmontgomery December 6, 2024 00:41
@grynspan
Copy link
Contributor Author

grynspan commented Dec 9, 2024

@swift-ci test

@grynspan grynspan merged commit 906092d into main Dec 10, 2024
3 checks passed
@grynspan grynspan deleted the jgrynspan/coregraphics-overlay branch December 10, 2024 02:20
grynspan added a commit that referenced this pull request Dec 19, 2024
This PR adds on to the Core Graphics cross-import overlay added in #827 to allow attaching
instances of `NSImage` to a test.

`NSImage` is a more complicated animal because it is not `Sendable`, but we don't want to
make a (potentially very expensive) deep copy of its data until absolutely necessary. So
we check inside the image to see if its contained representations are known to be safely
copyable (i.e. copies made with `NSCopying` do not share any mutable state with their
originals.) If it looks safe to make a copy of the image by calling `copy()`, we do so;
otherwise, we try to make a deep copy of the image.

Due to how Swift implements polymorphism in protocol requirements, and because we don't
really know what they're doing, subclasses of `NSImage` just get a call to `copy()`
instead of deep introspection.

`UIImage` support will be implemented in a separate PR.

> [!NOTE]
> Attachments remain an experimental feature.
@grynspan grynspan added the cross-import-overlays 🍰 Cross-import overlays (Foundation, Core Graphics, etc.) label May 14, 2025
grynspan added a commit that referenced this pull request May 20, 2025
This PR adds on to the Core Graphics cross-import overlay added in #827 to allow attaching
instances of `NSImage` to a test.

`NSImage` is a more complicated animal because it is not `Sendable`, but we don't want to
make a (potentially very expensive) deep copy of its data until absolutely necessary. So
we check inside the image to see if its contained representations are known to be safely
copyable (i.e. copies made with `NSCopying` do not share any mutable state with their
originals.) If it looks safe to make a copy of the image by calling `copy()`, we do so;
otherwise, we try to make a deep copy of the image.

Due to how Swift implements polymorphism in protocol requirements, and because we don't
really know what they're doing, subclasses of `NSImage` just get a call to `copy()`
instead of deep introspection.

`UIImage` support will be implemented in a separate PR.

> [!NOTE]
> Attachments remain an experimental feature.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
attachments/activities 🖇️ Work related to attachments and/or activities cross-import-overlays 🍰 Cross-import overlays (Foundation, Core Graphics, etc.) darwin 🍎 macOS, iOS, watchOS, tvOS, and visionOS support enhancement New feature or request public-api Affects public API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants