diff options
Diffstat (limited to 'platform/ios/Classes')
-rw-r--r-- | platform/ios/Classes/MuDocumentController.h | 4 | ||||
-rw-r--r-- | platform/ios/Classes/MuDocumentController.m | 68 | ||||
-rw-r--r-- | platform/ios/Classes/MuInkView.h | 21 | ||||
-rw-r--r-- | platform/ios/Classes/MuInkView.m | 84 | ||||
-rw-r--r-- | platform/ios/Classes/MuPageView.h | 5 | ||||
-rw-r--r-- | platform/ios/Classes/MuPageViewNormal.h | 2 | ||||
-rw-r--r-- | platform/ios/Classes/MuPageViewNormal.m | 131 | ||||
-rw-r--r-- | platform/ios/Classes/MuPageViewReflow.m | 5 |
8 files changed, 293 insertions, 27 deletions
diff --git a/platform/ios/Classes/MuDocumentController.h b/platform/ios/Classes/MuDocumentController.h index ab95a88a..32bd36f4 100644 --- a/platform/ios/Classes/MuDocumentController.h +++ b/platform/ios/Classes/MuDocumentController.h @@ -24,7 +24,8 @@ enum BARMODE_ANNOTATION, BARMODE_HIGHLIGHT, BARMODE_UNDERLINE, - BARMODE_STRIKE + BARMODE_STRIKE, + BARMODE_INK }; @interface MuDocumentController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate, UISearchBarDelegate, MuDialogCreator> @@ -41,6 +42,7 @@ enum UIBarButtonItem *nextButton, *prevButton, *cancelButton, *searchButton, *outlineButton, *linkButton; UIBarButtonItem *moreButton; UIBarButtonItem *highlightButton, *underlineButton, *strikeoutButton; + UIBarButtonItem *inkButton; UIBarButtonItem *tickButton; UIBarButtonItem *reflowButton; UIBarButtonItem *sliderWrapper; diff --git a/platform/ios/Classes/MuDocumentController.m b/platform/ios/Classes/MuDocumentController.m index 1cf210fb..bda52900 100644 --- a/platform/ios/Classes/MuDocumentController.m +++ b/platform/ios/Classes/MuDocumentController.m @@ -160,6 +160,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out highlightButton = [self resourceBasedButton:@"ic_highlight" withAction:@selector(onHighlight:)]; underlineButton = [self resourceBasedButton:@"ic_underline" withAction:@selector(onUnderline:)]; strikeoutButton = [self resourceBasedButton:@"ic_strike" withAction:@selector(onStrikeout:)]; + inkButton = [self resourceBasedButton:@"ic_pen" withAction:@selector(onInk:)]; tickButton = [self resourceBasedButton:@"ic_check" withAction:@selector(onTick:)]; searchBar = [[UISearchBar alloc] initWithFrame: CGRectMake(0,0,50,32)]; [searchBar setPlaceholder: @"Search"]; @@ -195,6 +196,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out [highlightButton release]; highlightButton = nil; [underlineButton release]; underlineButton = nil; [strikeoutButton release]; strikeoutButton = nil; + [inkButton release]; inkButton = nil; [tickButton release]; tickButton = nil; [canvas release]; canvas = nil; @@ -328,7 +330,7 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out - (void) showAnnotationMenu { - [[self navigationItem] setRightBarButtonItems:[NSArray arrayWithObjects:strikeoutButton, underlineButton, highlightButton, nil]]; + [[self navigationItem] setRightBarButtonItems:[NSArray arrayWithObjects:inkButton, strikeoutButton, underlineButton, highlightButton, nil]]; [[self navigationItem] setLeftBarButtonItem:cancelButton]; barmode = BARMODE_ANNOTATION; } @@ -356,6 +358,24 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out } } +- (void) inkModeOn +{ + [[self navigationItem] setRightBarButtonItems:[NSArray arrayWithObject:tickButton]]; + for (UIView<MuPageView> *view in [canvas subviews]) + { + if ([view number] == current) + [view inkModeOn]; + } +} + +- (void) inkModeOff +{ + for (UIView<MuPageView> *view in [canvas subviews]) + { + [view inkModeOff]; + } +} + - (void) onHighlight: (id)sender { barmode = BARMODE_HIGHLIGHT; @@ -374,6 +394,12 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out [self textSelectModeOn]; } +- (void) onInk: (id)sender +{ + barmode = BARMODE_INK; + [self inkModeOn]; +} + - (void) onShowSearch: (id)sender { [[self navigationItem] setRightBarButtonItems: @@ -386,26 +412,29 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out - (void) onTick: (id)sender { - int type; - switch (barmode) - { - case BARMODE_HIGHLIGHT: - type = FZ_ANNOT_HIGHLIGHT; - break; - - case BARMODE_UNDERLINE: - type = FZ_ANNOT_UNDERLINE; - break; - - case BARMODE_STRIKE: - type = FZ_ANNOT_STRIKEOUT; - break; - } for (UIView<MuPageView> *view in [canvas subviews]) { if ([view number] == current) - [view saveMarkup:type]; + { + switch (barmode) + { + case BARMODE_HIGHLIGHT: + [view saveSelectionAsMarkup:FZ_ANNOT_HIGHLIGHT]; + break; + + case BARMODE_UNDERLINE: + [view saveSelectionAsMarkup:FZ_ANNOT_UNDERLINE]; + break; + + case BARMODE_STRIKE: + [view saveSelectionAsMarkup:FZ_ANNOT_STRIKEOUT]; + break; + + case BARMODE_INK: + [view saveInk]; + } + } } [self showAnnotationMenu]; @@ -433,6 +462,11 @@ static void flattenOutline(NSMutableArray *titles, NSMutableArray *pages, fz_out [self showAnnotationMenu]; [self textSelectModeOff]; break; + + case BARMODE_INK: + [self showAnnotationMenu]; + [self inkModeOff]; + break; } } diff --git a/platform/ios/Classes/MuInkView.h b/platform/ios/Classes/MuInkView.h new file mode 100644 index 00000000..98b7b28d --- /dev/null +++ b/platform/ios/Classes/MuInkView.h @@ -0,0 +1,21 @@ +// +// MuInkView.h +// MuPDF +// +// Copyright (c) 2013 Artifex Software, Inc. All rights reserved. +// + +#import <UIKit/UIKit.h> + +@interface MuInkView : UIView +{ + CGSize pageSize; + NSMutableArray *curves; + UIColor *color; +} + +@property(readonly) NSArray *curves; + +- (id) initWithPageSize:(CGSize)pageSize; + +@end diff --git a/platform/ios/Classes/MuInkView.m b/platform/ios/Classes/MuInkView.m new file mode 100644 index 00000000..6ac4d1dc --- /dev/null +++ b/platform/ios/Classes/MuInkView.m @@ -0,0 +1,84 @@ +// +// MuInkView.m +// MuPDF +// +// Copyright (c) 2013 Artifex Software, Inc. All rights reserved. +// + +#include "common.h" +#import "MuInkView.h" + +@implementation MuInkView + +- (id) initWithPageSize:(CGSize)_pageSize +{ + self = [super initWithFrame:CGRectMake(0, 0, 100, 100)]; + if (self) { + [self setOpaque:NO]; + pageSize = _pageSize; + color = [[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0] retain]; + curves = [[NSMutableArray array] retain]; + UIPanGestureRecognizer *rec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onDrag:)]; + [self addGestureRecognizer:rec]; + [rec release]; + } + return self; +} + +@synthesize curves; + +-(void)dealloc +{ + [curves release]; + [color release]; + [super dealloc]; +} + +-(void) onDrag:(UIPanGestureRecognizer *)rec +{ + CGSize scale = fitPageToScreen(pageSize, self.bounds.size); + CGPoint p = [rec locationInView:self]; + p.x /= scale.width; + p.y /= scale.height; + + if (rec.state == UIGestureRecognizerStateBegan) + [curves addObject:[NSMutableArray array]]; + + NSMutableArray *curve = [curves lastObject]; + [curve addObject:[NSValue valueWithCGPoint:p]]; + + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)rect +{ + CGSize scale = fitPageToScreen(pageSize, self.bounds.size); + CGContextRef cref = UIGraphicsGetCurrentContext(); + CGContextScaleCTM(cref, scale.width, scale.height); + + [color set]; + CGContextSetLineWidth(cref, 5.0); + + for (NSArray *curve in curves) + { + if (curve.count >= 2) + { + CGPoint pt = [[curve objectAtIndex:0] CGPointValue]; + CGContextBeginPath(cref); + CGContextMoveToPoint(cref, pt.x, pt.y); + CGPoint lpt = pt; + + for (int i = 1; i < curve.count; i++) + { + pt = [[curve objectAtIndex:i] CGPointValue]; + CGContextAddQuadCurveToPoint(cref, lpt.x, lpt.y, (pt.x + lpt.x)/2, (pt.y + lpt.y)/2); + lpt = pt; + } + + CGContextAddLineToPoint(cref, pt.x, pt.y); + CGContextStrokePath(cref); + } + } +} + +@end diff --git a/platform/ios/Classes/MuPageView.h b/platform/ios/Classes/MuPageView.h index 690d8beb..58d33f75 100644 --- a/platform/ios/Classes/MuPageView.h +++ b/platform/ios/Classes/MuPageView.h @@ -20,5 +20,8 @@ -(MuTapResult *) handleTap:(CGPoint)pt; -(void) textSelectModeOn; -(void) textSelectModeOff; --(void) saveMarkup:(int)type; +-(void) inkModeOn; +-(void) inkModeOff; +-(void) saveSelectionAsMarkup:(int)type; +-(void) saveInk; @end diff --git a/platform/ios/Classes/MuPageViewNormal.h b/platform/ios/Classes/MuPageViewNormal.h index 9232e359..cd442baf 100644 --- a/platform/ios/Classes/MuPageViewNormal.h +++ b/platform/ios/Classes/MuPageViewNormal.h @@ -18,6 +18,7 @@ #import "MuDocRef.h" #import "MuDialogCreator.h" #import "MuTextSelectView.h" +#import "MuInkView.h" @interface MuPageViewNormal : UIScrollView <UIScrollViewDelegate,MuPageView> { @@ -37,6 +38,7 @@ MuHitView *hitView; MuHitView *linkView; MuTextSelectView *textSelectView; + MuInkView *inkView; NSArray *widgetRects; CGSize pageSize; CGRect tileFrame; diff --git a/platform/ios/Classes/MuPageViewNormal.m b/platform/ios/Classes/MuPageViewNormal.m index 6262a7b1..64a70079 100644 --- a/platform/ios/Classes/MuPageViewNormal.m +++ b/platform/ios/Classes/MuPageViewNormal.m @@ -9,13 +9,13 @@ #include "mupdf/pdf.h" #import "MuWord.h" #import "MuTextFieldController.h" -#import "MuTextSelectView.h" #import "MuPageViewNormal.h" #define STRIKE_HEIGHT (0.375f) #define UNDERLINE_HEIGHT (0.075f) #define LINE_THICKNESS (0.07f) +#define INK_THICKNESS (4.0f) static void releasePixmap(void *info, const void *data, size_t size) { @@ -254,6 +254,68 @@ static void addMarkupAnnot(fz_document *doc, fz_page *page, int type, NSArray *r } } +static void addInkAnnot(fz_document *doc, fz_page *page, NSArray *curves) +{ + pdf_document *idoc; + fz_point *pts = NULL; + int *counts = NULL; + int total; + float color[3] = {1.0, 0.0, 0.0}; + + idoc = pdf_specifics(doc); + if (!idoc) + return; + + fz_var(pts); + fz_var(counts); + fz_try(ctx) + { + int i, j, k, n; + pdf_annot *annot; + + n = curves.count; + + counts = fz_malloc_array(ctx, n, sizeof(int)); + total = 0; + + for (i = 0; i < n; i++) + { + NSArray *curve = [curves objectAtIndex:i]; + counts[i] = curve.count; + total += curve.count; + } + + pts = fz_malloc_array(ctx, total, sizeof(fz_point)); + + k = 0; + for (i = 0; i < n; i++) + { + NSArray *curve = [curves objectAtIndex:i]; + int count = counts[i]; + + for (j = 0; j < count; j++) + { + CGPoint pt = [[curve objectAtIndex:j] CGPointValue]; + pts[k].x = pt.x; + pts[k].y = pt.y; + k++; + } + } + + annot = pdf_create_annot(idoc, (pdf_page *)page, FZ_ANNOT_INK); + pdf_set_ink_annot_list(idoc, annot, pts, counts, n, color, INK_THICKNESS); + } + fz_always(ctx) + { + fz_free(ctx, pts); + fz_free(ctx, counts); + } + fz_catch(ctx) + { + printf("Annotation creation failed\n"); + } +} + static int setFocussedWidgetText(fz_document *doc, fz_page *page, const char *text) { int accepted; @@ -609,6 +671,7 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa [linkView release]; [hitView release]; [textSelectView release]; + [inkView release]; [tileView release]; [loadingView release]; [imageView release]; @@ -688,6 +751,14 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa }); } +- (void) inkModeOn +{ + inkView = [[MuInkView alloc] initWithPageSize:pageSize]; + if (imageView) + [inkView setFrame:[imageView frame]]; + [self addSubview:inkView]; +} + - (void) textSelectModeOff { [textSelectView removeFromSuperview]; @@ -695,7 +766,14 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa textSelectView = nil; } --(void) saveMarkup:(int)type +- (void) inkModeOff +{ + [inkView removeFromSuperview]; + [inkView release]; + inkView = nil; +} + +-(void) saveSelectionAsMarkup:(int)type { CGRect tframe = tileFrame; float tscale = tileScale; @@ -707,13 +785,38 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa if (rects.count == 0) return; + [rects retain]; + dispatch_async(queue, ^{ addMarkupAnnot(doc, page, type, rects); + [rects release]; [self updatePageAndTileWithTileFrame:tframe tileScale:tscale viewFrame:vframe]; }); [self textSelectModeOff]; } +-(void) saveInk +{ + CGRect tframe = tileFrame; + float tscale = tileScale; + CGRect vframe = tframe; + vframe.origin.x -= imageView.frame.origin.x; + vframe.origin.y -= imageView.frame.origin.y; + + NSArray *curves = inkView.curves; + if (curves.count == 0) + return; + + [curves retain]; + + dispatch_async(queue, ^{ + addInkAnnot(doc, page, curves); + [curves release]; + [self updatePageAndTileWithTileFrame:tframe tileScale:tscale viewFrame:vframe]; + }); + [self inkModeOff]; +} + - (void) resetZoomAnimated: (BOOL)animated { // discard tile and any pending tile jobs @@ -780,6 +883,8 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa [self bringSubviewToFront: hitView]; if (textSelectView) [self bringSubviewToFront:textSelectView]; + if (inkView) + [self bringSubviewToFront:inkView]; } else { [imageView setImage: image]; } @@ -853,14 +958,19 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa if (imageView) { + CGRect frm = [imageView frame]; + if (hitView) - [hitView setFrame: [imageView frame]]; + [hitView setFrame: frm]; if (linkView) - [linkView setFrame:[imageView frame]]; + [linkView setFrame:frm]; if (textSelectView) - [textSelectView setFrame:[imageView frame]]; + [textSelectView setFrame:frm]; + + if (inkView) + [inkView setFrame:frm]; } } @@ -925,6 +1035,8 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa [self bringSubviewToFront:linkView]; if (textSelectView) [self bringSubviewToFront:textSelectView]; + if (inkView) + [self bringSubviewToFront:inkView]; } else { printf("discard tile\n"); } @@ -963,11 +1075,16 @@ static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_displa { if (imageView) { + CGRect frm = [imageView frame]; + if (hitView) - [hitView setFrame: [imageView frame]]; + [hitView setFrame: frm]; if (textSelectView) - [textSelectView setFrame:[imageView frame]]; + [textSelectView setFrame:frm]; + + if (inkView) + [inkView setFrame:frm]; } } diff --git a/platform/ios/Classes/MuPageViewReflow.m b/platform/ios/Classes/MuPageViewReflow.m index f81f055e..4c4bd445 100644 --- a/platform/ios/Classes/MuPageViewReflow.m +++ b/platform/ios/Classes/MuPageViewReflow.m @@ -124,7 +124,10 @@ NSString *textAsHtml(fz_document *doc, int pageNum) -(void) clearSearchResults {} -(void) textSelectModeOn {} -(void) textSelectModeOff {} --(void) saveMarkup:(int)type {} +-(void) inkModeOn {} +-(void) inkModeOff {} +-(void) saveSelectionAsMarkup:(int)type {} +-(void) saveInk {} -(void) resetZoomAnimated: (BOOL)animated { |