Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

Added capability to show "Freetext" annotations along with Form. #13

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion ILPDFKit/Controller/PDFViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,15 @@ -(void)loadPDFView
self.view.frame = CGRectMake(0,self.view.frame.origin.y,frm.size.width,frm.size.height-self.view.frame.origin.y);
CGPoint margins = [self getMargins];
NSArray* additionViews = [_document.forms createWidgetAnnotationViewsForSuperviewWithWidth:frm.size.width Margin:margins.x HMargin:margins.y];
_pdfView = [[PDFView alloc] initWithFrame:self.view.bounds DataOrPath:pass AdditionViews:additionViews];

//Fetch annotations for the page..
NSMutableArray *annotations=[[NSMutableArray alloc] init];
for(PDFPage *page in _document.pages){
[annotations addObjectsFromArray:[page showAnnotationsForPageWithWidth:frm.size.width XMargin:margins.x YMargin:margins.y]];
}

_pdfView = [[PDFView alloc] initWithFrame:self.view.bounds DataOrPath:pass AdditionViews:additionViews Annotations:annotations];

[self.view addSubview:_pdfView];
}

Expand Down
10 changes: 10 additions & 0 deletions ILPDFKit/Model/PDFPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
PDFPage consists of the data representing the page info.
*/

@class PDFDocument;
@class PDFDictionary;

@interface PDFPage : NSObject
Expand Down Expand Up @@ -89,4 +90,13 @@
*/
@property(nonatomic,readonly) PDFDictionary* resources;

/** The reference of the actual PDFDocument object
*/
@property(nonatomic, assign) PDFDocument *document;


/** Show annotations for the page..
*/
-(NSMutableArray *)showAnnotationsForPageWithWidth:(CGFloat)vwidth XMargin:(CGFloat)xmargin YMargin:(CGFloat)ymargin;

@end
173 changes: 172 additions & 1 deletion ILPDFKit/Model/PDFPage.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

#import "PDFPage.h"
#import "PDFDictionary.h"

#import "PDFAnnotation.h"
#import "PDFDocument.h"

@interface PDFPage()

Expand Down Expand Up @@ -135,4 +136,174 @@ -(CGRect)rotateBox:(CGRect)box
return ret;
}

#pragma mark - Annotations

-(NSMutableArray *)showAnnotationsForPageWithWidth:(CGFloat)vwidth XMargin:(CGFloat)xmargin YMargin:(CGFloat)ymargin{

CGPDFPageRef pPage=self.page;

NSMutableArray* pdfAnnots = [[NSMutableArray alloc] init];

CGPDFDictionaryRef pageDictionary = CGPDFPageGetDictionary(pPage);
CGPDFArrayRef outputArray;
if(!CGPDFDictionaryGetArray(pageDictionary, "Annots", &outputArray)) {
return nil;
}
else{
int arrayCount = CGPDFArrayGetCount( outputArray );
for( int j = 0; j < arrayCount; ++j ) {
CGPDFObjectRef aDictObj;
if(!CGPDFArrayGetObject(outputArray, j, &aDictObj)) {
break;
}

CGPDFDictionaryRef annotDict;
if(!CGPDFObjectGetValue(aDictObj, kCGPDFObjectTypeDictionary, &annotDict)) {
break;
}

const char *annotationType;
CGPDFDictionaryGetName(annotDict, "Subtype", &annotationType);

NSString* type = [NSString stringWithUTF8String:annotationType];

BOOL freeTextCustomAnotToShow=YES;
CGPDFDictionaryRef apDict;
if(CGPDFDictionaryGetDictionary(annotDict, "AP", &apDict)){
int count = CGPDFDictionaryGetCount(apDict);
if(count>0 && [type isEqualToString:FREE_TEXT_ANNOTATION])
freeTextCustomAnotToShow=NO;
}

CGPDFArrayRef rectArray;
if(!CGPDFDictionaryGetArray(annotDict, "Rect", &rectArray)) {
break;
}

int arrayCount = CGPDFArrayGetCount( rectArray );
CGPDFReal coords[4];
for( int k = 0; k < arrayCount; ++k ) {
CGPDFObjectRef rectObj;
if(!CGPDFArrayGetObject(rectArray, k, &rectObj)) {
break;
}

CGPDFReal coord;
if(!CGPDFObjectGetValue(rectObj, kCGPDFObjectTypeReal, &coord)) {
break;
}

coords[k] = coord;
}

CGRect rect = CGRectMake(coords[0],coords[1],coords[2],coords[3]);

UIColor *annotColor = [UIColor blackColor];
CGPDFArrayRef colorArray;
if(CGPDFDictionaryGetArray(annotDict, "C", &colorArray)) {
int cArrayCount = CGPDFArrayGetCount( colorArray );
CGPDFReal colors[3];
for( int k = 0; k < cArrayCount; ++k ) {
CGPDFObjectRef colorObj;
if(!CGPDFArrayGetObject(colorArray, k, &colorObj)) {
break;
}
CGPDFReal color;
if(!CGPDFObjectGetValue(colorObj, kCGPDFObjectTypeReal, &color)) {
break;
}
colors[k] = color;
}
annotColor=[UIColor colorWithRed:colors[0] green:colors[1] blue:colors[2] alpha:1];

}
rect.size.width -= rect.origin.x;
rect.size.height -= rect.origin.y;

//to show the annotation on the right position a +5 is needed. It may
//be needed because the content inset Top of the ResizableTextView is set
//to -5 ?Dont know why this effects the y value of the frame?
rect.origin.y +=5;
CGRect cropBox=[self cropBox];
CGFloat width = cropBox.size.width;
CGFloat maxWidth = width;
for(PDFPage* pg in self.document.pages)
{
if([pg cropBox].size.width > maxWidth)maxWidth = [pg cropBox].size.width;
}

CGFloat hmargin = ((maxWidth-width)/2)*((vwidth-2*xmargin)/maxWidth)+xmargin;



CGFloat height = cropBox.size.height;
CGRect correctedFrame = CGRectMake(rect.origin.x-cropBox.origin.x, height-rect.origin.y-rect.size.height-cropBox.origin.y, rect.size.width, rect.size.height);

CGFloat realWidth = vwidth-2*hmargin;

CGFloat factor = realWidth/width;

CGFloat pageOffset = 0;

for(NSUInteger c = 0; c < self.pageNumber-1;c++)
{
PDFPage* pg = [self.document.pages objectAtIndex:c];
CGFloat iwidth = [pg cropBox].size.width;
CGFloat ihmargin = ((maxWidth-iwidth)/2)*((vwidth-2*xmargin)/maxWidth)+xmargin;
CGFloat iheight = [pg cropBox].size.height;
CGFloat irealWidth = vwidth-2*ihmargin;
CGFloat ifactor = irealWidth/iwidth;
pageOffset+= iheight*ifactor+ymargin;
}


CGRect pageRect = CGRectIntegral(CGRectMake(correctedFrame.origin.x*factor+hmargin, correctedFrame.origin.y*factor+ymargin, correctedFrame.size.width*factor, correctedFrame.size.height*factor));



CGRect uiBaseRect = CGRectIntegral(CGRectMake(pageRect.origin.x, pageRect.origin.y+pageOffset, pageRect.size.width, pageRect.size.height));


PDFAnnotation *annotation = [[PDFAnnotation alloc] initWithPDFDictionary:annotDict andType:type];


CGSize strSize=[annotation.textString sizeWithFont:annotation.font];

if(uiBaseRect.size.width<strSize.width)
uiBaseRect.size.width=strSize.width+30.0;
else
uiBaseRect.size.width+=50.0;

if(uiBaseRect.size.height<strSize.height){
uiBaseRect.size.height=strSize.height+30.0;
}else
uiBaseRect.size.height+=50.0;

// FreeText annotations are identified by FreeText name stored in Subtype key in annotation dictionary.
if ([type isEqualToString:FREE_TEXT_ANNOTATION] && freeTextCustomAnotToShow){
UITextView *annotationView = [[UITextView alloc] initWithFrame:uiBaseRect];
annotationView.font = annotation.font;
annotationView.text = annotation.textString;
annotationView.textColor = annotation.textColor;
annotationView.backgroundColor = [UIColor clearColor];
annotationView.textAlignment = annotation.textAlignment;
[annotationView setEditable:NO];
annotationView.scrollEnabled=NO;

if (annotation.borderWidth != 0) {
annotationView.layer.borderColor = annotation.textColor.CGColor;
annotationView.layer.borderWidth = annotation.borderWidth;
}

annotation.annotationView = annotationView;
[pdfAnnots addObject:annotation];

}else{
// you may support more annotations
}
}
}
return pdfAnnots;
}

@end
61 changes: 61 additions & 0 deletions ILPDFKit/View/PDFAnnotation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// PDFAnnotation.h
// ILPDFKitSample
//
// Created by Ved Prakash on 6/10/14.
// Copyright (c) 2014 Iwe Labs. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
The identifier for FreeText annotations
*/
#define FREE_TEXT_ANNOTATION @"FreeText"

@interface PDFAnnotation : NSObject
/**
Defines the type of the annotation. In this version only FreeText is supported
*/
@property(nonatomic,retain) NSString * annotationType;

/**
Defines the font of a FreeText annotation.
*/
@property(nonatomic,retain) UIFont * font;

/**
The text of a FreeText annotation
*/
@property(nonatomic,retain) NSString * textString;

/**
The view showing the annoatation.
*/
@property(nonatomic,retain) UIView * annotationView;

/**
The text color of a FreeText annotation
*/
@property(nonatomic,retain) UIColor* textColor;

/**
The alignment of a the text in a FreeText annotation
*/
@property UITextAlignment textAlignment;

/**
The border Width of a Square or FreeText annotation. If the FreeText
annotation is without border this value should be 0
*/
@property CGFloat borderWidth;

/**
Initializes an PDFAnnotation with a specified PDF dictionary containing
the annotation properties and a specified type
@param annotDict The CGPDFDictionaryRef containing the annotation properties
@param type The annotation type
@return The newly initialized PDFAnnotation
*/
-(id)initWithPDFDictionary:(CGPDFDictionaryRef)annotDict andType:(NSString*)type;
@end
111 changes: 111 additions & 0 deletions ILPDFKit/View/PDFAnnotation.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// PDFAnnotation.m
// ILPDFKitSample
//
// Created by Ved Prakash on 6/10/14.
// Copyright (c) 2014 Iwe Labs. All rights reserved.
//

#import "PDFAnnotation.h"

@implementation PDFAnnotation
@synthesize annotationType,font,textString;
@synthesize textColor;
@synthesize textAlignment;
@synthesize borderWidth;


-(id)initWithPDFDictionary:(CGPDFDictionaryRef)annotDict andType:(NSString *)type{
self=[super init];
self.annotationType = type;

if ([type isEqualToString:FREE_TEXT_ANNOTATION]){

CGPDFStringRef fontTypeRef;
if(CGPDFDictionaryGetString(annotDict, "DA", &fontTypeRef)) {
NSString* fontType = (__bridge NSString *)CGPDFStringCopyTextString(fontTypeRef);
NSArray *firstWords = [fontType componentsSeparatedByString:@" "];
NSString *tempStr = [firstWords objectAtIndex:0];
fontType = [tempStr substringFromIndex:1];

tempStr=[firstWords objectAtIndex:1];
NSInteger fontSize = [tempStr intValue];
int rgIndex=0;//Color
for(NSString *val in firstWords){
if([[val lowercaseString] isEqualToString:@"rg"]){
//Colors will be defined in 3 indexes less than rg index
break;
}
rgIndex++;
}
if (rgIndex>0 && rgIndex>4) {
CGFloat red = [[firstWords objectAtIndex:rgIndex-3] floatValue];
CGFloat green = [[firstWords objectAtIndex:rgIndex-2] floatValue];
CGFloat blue = [[firstWords objectAtIndex:rgIndex-1] floatValue];
self.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:1];
}
else{
self.textColor = [UIColor blackColor];
}
self.font = [UIFont fontWithName:fontType size:fontSize];
}
else{
textColor=[UIColor blackColor];
self.font = [UIFont fontWithName:@"Helvetica" size:12];
}
CGPDFInteger textAlignmentRef;
if (CGPDFDictionaryGetInteger(annotDict, "Q", &textAlignmentRef)) {
switch (textAlignmentRef) {
case 1:
self.textAlignment = UITextAlignmentCenter;
break;
case 2:
self.textAlignment = UITextAlignmentRight;
break;

default:
self.textAlignment = UITextAlignmentLeft;
break;
}
}
else self.textAlignment = UITextAlignmentLeft;

CGPDFStringRef textStringRef;
if(CGPDFDictionaryGetString(annotDict, "Contents", &textStringRef)) {
self.textString = (__bridge NSString *)CGPDFStringCopyTextString(textStringRef);
}

}
CGPDFArrayRef borderArray;
if (CGPDFDictionaryGetArray(annotDict, "Border",&borderArray)){
int cArrayCount = CGPDFArrayGetCount( borderArray );
for( int k = 0; k < cArrayCount; ++k ) {
CGPDFObjectRef borderObj;
if(!CGPDFArrayGetObject(borderArray, k, &borderObj)) {
break;
}
CGPDFReal border;
if(!CGPDFObjectGetValue(borderObj, kCGPDFObjectTypeReal, &border)) {
break;
}

if (k==2) {
self.borderWidth = border;
}
}
}
else{
self.borderWidth = 1;
}

CGPDFDictionaryRef borderStyleDict;
if (CGPDFDictionaryGetDictionary(annotDict, "BS",&borderStyleDict)){
CGPDFReal borderStyleWidth;
if(CGPDFDictionaryGetNumber(borderStyleDict, "W", &borderStyleWidth)){
self.borderWidth = borderStyleWidth;
}
}

return self;
}
@end
Loading