Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create a PDF with Annots?

I am trying to generate a PDF in code that has Annotations such as Widgets and Links. I can generate the PDF and modify the document info and the MediaBox of the page, but I can't figure out how to add to the Annotations. I try to add it to the page dictionary but for some reason the PDF isn't accepting it.

Does anyone know how to add Annotations to a newly created PDF? Below is the code I have to generate the PDF and the test Annotation dictionary I am trying to add to it:

-(void) createPDFFile: (CGPDFPageRef) pageRef{

CGContextRef pdfContext;

CFStringRef path;

CFURLRef url;


CFMutableDictionaryRef myDictionary = NULL;

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
 NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
 const char *filepath = [[documentsDirectory stringByAppendingString:@"/fileTest.pdf"] UTF8String];

path = CFStringCreateWithCString (NULL, filepath, kCFStringEncodingUTF8);

url = CFURLCreateWithFileSystemPath (NULL, path,  kCFURLPOSIXPathStyle, 0);

CFRelease (path);

myDictionary = CFDictionaryCreateMutable(NULL, 0,

                                         &kCFTypeDictionaryKeyCallBacks,

                                         &kCFTypeDictionaryValueCallBacks); 

CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File"));

CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name"));

CGRect pageRect = self.bounds;
pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary); // 5

CFRelease(myDictionary);

CFRelease(url);

CGRect mediaBox;
mediaBox = CGRectMake (0, 0, pageRect.size.width, 100);
CFStringRef myKeys[1];

CFTypeRef myValues[1];

myKeys[0] = CFSTR("MediaBox");

myValues[0] = (CFTypeRef) CFDataCreate(NULL,(const UInt8 *)&mediaBox, sizeof (CGRect));

CFDictionaryRef pageDictionary = CFDictionaryCreate(NULL, (const void **) myKeys,
                                                    (const void **) myValues, 1,
                                                    &kCFTypeDictionaryKeyCallBacks,
                                                    & kCFTypeDictionaryValueCallBacks);
CFMutableDictionaryRef pageDictionaryMutable = CFDictionaryCreateMutableCopy(NULL, 0, pageDictionary);

CFMutableDictionaryRef  metaDataDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks); 

CFDictionarySetValue(metaDataDictionary, CFSTR("DA"), CFSTR("/Helvetica 10 Tf 0 g"));
CFDictionarySetValue(metaDataDictionary, CFSTR("F"), CFSTR("4"));
CFDictionarySetValue(metaDataDictionary, CFSTR("FT"), CFSTR("Tx"));
CFDictionarySetValue(metaDataDictionary, CFSTR("Subtype"), CFSTR("Widget"));
CFDictionarySetValue(metaDataDictionary, CFSTR("T"), CFSTR("undefined"));
CFDictionarySetValue(metaDataDictionary, CFSTR("Type"), CFSTR("Annot"));
CFDictionarySetValue(metaDataDictionary, CFSTR("V"), CFSTR(""));
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault,0, &kCFTypeArrayCallBacks);
CFArrayInsertValueAtIndex(array, 0, metaDataDictionary);

CFDictionarySetValue(pageDictionaryMutable, CFSTR("Annots"), array);


CGPDFContextBeginPage (pdfContext, pageDictionaryMutable);


CGPDFContextEndPage (pdfContext);

CGContextRelease (pdfContext);

CFRelease(pageDictionary);}

Printing out the CFMutableDictionary pageDictionaryMutable shows that the Annots dictionary should be added to the PDF as well as the MediaBox:

(gdb) po pageDictionaryMutable
{
    Annots =     (
                {
            DA = "/Helvetica 10 Tf 0 g";
            F = 4;
            FT = Tx;
            Subtype = Widget;
            T = undefined;
            Type = Annot;
            V = "";
        }
    );
    MediaBox = <00000000 00000000 00008044 0000c842>;
}

The Media Box takes but the Annots does not. Please help anyone!

like image 498
user1680628 Avatar asked Nov 03 '22 15:11

user1680628


1 Answers

Take a look at the PoDoFo Library: http://podofo.sourceforge.net

PoDoFo is licensed in parts under the GPL and the LGPL.

With it you can modify the pdf file and add Annotations to it. It's portable to iOS. Look at the documentation, if it can handle what you want and to see how it works.

If you're interested you can also look at this sample project on GitHub. There I integrated the library to an iOS project and you can add FreeText and Square Annotations using an iPad.

like image 185
el flex Avatar answered Nov 09 '22 10:11

el flex