Last active
April 7, 2024 13:10
-
-
Save krzyzanowskim/5f2a090f258b075c142a83d0744ba1b7 to your computer and use it in GitHub Desktop.
Minimal setup of TextKit2 components to produce PDF document
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
let loremIpsum = """ | |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque erat risus, laoreet et eros id, lobortis elementum sem. Nullam nec magna massa. Donec gravida felis at odio tincidunt pretium et in orci. Curabitur suscipit porta purus non faucibus. Cras dapibus felis eu enim rutrum, vel aliquet lacus volutpat. Quisque fermentum vulputate dictum. Morbi mattis orci quis dui posuere, id vulputate turpis tempus. Sed vulputate augue at ullamcorper feugiat. Phasellus nec lacus eget sapien congue lacinia vel et nulla. Phasellus sollicitudin gravida dapibus. Donec molestie ullamcorper lacus eu rutrum. Praesent lacinia dignissim dui eu ultricies. Integer in lacus lobortis, porttitor sem eu, tincidunt dolor. Cras dignissim nisl in maximus ullamcorper. | |
Proin nec vulputate magna. In interdum leo sit amet arcu consequat facilisis. Fusce ut malesuada ante, nec malesuada nisl. Mauris porta velit quis tortor mollis, in suscipit augue efficitur. Praesent eleifend mollis neque, non semper diam tempus at. Cras sed nibh ac ante vehicula aliquet id eu velit. In hac habitasse platea dictumst. Aliquam id odio leo. Aenean eget porta nulla, a commodo ipsum. Suspendisse id molestie orci. Vivamus iaculis pulvinar augue id volutpat. Curabitur in lorem lectus. Quisque sit amet urna ut felis lobortis finibus. Pellentesque non turpis in tortor efficitur pellentesque in eget odio. | |
""" | |
let textContainer = NSTextContainer() | |
textContainer.lineFragmentPadding = 0 | |
textContainer.size.width = 300 | |
let contentManager = NSTextContentStorage() | |
let layoutManager = NSTextLayoutManager() | |
layoutManager.textContainer = textContainer | |
contentManager.addTextLayoutManager(layoutManager) | |
contentManager.attributedString = NSAttributedString(string: loremIpsum) | |
// First layout in the text container | |
layoutManager.ensureLayout(for: contentManager.documentRange) | |
// Adjust text container size to the size required to layout content | |
textContainer.size = layoutManager.usageBoundsForTextContainer.size | |
layoutManager.ensureLayout(for: contentManager.documentRange) | |
// Draw/Layout fragments | |
// create PDF CGContext boilerplate | |
let pdfData = NSMutableData() | |
var mediaBox = CGRect(origin: .zero, size: textContainer.size) | |
let context = CGContext(consumer: CGDataConsumer(data: pdfData)!, mediaBox: &mediaBox, nil)! | |
context.beginPage(mediaBox: &mediaBox) | |
context.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: mediaBox.size.height)) | |
layoutManager.enumerateTextLayoutFragments(from: contentManager.documentRange.location, options: [.ensuresLayout], using: { textLayoutFragment in | |
textLayoutFragment.draw(at: textLayoutFragment.layoutFragmentFrame.origin, in: context) | |
return true | |
}) | |
//let viewportDelegate = CustomViewportDelegate(context: context) | |
//layoutManager.textViewportLayoutController.delegate = viewportDelegate | |
//layoutManager.textViewportLayoutController.layoutViewport() | |
// Write PDF to file | |
context.endPage() | |
context.closePDF() | |
try! pdfData.write(to: URL(filePath: "/Users/marcinkrzyzanowski/Downloads/output.pdf")) | |
//class CustomViewportDelegate: NSObject, NSTextViewportLayoutControllerDelegate { | |
// let context: CGContext | |
// | |
// init(context: CGContext) { | |
// self.context = context | |
// } | |
// | |
// func viewportBounds(for textViewportLayoutController: NSTextViewportLayoutController) -> CGRect { | |
// CGRect( | |
// origin: .zero, | |
// size: textViewportLayoutController.textLayoutManager?.textContainer?.size ?? .zero | |
// ) | |
// } | |
// | |
// func textViewportLayoutController(_ textViewportLayoutController: NSTextViewportLayoutController, configureRenderingSurfaceFor textLayoutFragment: NSTextLayoutFragment) { | |
// textLayoutFragment.draw( | |
// at: textLayoutFragment.layoutFragmentFrame.origin, | |
// in: context | |
// ) | |
// } | |
//} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment