janabananaThank-You for tagging along in this voyage!However, your comment confuses me on several points:first you make no comment as to my Word or TextEdit suggested actions... can you confirm the behavior I have observed? (what OS?)you say 'tested in my app' -- so you wrote all the code involved?you say 'saved it as a pdf' - this is using your code or using the standard macOS 'Print' - 'Save As'?in your app are you using NSPrintOperation to render the attributed string within an NSTextView or are you doing something different?
Post
Replies
Boosts
Views
Activity
To Anyone Tagging Along;OMG It appears to me now that this is the expected behavior!Create a new Word document or TextEdit..Enter some text and assign a link to this text.Now use 'Print' and then 'Save as PDF' to save a document.Now open that newly created .pdf file.No hyperlinks!! You may see text that has link color but the underlying hyperlink is not embedded in the .pdf file!BTW this is tru for Catalina and High Sierra (10.13.6)Has it always been like this? It doesn't seem so to me but I can't point to anything.Steve
symczyk;Thanks for the traction. Your contributions here are appreciated!!You say above: '...For creating a PDF from a text view's contents, you're better off going with NSPrintOperation...'Yeah, that's where I started this thread. Below is that code.I'm back to the original question: This code produces a .pdf file BUT that .pdf does not contain the NSAttributedString shown in the NSTextView. The .pdf file only contains the .string value of the source NSAttributedString.- (PDFDocument *) pdfForAttributedString:(NSView *)thisView {
NSString *globUniq = [[NSProcessInfo processInfo] globallyUniqueString];
NSURL *printURL = [NSURL URLWithString:[[self.tempDirectoryURL path] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf", globUniq]]];
NSMutableDictionary *dict = [[NSPrintInfo sharedPrintInfo] dictionary];
[dict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
[dict setObject:printURL forKey:NSPrintJobSavingURL];
//set 1 in margins
[dict setObject:[NSNumber numberWithFloat:72.0] forKey:NSTopMarginDocumentAttribute];
[dict setObject:[NSNumber numberWithFloat:72.0] forKey:NSBottomMarginDocumentAttribute];
[dict setObject:[NSNumber numberWithFloat:72.0] forKey:NSLeftMarginDocumentAttribute];
[dict setObject:[NSNumber numberWithFloat:72.0] forKey:NSRightMarginDocumentAttribute];
//centering
[dict setObject:[NSNumber numberWithBool:0] forKey:NSPrintHorizontallyCentered];
[dict setObject:[NSNumber numberWithBool:0] forKey:NSPrintVerticallyCentered];
NSPrintInfo *pix = [[NSPrintInfo alloc] initWithDictionary:dict];
[pix setHorizontalPagination:NSPrintingPaginationModeFit];//NSPrintingPaginationModeFit NSAutoPagination
[pix setVerticalPagination:NSPrintingPaginationModeFit];//NSAutoPagination
//setup dataObject
NSMutableData *output = [[NSMutableData alloc] init];
NSPrintOperation *op = [NSPrintOperation PDFOperationWithView:thisView insideRect:thisView.frame toData:output printInfo:pix];
//hide UI
[op setShowsPrintPanel:NO];
[op setShowsProgressPanel:NO];
//do the thing
if ([op runOperation]) {
PDFDocument * doc = [[PDFDocument alloc] initWithData:output];
return doc;
} else {
return nil;
}
}
any code you might show about how to 'create pages as long as there is text remaining' would be appreciated!
I don't understand how your 2 lines of code produce a .pdf document.You ask 'what precisely is your problem'?I have posted 2 different sets of code which DO produce .pdf files. My problem is is that these file do not produce the source attributedString -- they appear to produce the .string value of the NSAttributedString.My precise problem is that I am trying to produce a .pdf file which is an attributed string.
I am interested in looking at the solution you propose! Please post!
szymczykThanks for taking the time to reply.I followed up on your pointers to Apple Quartz 2D and the link you provided.The code below is based on both of those source and this code functions as expected.BUT it yields exactly the same output - the resulting .pdf file does not show an attributed string - it simply shows the .string value.Surely I'm missing something!Can someone provide any guidance?My suspicions center on 'pageDictionary' and 'CTFrameDraw(). [but what do I know]- (PDFDocument *) pdfForAttributedString:(NSAttributedString *)thisAtrributedString {
NSString *tDir = self.tempDirectoryURL.path;
NSString *globUniq = [[NSProcessInfo processInfo] globallyUniqueString];
NSString *newFileName = [tDir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf", globUniq]];
const char *filename = [newFileName UTF8String];
CFStringRef path = CFStringCreateWithCString (NULL, filename, kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0);
CFRelease (path);
CFMutableDictionaryRef myDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR(“XYZ - a macOS app"));
CGContextRef pdfContext = CGPDFContextCreateWithURL (url, nil, myDictionary); // Quartz assumes 8.5 x 11
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(thiscfAttr);
CFRange textRange = CFRangeMake(0, CFAttributedStringGetLength(thiscfAttr));
CFRange pageRange;
CGSize pageSize = CGSizeMake(612.0, 792.0);
CFAttributedStringRef thiscfAttr = (__bridge CFAttributedStringRef)(thisAtrributedString);
CTFramesetterSuggestFrameSizeWithConstraints(framesetter, textRange, nil, pageSize, &pageRange);
CGRect pageRect = CGRectMake(72.0, 72.0, 468.0, 648.0);// 1” margins
CGPathRef framePath = CGPathCreateWithRect(pageRect, nil);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, pageRange, framePath, nil);
CFMutableDictionaryRef pageDictionary = NULL;
CGPDFContextBeginPage (pdfContext, pageDictionary);
CTFrameDraw(frame, pdfContext);
CGPDFContextEndPage (pdfContext);
CGPDFContextClose(pdfContext);
NSURL *printURL = (__bridge NSURL *)(url);
PDFDocument *doc = [[PDFDocument alloc] initWithURL:printURL];
return doc;
}