You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
(23) |
Apr
(254) |
May
(252) |
Jun
(209) |
Jul
(198) |
Aug
(192) |
Sep
(207) |
Oct
(120) |
Nov
(179) |
Dec
(52) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(48) |
Feb
(69) |
Mar
(129) |
Apr
(250) |
May
(113) |
Jun
(177) |
Jul
(228) |
Aug
(155) |
Sep
(218) |
Oct
(185) |
Nov
(109) |
Dec
(88) |
2009 |
Jan
(83) |
Feb
(39) |
Mar
(70) |
Apr
(47) |
May
(48) |
Jun
(67) |
Jul
(61) |
Aug
(97) |
Sep
(221) |
Oct
(141) |
Nov
(70) |
Dec
(61) |
2010 |
Jan
(45) |
Feb
(76) |
Mar
(178) |
Apr
(106) |
May
(57) |
Jun
(32) |
Jul
(64) |
Aug
(98) |
Sep
(96) |
Oct
(19) |
Nov
(34) |
Dec
(117) |
2011 |
Jan
(55) |
Feb
(48) |
Mar
(64) |
Apr
(21) |
May
(39) |
Jun
(53) |
Jul
(99) |
Aug
(56) |
Sep
(39) |
Oct
(26) |
Nov
(19) |
Dec
(69) |
2012 |
Jan
(17) |
Feb
(40) |
Mar
(17) |
Apr
|
May
(2) |
Jun
(8) |
Jul
(2) |
Aug
(10) |
Sep
(10) |
Oct
(38) |
Nov
(48) |
Dec
(70) |
2013 |
Jan
(43) |
Feb
(47) |
Mar
(39) |
Apr
(37) |
May
(25) |
Jun
(6) |
Jul
(20) |
Aug
(49) |
Sep
(33) |
Oct
(34) |
Nov
(75) |
Dec
(6) |
2014 |
Jan
(32) |
Feb
(10) |
Mar
(17) |
Apr
|
May
|
Jun
(26) |
Jul
(5) |
Aug
|
Sep
(4) |
Oct
(23) |
Nov
(80) |
Dec
(48) |
2015 |
Jan
(80) |
Feb
(50) |
Mar
(58) |
Apr
(20) |
May
(11) |
Jun
(16) |
Jul
(24) |
Aug
(27) |
Sep
(56) |
Oct
(30) |
Nov
(16) |
Dec
(6) |
2016 |
Jan
(31) |
Feb
(14) |
Mar
(23) |
Apr
(17) |
May
(40) |
Jun
(12) |
Jul
(17) |
Aug
(9) |
Sep
(32) |
Oct
(36) |
Nov
(23) |
Dec
(9) |
2017 |
Jan
(37) |
Feb
(23) |
Mar
(65) |
Apr
(22) |
May
(6) |
Jun
(3) |
Jul
|
Aug
|
Sep
(3) |
Oct
(22) |
Nov
(63) |
Dec
(71) |
2018 |
Jan
(83) |
Feb
(21) |
Mar
(35) |
Apr
(44) |
May
(14) |
Jun
(12) |
Jul
(8) |
Aug
(18) |
Sep
(10) |
Oct
(145) |
Nov
(144) |
Dec
(76) |
2019 |
Jan
(18) |
Feb
(28) |
Mar
(5) |
Apr
(208) |
May
(291) |
Jun
(158) |
Jul
(27) |
Aug
(8) |
Sep
(10) |
Oct
(83) |
Nov
(41) |
Dec
(31) |
2020 |
Jan
(16) |
Feb
(46) |
Mar
(100) |
Apr
(78) |
May
(69) |
Jun
(71) |
Jul
(28) |
Aug
(131) |
Sep
(176) |
Oct
(89) |
Nov
(147) |
Dec
(19) |
2021 |
Jan
(19) |
Feb
(25) |
Mar
(91) |
Apr
(98) |
May
(14) |
Jun
(44) |
Jul
(8) |
Aug
(3) |
Sep
(38) |
Oct
(57) |
Nov
(97) |
Dec
(74) |
2022 |
Jan
(89) |
Feb
(47) |
Mar
(15) |
Apr
(50) |
May
(54) |
Jun
(56) |
Jul
(80) |
Aug
(12) |
Sep
(11) |
Oct
(60) |
Nov
(48) |
Dec
(4) |
2023 |
Jan
(75) |
Feb
(49) |
Mar
(84) |
Apr
(24) |
May
(13) |
Jun
(74) |
Jul
(32) |
Aug
(66) |
Sep
(50) |
Oct
(38) |
Nov
(105) |
Dec
(181) |
2024 |
Jan
(21) |
Feb
(49) |
Mar
(77) |
Apr
(84) |
May
(20) |
Jun
(71) |
Jul
(53) |
Aug
(33) |
Sep
(54) |
Oct
(124) |
Nov
(151) |
Dec
(73) |
2025 |
Jan
(61) |
Feb
(17) |
Mar
(136) |
Apr
(72) |
May
(200) |
Jun
(238) |
Jul
(91) |
Aug
(8) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <ho...@us...> - 2007-09-10 18:01:15
|
Revision: 2881 http://skim-app.svn.sourceforge.net/skim-app/?rev=2881&view=rev Author: hofman Date: 2007-09-10 11:01:06 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Hack to use the background color of a free text annotation for editing. Modified Paths: -------------- trunk/NSCell_SKExtensions.h trunk/NSCell_SKExtensions.m trunk/SKPDFView.m Modified: trunk/NSCell_SKExtensions.h =================================================================== --- trunk/NSCell_SKExtensions.h 2007-09-10 17:10:16 UTC (rev 2880) +++ trunk/NSCell_SKExtensions.h 2007-09-10 18:01:06 UTC (rev 2881) @@ -44,3 +44,18 @@ @interface NSCell (SKExtensions) - (NSColor *)replacementHighlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView; @end + + +@interface NSTextFieldCell (SKExtensions) +- (NSText *)replacementSetUpFieldEditorAttributes:(NSText *)textObj; +@end + + +@interface NSTextField (SKExtensions) +- (void)replacementSetDelegate:(id)delegate; +@end + + +@interface NSObject (SKExtendedNSTextFieldDelegate) +- (NSColor *)control:(NSControl *)control backgroundColorForFieldEditor:(NSText *)textObj; +@end Modified: trunk/NSCell_SKExtensions.m =================================================================== --- trunk/NSCell_SKExtensions.m 2007-09-10 17:10:16 UTC (rev 2880) +++ trunk/NSCell_SKExtensions.m 2007-09-10 18:01:06 UTC (rev 2881) @@ -40,6 +40,7 @@ #import "NSCell_SKExtensions.h" #import "OBUtilities.h" +#import "SKPDFView.h" @implementation NSCell (SKExtensions) @@ -58,3 +59,52 @@ } @end + + +@implementation NSTextFieldCell (SKExtensions) + +static IMP originalSetUpFieldEditorAttributes = NULL; + ++ (void)load { + originalSetUpFieldEditorAttributes = OBReplaceMethodImplementationWithSelector(self, @selector(setUpFieldEditorAttributes:), @selector(replacementSetUpFieldEditorAttributes:)); +} + +- (NSText *)replacementSetUpFieldEditorAttributes:(NSText *)textObj { + textObj = originalSetUpFieldEditorAttributes(self, _cmd, textObj); + if ([textObj respondsToSelector:@selector(setBackgroundColor:)] && [[self controlView] respondsToSelector:@selector(setBackgroundColor:)] && [[self controlView] respondsToSelector:@selector(delegate)]) { + id delegate = [(NSTextField *)[self controlView] delegate]; + if ([delegate respondsToSelector:@selector(control:backgroundColorForFieldEditor:)]) { + NSColor *color = [delegate control:(NSTextField *)[self controlView] backgroundColorForFieldEditor:textObj]; + if (color) { + [(NSTextField *)[self controlView] setBackgroundColor:color]; + [(NSTextView *)textObj setBackgroundColor:color]; + } + } + } + return textObj; +} + +@end + + +@implementation NSTextField (SKExtensions) + +static IMP originalSetDelegate = NULL; + ++ (void)load { + originalSetDelegate = OBReplaceMethodImplementationWithSelector(self, @selector(setDelegate:), @selector(replacementSetDelegate:)); +} + +- (void)replacementSetDelegate:(id)delegate { + originalSetDelegate(self, _cmd, delegate); + NSText *currentEditor = [self currentEditor]; + if (currentEditor && [currentEditor respondsToSelector:@selector(setBackgroundColor:)] && [delegate respondsToSelector:@selector(control:backgroundColorForFieldEditor:)]) { + NSColor *color = [delegate control:self backgroundColorForFieldEditor:currentEditor]; + if (color) { + [(NSTextField *)self setBackgroundColor:color]; + [(NSTextView *)currentEditor setBackgroundColor:color]; + } + } +} + +@end Modified: trunk/SKPDFView.m =================================================================== --- trunk/SKPDFView.m 2007-09-10 17:10:16 UTC (rev 2880) +++ trunk/SKPDFView.m 2007-09-10 18:01:06 UTC (rev 2881) @@ -1957,6 +1957,12 @@ return rv; } +- (NSColor *)control:(NSControl *)control backgroundColorForFieldEditor:(NSText *)textObj { + if (editAnnotation) + return [activeAnnotation color]; + return nil; +} + - (void)selectNextActiveAnnotation:(id)sender { PDFDocument *pdfDoc = [self document]; int numberOfPages = [pdfDoc pageCount]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 17:10:57
|
Revision: 2880 http://skim-app.svn.sourceforge.net/skim-app/?rev=2880&view=rev Author: hofman Date: 2007-09-10 10:10:16 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Rewrite FDF parser. Use CGPDFDocument to parse the document after fooling it that the data is PDF. Modified Paths: -------------- trunk/SKDocument.m trunk/SKFDFParser.h trunk/SKFDFParser.m Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-10 17:09:31 UTC (rev 2879) +++ trunk/SKDocument.m 2007-09-10 17:10:16 UTC (rev 2880) @@ -671,9 +671,9 @@ if ([extension caseInsensitiveCompare:@"skim"] == NSOrderedSame) { array = [NSKeyedUnarchiver unarchiveObjectWithFile:[notesURL path]]; } else { - NSString *fdfString = [NSString stringWithContentsOfURL:notesURL encoding:NSISOLatin1StringEncoding error:NULL]; - if (fdfString) - array = [SKFDFParser noteDictionariesFromFDFString:fdfString]; + NSData *fdfData = [NSData dataWithContentsOfURL:notesURL]; + if (fdfData) + array = [SKFDFParser noteDictionariesFromFDFData:fdfData]; } if (array) { Modified: trunk/SKFDFParser.h =================================================================== --- trunk/SKFDFParser.h 2007-09-10 17:09:31 UTC (rev 2879) +++ trunk/SKFDFParser.h 2007-09-10 17:10:16 UTC (rev 2880) @@ -37,11 +37,9 @@ */ #import <Cocoa/Cocoa.h> +#import <ApplicationServices/ApplicationServices.h> -@interface SKFDFParser : NSObject { - NSDictionary *fdfDictionary; - NSString *fdfString; -} -+ (NSArray *)noteDictionariesFromFDFString:(NSString *)string; +@interface SKFDFParser : NSObject ++ (NSArray *)noteDictionariesFromFDFData:(NSData *)data; @end Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-10 17:09:31 UTC (rev 2879) +++ trunk/SKFDFParser.m 2007-09-10 17:10:16 UTC (rev 2880) @@ -44,767 +44,285 @@ @interface SKFDFParser (SKPrivate) -- (id)initWithString:(NSString *)aString; -- (BOOL)parseFDFString; -- (NSArray *)noteDictionaries; -- (NSDictionary *)noteDictionary:(NSDictionary *)dict; -- (id)value:(id)value ofClass:(Class)aClass; -- (NSString *)stringValue:(id)value; -- (NSNumber *)numberValue:(id)value; -- (NSArray *)arrayValue:(id)value; -- (NSDictionary *)dictionaryValue:(id)value; ++ (NSDictionary *)noteDictionaryFromPDFDictionary:(CGPDFDictionaryRef)annot; @end -@interface NSScanner (SKFDFParserExtensions) -- (BOOL)scanFDFObject:(id *)object; -- (BOOL)scanFDFArray:(NSArray **)array; -- (BOOL)scanFDFDictionary:(NSDictionary **)dictionary; -- (BOOL)scanFDFString:(NSString **)string; -- (BOOL)scanFDFHexString:(NSString **)string; -- (BOOL)scanFDFName:(NSString **)string; -- (BOOL)scanFDFNumber:(NSNumber **)number; -- (BOOL)scanFDFBoolean:(id *)boolNumber; -- (BOOL)scanFDFIndirectObject:(id *)object; -- (BOOL)scanFDFComment:(NSString **)comment; -@end +@implementation SKFDFParser -#pragma mark - +static const void *getCFDataBytePointer(void *info) { return CFDataGetBytePtr((CFDataRef)info); } +static void releaseCFData(void *info) { CFRelease((CFDataRef)info); } -@interface SKIndirectObject : NSObject <NSCopying> { - unsigned int objectNumber; - unsigned int generationNumber; -} -+ (id)indirectObjectWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber; -- (id)initWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber; -- (unsigned int)objectNumber; -- (unsigned int)generationNumber; -@end ++ (NSArray *)noteDictionariesFromFDFData:(NSData *)data { + const char *pdfHeader = "%PDF"; + unsigned pdfHeaderLength = strlen(pdfHeader); + + if ([data length] < pdfHeaderLength) + return NO; + + NSMutableData *pdfData = [data mutableCopy]; + + [pdfData replaceBytesInRange:NSMakeRange(0, pdfHeaderLength) withBytes:pdfHeader length:pdfHeaderLength]; -#pragma mark - - -@implementation SKFDFParser - -+ (NSArray *)noteDictionariesFromFDFString:(NSString *)string { - NSArray *notes = nil; - SKFDFParser *parser = [[self alloc] initWithString:string]; + static const CGDataProviderDirectAccessCallbacks callbacks = {&getCFDataBytePointer, NULL, NULL, &releaseCFData }; + void *info = (void *)pdfData; + CGDataProviderRef provider = CGDataProviderCreateDirectAccess(info, [pdfData length], &callbacks); + CGPDFDocumentRef document = CGPDFDocumentCreateWithProvider(provider); + NSMutableArray *notes = nil; - if ([parser parseFDFString]) - notes = [parser noteDictionaries]; - [parser release]; + if (document) { + CGPDFDictionaryRef catalog = CGPDFDocumentGetCatalog(document); + CGPDFDictionaryRef fdfDict; + CGPDFArrayRef annots; + + if (catalog && + CGPDFDictionaryGetDictionary(catalog, "FDF", &fdfDict) && + CGPDFDictionaryGetArray(fdfDict, "Annots", &annots)) { + + size_t i, count = CGPDFArrayGetCount(annots); + notes = [NSMutableArray arrayWithCapacity:count]; + for (i = 0; i < count; i++) { + CGPDFDictionaryRef annot; + NSDictionary *note; + if (CGPDFArrayGetDictionary(annots, i, &annot) && + (note = [self noteDictionaryFromPDFDictionary:annot])) { + [notes addObject:note]; + } + } + } + + CGPDFDocumentRelease(document); + } + CGDataProviderRelease(provider); + [pdfData release]; + return notes; } -- (id)initWithString:(NSString *)string { - if (self = [super init]) { - fdfString = [string retain]; - fdfDictionary = nil; - } - return self; -} - -- (void)dealloc { - [fdfString release]; - [fdfDictionary release]; - [super dealloc]; -} - -- (BOOL)parseFDFString { - NSMutableDictionary *fdfDict = [[NSMutableDictionary alloc] init]; ++ (NSDictionary *)noteDictionaryFromPDFDictionary:(CGPDFDictionaryRef)annot { + if (annot == NULL) + return nil; - NSDictionary *dictionary; - int objNumber, genNumber; - id object; + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + CGPDFDictionaryRef dict; + CGPDFArrayRef array; + CGPDFStringRef string; + const char *name; + CGPDFReal real; + CGPDFInteger integer; BOOL success = YES; - NSScanner *scanner = [[NSScanner alloc] initWithString:fdfString]; + if (CGPDFDictionaryGetName(annot, "Type", &name) == NO || strcmp(name, "Annot") != 0) { + success = NO; + } - // Scan the FDF header - [scanner scanString:@"%FDF-1.2" intoString:NULL]; - while ([scanner scanFDFComment:NULL]); + if (CGPDFDictionaryGetName(annot, "Subtype", &name)) { + [dictionary setObject:[NSString stringWithFormat:@"%s", name] forKey:@"type"]; + } else { + success = NO; + } - // Scan the FDF body - while (success && [scanner scanInt:&objNumber]) { - while ([scanner scanFDFComment:NULL]); - if (success = [scanner scanInt:&genNumber]) { - while ([scanner scanFDFComment:NULL]); - if (success = [scanner scanString:@"obj" intoString:NULL] && [scanner scanFDFObject:&object]) { - while ([scanner scanFDFComment:NULL]); - if ([object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { - object = @""; - if ([scanner scanUpToString:@"endstream" intoString:&object] && [scanner scanString:@"endstream" intoString:NULL]) { - int end = [object length]; - unichar ch = end ? [object characterAtIndex:end - 1] : 0; - if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { - end--; - if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') - end--; - object = [object substringToIndex:end]; - } - } - } - if (success) { - success = [scanner scanString:@"endobj" intoString:NULL]; - while ([scanner scanFDFComment:NULL]); - [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; - } - } + if (CGPDFDictionaryGetArray(annot, "Rect", &array)) { + CGPDFReal l, b, r, t; + if (CGPDFArrayGetCount(array) == 4 && CGPDFArrayGetNumber(array, 0, &l) && CGPDFArrayGetNumber(array, 1, &b) && CGPDFArrayGetNumber(array, 2, &r) && CGPDFArrayGetNumber(array, 3, &t)) { + [dictionary setObject:NSStringFromRect(NSMakeRect(l, b, r - l, t - b)) forKey:@"bounds"]; } + } else { + success = NO; } - // Scan the FDF cross reference table, if present - if (success) { - while ([scanner scanString:@"xref" intoString:NULL]) { - while ([scanner scanFDFComment:NULL]); - while ([scanner scanInt:NULL] && [scanner scanInt:NULL]) { - [scanner scanString:@"n" intoString:NULL] || [scanner scanString:@"f" intoString:NULL]; - while ([scanner scanFDFComment:NULL]); - } - } + if (CGPDFDictionaryGetInteger(annot, "Page", &integer)) { + [dictionary setObject:[NSNumber numberWithInt:integer] forKey:@"pageIndex"]; + } else { + success = NO; } - // Scan the FDF trailer - if (success = success && [scanner scanString:@"trailer" intoString:NULL]) { - while ([scanner scanFDFComment:NULL]); - if (success = [scanner scanFDFDictionary:&dictionary]) { - while ([scanner scanFDFComment:NULL]); - [fdfDict setObject:dictionary forKey:@"trailer"]; - [scanner scanString:@"%%EOF" intoString:NULL]; + if (CGPDFDictionaryGetString(annot, "Contents", &string)) { + NSString *contents = (NSString *)CGPDFStringCopyTextString(string); + if (contents) + [dictionary setObject:contents forKey:@"contents"]; + [contents release]; + } + + if (CGPDFDictionaryGetArray(annot, "C", &array)) { + CGPDFReal r, g, b; + if (CGPDFArrayGetCount(array) == 3 && CGPDFArrayGetNumber(array, 0, &r) && CGPDFArrayGetNumber(array, 1, &g) && CGPDFArrayGetNumber(array, 2, &b)) { + [dictionary setObject:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0] forKey:@"color"]; } } - [scanner release]; - - if (success) - fdfDictionary = fdfDict; - else - [fdfDict release]; - - return success; -} - -- (NSArray *)noteDictionaries { - NSMutableArray *array = nil; - NSDictionary *trailer; - NSDictionary *root; - NSDictionary *fdfDict; - NSArray *annots; - - if ((trailer = [self dictionaryValue:[fdfDictionary objectForKey:@"trailer"]]) && - (root = [self dictionaryValue:[trailer objectForKey:@"Root"]]) && - (fdfDict = [self dictionaryValue:[root objectForKey:@"FDF"]]) && - (annots = [self arrayValue:[fdfDict objectForKey:@"Annots"]])) { - - NSEnumerator *annotEnum = [annots objectEnumerator]; - NSDictionary *dict; - - array = [NSMutableArray arrayWithCapacity:[annots count]]; - while (dict = [annotEnum nextObject]) { - if (dict = [self noteDictionary:[self dictionaryValue:dict]]) - [array addObject:dict]; + if (CGPDFDictionaryGetArray(annot, "IC", &array)) { + CGPDFReal r, g, b; + if (CGPDFArrayGetCount(array) == 3 && CGPDFArrayGetNumber(array, 0, &r) && CGPDFArrayGetNumber(array, 1, &g) && CGPDFArrayGetNumber(array, 2, &b)) { + [dictionary setObject:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0] forKey:@"interiorColor"]; } } - return array; -} - -- (id)value:(id)value ofClass:(Class)aClass { - while ([value isKindOfClass:[SKIndirectObject class]]) - value = [fdfDictionary objectForKey:value]; - return (aClass == Nil || [value isKindOfClass:aClass]) ? value : nil; -} - -- (NSString *)stringValue:(id)value { - return [self value:value ofClass:[NSString class]]; -} - -- (NSNumber *)numberValue:(id)value { - return [self value:value ofClass:[NSNumber class]]; -} - -- (NSArray *)arrayValue:(id)value { - return [self value:value ofClass:[NSArray class]]; -} - -- (NSDictionary *)dictionaryValue:(id)value { - return [self value:value ofClass:[NSDictionary class]]; -} - -- (NSDictionary *)noteDictionary:(NSDictionary *)dict { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - NSSet *validTypes = [NSSet setWithObjects:@"FreeText", @"Note", @"Circle", @"Square", @"Highlight", @"Underline", @"StrikeOut", @"Line", nil]; - NSEnumerator *keyEnum = [dict keyEnumerator]; - NSString *key; - BOOL success = dict != nil; - - while (success && (key = [keyEnum nextObject])) { - id value = [dict valueForKey:key]; - - if ([key isEqualToString:@"Type"]) { - if (value = [self stringValue:value]) { - if ([value isEqualToString:@"Annot"] == NO) { - success = NO; + if (CGPDFDictionaryGetDictionary(annot, "BS", &dict)) { + if (CGPDFDictionaryGetNumber(dict, "W", &real)) { + if (real > 0.0) { + [dictionary setObject:[NSNumber numberWithFloat:real] forKey:@"lineWidth"]; + if (CGPDFDictionaryGetName(dict, "S", &name)) { + int style = kPDFBorderStyleSolid; + if (strcmp(name, "S") == 0) + style = kPDFBorderStyleSolid; + else if (strcmp(name, "D") == 0) + style = kPDFBorderStyleDashed; + else if (strcmp(name, "B") == 0) + style = kPDFBorderStyleBeveled; + else if (strcmp(name, "I") == 0) + style = kPDFBorderStyleInset; + else if (strcmp(name, "U") == 0) + style = kPDFBorderStyleUnderline; + [dictionary setObject:[NSNumber numberWithInt:style] forKey:@"borderStyle"]; } - } else { - success = NO; - } - } else if ([key isEqualToString:@"Subtype"]) { - if (value = [self stringValue:value]) { - if ([value isEqualToString:@"Text"]) - value = @"Note"; - if ([validTypes containsObject:value]) { - [dictionary setObject:value forKey:@"type"]; - } else { - success = NO; + if (CGPDFDictionaryGetArray(annot, "D", &array)) { + size_t i, count = CGPDFArrayGetCount(array); + NSMutableArray *dp = [NSMutableArray array]; + for (i = 0; i < count; i++) { + if (CGPDFArrayGetNumber(array, i, &real)) + [dp addObject:[NSNumber numberWithFloat:real]]; + } + [dictionary setObject:dp forKey:@"dashPattern"]; } - } else { - success = NO; } - } else if ([key isEqualToString:@"Contents"]) { - if (value = [self stringValue:value]) { - [dictionary setObject:value forKey:@"contents"]; - } else { - success = NO; - } - } else if ([key isEqualToString:@"Rect"]) { - if ((value = [self arrayValue:value]) && [value count] == 4) { - NSNumber *l = [self numberValue:[value objectAtIndex:0]]; - NSNumber *b = [self numberValue:[value objectAtIndex:1]]; - NSNumber *r = [self numberValue:[value objectAtIndex:2]]; - NSNumber *t = [self numberValue:[value objectAtIndex:3]]; - if (l && b && r && t) { - NSRect rect; - rect.origin.x = [l floatValue]; - rect.origin.y = [b floatValue]; - rect.size.width = [r floatValue] - NSMinX(rect); - rect.size.height = [t floatValue] - NSMinY(rect); - [dictionary setObject:NSStringFromRect(rect) forKey:@"bounds"]; - } else { - success = NO; + } + } else if (CGPDFDictionaryGetArray(annot, "Border", &array)) { + size_t i, count = CGPDFArrayGetCount(array); + if (count > 2 && CGPDFArrayGetNumber(array, 2, &real) && real > 0.0) { + [dictionary setObject:[NSNumber numberWithFloat:real] forKey:@"lineWidth"]; + CGPDFArrayRef dp; + if (count > 3 && CGPDFArrayGetArray(array, 3, &dp)) { + count = CGPDFArrayGetCount(dp); + NSMutableArray *dashPattern = [NSMutableArray arrayWithCapacity:count]; + for (i = 0; i < count; i++) { + if (CGPDFArrayGetNumber(dp, i, &real)) + [dashPattern addObject:[NSNumber numberWithFloat:real]]; } + [dictionary setObject:dashPattern forKey:@"dashPattern"]; + [dictionary setObject:[NSNumber numberWithInt:kPDFBorderStyleDashed] forKey:@"borderStyle"]; } else { - success = NO; + [dictionary setObject:[NSNumber numberWithInt:kPDFBorderStyleSolid] forKey:@"borderStyle"]; } - } else if ([key isEqualToString:@"Page"]) { - if (value = [self numberValue:value]) { - [dictionary setObject:value forKey:@"pageIndex"]; - } else { - success = NO; - } - } else if ([key isEqualToString:@"C"]) { - if ((value = [self arrayValue:value]) && [value count] == 3) { - NSNumber *r = [self numberValue:[value objectAtIndex:0]]; - NSNumber *g = [self numberValue:[value objectAtIndex:1]]; - NSNumber *b = [self numberValue:[value objectAtIndex:2]]; - if (r && g && b) { - [dictionary setObject:[NSColor colorWithCalibratedRed:[r floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0] forKey:@"color"]; - } else { - success = NO; - } - } else { - success = NO; - } - } else if ([key isEqualToString:@"BS"]) { - if (value = [self dictionaryValue:value]) { - NSNumber *width = [self numberValue:[value objectForKey:@"W"]]; - NSString *s = [self stringValue:[value objectForKey:@"S"]]; - NSArray *dashPattern = [self arrayValue:[value objectForKey:@"D"]]; - int style = kPDFBorderStyleSolid; - if ([s isEqualToString:@"S"]) - style = kPDFBorderStyleSolid; - else if ([s isEqualToString:@"D"]) - style = kPDFBorderStyleDashed; - else if ([s isEqualToString:@"B"]) - style = kPDFBorderStyleBeveled; - else if ([s isEqualToString:@"I"]) - style = kPDFBorderStyleInset; - else if ([s isEqualToString:@"U"]) - style = kPDFBorderStyleUnderline; - if (width && [width floatValue] > 0.0) { - [dictionary setObject:width forKey:@"lineWidth"]; - [dictionary setObject:[NSNumber numberWithInt:style] forKey:@"borderStyle"]; - if (dashPattern) - [dictionary setObject:dashPattern forKey:@"dashPattern"]; - } - } else { - success = NO; - } - } else if ([key isEqualToString:@"Border"]) { - if ([value isKindOfClass:[NSArray class]] == NO) { - success = NO; - break; - } - NSNumber *width = [value count] > 2 ? [self numberValue:[value objectAtIndex:2]] : nil; - NSArray *dashPattern = [value count] > 3 ? [self arrayValue:[value objectAtIndex:2]] : nil; - if (width && [width floatValue] > 0.0) { - [dictionary setObject:width forKey:@"lineWidth"]; - [dictionary setObject:[NSNumber numberWithInt:dashPattern ? kPDFBorderStyleDashed : kPDFBorderStyleSolid] forKey:@"borderStyle"]; - if (dashPattern) - [dictionary setObject:dashPattern forKey:@"dashPattern"]; - } - } else if ([key isEqualToString:@"Name"]) { - if (value = [self stringValue:value]) { - int icon = kPDFTextAnnotationIconNote; - if ([value isEqualToString:@"Comment"]) - icon = kPDFTextAnnotationIconComment; - else if ([value isEqualToString:@"Key"]) - icon = kPDFTextAnnotationIconKey; - else if ([value isEqualToString:@"Note"]) - icon = kPDFTextAnnotationIconNote; - else if ([value isEqualToString:@"NewParagraph"]) - icon = kPDFTextAnnotationIconNewParagraph; - else if ([value isEqualToString:@"Paragraph"]) - icon = kPDFTextAnnotationIconParagraph; - else if ([value isEqualToString:@"Insert"]) - icon = kPDFTextAnnotationIconInsert; - [dictionary setObject:[NSNumber numberWithInt:icon] forKey:@"iconType"]; - } else { - success = NO; - } - } else if ([key isEqualToString:@"IC"]) { - if ((value = [self arrayValue:value]) && [value count] == 3) { - NSNumber *r = [self numberValue:[value objectAtIndex:0]]; - NSNumber *g = [self numberValue:[value objectAtIndex:1]]; - NSNumber *b = [self numberValue:[value objectAtIndex:2]]; - if (r && g && b) { - [dictionary setObject:[NSColor colorWithCalibratedRed:[r floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0] forKey:@"interiorColor"]; - } else { - success = NO; - } - } else { - success = NO; - } - } else if ([key isEqualToString:@"LE"]) { - if ((value = [self arrayValue:value]) && [value count] == 2) { - NSString *start = [self stringValue:[value objectAtIndex:0]]; - NSString *end = [self stringValue:[value objectAtIndex:1]]; - int startStyle = kPDFLineStyleNone; - int endStyle = kPDFLineStyleNone; - if ([start isEqualToString:@"None"]) + } + } + + if (CGPDFDictionaryGetName(annot, "Name", &name)) { + int icon = kPDFTextAnnotationIconNote; + if (strcmp(name, "Comment") == 0) + icon = kPDFTextAnnotationIconComment; + else if (strcmp(name, "Key") == 0) + icon = kPDFTextAnnotationIconKey; + else if (strcmp(name, "Note") == 0) + icon = kPDFTextAnnotationIconNote; + else if (strcmp(name, "NewParagraph") == 0) + icon = kPDFTextAnnotationIconNewParagraph; + else if (strcmp(name, "Paragraph") == 0) + icon = kPDFTextAnnotationIconParagraph; + else if (strcmp(name, "Insert") == 0) + icon = kPDFTextAnnotationIconInsert; + [dictionary setObject:[NSNumber numberWithInt:icon] forKey:@"iconType"]; + } + + if (CGPDFDictionaryGetArray(annot, "LE", &array)) { + int startStyle = kPDFLineStyleNone; + int endStyle = kPDFLineStyleNone; + if (CGPDFArrayGetCount(array) == 2) { + if (CGPDFArrayGetName(array, 0, &name)) { + if (strcmp(name, "None") == 0) startStyle = kPDFLineStyleNone; - else if ([start isEqualToString:@"Square"]) + else if (strcmp(name, "Square") == 0) startStyle = kPDFLineStyleSquare; - else if ([start isEqualToString:@"Circle"]) + else if (strcmp(name, "Circle") == 0) startStyle = kPDFLineStyleCircle; - else if ([start isEqualToString:@"Diamond"]) + else if (strcmp(name, "Diamond") == 0) startStyle = kPDFLineStyleDiamond; - else if ([start isEqualToString:@"OpenArrow"]) + else if (strcmp(name, "OpenArrow") == 0) startStyle = kPDFLineStyleOpenArrow; - else if ([start isEqualToString:@"ClosedArrow"]) + else if (strcmp(name, "ClosedArrow") == 0) startStyle = kPDFLineStyleClosedArrow; - if ([end isEqualToString:@"None"]) + } + if (CGPDFArrayGetName(array, 1, &name)) { + if (strcmp(name, "None") == 0) startStyle = kPDFLineStyleNone; - else if ([end isEqualToString:@"Square"]) + else if (strcmp(name, "Square") == 0) endStyle = kPDFLineStyleSquare; - else if ([end isEqualToString:@"Circle"]) + else if (strcmp(name, "Circle") == 0) endStyle = kPDFLineStyleCircle; - else if ([end isEqualToString:@"Diamond"]) + else if (strcmp(name, "Diamond") == 0) endStyle = kPDFLineStyleDiamond; - else if ([end isEqualToString:@"OpenArrow"]) + else if (strcmp(name, "OpenArrow") == 0) endStyle = kPDFLineStyleOpenArrow; - else if ([end isEqualToString:@"ClosedArrow"]) + else if (strcmp(name, "ClosedArrow") == 0) endStyle = kPDFLineStyleClosedArrow; - [dictionary setObject:[NSNumber numberWithInt:startStyle] forKey:@"startLineStyle"]; - [dictionary setObject:[NSNumber numberWithInt:endStyle] forKey:@"endLineStyle"]; - } else { - success = NO; } - } else if ([key isEqualToString:@"QuadPoints"]) { - if ((value = [self arrayValue:value]) && [value count] % 8 == 0) { - NSMutableArray *quadPoints = [NSMutableArray array]; - int i, count = [value count]; - for (i = 0; i < count; i++) { - NSPoint point; - point.x = [[value objectAtIndex:i] floatValue]; - point.y = [[value objectAtIndex:++i] floatValue]; + } + [dictionary setObject:[NSNumber numberWithInt:endStyle] forKey:@"endLineStyle"]; + [dictionary setObject:[NSNumber numberWithInt:startStyle] forKey:@"startLineStyle"]; + } + + if (CGPDFDictionaryGetArray(annot, "QuadPoints", &array)) { + size_t i, count = CGPDFArrayGetCount(array); + if (i % 8 == 0) { + NSMutableArray *quadPoints = [NSMutableArray arrayWithCapacity:count / 2]; + for (i = 0; i < count; i++) { + NSPoint point; + if (CGPDFArrayGetNumber(array, i, &point.x) && CGPDFArrayGetNumber(array, i, &point.y)) [quadPoints addObject:NSStringFromPoint(point)]; - } - [dictionary setObject:quadPoints forKey:@"quadrilateralPoints"]; - } else { - success = NO; } - } else if ([key isEqualToString:@"DA"]) { - if (value = [self stringValue:value]) { - NSScanner *scanner = [NSScanner scannerWithString:value]; - NSString *fontName; - float fontSize; - if ([scanner scanUpToString:@"Tf" intoString:NULL] && [scanner isAtEnd] == NO) { - unsigned location = [scanner scanLocation]; - NSRange r = [value rangeOfString:@"/" options:NSBackwardsSearch range:NSMakeRange(0, location)]; - if (r.location != NSNotFound) { - [scanner setScanLocation:NSMaxRange(r)]; - if ([scanner scanCharactersFromSet:[NSCharacterSet nonWhitespaceAndNewlineCharacterSet] intoString:&fontName] && - [scanner scanFloat:&fontSize] && - [scanner scanString:@"Tf" intoString:NULL] && - [scanner scanLocation] == location + 2) { - NSFont *font = [NSFont fontWithName:fontName size:fontSize]; - if (font == nil) { - fontName = [[NSUserDefaults standardUserDefaults] stringForKey:SKTextNoteFontNameKey]; - font = [NSFont fontWithName:fontName size:fontSize]; - } - if (font) - [dictionary setObject:font forKey:@"font"]; - } - } - } - } + [dictionary setObject:quadPoints forKey:@"quadrilateralPoints"]; } } + if (CGPDFDictionaryGetString(annot, "DA", &string)) { + NSString *da = (NSString *)CGPDFStringCopyTextString(string); + if (da) { + NSScanner *scanner = [NSScanner scannerWithString:da]; + NSString *fontName; + float fontSize; + if ([scanner scanUpToString:@"Tf" intoString:NULL] && [scanner isAtEnd] == NO) { + unsigned location = [scanner scanLocation]; + NSRange r = [da rangeOfString:@"/" options:NSBackwardsSearch range:NSMakeRange(0, location)]; + if (r.location != NSNotFound) { + [scanner setScanLocation:NSMaxRange(r)]; + if ([scanner scanCharactersFromSet:[NSCharacterSet nonWhitespaceAndNewlineCharacterSet] intoString:&fontName] && + [scanner scanFloat:&fontSize] && + [scanner scanString:@"Tf" intoString:NULL] && + [scanner scanLocation] == location + 2) { + NSFont *font = [NSFont fontWithName:fontName size:fontSize]; + if (font == nil) { + fontName = [[NSUserDefaults standardUserDefaults] stringForKey:SKTextNoteFontNameKey]; + font = [NSFont fontWithName:fontName size:fontSize]; + } + if (font) + [dictionary setObject:font forKey:@"font"]; + } + } + } + [da release]; + } + } + + NSSet *validTypes = [NSSet setWithObjects:@"FreeText", @"Note", @"Circle", @"Square", @"Highlight", @"Underline", @"StrikeOut", @"Line", nil]; NSString *type = [dictionary objectForKey:@"type"]; NSString *contents; - if ([type isEqualToString:@"Note"]) { + if ([type isEqualToString:@"Text"]) { + [dictionary setObject:@"Note" forKey:@"type"]; if (contents = [dictionary objectForKey:@"contents"]) { unsigned contentsEnd, end; [contents getLineStart:NULL end:&end contentsEnd:&contentsEnd forRange:NSMakeRange(0, 0)]; - if (end < [contents length]) { + if (contentsEnd < end) { [dictionary setObject:[contents substringToIndex:contentsEnd] forKey:@"contents"]; - [dictionary setObject:[[[NSAttributedString alloc] initWithString:[contents substringFromIndex:end]] autorelease] forKey:@"text"]; + if (end < [contents length]) + [dictionary setObject:[[[NSAttributedString alloc] initWithString:[contents substringFromIndex:end]] autorelease] forKey:@"text"]; } } + } else if ([validTypes containsObject:type] == NO) { + success = NO; } return success ? dictionary : nil; } @end - -#pragma mark - - -@implementation NSScanner (SKFDFParserExtensions) - -- (BOOL)scanFDFObject:(id *)object { - id tmpObject = nil; - BOOL success; - - while ([self scanFDFComment:NULL]); - - success = [self scanFDFName:&tmpObject] || - [self scanFDFArray:&tmpObject] || - [self scanFDFDictionary:&tmpObject] || - [self scanFDFString:&tmpObject] || - [self scanFDFHexString:&tmpObject] || - [self scanFDFIndirectObject:&tmpObject] || - [self scanFDFNumber:&tmpObject] || - [self scanFDFBoolean:&tmpObject] || - [self scanString:@"null" intoString:NULL]; - - if (success && object) - *object = tmpObject; - - return success; -} - -- (BOOL)scanFDFArray:(NSArray **)array { - NSMutableArray *tmpArray = [NSMutableArray array]; - id object; - BOOL success = [self scanString:@"[" intoString:NULL]; - - while (success) { - while ([self scanFDFComment:NULL]); - if ([self scanString:@"]" intoString:NULL]) { - break; - } else if (success = [self scanFDFObject:&object]) { - if (object) - [tmpArray addObject:object]; - } - } - - if (success && array) - *array = tmpArray; - - return success; -} - -- (BOOL)scanFDFDictionary:(NSDictionary **)dictionary { - NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary]; - NSString *key; - id object; - BOOL success = [self scanString:@"<<" intoString:NULL]; - - while (success) { - while ([self scanFDFComment:NULL]); - if ([self scanString:@">>" intoString:NULL]) { - break; - } else if (success = ([self scanFDFName:&key] && [self scanFDFObject:&object])) { - if (object) - [tmpDict setObject:object forKey:key]; - } - } - - if (success && dictionary) - *dictionary = tmpDict; - - return success; -} - -- (BOOL)scanFDFString:(NSString **)string { - static NSCharacterSet *specialCharSet = nil; - if (specialCharSet == nil) - specialCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"\\)"] retain]; - - static NSCharacterSet *octalCharSet = nil; - if (octalCharSet == nil) - octalCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"01234567"] retain]; - - NSMutableString *tmpString = [NSMutableString string]; - NSString *s; - unichar ch; - BOOL success; - - if (success = [self scanString:@"(" intoString:NULL]) { - NSCharacterSet *skipChars = [[self charactersToBeSkipped] retain]; - [self setCharactersToBeSkipped:nil]; - - while (success) { - if ([self scanUpToCharactersFromSet:specialCharSet intoString:&s]) - [tmpString appendString:s]; - if ([self scanCharacter:&ch]) { - if (ch == ')') { - break; - } else if (ch == '\\') { - if ([self scanCharacter:&ch]) { - if (ch == 'n') { - [tmpString appendString:@"\n"]; - } else if (ch == 'r') { - [tmpString appendString:@"\r"]; - } else if (ch == 't') { - [tmpString appendString:@"\r"]; - } else if (ch == 'b') { - [tmpString appendString:@"\b"]; - } else if (ch == 'f') { - [tmpString appendString:@"\f"]; - } else if (ch == '(') { - [tmpString appendString:@"("]; - } else if (ch == ')') { - [tmpString appendString:@")"]; - } else if (ch == '\\') { - [tmpString appendString:@"\\"]; - } else if ([octalCharSet characterIsMember:ch]) { - char octal = ch; - if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { - [self scanCharacter:NULL]; - octal = 8 * octal + ch; - if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { - [self scanCharacter:NULL]; - octal = 8 * octal + ch; - } - } - NSString *s = [[NSString alloc] initWithBytes:&octal length:1 encoding:NSISOLatin1StringEncoding]; - if (success = s != nil) - [tmpString appendString:s]; - [s release]; - } else if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { - if (ch == '\r') - [self scanString:@"\n" intoString:NULL]; - } else { - [self setScanLocation:[self scanLocation] - 1]; - } - } else { - success = NO; - } - } - } else { - success = NO; - } - } - - [self setCharactersToBeSkipped:skipChars]; - [skipChars release]; - } - - if (success && string) - *string = tmpString; - - return success; -} - -static inline int hexCharacterNumber(unichar ch) { - if (ch >= '0' && ch <= '9') - return ch - '0'; - if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - return 0; -} - -- (BOOL)scanFDFHexString:(NSString **)string { - static NSCharacterSet *hexCharSet = nil; - if (hexCharSet == nil) - hexCharSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"] retain]; - - int rewindLoc = [self scanLocation]; - NSString *hexString = nil; - unichar ch; - char hexChar; - char *bytes = NULL; - int length = 0; - BOOL isFirst = YES; - BOOL done = NO; - BOOL success = [self scanString:@"<" intoString:NULL]; - - while (done == NO && success && (success = [self scanCharacter:&ch])) { - hexChar = 0; - if ([hexCharSet characterIsMember:ch]) { - hexChar += hexCharacterNumber(ch); - } else if (ch == '>') { - done = YES; - } else { - success = NO; - } - if (isFirst) { - hexChar *= 16; - } else { - length++; - bytes = NSZoneRealloc([self zone], bytes, length * sizeof(char)); - bytes[length - 1] = hexChar; - hexChar = 0; - } - isFirst = !isFirst; - } - - if (success) { - hexString = length == 0 ? @"" : [[[NSString alloc] initWithBytes:bytes length:length encoding:NSISOLatin1StringEncoding] autorelease]; - success = hexString != nil; - } - - if (bytes) - NSZoneFree([self zone], bytes); - - if (success == NO) - [self setScanLocation:rewindLoc]; - - if (success && string) - *string = hexString; - - return success; -} - -- (BOOL)scanFDFName:(NSString **)string { - static NSCharacterSet *whitespaceOrDelimiterCharSet = nil; - if (whitespaceOrDelimiterCharSet == nil) { - NSMutableCharacterSet *tmpSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy]; - [tmpSet addCharactersInString:@"()<>[]{}/%"]; - whitespaceOrDelimiterCharSet = [tmpSet copy]; - [tmpSet release]; - } - - BOOL success; - - if (success = [self scanString:@"/" intoString:NULL]) { - NSCharacterSet *skipChars = [[self charactersToBeSkipped] retain]; - [self setCharactersToBeSkipped:nil]; - success = [self scanUpToCharactersFromSet:whitespaceOrDelimiterCharSet intoString:string]; - [self setCharactersToBeSkipped:skipChars]; - [skipChars release]; - } - - return success; -} - -- (BOOL)scanFDFNumber:(NSNumber **)number { - float f; - BOOL success = [self scanFloat:&f]; - - if (success && number) - *number = [NSNumber numberWithFloat:f]; - - return success; -} - -- (BOOL)scanFDFBoolean:(id *)boolNumber { - NSNumber *tmpBoolNumber = nil; - BOOL success; - - if (success = [self scanString:@"true" intoString:NULL]) - tmpBoolNumber = [NSNumber numberWithBool:YES]; - else if (success = [self scanString:@"false" intoString:NULL]) - tmpBoolNumber = [NSNumber numberWithBool:NO]; - - if (success && boolNumber) - *boolNumber = tmpBoolNumber; - - return success; -} - -- (BOOL)scanFDFIndirectObject:(id *)object { - int rewindLoc = [self scanLocation]; - id tmpObject; - int objNumber, genNumber; - BOOL success; - - if (success = [self scanInt:&objNumber] && [self scanInt:&genNumber] && [self scanString:@"R" intoString:NULL]) { - tmpObject = [SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]; - } else { - [self setScanLocation:rewindLoc]; - } - - if (success && object) - *object = tmpObject; - - return success; -} - -- (BOOL)scanFDFComment:(NSString **)comment { - NSString *tmpComment = @""; - BOOL success; - - if (success = [self scanString:@"%" intoString:NULL]) { - NSCharacterSet *skipChars = [[self charactersToBeSkipped] retain]; - [self setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]]; - [self scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:&tmpComment]; - [self setCharactersToBeSkipped:skipChars]; - [skipChars release]; - } - - if (success && comment) - *comment = tmpComment; - - return success; -} - -@end - -#pragma mark - - -@implementation SKIndirectObject : NSObject - -+ (id)indirectObjectWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber { - return [[[self alloc] initWithNumber:objNumber generation:genNumber] autorelease]; -} - -- (id)initWithNumber:(unsigned int)objNumber generation:(unsigned int)genNumber { - if (self = [super init]) { - objectNumber = objNumber; - generationNumber = genNumber; - } - return self; -} - -- (id)copyWithZone:(NSZone *)aZone { - return [self retain]; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"<%@: %i %i>",[self class], objectNumber, generationNumber]; -} - -- (BOOL)isEqual:(id)other { - return [self isMemberOfClass:[other class]] && [self objectNumber] == [other objectNumber] && [self generationNumber] == [other generationNumber]; -} - -- (unsigned int)hash { - return (objectNumber << 16) | generationNumber; -} - -- (unsigned int)objectNumber { - return objectNumber; -} - -- (unsigned int)generationNumber { - return generationNumber; -} - -@end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 17:09:35
|
Revision: 2879 http://skim-app.svn.sourceforge.net/skim-app/?rev=2879&view=rev Author: hofman Date: 2007-09-10 10:09:31 -0700 (Mon, 10 Sep 2007) Log Message: ----------- update Dutch localization Modified Paths: -------------- trunk/Dutch.lproj/Localizable.strings trunk/Dutch.lproj/MainWindow.nib/data.dependency Modified: trunk/Dutch.lproj/Localizable.strings =================================================================== (Binary files differ) Modified: trunk/Dutch.lproj/MainWindow.nib/data.dependency =================================================================== --- trunk/Dutch.lproj/MainWindow.nib/data.dependency 2007-09-10 12:09:33 UTC (rev 2878) +++ trunk/Dutch.lproj/MainWindow.nib/data.dependency 2007-09-10 17:09:31 UTC (rev 2879) @@ -4,6 +4,7 @@ <dict> <key>IBPaletteDependency</key> <array> + <string>Controllers</string> <string>PDFKit</string> </array> </dict> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 12:09:34
|
Revision: 2878 http://skim-app.svn.sourceforge.net/skim-app/?rev=2878&view=rev Author: hofman Date: 2007-09-10 05:09:33 -0700 (Mon, 10 Sep 2007) Log Message: ----------- remove experimental code Modified Paths: -------------- trunk/SKDocument.m Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-10 11:44:08 UTC (rev 2877) +++ trunk/SKDocument.m 2007-09-10 12:09:33 UTC (rev 2878) @@ -674,10 +674,6 @@ NSString *fdfString = [NSString stringWithContentsOfURL:notesURL encoding:NSISOLatin1StringEncoding error:NULL]; if (fdfString) array = [SKFDFParser noteDictionariesFromFDFString:fdfString]; - - CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL((CFURLRef)notesURL); - NSLog(@"%@",pdfDoc); - if (pdfDoc) CGPDFDocumentRelease(pdfDoc); } if (array) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 11:44:15
|
Revision: 2877 http://skim-app.svn.sourceforge.net/skim-app/?rev=2877&view=rev Author: hofman Date: 2007-09-10 04:44:08 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Make scale and page toolbar items a bit larger. Update Dutch localization. Modified Paths: -------------- trunk/Dutch.lproj/MainWindow.nib/info.nib trunk/Dutch.lproj/MainWindow.nib/keyedobjects.nib trunk/English.lproj/MainWindow.nib/info.nib trunk/English.lproj/MainWindow.nib/keyedobjects.nib trunk/French.lproj/MainWindow.nib/info.nib trunk/French.lproj/MainWindow.nib/keyedobjects.nib trunk/Italian.lproj/MainWindow.nib/info.nib trunk/Italian.lproj/MainWindow.nib/keyedobjects.nib trunk/SKDocument.m trunk/SKMainWindowController.m Modified: trunk/Dutch.lproj/MainWindow.nib/info.nib =================================================================== --- trunk/Dutch.lproj/MainWindow.nib/info.nib 2007-09-10 10:21:56 UTC (rev 2876) +++ trunk/Dutch.lproj/MainWindow.nib/info.nib 2007-09-10 11:44:08 UTC (rev 2877) @@ -7,7 +7,7 @@ <key>IBEditorPositions</key> <dict> <key>168</key> - <string>601 508 237 265 0 0 1440 938 </string> + <string>601 508 255 265 0 0 1440 938 </string> <key>224</key> <string>610 420 220 442 0 0 1440 938 </string> <key>256</key> @@ -29,12 +29,6 @@ <array> <integer>208</integer> </array> - <key>IBOpenObjects</key> - <array> - <integer>224</integer> - <integer>256</integer> - <integer>502</integer> - </array> <key>IBSystem Version</key> <string>8R218</string> </dict> Modified: trunk/Dutch.lproj/MainWindow.nib/keyedobjects.nib =================================================================== (Binary files differ) Modified: trunk/English.lproj/MainWindow.nib/info.nib =================================================================== --- trunk/English.lproj/MainWindow.nib/info.nib 2007-09-10 10:21:56 UTC (rev 2876) +++ trunk/English.lproj/MainWindow.nib/info.nib 2007-09-10 11:44:08 UTC (rev 2877) @@ -7,7 +7,7 @@ <key>IBEditorPositions</key> <dict> <key>168</key> - <string>601 508 237 265 0 0 1440 938 </string> + <string>601 508 255 265 0 0 1440 938 </string> <key>224</key> <string>610 420 220 442 0 0 1440 938 </string> <key>256</key> @@ -31,20 +31,20 @@ </array> <key>IBOpenObjects</key> <array> + <integer>585</integer> + <integer>208</integer> + <integer>502</integer> <integer>553</integer> - <integer>5</integer> - <integer>694</integer> - <integer>208</integer> <integer>314</integer> - <integer>502</integer> - <integer>633</integer> - <integer>687</integer> - <integer>511</integer> <integer>256</integer> - <integer>539</integer> - <integer>585</integer> + <integer>694</integer> <integer>224</integer> <integer>168</integer> + <integer>633</integer> + <integer>539</integer> + <integer>511</integer> + <integer>687</integer> + <integer>5</integer> </array> <key>IBSystem Version</key> <string>8R218</string> Modified: trunk/English.lproj/MainWindow.nib/keyedobjects.nib =================================================================== (Binary files differ) Modified: trunk/French.lproj/MainWindow.nib/info.nib =================================================================== --- trunk/French.lproj/MainWindow.nib/info.nib 2007-09-10 10:21:56 UTC (rev 2876) +++ trunk/French.lproj/MainWindow.nib/info.nib 2007-09-10 11:44:08 UTC (rev 2877) @@ -7,7 +7,7 @@ <key>IBEditorPositions</key> <dict> <key>168</key> - <string>681 670 237 265 0 0 1600 1178 </string> + <string>601 508 255 265 0 0 1440 938 </string> <key>224</key> <string>610 420 220 442 0 0 1440 938 </string> <key>256</key> @@ -33,6 +33,7 @@ <array> <integer>314</integer> <integer>502</integer> + <integer>168</integer> <integer>224</integer> <integer>256</integer> </array> Modified: trunk/French.lproj/MainWindow.nib/keyedobjects.nib =================================================================== (Binary files differ) Modified: trunk/Italian.lproj/MainWindow.nib/info.nib =================================================================== --- trunk/Italian.lproj/MainWindow.nib/info.nib 2007-09-10 10:21:56 UTC (rev 2876) +++ trunk/Italian.lproj/MainWindow.nib/info.nib 2007-09-10 11:44:08 UTC (rev 2877) @@ -7,7 +7,7 @@ <key>IBEditorPositions</key> <dict> <key>168</key> - <string>601 507 237 267 0 0 1440 938 </string> + <string>601 507 255 267 0 0 1440 938 </string> <key>224</key> <string>610 420 220 442 0 0 1440 938 </string> <key>256</key> @@ -31,19 +31,19 @@ </array> <key>IBOpenObjects</key> <array> - <integer>676</integer> <integer>256</integer> - <integer>5</integer> + <integer>628</integer> + <integer>677</integer> <integer>208</integer> + <integer>314</integer> <integer>224</integer> - <integer>677</integer> + <integer>553</integer> + <integer>676</integer> + <integer>5</integer> <integer>168</integer> - <integer>314</integer> - <integer>539</integer> - <integer>628</integer> <integer>511</integer> <integer>502</integer> - <integer>553</integer> + <integer>539</integer> </array> <key>IBSystem Version</key> <string>8R218</string> Modified: trunk/Italian.lproj/MainWindow.nib/keyedobjects.nib =================================================================== (Binary files differ) Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-10 10:21:56 UTC (rev 2876) +++ trunk/SKDocument.m 2007-09-10 11:44:08 UTC (rev 2877) @@ -674,6 +674,10 @@ NSString *fdfString = [NSString stringWithContentsOfURL:notesURL encoding:NSISOLatin1StringEncoding error:NULL]; if (fdfString) array = [SKFDFParser noteDictionariesFromFDFString:fdfString]; + + CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL((CFURLRef)notesURL); + NSLog(@"%@",pdfDoc); + if (pdfDoc) CGPDFDocumentRelease(pdfDoc); } if (array) { Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-10 10:21:56 UTC (rev 2876) +++ trunk/SKMainWindowController.m 2007-09-10 11:44:08 UTC (rev 2877) @@ -3729,7 +3729,7 @@ - (void)typeSelectHelper:(SKTypeSelectHelper *)typeSelectHelper didFailToFindMatchForSearchString:(NSString *)searchString { if ([typeSelectHelper isEqual:[thumbnailTableView typeSelectHelper]] || [typeSelectHelper isEqual:[pdfView typeSelectHelper]]) { - [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: %@", @"Status message"), searchString]]; + [statusBar setLeftStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; } else if ([typeSelectHelper isEqual:[noteOutlineView typeSelectHelper]]) { [statusBar setRightStringValue:[NSString stringWithFormat:NSLocalizedString(@"No match: \"%@\"", @"Status message"), searchString]]; } else if ([typeSelectHelper isEqual:[outlineView typeSelectHelper]]) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 10:22:08
|
Revision: 2876 http://skim-app.svn.sourceforge.net/skim-app/?rev=2876&view=rev Author: hofman Date: 2007-09-10 03:21:56 -0700 (Mon, 10 Sep 2007) Log Message: ----------- Retain and autorelease the appcast URL in the local pool. Don't know if that prevents a crash. Modified Paths: -------------- trunk/vendorsrc/andymatuschak/Sparkle/SUAppcast.m Modified: trunk/vendorsrc/andymatuschak/Sparkle/SUAppcast.m =================================================================== --- trunk/vendorsrc/andymatuschak/Sparkle/SUAppcast.m 2007-09-10 00:19:59 UTC (rev 2875) +++ trunk/vendorsrc/andymatuschak/Sparkle/SUAppcast.m 2007-09-10 10:21:56 UTC (rev 2876) @@ -43,7 +43,7 @@ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSError *error = nil; - NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0]; + NSURLRequest *request = [NSURLRequest requestWithURL:[[url retain] autorelease] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0]; NSURLResponse *response = nil; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSXMLDocument *document = nil; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 00:20:03
|
Revision: 2875 http://skim-app.svn.sourceforge.net/skim-app/?rev=2875&view=rev Author: hofman Date: 2007-09-09 17:19:59 -0700 (Sun, 09 Sep 2007) Log Message: ----------- The cross reference able of an FDF file can contain letters f or n. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-10 00:09:03 UTC (rev 2874) +++ trunk/SKFDFParser.m 2007-09-10 00:19:59 UTC (rev 2875) @@ -157,7 +157,8 @@ if (success) { while ([scanner scanString:@"xref" intoString:NULL]) { while ([scanner scanFDFComment:NULL]); - while ([scanner scanInt:NULL]) { + while ([scanner scanInt:NULL] && [scanner scanInt:NULL]) { + [scanner scanString:@"n" intoString:NULL] || [scanner scanString:@"f" intoString:NULL]; while ([scanner scanFDFComment:NULL]); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-10 00:09:06
|
Revision: 2874 http://skim-app.svn.sourceforge.net/skim-app/?rev=2874&view=rev Author: hofman Date: 2007-09-09 17:09:03 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Order of keys in FDF dictionary. Modified Paths: -------------- trunk/SKPDFAnnotationNote.m Modified: trunk/SKPDFAnnotationNote.m =================================================================== --- trunk/SKPDFAnnotationNote.m 2007-09-09 23:20:10 UTC (rev 2873) +++ trunk/SKPDFAnnotationNote.m 2007-09-10 00:09:03 UTC (rev 2874) @@ -228,20 +228,15 @@ NSRect bounds = [self bounds]; float r, g, b, a = 0.0; PDFBorder *border = [self border]; + NSString *contents = [self contents]; [[self color] getRed:&r green:&g blue:&b alpha:&a]; [string appendString:@"/Type/Annot/Subtype/"]; [string appendString:[[self type] isEqualToString:@"Note"] ? @"Text" : [self type]]; - [string appendString:@"/Contents("]; - [string appendString:[self contents] ? [[self contents] stringByEscapingParenthesis] : @""]; - if ([self text]) { - [string appendString:@"\n"]; - [string appendString:[[[self text] string] stringByEscapingParenthesis]]; - } - [string appendString:@")"]; [string appendFormat:@"/Rect[%f %f %f %f]", NSMinX(bounds), NSMinY(bounds), NSMaxX(bounds), NSMaxY(bounds)]; + [string appendFormat:@"/Page %i", [self pageIndex]]; + [string appendString:@"/F 4"]; if (a > 0.0) [string appendFormat:@"/C[%f %f %f]", r, g, b]; - [string appendFormat:@"/Page %i", [self pageIndex]]; if (border) { [string appendFormat:@"/BS<</W %f/S", [border lineWidth]]; switch ([border style]) { @@ -264,6 +259,13 @@ [string appendFormat:@"/D[%@]", [[[border dashPattern] valueForKey:@"stringValue"] componentsJoinedByString:@" "]]; [string appendString:@">>"]; } + [string appendString:@"/Contents("]; + [string appendString:contents ? [contents stringByEscapingParenthesis] : @""]; + if ([self text]) { + [string appendString:@"\n"]; + [string appendString:[[[self text] string] stringByEscapingParenthesis]]; + } + [string appendString:@")"]; return string; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 23:20:13
|
Revision: 2873 http://skim-app.svn.sourceforge.net/skim-app/?rev=2873&view=rev Author: hofman Date: 2007-09-09 16:20:10 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Ignore escaped newlines in FDF strings. Ignore backslash if it is followed by a non-special character. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 22:04:54 UTC (rev 2872) +++ trunk/SKFDFParser.m 2007-09-09 23:20:10 UTC (rev 2873) @@ -131,7 +131,7 @@ while ([scanner scanFDFComment:NULL]); if (success = [scanner scanString:@"obj" intoString:NULL] && [scanner scanFDFObject:&object]) { while ([scanner scanFDFComment:NULL]); - if (success = [object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { + if ([object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { object = @""; if ([scanner scanUpToString:@"endstream" intoString:&object] && [scanner scanString:@"endstream" intoString:NULL]) { int end = [object length]; @@ -594,8 +594,12 @@ if (success = s != nil) [tmpString appendString:s]; [s release]; - } else - success = NO; + } else if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { + if (ch == '\r') + [self scanString:@"\n" intoString:NULL]; + } else { + [self setScanLocation:[self scanLocation] - 1]; + } } else { success = NO; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 22:04:55
|
Revision: 2872 http://skim-app.svn.sourceforge.net/skim-app/?rev=2872&view=rev Author: hofman Date: 2007-09-09 15:04:54 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Set any type of indirect object from FDF string. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 21:47:05 UTC (rev 2871) +++ trunk/SKFDFParser.m 2007-09-09 22:04:54 UTC (rev 2872) @@ -129,29 +129,26 @@ while ([scanner scanFDFComment:NULL]); if (success = [scanner scanInt:&genNumber]) { while ([scanner scanFDFComment:NULL]); - if (success = [scanner scanString:@"obj" intoString:NULL]) { - if (success = [scanner scanFDFObject:&object]) { - if ([object isKindOfClass:[NSDictionary class]]) { - while ([scanner scanFDFComment:NULL]); - if ([scanner scanString:@"stream" intoString:NULL]) { - object = @""; - if ([scanner scanUpToString:@"endstream" intoString:&object] && [scanner scanString:@"endstream" intoString:NULL]) { - int end = [object length]; - unichar ch = end ? [object characterAtIndex:end - 1] : 0; - if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { - end--; - if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') - end--; - object = [object substringToIndex:end]; - } - } + if (success = [scanner scanString:@"obj" intoString:NULL] && [scanner scanFDFObject:&object]) { + while ([scanner scanFDFComment:NULL]); + if (success = [object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { + object = @""; + if ([scanner scanUpToString:@"endstream" intoString:&object] && [scanner scanString:@"endstream" intoString:NULL]) { + int end = [object length]; + unichar ch = end ? [object characterAtIndex:end - 1] : 0; + if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { + end--; + if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') + end--; + object = [object substringToIndex:end]; } - [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; - while ([scanner scanFDFComment:NULL]); - success = [scanner scanString:@"endobj" intoString:NULL]; - while ([scanner scanFDFComment:NULL]); } } + if (success) { + success = [scanner scanString:@"endobj" intoString:NULL]; + while ([scanner scanFDFComment:NULL]); + [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; + } } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 21:47:07
|
Revision: 2871 http://skim-app.svn.sourceforge.net/skim-app/?rev=2871&view=rev Author: hofman Date: 2007-09-09 14:47:05 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Don't scan newlines when they are skipped. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 21:26:07 UTC (rev 2870) +++ trunk/SKFDFParser.m 2007-09-09 21:47:05 UTC (rev 2871) @@ -135,9 +135,7 @@ while ([scanner scanFDFComment:NULL]); if ([scanner scanString:@"stream" intoString:NULL]) { object = @""; - [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; - - if ([scanner scanUpToString:@"endstream" intoString:&object]) { + if ([scanner scanUpToString:@"endstream" intoString:&object] && [scanner scanString:@"endstream" intoString:NULL]) { int end = [object length]; unichar ch = end ? [object characterAtIndex:end - 1] : 0; if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { @@ -147,7 +145,6 @@ object = [object substringToIndex:end]; } } - [scanner scanString:@"endstream" intoString:NULL]; } [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; while ([scanner scanFDFComment:NULL]); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 21:26:11
|
Revision: 2870 http://skim-app.svn.sourceforge.net/skim-app/?rev=2870&view=rev Author: hofman Date: 2007-09-09 14:26:07 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Some more code cleaning in FDF parsing. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 21:16:16 UTC (rev 2869) +++ trunk/SKFDFParser.m 2007-09-09 21:26:07 UTC (rev 2870) @@ -481,20 +481,20 @@ - (BOOL)scanFDFObject:(id *)object { id tmpObject = nil; - BOOL success = YES; + BOOL success; - do { - success = [self scanFDFName:&tmpObject] || - [self scanFDFArray:&tmpObject] || - [self scanFDFDictionary:&tmpObject] || - [self scanFDFString:&tmpObject] || - [self scanFDFHexString:&tmpObject] || - [self scanFDFIndirectObject:&tmpObject] || - [self scanFDFNumber:&tmpObject] || - [self scanFDFBoolean:&tmpObject] || - [self scanString:@"null" intoString:NULL]; - } while (success == NO && [self isAtEnd] == NO && [self scanFDFComment:NULL]); + while ([self scanFDFComment:NULL]); + success = [self scanFDFName:&tmpObject] || + [self scanFDFArray:&tmpObject] || + [self scanFDFDictionary:&tmpObject] || + [self scanFDFString:&tmpObject] || + [self scanFDFHexString:&tmpObject] || + [self scanFDFIndirectObject:&tmpObject] || + [self scanFDFNumber:&tmpObject] || + [self scanFDFBoolean:&tmpObject] || + [self scanString:@"null" intoString:NULL]; + if (success && object) *object = tmpObject; @@ -503,19 +503,13 @@ - (BOOL)scanFDFArray:(NSArray **)array { NSMutableArray *tmpArray = [NSMutableArray array]; - unichar ch; id object; BOOL success = [self scanString:@"[" intoString:NULL]; while (success) { while ([self scanFDFComment:NULL]); - if ([self peekCharacter:&ch] == NO) { - success = NO; + if ([self scanString:@"]" intoString:NULL]) { break; - } - if (ch == ']') { - [self scanCharacter:NULL]; - break; } else if (success = [self scanFDFObject:&object]) { if (object) [tmpArray addObject:object]; @@ -536,13 +530,11 @@ while (success) { while ([self scanFDFComment:NULL]); - if ([self scanFDFName:&key]) { - if ((success = [self scanFDFObject:&object]) && object) - [tmpDict setObject:object forKey:key]; - } else if ([self scanString:@">>" intoString:NULL]) { + if ([self scanString:@">>" intoString:NULL]) { break; - } else { - success = NO; + } else if (success = ([self scanFDFName:&key] && [self scanFDFObject:&object])) { + if (object) + [tmpDict setObject:object forKey:key]; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 21:16:17
|
Revision: 2869 http://skim-app.svn.sourceforge.net/skim-app/?rev=2869&view=rev Author: hofman Date: 2007-09-09 14:16:16 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Simplify some code using convenience methods. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 21:04:19 UTC (rev 2868) +++ trunk/SKFDFParser.m 2007-09-09 21:16:16 UTC (rev 2869) @@ -192,29 +192,21 @@ - (NSArray *)noteDictionaries { NSMutableArray *array = nil; NSDictionary *trailer; - SKIndirectObject *root; - NSDictionary *rootDict; + NSDictionary *root; NSDictionary *fdfDict; NSArray *annots; - if ((trailer = [fdfDictionary objectForKey:@"trailer"]) && - ([trailer isKindOfClass:[NSDictionary class]]) && - (root = [trailer objectForKey:@"Root"]) && - ([root isKindOfClass:[SKIndirectObject class]]) && - (rootDict = [fdfDictionary objectForKey:root]) && - ([rootDict isKindOfClass:[NSDictionary class]]) && - (fdfDict = [rootDict objectForKey:@"FDF"]) && - ([fdfDict isKindOfClass:[NSDictionary class]]) && - (annots = [fdfDict objectForKey:@"Annots"]) && - ([annots isKindOfClass:[NSArray class]])) { + if ((trailer = [self dictionaryValue:[fdfDictionary objectForKey:@"trailer"]]) && + (root = [self dictionaryValue:[trailer objectForKey:@"Root"]]) && + (fdfDict = [self dictionaryValue:[root objectForKey:@"FDF"]]) && + (annots = [self arrayValue:[fdfDict objectForKey:@"Annots"]])) { NSEnumerator *annotEnum = [annots objectEnumerator]; NSDictionary *dict; - array = [NSMutableArray array]; + array = [NSMutableArray arrayWithCapacity:[annots count]]; while (dict = [annotEnum nextObject]) { - if ((dict = [self dictionaryValue:dict]) && - (dict = [self noteDictionary:dict])) + if (dict = [self noteDictionary:[self dictionaryValue:dict]]) [array addObject:dict]; } } @@ -249,7 +241,7 @@ NSSet *validTypes = [NSSet setWithObjects:@"FreeText", @"Note", @"Circle", @"Square", @"Highlight", @"Underline", @"StrikeOut", @"Line", nil]; NSEnumerator *keyEnum = [dict keyEnumerator]; NSString *key; - BOOL success = YES; + BOOL success = dict != nil; while (success && (key = [keyEnum nextObject])) { id value = [dict valueForKey:key]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 21:04:28
|
Revision: 2868 http://skim-app.svn.sourceforge.net/skim-app/?rev=2868&view=rev Author: hofman Date: 2007-09-09 14:04:19 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Ignore comments inside FDF dictionaries and arrays. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 20:58:00 UTC (rev 2867) +++ trunk/SKFDFParser.m 2007-09-09 21:04:19 UTC (rev 2868) @@ -129,7 +129,7 @@ while ([scanner scanFDFComment:NULL]); if (success = [scanner scanInt:&genNumber]) { while ([scanner scanFDFComment:NULL]); - if ([scanner scanString:@"obj" intoString:NULL]) { + if (success = [scanner scanString:@"obj" intoString:NULL]) { if (success = [scanner scanFDFObject:&object]) { if ([object isKindOfClass:[NSDictionary class]]) { while ([scanner scanFDFComment:NULL]); @@ -516,8 +516,7 @@ BOOL success = [self scanString:@"[" intoString:NULL]; while (success) { - [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - + while ([self scanFDFComment:NULL]); if ([self peekCharacter:&ch] == NO) { success = NO; break; @@ -544,8 +543,8 @@ BOOL success = [self scanString:@"<<" intoString:NULL]; while (success) { + while ([self scanFDFComment:NULL]); if ([self scanFDFName:&key]) { - [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; if ((success = [self scanFDFObject:&object]) && object) [tmpDict setObject:object forKey:key]; } else if ([self scanString:@">>" intoString:NULL]) { @@ -553,7 +552,6 @@ } else { success = NO; } - [self scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; } if (success && dictionary) @@ -668,8 +666,6 @@ hexChar = 0; if ([hexCharSet characterIsMember:ch]) { hexChar += hexCharacterNumber(ch); - } else if ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:ch]) { - // ignore } else if (ch == '>') { done = YES; } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 20:58:07
|
Revision: 2867 http://skim-app.svn.sourceforge.net/skim-app/?rev=2867&view=rev Author: hofman Date: 2007-09-09 13:58:00 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Ignore charactersToBeSkipped while scanning a single character. Modified Paths: -------------- trunk/NSScanner_SKExtensions.m Modified: trunk/NSScanner_SKExtensions.m =================================================================== --- trunk/NSScanner_SKExtensions.m 2007-09-09 20:21:28 UTC (rev 2866) +++ trunk/NSScanner_SKExtensions.m 2007-09-09 20:58:00 UTC (rev 2867) @@ -42,21 +42,32 @@ @implementation NSScanner (SKExtensions) - (BOOL)scanCharacter:(unichar *)ch { - if ([self isAtEnd]) - return NO; - int location = [self scanLocation]; - if (ch != NULL) - *ch = [[self string] characterAtIndex:location]; - [self setScanLocation:location + 1]; - return YES; + int location, length = [[self string] length]; + unichar character; + BOOL success = NO; + for (location = [self scanLocation]; success == NO && location < length; location++) { + character = [[self string] characterAtIndex:location]; + success = [[self charactersToBeSkipped] characterIsMember:character] == NO; + } + if (success) { + if (ch != NULL) + *ch = character; + [self setScanLocation:location]; + } + return success; } - (BOOL)peekCharacter:(unichar *)ch { - if ([self isAtEnd]) - return NO; - if (ch != NULL) - *ch = [[self string] characterAtIndex:[self scanLocation]]; - return YES; + int location, length = [[self string] length]; + unichar character; + BOOL success = NO; + for (location = [self scanLocation]; success == NO && location < length; location++) { + character = [[self string] characterAtIndex:location]; + success = [[self charactersToBeSkipped] characterIsMember:character] == NO; + } + if (success && ch != NULL) + *ch = character; + return success; } @end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 20:21:29
|
Revision: 2866 http://skim-app.svn.sourceforge.net/skim-app/?rev=2866&view=rev Author: hofman Date: 2007-09-09 13:21:28 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Add a /DS element to the FDF dictionary of a freetext annotation. Modified Paths: -------------- trunk/SKPDFAnnotationNote.m Modified: trunk/SKPDFAnnotationNote.m =================================================================== --- trunk/SKPDFAnnotationNote.m 2007-09-09 19:44:20 UTC (rev 2865) +++ trunk/SKPDFAnnotationNote.m 2007-09-09 20:21:28 UTC (rev 2866) @@ -1142,7 +1142,7 @@ - (NSString *)fdfString { NSMutableString *string = [[[super fdfString] mutableCopy] autorelease]; - [string appendFormat:@"/DA(/%@ %f Tf)", [[self font] fontName], [[self font] pointSize]]; + [string appendFormat:@"/DA(/%@ %f Tf)/DS(font: %@ %fpt)", [[self font] fontName], [[self font] pointSize], [[self font] fontName], [[self font] pointSize]]; return string; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 19:44:21
|
Revision: 2865 http://skim-app.svn.sourceforge.net/skim-app/?rev=2865&view=rev Author: hofman Date: 2007-09-09 12:44:20 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Update release notes. Modified Paths: -------------- trunk/ReleaseNotes.rtf Modified: trunk/ReleaseNotes.rtf =================================================================== --- trunk/ReleaseNotes.rtf 2007-09-09 19:41:33 UTC (rev 2864) +++ trunk/ReleaseNotes.rtf 2007-09-09 19:44:20 UTC (rev 2865) @@ -1,6 +1,7 @@ {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410 {\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fnil\fcharset77 LucidaGrande;\f2\fswiss\fcharset77 Helvetica-Bold; -\f3\fswiss\fcharset77 Helvetica-BoldOblique;\f4\fnil\fcharset77 LucidaGrande-Bold;} +\f3\fnil\fcharset77 LucidaSans-Typewriter;\f4\fswiss\fcharset77 Helvetica-BoldOblique;\f5\fnil\fcharset77 LucidaGrande-Bold; +} {\colortbl;\red255\green255\blue255;} {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1} {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid2} @@ -105,8 +106,10 @@ {\list\listtemplateid101\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid101} {\list\listtemplateid102\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid102} {\list\listtemplateid103\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid103} -{\list\listtemplateid104\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid104}} -{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}{\listoverride\listid12\listoverridecount0\ls12}{\listoverride\listid13\listoverridecount0\ls13}{\listoverride\listid14\listoverridecount0\ls14}{\listoverride\listid15\listoverridecount0\ls15}{\listoverride\listid16\listoverridecount0\ls16}{\listoverride\listid17\listoverridecount0\ls17}{\listoverride\listid18\listoverridecount0\ls18}{\listoverride\listid19\listoverridecount0\ls19}{\listoverride\listid20\listoverridecount0\ls20}{\listoverride\listid21\listoverridecount0\ls21}{\listoverride\listid22\listoverridecount0\ls22}{\listoverride\listid23\listoverridecount0\ls23}{\listoverride\listid24\listoverridecount0\ls24}{\listoverride\listid25\listoverridecount0\ls25}{\listoverride\listid26\listoverridecount0\ls26}{\listoverride\listid27\listoverridecount0\ls27}{\listoverride\listid28\listoverridecount0\ls28}{\listoverride\listid29\listoverridecount0\ls29}{\listoverride\listid30\listoverridecount0\ls30}{\listoverride\listid31\listoverridecount0\ls31}{\listoverride\listid32\listoverridecount0\ls32}{\listoverride\listid33\listoverridecount0\ls33}{\listoverride\listid34\listoverridecount0\ls34}{\listoverride\listid35\listoverridecount0\ls35}{\listoverride\listid36\listoverridecount0\ls36}{\listoverride\listid37\listoverridecount0\ls37}{\listoverride\listid38\listoverridecount0\ls38}{\listoverride\listid39\listoverridecount0\ls39}{\listoverride\listid40\listoverridecount0\ls40}{\listoverride\listid41\listoverridecount0\ls41}{\listoverride\listid42\listoverridecount0\ls42}{\listoverride\listid43\listoverridecount0\ls43}{\listoverride\listid44\listoverridecount0\ls44}{\listoverride\listid45\listoverridecount0\ls45}{\listoverride\listid46\listoverridecount0\ls46}{\listoverride\listid47\listoverridecount0\ls47}{\listoverride\listid48\listoverridecount0\ls48}{\listoverride\listid49\listoverridecount0\ls49}{\listoverride\listid50\listoverridecount0\ls50}{\listoverride\listid51\listoverridecount0\ls51}{\listoverride\listid52\listoverridecount0\ls52}{\listoverride\listid53\listoverridecount0\ls53}{\listoverride\listid54\listoverridecount0\ls54}{\listoverride\listid55\listoverridecount0\ls55}{\listoverride\listid56\listoverridecount0\ls56}{\listoverride\listid57\listoverridecount0\ls57}{\listoverride\listid58\listoverridecount0\ls58}{\listoverride\listid59\listoverridecount0\ls59}{\listoverride\listid60\listoverridecount0\ls60}{\listoverride\listid61\listoverridecount0\ls61}{\listoverride\listid62\listoverridecount0\ls62}{\listoverride\listid63\listoverridecount0\ls63}{\listoverride\listid64\listoverridecount0\ls64}{\listoverride\listid65\listoverridecount0\ls65}{\listoverride\listid66\listoverridecount0\ls66}{\listoverride\listid67\listoverridecount0\ls67}{\listoverride\listid68\listoverridecount0\ls68}{\listoverride\listid69\listoverridecount0\ls69}{\listoverride\listid70\listoverridecount0\ls70}{\listoverride\listid71\listoverridecount0\ls71}{\listoverride\listid72\listoverridecount0\ls72}{\listoverride\listid73\listoverridecount0\ls73}{\listoverride\listid74\listoverridecount0\ls74}{\listoverride\listid75\listoverridecount0\ls75}{\listoverride\listid76\listoverridecount0\ls76}{\listoverride\listid77\listoverridecount0\ls77}{\listoverride\listid78\listoverridecount0\ls78}{\listoverride\listid79\listoverridecount0\ls79}{\listoverride\listid80\listoverridecount0\ls80}{\listoverride\listid81\listoverridecount0\ls81}{\listoverride\listid82\listoverridecount0\ls82}{\listoverride\listid83\listoverridecount0\ls83}{\listoverride\listid84\listoverridecount0\ls84}{\listoverride\listid85\listoverridecount0\ls85}{\listoverride\listid86\listoverridecount0\ls86}{\listoverride\listid87\listoverridecount0\ls87}{\listoverride\listid88\listoverridecount0\ls88}{\listoverride\listid89\listoverridecount0\ls89}{\listoverride\listid90\listoverridecount0\ls90}{\listoverride\listid91\listoverridecount0\ls91}{\listoverride\listid92\listoverridecount0\ls92}{\listoverride\listid93\listoverridecount0\ls93}{\listoverride\listid94\listoverridecount0\ls94}{\listoverride\listid95\listoverridecount0\ls95}{\listoverride\listid96\listoverridecount0\ls96}{\listoverride\listid97\listoverridecount0\ls97}{\listoverride\listid98\listoverridecount0\ls98}{\listoverride\listid99\listoverridecount0\ls99}{\listoverride\listid100\listoverridecount0\ls100}{\listoverride\listid101\listoverridecount0\ls101}{\listoverride\listid102\listoverridecount0\ls102}{\listoverride\listid103\listoverridecount0\ls103}{\listoverride\listid104\listoverridecount0\ls104}} +{\list\listtemplateid104\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid104} +{\list\listtemplateid105\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid105} +{\list\listtemplateid106\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid106}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}{\listoverride\listid8\listoverridecount0\ls8}{\listoverride\listid9\listoverridecount0\ls9}{\listoverride\listid10\listoverridecount0\ls10}{\listoverride\listid11\listoverridecount0\ls11}{\listoverride\listid12\listoverridecount0\ls12}{\listoverride\listid13\listoverridecount0\ls13}{\listoverride\listid14\listoverridecount0\ls14}{\listoverride\listid15\listoverridecount0\ls15}{\listoverride\listid16\listoverridecount0\ls16}{\listoverride\listid17\listoverridecount0\ls17}{\listoverride\listid18\listoverridecount0\ls18}{\listoverride\listid19\listoverridecount0\ls19}{\listoverride\listid20\listoverridecount0\ls20}{\listoverride\listid21\listoverridecount0\ls21}{\listoverride\listid22\listoverridecount0\ls22}{\listoverride\listid23\listoverridecount0\ls23}{\listoverride\listid24\listoverridecount0\ls24}{\listoverride\listid25\listoverridecount0\ls25}{\listoverride\listid26\listoverridecount0\ls26}{\listoverride\listid27\listoverridecount0\ls27}{\listoverride\listid28\listoverridecount0\ls28}{\listoverride\listid29\listoverridecount0\ls29}{\listoverride\listid30\listoverridecount0\ls30}{\listoverride\listid31\listoverridecount0\ls31}{\listoverride\listid32\listoverridecount0\ls32}{\listoverride\listid33\listoverridecount0\ls33}{\listoverride\listid34\listoverridecount0\ls34}{\listoverride\listid35\listoverridecount0\ls35}{\listoverride\listid36\listoverridecount0\ls36}{\listoverride\listid37\listoverridecount0\ls37}{\listoverride\listid38\listoverridecount0\ls38}{\listoverride\listid39\listoverridecount0\ls39}{\listoverride\listid40\listoverridecount0\ls40}{\listoverride\listid41\listoverridecount0\ls41}{\listoverride\listid42\listoverridecount0\ls42}{\listoverride\listid43\listoverridecount0\ls43}{\listoverride\listid44\listoverridecount0\ls44}{\listoverride\listid45\listoverridecount0\ls45}{\listoverride\listid46\listoverridecount0\ls46}{\listoverride\listid47\listoverridecount0\ls47}{\listoverride\listid48\listoverridecount0\ls48}{\listoverride\listid49\listoverridecount0\ls49}{\listoverride\listid50\listoverridecount0\ls50}{\listoverride\listid51\listoverridecount0\ls51}{\listoverride\listid52\listoverridecount0\ls52}{\listoverride\listid53\listoverridecount0\ls53}{\listoverride\listid54\listoverridecount0\ls54}{\listoverride\listid55\listoverridecount0\ls55}{\listoverride\listid56\listoverridecount0\ls56}{\listoverride\listid57\listoverridecount0\ls57}{\listoverride\listid58\listoverridecount0\ls58}{\listoverride\listid59\listoverridecount0\ls59}{\listoverride\listid60\listoverridecount0\ls60}{\listoverride\listid61\listoverridecount0\ls61}{\listoverride\listid62\listoverridecount0\ls62}{\listoverride\listid63\listoverridecount0\ls63}{\listoverride\listid64\listoverridecount0\ls64}{\listoverride\listid65\listoverridecount0\ls65}{\listoverride\listid66\listoverridecount0\ls66}{\listoverride\listid67\listoverridecount0\ls67}{\listoverride\listid68\listoverridecount0\ls68}{\listoverride\listid69\listoverridecount0\ls69}{\listoverride\listid70\listoverridecount0\ls70}{\listoverride\listid71\listoverridecount0\ls71}{\listoverride\listid72\listoverridecount0\ls72}{\listoverride\listid73\listoverridecount0\ls73}{\listoverride\listid74\listoverridecount0\ls74}{\listoverride\listid75\listoverridecount0\ls75}{\listoverride\listid76\listoverridecount0\ls76}{\listoverride\listid77\listoverridecount0\ls77}{\listoverride\listid78\listoverridecount0\ls78}{\listoverride\listid79\listoverridecount0\ls79}{\listoverride\listid80\listoverridecount0\ls80}{\listoverride\listid81\listoverridecount0\ls81}{\listoverride\listid82\listoverridecount0\ls82}{\listoverride\listid83\listoverridecount0\ls83}{\listoverride\listid84\listoverridecount0\ls84}{\listoverride\listid85\listoverridecount0\ls85}{\listoverride\listid86\listoverridecount0\ls86}{\listoverride\listid87\listoverridecount0\ls87}{\listoverride\listid88\listoverridecount0\ls88}{\listoverride\listid89\listoverridecount0\ls89}{\listoverride\listid90\listoverridecount0\ls90}{\listoverride\listid91\listoverridecount0\ls91}{\listoverride\listid92\listoverridecount0\ls92}{\listoverride\listid93\listoverridecount0\ls93}{\listoverride\listid94\listoverridecount0\ls94}{\listoverride\listid95\listoverridecount0\ls95}{\listoverride\listid96\listoverridecount0\ls96}{\listoverride\listid97\listoverridecount0\ls97}{\listoverride\listid98\listoverridecount0\ls98}{\listoverride\listid99\listoverridecount0\ls99}{\listoverride\listid100\listoverridecount0\ls100}{\listoverride\listid101\listoverridecount0\ls101}{\listoverride\listid102\listoverridecount0\ls102}{\listoverride\listid103\listoverridecount0\ls103}{\listoverride\listid104\listoverridecount0\ls104}{\listoverride\listid105\listoverridecount0\ls105}{\listoverride\listid106\listoverridecount0\ls106}} \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural \f0\fs60 \cf0 Skim Release Notes\ @@ -115,14 +118,53 @@ \f1\fs22 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f2\b\fs28 \cf0 Changes since 0.7\ +\f2\b\fs28 \cf0 Changes since 0.8\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 New Features\ +\f1\b0\fs22 \cf0 Last update: 9 September 2007 (rev +\f3\fs20 2864) +\f1\fs22 \ +\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural + +\f2\b\fs28 \cf0 \ +\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural + +\f4\i\fs26 \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural \ls1\ilvl0 +\f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Use blue background for some tables.\ +{\listtext \'a5 }Name files inside a bundle the same as the bundle.\ +{\listtext \'a5 }Add contextual menu items to note window to auto-size a single row or all rows.\ +{\listtext \'a5 }Support for import and export of FDF files, allowing interchange of notes with Adobe.\ +{\listtext \'a5 }New hidden default for the size of the preview tool-tip.\ +\pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural + +\f2\b\fs28 \cf0 \ +\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural + +\f4\i\fs26 \cf0 Bugs Fixed\ +\pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural +\ls2\ilvl0 +\f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Always use the currebnt selection for snapshots when available.\ +{\listtext \'a5 }Show full size of the content of a PDF bundle in info window.\ +{\listtext \'a5 }Fix a crasher when loading a password protected file.\ +{\listtext \'a5 }Update page labels and page clumn widths when unlocking a file.\ +{\listtext \'a5 }Report failing type-select in the status bar.\ +{\listtext \'a5 }Allow non-ASCII characters, such as accents, in type-select.\ +{\listtext \'a5 }Make sure the message in the search results table changes at the end of a search.\ +\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural + +\f2\b\fs28 \cf0 \ +Changes since 0.7\ +\pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural +\cf0 \ +\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural + +\f4\i\fs26 \cf0 New Features\ +\pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural +\ls3\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Hold down Shift key while moving the end points of a line to restrict the angle of a line to multiples of 45 degrees.\ {\listtext \'a5 }You can now save the PDF and notes together in a bundle. This format is safe for email and version control.\ {\listtext \'a5 }Notes in PDF bundles can be searched through Spotlight.\ @@ -141,9 +183,9 @@ \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls2\ilvl0 +\ls4\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Add white outline to magnify cursors so they are visible on a dark background.\ {\listtext \'a5 }Adjust the size of page columns so they use as little space as possible.\ {\listtext \'a5 }Periodically save current documents, so the last open files can be opened after a crash.\ @@ -164,9 +206,9 @@ \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 New Features\ +\f4\i\fs26 \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls3\ilvl0 +\ls5\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }You can now resize all rows of the notes table to view the full text.\ {\listtext \'a5 }PDFSync from the editor now shows an indication of the target location.\ {\listtext \'a5 }The tool tip of the table of contents and the table of search results now shows a preview of the target location.\ @@ -188,9 +230,9 @@ \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls4\ilvl0 +\ls6\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Fix spell checking freeze for single page PDFs.\ {\listtext \'a5 }Selecting text is now completely disabled in presentation mode.\ {\listtext \'a5 }Changed shortcuts of Search PDF and Presentation to be consistent with other application.\ @@ -219,14 +261,14 @@ \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls5\ilvl0 +\ls7\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Fix updater.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls6\ilvl0\cf0 {\listtext \'a5 }Make sure side panes are opened at the saved widths.\ +\ls8\ilvl0\cf0 {\listtext \'a5 }Make sure side panes are opened at the saved widths.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls7\ilvl0\cf0 {\listtext \'a5 }Fix a typo in the scripting dictionary.\ +\ls9\ilvl0\cf0 {\listtext \'a5 }Fix a typo in the scripting dictionary.\ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural @@ -236,9 +278,9 @@ \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 New Features\ +\f4\i\fs26 \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls8\ilvl0 +\ls10\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Default print settings automatically choose landscape for wide pages.\ {\listtext \'a5 }Hidden preference for custom dvi conversion utilitiesto read DVI (e.g. dvips).\ {\listtext \'a5 }You can now spell-check a PDF.\ @@ -248,16 +290,16 @@ {\listtext \'a5 }New View menu item to show the file at the real size at which it would be printed.\ {\listtext \'a5 }Added a Speech menu to Edit menu.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls9\ilvl0\cf0 {\listtext \'a5 }Added keyboard shortcuts 'p' and 'a' to toggle pages and auto-resize in presentation mode.\ +\ls11\ilvl0\cf0 {\listtext \'a5 }Added keyboard shortcuts 'p' and 'a' to toggle pages and auto-resize in presentation mode.\ {\listtext \'a5 }Added French localization. (Thanks Corentin Cras-M\'8eneur!)\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls10\ilvl0 +\ls12\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Correct display of zero line width in Line inspector panel.\ {\listtext \'a5 }Fix broken Note preferences in Italian localization.\ {\listtext \'a5 }Improved security for PDFSync, escape special shell characters.\ @@ -270,7 +312,7 @@ {\listtext \'a5 }Fix layout issues in main window.\ {\listtext \'a5 }Reopen snapshots after a reload at the correct zoom factor.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls11\ilvl0\cf0 {\listtext \'a5 }Notes sorted by contents ignores case and uses numeric compare.\ +\ls13\ilvl0\cf0 {\listtext \'a5 }Notes sorted by contents ignores case and uses numeric compare.\ {\listtext \'a5 }Ignore empty Spotlight search text.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural @@ -281,9 +323,9 @@ \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 New Features\ +\f4\i\fs26 \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls12\ilvl0 +\ls14\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Added some more sorting keys for use in text export templates.\ {\listtext \'a5 }Reorganized document info window, with some new properties.\ {\listtext \'a5 }You can now navigate through a presentation using mouse clicks.\ @@ -291,17 +333,17 @@ {\listtext \'a5 }Added an optional status bar, displaying the page number, number and pages, as well as informatino about the tool mode, if it applies.\ {\listtext \'a5 }You can now print documents from AppleScript.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls13\ilvl0\cf0 {\listtext \'a5 }Pdfsync from AppleScript now goes separately through the go command instead of the open command.\ +\ls15\ilvl0\cf0 {\listtext \'a5 }Pdfsync from AppleScript now goes separately through the go command instead of the open command.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls14\ilvl0\cf0 {\listtext \'a5 }You can now quickly rotate through tool modes using Shift-modified arrow keys.\ +\ls16\ilvl0\cf0 {\listtext \'a5 }You can now quickly rotate through tool modes using Shift-modified arrow keys.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls15\ilvl0 +\ls17\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Prevent chaching of update info for updater.\ {\listtext \'a5 }Fix the default text export templates.\ {\listtext \'a5 }Allow other active application windows in front of Skim in presentation mode.\ @@ -322,9 +364,9 @@ \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 New Features\ +\f4\i\fs26 \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls16\ilvl0 +\ls18\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }You can now hide all notes and highlights.\ {\listtext \'a5 }Remember last exported type.\ {\listtext \'a5 }Keyboard shortcut for Export.\ @@ -342,13 +384,13 @@ {\listtext \'a5 }You can now change the icon type of anchored notes from the note's window to some standard proofreader marks.\ {\listtext \'a5 }Hidden default for icon type of anchored notes (SKAnchoredNoteiconType).\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls17\ilvl0\cf0 {\listtext \'a5 }Skim now saves the file type and creator code.\ +\ls19\ilvl0\cf0 {\listtext \'a5 }Skim now saves the file type and creator code.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls18\ilvl0\cf0 {\listtext \'a5 }The reading bar is now shown on the thumbnails.\ +\ls20\ilvl0\cf0 {\listtext \'a5 }The reading bar is now shown on the thumbnails.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls19\ilvl0\cf0 {\listtext \'a5 }Add border/line properties to circle, box, text and line notes. Accessible through a new inspector panel and AppleScript.\ +\ls21\ilvl0\cf0 {\listtext \'a5 }Add border/line properties to circle, box, text and line notes. Accessible through a new inspector panel and AppleScript.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls20\ilvl0\cf0 {\listtext \'a5 }Allow setting the interior (fill) color for circles and boxes. Select the check button at the bottom of the color panel.\ +\ls22\ilvl0\cf0 {\listtext \'a5 }Allow setting the interior (fill) color for circles and boxes. Select the check button at the bottom of the color panel.\ {\listtext \'a5 }Add a TeX editor perset for LyX.\ {\listtext \'a5 }You can now reopen snapshots from a previous run.\ {\listtext \'a5 }New preferences for line styles and interior colors.\ @@ -361,9 +403,9 @@ \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls21\ilvl0 +\ls23\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Use old-style check for network availability for the updater, as the newer API is not reliable for dial-up connections.\ {\listtext \'a5 }Never add a new note on a click in note tool mode, because undoing such an addition can also remove a text edit in progress.\ {\listtext \'a5 }Update the window title when the document is reloaded; the number of pages can change. \ @@ -373,7 +415,7 @@ {\listtext \'a5 }Add help about cropping pages.\ {\listtext \'a5 }Start and end points for arrow notes in AppleScript are now relative to the page, and changing them automatically changes the bounds.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls22\ilvl0\cf0 {\listtext \'a5 }The side panels in full screen mode are now hidden when you switch to another application.\ +\ls24\ilvl0\cf0 {\listtext \'a5 }The side panels in full screen mode are now hidden when you switch to another application.\ {\listtext \'a5 }Renamed "Arrow" to "Line", as it now allows more general line styles. Also change some keyboard shortcuts.\ {\listtext \'a5 }Enable Password menu item for encrypted files that are flagged as unlocked, as the latter is unreliable in PDFKit.\ {\listtext \'a5 }Fix tab-loop for PDFs with fiallable forms. Also add some help about fillable forms.\ @@ -394,9 +436,9 @@ \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls23\ilvl0 +\ls25\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Fixed installation of new versions by updater.\ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural @@ -404,199 +446,199 @@ Changes since 0.3\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\f3\i\fs26 \cf0 \ +\f4\i\fs26 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls24\ilvl0 +\ls26\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Add a menu item in the Help menu to visit the web site.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls25\ilvl0\cf0 {\listtext \'a5 }Add single-character shortcuts to change the note style in note mode (t, n, c, b, h, u, s, a).\ +\ls27\ilvl0\cf0 {\listtext \'a5 }Add single-character shortcuts to change the note style in note mode (t, n, c, b, h, u, s, a).\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls26\ilvl0\cf0 {\listtext \'a5 }Fix PDFSync support to work with file names containing spaces.\ +\ls28\ilvl0\cf0 {\listtext \'a5 }Fix PDFSync support to work with file names containing spaces.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls27\ilvl0\cf0 {\listtext \'a5 }Add hidden default for activation of navigation buttons in presentation mode (SKActivatePresentationNavigationAtBottom).\ +\ls29\ilvl0\cf0 {\listtext \'a5 }Add hidden default for activation of navigation buttons in presentation mode (SKActivatePresentationNavigationAtBottom).\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls28\ilvl0\cf0 {\listtext \'a5 }Start search using the find panel at the current page when there is no selection.\ +\ls30\ilvl0\cf0 {\listtext \'a5 }Start search using the find panel at the current page when there is no selection.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls29\ilvl0\cf0 {\listtext \'a5 }Wrap selection using the find panel.\ +\ls31\ilvl0\cf0 {\listtext \'a5 }Wrap selection using the find panel.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls30\ilvl0\cf0 {\listtext \'a5 }Add support for apple remote control. It can be disabled through the hidden default SKEnableAppleRemote.\ +\ls32\ilvl0\cf0 {\listtext \'a5 }Add support for apple remote control. It can be disabled through the hidden default SKEnableAppleRemote.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls31\ilvl0\cf0 {\listtext \'a5 }Hidden defaults for line ending style of arrows (SKLineNoteStartLineStyle, SKLineNoteEndLineStyle).\ +\ls33\ilvl0\cf0 {\listtext \'a5 }Hidden defaults for line ending style of arrows (SKLineNoteStartLineStyle, SKLineNoteEndLineStyle).\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls32\ilvl0\cf0 {\listtext \'a5 }Hidden pref option for reading missing notes from separate .skim file (SKReadMissingNotesFromSkimFileOption). \ +\ls34\ilvl0\cf0 {\listtext \'a5 }Hidden pref option for reading missing notes from separate .skim file (SKReadMissingNotesFromSkimFileOption). \ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls33\ilvl0\cf0 {\listtext \'a5 }You can now open the corresponding PDF from a Skim Notes document.\ +\ls35\ilvl0\cf0 {\listtext \'a5 }You can now open the corresponding PDF from a Skim Notes document.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls34\ilvl0\cf0 {\listtext \'a5 }Skim can now read TIFF images from the clipboard.\ +\ls36\ilvl0\cf0 {\listtext \'a5 }Skim can now read TIFF images from the clipboard.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls35\ilvl0\cf0 {\listtext \'a5 }New select tool. Allows you to copy PDF and TIFF images from a section of a page.\ +\ls37\ilvl0\cf0 {\listtext \'a5 }New select tool. Allows you to copy PDF and TIFF images from a section of a page.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls36\ilvl0\cf0 {\listtext \'a5 }You can now search Skim note files from Spotlight.\ +\ls38\ilvl0\cf0 {\listtext \'a5 }You can now search Skim note files from Spotlight.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls37\ilvl0\cf0 {\listtext \'a5 }New Crop menu items and toolbar button.\ +\ls39\ilvl0\cf0 {\listtext \'a5 }New Crop menu items and toolbar button.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls38\ilvl0\cf0 {\listtext \'a5 }Cropping and page rotation are now undoable.\ +\ls40\ilvl0\cf0 {\listtext \'a5 }Cropping and page rotation are now undoable.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls39\ilvl0\cf0 {\listtext \'a5 }Allow reverting a document when it has changed on disk.\ +\ls41\ilvl0\cf0 {\listtext \'a5 }Allow reverting a document when it has changed on disk.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls40\ilvl0\cf0 {\listtext \'a5 }New menu item to set the selection from the content of the page.\ +\ls42\ilvl0\cf0 {\listtext \'a5 }New menu item to set the selection from the content of the page.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls41\ilvl0\cf0 {\listtext \'a5 }Hidden defaults for automatic crop box margins (SKAutoCropBoxMarginWidth, SKAutoCropBoxMarginHeight).\ +\ls43\ilvl0\cf0 {\listtext \'a5 }Hidden defaults for automatic crop box margins (SKAutoCropBoxMarginWidth, SKAutoCropBoxMarginHeight).\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls42\ilvl0\cf0 {\listtext \'a5 }New Zoom To Selection menu item and toolbar button.\ +\ls44\ilvl0\cf0 {\listtext \'a5 }New Zoom To Selection menu item and toolbar button.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls43\ilvl0\cf0 {\listtext \'a5 }New preference option to open files fit to the PDF.\ +\ls45\ilvl0\cf0 {\listtext \'a5 }New preference option to open files fit to the PDF.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls44\ilvl0\cf0 {\listtext \'a5 }You can now join markup highlights using shift-click, or by selecting a highlight before adding a new one.\ +\ls46\ilvl0\cf0 {\listtext \'a5 }You can now join markup highlights using shift-click, or by selecting a highlight before adding a new one.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls45\ilvl0\cf0 {\listtext \'a5 }You can now supply templates for text export of notes. See the wiki for more information.\ +\ls47\ilvl0\cf0 {\listtext \'a5 }You can now supply templates for text export of notes. See the wiki for more information.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls46\ilvl0 +\ls48\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Fix links in help.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls47\ilvl0\cf0 {\listtext \'a5 }Don't create a new note in note tool mode on mousedown outside a page.\ +\ls49\ilvl0\cf0 {\listtext \'a5 }Don't create a new note in note tool mode on mousedown outside a page.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls48\ilvl0\cf0 {\listtext \'a5 }Don't add new resizable notes in note tool mode when just clicking.\ +\ls50\ilvl0\cf0 {\listtext \'a5 }Don't add new resizable notes in note tool mode when just clicking.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls49\ilvl0\cf0 {\listtext \'a5 }You can now access links that are "hidden" by transparent highlights and arrows.\ +\ls51\ilvl0\cf0 {\listtext \'a5 }You can now access links that are "hidden" by transparent highlights and arrows.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls50\ilvl0\cf0 {\listtext \'a5 }Scroll reading bar to visible when it is shown.\ +\ls52\ilvl0\cf0 {\listtext \'a5 }Scroll reading bar to visible when it is shown.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls51\ilvl0\cf0 {\listtext \'a5 }Scroll to previous position on page when reloading PDF.\ +\ls53\ilvl0\cf0 {\listtext \'a5 }Scroll to previous position on page when reloading PDF.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls52\ilvl0\cf0 {\listtext \'a5 }Escape spaces in TeX editor command.\ +\ls54\ilvl0\cf0 {\listtext \'a5 }Escape spaces in TeX editor command.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls53\ilvl0\cf0 {\listtext \'a5 }Thumbnails now use the current display box.\ +\ls55\ilvl0\cf0 {\listtext \'a5 }Thumbnails now use the current display box.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls54\ilvl0\cf0 {\listtext \'a5 }Retry automatic reloading of files changed on disk a few times.\ +\ls56\ilvl0\cf0 {\listtext \'a5 }Retry automatic reloading of files changed on disk a few times.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls54\ilvl0 +\ls56\ilvl0 \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \cf0 Changes since 0.2\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\f3\i\fs26 \cf0 \ +\f4\i\fs26 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \cf0 New Features\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls55\ilvl0 +\ls57\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }Add shortcuts for bigger/smaller font sizes.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls56\ilvl0\cf0 {\listtext \'a5 }Command-click a snapshot.\ +\ls58\ilvl0\cf0 {\listtext \'a5 }Command-click a snapshot.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls57\ilvl0\cf0 {\listtext \'a5 }We now print notes and highlights.\ +\ls59\ilvl0\cf0 {\listtext \'a5 }We now print notes and highlights.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls58\ilvl0\cf0 {\listtext \'a5 }Add copy/cut/paste items to the contextual menu, when they apply.\ +\ls60\ilvl0\cf0 {\listtext \'a5 }Add copy/cut/paste items to the contextual menu, when they apply.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls59\ilvl0\cf0 {\listtext \'a5 }You can now make a snapshot of a page by Command-clicking a thumbnail.\ +\ls61\ilvl0\cf0 {\listtext \'a5 }You can now make a snapshot of a page by Command-clicking a thumbnail.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls60\ilvl0\cf0 {\listtext \'a5 }Added Dutch localization.\ +\ls62\ilvl0\cf0 {\listtext \'a5 }Added Dutch localization.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls61\ilvl0\cf0 {\listtext \'a5 }We now do not leave Full Screen when switching to another application.\ +\ls63\ilvl0\cf0 {\listtext \'a5 }We now do not leave Full Screen when switching to another application.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls62\ilvl0\cf0 {\listtext \'a5 }Export notes as RTF.\ +\ls64\ilvl0\cf0 {\listtext \'a5 }Export notes as RTF.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls63\ilvl0\cf0 {\listtext \'a5 }Add preference options for default note/highlight colors and text note font.\ +\ls65\ilvl0\cf0 {\listtext \'a5 }Add preference options for default note/highlight colors and text note font.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls64\ilvl0\cf0 {\listtext \'a5 }Add menu item to save the current PDF display settings to be used for new documents.\ +\ls66\ilvl0\cf0 {\listtext \'a5 }Add menu item to save the current PDF display settings to be used for new documents.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls65\ilvl0\cf0 {\listtext \'a5 }Search results from the Find Panel are now also highlighted with a red oval.\ +\ls67\ilvl0\cf0 {\listtext \'a5 }Search results from the Find Panel are now also highlighted with a red oval.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls66\ilvl0\cf0 {\listtext \'a5 }Select search field when opening the Contents pane in full screen mode.\ +\ls68\ilvl0\cf0 {\listtext \'a5 }Select search field when opening the Contents pane in full screen mode.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls67\ilvl0\cf0 {\listtext \'a5 }You can now reset all preferences or all preferences in a pane.\ +\ls69\ilvl0\cf0 {\listtext \'a5 }You can now reset all preferences or all preferences in a pane.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls68\ilvl0\cf0 {\listtext \'a5 }Added Italian localization. (Thanks Andrea Bergia!)\ +\ls70\ilvl0\cf0 {\listtext \'a5 }Added Italian localization. (Thanks Andrea Bergia!)\ {\listtext \'a5 }Screensaver and sleep are now disabled in Presentation mode.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls69\ilvl0\cf0 {\listtext \'a5 }Skim can now return to the last page viewed in a document.\ +\ls71\ilvl0\cf0 {\listtext \'a5 }Skim can now return to the last page viewed in a document.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls70\ilvl0\cf0 {\listtext \'a5 }Link tool tips now show the top of the text when the link refers to the (empty) top of a page. \ +\ls72\ilvl0\cf0 {\listtext \'a5 }Link tool tips now show the top of the text when the link refers to the (empty) top of a page. \ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls71\ilvl0\cf0 {\listtext \'a5 }Skim can now also view separate Skim notes (.skim) files.\ +\ls73\ilvl0\cf0 {\listtext \'a5 }Skim can now also view separate Skim notes (.skim) files.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls72\ilvl0\cf0 {\listtext \'a5 }Using Sparkle for automatic updating. (Thanks Andy Matuschak!)\ +\ls74\ilvl0\cf0 {\listtext \'a5 }Using Sparkle for automatic updating. (Thanks Andy Matuschak!)\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls73\ilvl0\cf0 {\listtext \'a5 }Display the number of pages in the title bar.\ +\ls75\ilvl0\cf0 {\listtext \'a5 }Display the number of pages in the title bar.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls74\ilvl0\cf0 {\listtext \'a5 }Skim can now automatically backup a skim notes file whenever it saves a PDF file.\ +\ls76\ilvl0\cf0 {\listtext \'a5 }Skim can now automatically backup a skim notes file whenever it saves a PDF file.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls75\ilvl0\cf0 {\listtext \'a5 }You can now resize the current note using the arrow keys, when you hold down the Control key.\ +\ls77\ilvl0\cf0 {\listtext \'a5 }You can now resize the current note using the arrow keys, when you hold down the Control key.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls76\ilvl0\cf0 {\listtext \'a5 }Notes are now ordered according to page and location in page.\ +\ls78\ilvl0\cf0 {\listtext \'a5 }Notes are now ordered according to page and location in page.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls77\ilvl0\cf0 {\listtext \'a5 }Several improvements of Skim's custom tool-tips.\ +\ls79\ilvl0\cf0 {\listtext \'a5 }Several improvements of Skim's custom tool-tips.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls78\ilvl0\cf0 {\listtext \'a5 }Add a menu item to select the search field.\ +\ls80\ilvl0\cf0 {\listtext \'a5 }Add a menu item to select the search field.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls79\ilvl0\cf0 {\listtext \'a5 }You can now add arrows to a PDF document.\ +\ls81\ilvl0\cf0 {\listtext \'a5 }You can now add arrows to a PDF document.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls80\ilvl0\cf0 {\listtext \'a5 }You can now add notes from external .skim files rather than just overwriting them.\ +\ls82\ilvl0\cf0 {\listtext \'a5 }You can now add notes from external .skim files rather than just overwriting them.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls81\ilvl0\cf0 {\listtext \'a5 }PDFSync support. See the Wiki for more information.\ +\ls83\ilvl0\cf0 {\listtext \'a5 }PDFSync support. See the Wiki for more information.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls82\ilvl0\cf0 {\listtext \'a5 }You can now set transparent colors from the color panel. \ +\ls84\ilvl0\cf0 {\listtext \'a5 }You can now set transparent colors from the color panel. \ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls83\ilvl0\cf0 {\listtext \'a5 }You can now set separate PDF view settings for full screen mode. \ +\ls85\ilvl0\cf0 {\listtext \'a5 }You can now set separate PDF view settings for full screen mode. \ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls84\ilvl0\cf0 {\listtext \'a5 }Add a Look Up in Dictionary item to the contextual menu.\ +\ls86\ilvl0\cf0 {\listtext \'a5 }Add a Look Up in Dictionary item to the contextual menu.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls85\ilvl0\cf0 {\listtext \'a5 }You can now undo edits of notes and highlights.\ +\ls87\ilvl0\cf0 {\listtext \'a5 }You can now undo edits of notes and highlights.\ {\listtext \'a5 }Add a hidden preference (SKActivateFullScreenNavigationAtBottom) to show the navigation buttons in full screen mode only when moving the mouse at the bottom of the screen. \ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls86\ilvl0\cf0 {\listtext \'a5 }Add hidden preferences for the line widths of circles and boxes (SKCircleNoteLineWidth and SKSquareNoteLineWidth).\ +\ls88\ilvl0\cf0 {\listtext \'a5 }Add hidden preferences for the line widths of circles and boxes (SKCircleNoteLineWidth and SKSquareNoteLineWidth).\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls87\ilvl0\cf0 {\listtext \'a5 }New tool modes for ading notes or highlights.\ +\ls89\ilvl0\cf0 {\listtext \'a5 }New tool modes for ading notes or highlights.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural \f2\b\fs28 \cf0 \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\fs26 \cf0 Bugs Fixed\ +\f4\i\fs26 \cf0 Bugs Fixed\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls88\ilvl0 +\ls90\ilvl0 \f1\i0\b0\fs22 \cf0 {\listtext \'a5 }We now don't edit new text notes, so they can be moved, resized or deleted.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls89\ilvl0\cf0 {\listtext \'a5 }We now make sure new notes are added to a visible page.\ +\ls91\ilvl0\cf0 {\listtext \'a5 }We now make sure new notes are added to a visible page.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls90\ilvl0\cf0 {\listtext \'a5 }Disable the TOC menu item when there is no TOC.\ +\ls92\ilvl0\cf0 {\listtext \'a5 }Disable the TOC menu item when there is no TOC.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls91\ilvl0\cf0 {\listtext \'a5 }Return to the location that was viewed when reloading a document.\ +\ls93\ilvl0\cf0 {\listtext \'a5 }Return to the location that was viewed when reloading a document.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls92\ilvl0\cf0 {\listtext \'a5 }Search text in a PDf file asynchronously, so it does not block Skim.\ +\ls94\ilvl0\cf0 {\listtext \'a5 }Search text in a PDf file asynchronously, so it does not block Skim.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls93\ilvl0\cf0 {\listtext \'a5 }Fix crashes that can appear for links with missing URLs.\ +\ls95\ilvl0\cf0 {\listtext \'a5 }Fix crashes that can appear for links with missing URLs.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls94\ilvl0\cf0 {\listtext \'a5 }Add separators in the Notes menu for categories.\ +\ls96\ilvl0\cf0 {\listtext \'a5 }Add separators in the Notes menu for categories.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls95\ilvl0\cf0 {\listtext \'a5 }Fix a crasher when reverting a PDF-document.\ +\ls97\ilvl0\cf0 {\listtext \'a5 }Fix a crasher when reverting a PDF-document.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls96\ilvl0\cf0 {\listtext \'a5 }Fix typos in the Help and update for new features.\ +\ls98\ilvl0\cf0 {\listtext \'a5 }Fix typos in the Help and update for new features.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls97\ilvl0\cf0 {\listtext \'a5 }Fix a crasher when reverting the document. Unfortunately this disabled tool tips.\ +\ls99\ilvl0\cf0 {\listtext \'a5 }Fix a crasher when reverting the document. Unfortunately this disabled tool tips.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls98\ilvl0\cf0 {\listtext \'a5 }Open the contents pane to display the search term when opening from Spotlight.\ +\ls100\ilvl0\cf0 {\listtext \'a5 }Open the contents pane to display the search term when opening from Spotlight.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls99\ilvl0\cf0 {\listtext \'a5 }Save notes when auto-saving and exporting as PDF.\ +\ls101\ilvl0\cf0 {\listtext \'a5 }Save notes when auto-saving and exporting as PDF.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls100\ilvl0\cf0 {\listtext \'a5 }Remember the width of notes pane.\ +\ls102\ilvl0\cf0 {\listtext \'a5 }Remember the width of notes pane.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls101\ilvl0\cf0 {\listtext \'a5 }Fix leaks leading to excessive memory use.\ +\ls103\ilvl0\cf0 {\listtext \'a5 }Fix leaks leading to excessive memory use.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls102\ilvl0\cf0 {\listtext \'a5 }Fix back-tabbing through notes and links.\ +\ls104\ilvl0\cf0 {\listtext \'a5 }Fix back-tabbing through notes and links.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls103\ilvl0\cf0 {\listtext \'a5 }Zooming using the scroll-wheel now only affects the current window.\ +\ls105\ilvl0\cf0 {\listtext \'a5 }Zooming using the scroll-wheel now only affects the current window.\ \pard\tx220\tx720\tx1440\tx2880\tx4320\tx5760\tx7200\li720\fi-720\ql\qnatural -\ls104\ilvl0\cf0 {\listtext \'a5 }Lazy updating of page thumbnails to avoid slowdown when opening a file.\ +\ls106\ilvl0\cf0 {\listtext \'a5 }Lazy updating of page thumbnails to avoid slowdown when opening a file.\ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \f2\b\fs28 \cf0 \ @@ -622,7 +664,7 @@ \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\b\fs26 \cf0 Web Site\ +\f4\i\b\fs26 \cf0 Web Site\ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \f1\i0\b0\fs22 \cf0 \ @@ -630,7 +672,7 @@ \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\b\fs26 \cf0 Getting Help\ +\f4\i\b\fs26 \cf0 Getting Help\ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \f1\i0\b0\fs22 \cf0 \ @@ -638,11 +680,11 @@ \ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural -\f3\i\b\fs26 \cf0 Reporting Bugs\ +\f4\i\b\fs26 \cf0 Reporting Bugs\ \pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural \f1\i0\b0\fs22 \cf0 \ Bug reports should be submitted to the {\field{\*\fldinst{HYPERLINK "http://sourceforge.net/tracker/?group_id=192583&atid=941981"}}{\fldrslt bug tracker}} on SourceForge. -\f4\b Note: +\f5\b Note: \f1\b0 If you can, please assign the bug report to someone - if you don't personally know any developers, assign the bug to Mike (username mmcc). If you don't assign the bug to someone, nobody may notice it for a long time. Assigning it to someone sends them an email notification.\ } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 19:41:35
|
Revision: 2864 http://skim-app.svn.sourceforge.net/skim-app/?rev=2864&view=rev Author: hofman Date: 2007-09-09 12:41:33 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Split contents from FDF into contents and text for Note annotations. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 19:05:14 UTC (rev 2863) +++ trunk/SKFDFParser.m 2007-09-09 19:41:33 UTC (rev 2864) @@ -464,6 +464,20 @@ } } } + + NSString *type = [dictionary objectForKey:@"type"]; + NSString *contents; + if ([type isEqualToString:@"Note"]) { + if (contents = [dictionary objectForKey:@"contents"]) { + unsigned contentsEnd, end; + [contents getLineStart:NULL end:&end contentsEnd:&contentsEnd forRange:NSMakeRange(0, 0)]; + if (end < [contents length]) { + [dictionary setObject:[contents substringToIndex:contentsEnd] forKey:@"contents"]; + [dictionary setObject:[[[NSAttributedString alloc] initWithString:[contents substringFromIndex:end]] autorelease] forKey:@"text"]; + } + } + } + return success ? dictionary : nil; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 19:05:16
|
Revision: 2863 http://skim-app.svn.sourceforge.net/skim-app/?rev=2863&view=rev Author: hofman Date: 2007-09-09 12:05:14 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Add a convenience method to find the PDF file in a PDF bundle. Allow passing the PDF file name for the FDF string. Save an FDF file in the PDF bundle. Modified Paths: -------------- trunk/SKDocument.h trunk/SKDocument.m Modified: trunk/SKDocument.h =================================================================== --- trunk/SKDocument.h 2007-09-09 18:11:45 UTC (rev 2862) +++ trunk/SKDocument.h 2007-09-09 19:05:14 UTC (rev 2863) @@ -103,6 +103,7 @@ - (NSString *)notesString; - (NSData *)notesRTFData; - (NSString *)notesFDFString; +- (NSString *)notesFDFStringForFile:(NSString *)filename; - (NSDictionary *)currentDocumentSetup; Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-09 18:11:45 UTC (rev 2862) +++ trunk/SKDocument.m 2007-09-09 19:05:14 UTC (rev 2863) @@ -70,8 +70,15 @@ NSString *SKDocumentWillSaveNotification = @"SKDocumentWillSaveNotification"; -@interface SKDocument (Private) +@interface NSFileManager (SKDocumentExtensions) +- (NSString *)subfileWithExtension:(NSString *)extensions inPDFBundleAtPath:(NSString *)path; +@end + +#pragma mark - + +@interface SKDocument (SKPrivate) + - (void)setPDFData:(NSData *)data; - (void)setPDFDoc:(PDFDocument *)doc; - (void)setNoteDicts:(NSArray *)array; @@ -86,6 +93,7 @@ @end +#pragma mark - @implementation SKDocument @@ -247,7 +255,7 @@ if (success = [self writeToURL:tmpURL ofType:typeName error:outError]) { - NSSet *ourExtensions = [NSSet setWithObjects:@"pdf", @"skim", @"txt", @"text", @"rtf", @"plist", nil]; + NSSet *ourExtensions = [NSSet setWithObjects:@"pdf", @"skim", @"fdf", @"txt", @"text", @"rtf", @"plist", nil]; NSSet *ourImportantExtensions = [NSSet setWithObjects:@"pdf", @"skim", nil]; NSEnumerator *fileEnum; NSString *file; @@ -324,16 +332,18 @@ didWrite = [pdfData writeToURL:absoluteURL options:NSAtomicWrite error:outError] && [self saveNotesToExtendedAttributesAtURL:absoluteURL error:outError]; } else if ([typeName isEqualToString:SKPDFBundleDocumentType]) { - NSData *notesData = [[self notes] count] ? [NSKeyedArchiver archivedDataWithRootObject:[[self notes] valueForKey:@"dictionaryValue"]] : nil; - NSData *notesTextData = [[self notesString] dataUsingEncoding:NSUTF8StringEncoding]; - NSData *notesRTFData = [self notesRTFData]; + NSString *name = [[[absoluteURL path] lastPathComponent] stringByDeletingPathExtension]; + if ([name caseInsensitiveCompare:BUNDLE_DATA_FILENAME] == NSOrderedSame) + name = [name stringByAppendingString:@"1"]; + BOOL hasNotes = [[self notes] count] > 0; + NSData *notesData = hasNotes ? [NSKeyedArchiver archivedDataWithRootObject:[[self notes] valueForKey:@"dictionaryValue"]] : nil; + NSData *notesTextData = hasNotes ? [[self notesString] dataUsingEncoding:NSUTF8StringEncoding] : nil; + NSData *notesRTFData = hasNotes ? [self notesRTFData] : nil; + NSData *notesFDFData = hasNotes ? [[self notesFDFStringForFile:[name stringByAppendingPathExtension:@"pdf"]] dataUsingEncoding:NSISOLatin1StringEncoding] : nil; NSData *textData = [[[self pdfDocument] string] dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *info = [[SKInfoWindowController sharedInstance] infoForDocument:self]; NSData *infoData = [NSPropertyListSerialization dataFromPropertyList:info format:NSPropertyListXMLFormat_v1_0 errorDescription:NULL]; NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[NSDictionary dictionary]]; - NSString *name = [[[absoluteURL path] lastPathComponent] stringByDeletingPathExtension]; - if ([name caseInsensitiveCompare:BUNDLE_DATA_FILENAME] == NSOrderedSame) - name = [name stringByAppendingString:@"1"]; [fileWrapper addRegularFileWithContents:pdfData preferredFilename:[name stringByAppendingPathExtension:@"pdf"]]; if (notesData) [fileWrapper addRegularFileWithContents:notesData preferredFilename:[name stringByAppendingPathExtension:@"skim"]]; @@ -341,6 +351,8 @@ [fileWrapper addRegularFileWithContents:notesTextData preferredFilename:[name stringByAppendingPathExtension:@"txt"]]; if (notesRTFData) [fileWrapper addRegularFileWithContents:notesRTFData preferredFilename:[name stringByAppendingPathExtension:@"rtf"]]; + if (notesFDFData) + [fileWrapper addRegularFileWithContents:notesRTFData preferredFilename:[name stringByAppendingPathExtension:@"fdf"]]; if (textData) [fileWrapper addRegularFileWithContents:textData preferredFilename:[BUNDLE_DATA_FILENAME stringByAppendingPathExtension:@"txt"]]; if (infoData) @@ -374,6 +386,12 @@ else if (outError != NULL) *outError = [NSError errorWithDomain:SKDocumentErrorDomain code:1 userInfo:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Unable to write notes as text", @"Error description"), NSLocalizedDescriptionKey, nil]]; } else if ([typeName isEqualToString:SKNotesFDFDocumentType]) { + NSString *filePath = [[self fileURL] path]; + NSString *filename = [filePath lastPathComponent]; + if (filename && [[self fileType] isEqualToString:SKPDFBundleDocumentType]) { + NSString *pdfFile = [[NSFileManager defaultManager] subfileWithExtension:@"pdf" inPDFBundleAtPath:filePath]; + filename = pdfFile ? [filename stringByAppendingPathComponent:pdfFile] : nil; + } NSString *string = [self notesFDFString]; if (string) didWrite = [string writeToURL:absoluteURL atomically:YES encoding:NSISOLatin1StringEncoding error:outError]; @@ -417,6 +435,8 @@ [dict setObject:[NSNumber numberWithUnsignedLong:'PDFD'] forKey:NSFileHFSTypeCode]; else if ([[[absoluteURL path] pathExtension] isEqualToString:@"skim"] || [typeName isEqualToString:SKNotesDocumentType]) [dict setObject:[NSNumber numberWithUnsignedLong:'SKNT'] forKey:NSFileHFSTypeCode]; + else if ([[[absoluteURL path] pathExtension] isEqualToString:@"fdf"] || [typeName isEqualToString:SKNotesFDFDocumentType]) + [dict setObject:[NSNumber numberWithUnsignedLong:'FDF '] forKey:NSFileHFSTypeCode]; else if ([[[absoluteURL path] pathExtension] isEqualToString:@"rtf"] || [typeName isEqualToString:SKNotesRTFDocumentType]) [dict setObject:[NSNumber numberWithUnsignedLong:'RTF '] forKey:NSFileHFSTypeCode]; else if ([[[absoluteURL path] pathExtension] isEqualToString:@"txt"] || [typeName isEqualToString:SKNotesTextDocumentType]) @@ -527,51 +547,20 @@ } } } else if ([docType isEqualToString:SKPDFBundleDocumentType]) { - NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initWithPath:[absoluteURL path]]; - NSFileWrapper *pdfFW = nil; - NSFileWrapper *skimFW = nil; - NSDictionary *fileWrappers = [fileWrapper fileWrappers]; - NSArray *noteArray = nil; - NSString *name = [[[absoluteURL path] lastPathComponent] stringByDeletingPathExtension]; - if ([name caseInsensitiveCompare:BUNDLE_DATA_FILENAME] == NSOrderedSame) - name = [name stringByAppendingString:@"1"]; - - pdfFW = [fileWrappers objectForKey:[name stringByAppendingPathExtension:@"pdf"]]; - if ([pdfFW isRegularFile] == NO) - pdfFW = nil; - skimFW = [fileWrappers objectForKey:[name stringByAppendingPathExtension:@"skim"]]; - if ([skimFW isRegularFile] == NO) - skimFW = nil; - if (pdfFW == nil || skimFW == nil) { - NSArray *fws = [fileWrappers allValues]; - NSArray *extensions = [fws valueForKeyPath:@"filename.pathExtension.lowercaseString"]; - unsigned int index; - if (pdfFW == nil) { - index = [extensions indexOfObject:@"pdf"]; - if (index != NSNotFound) { - pdfFW = [fws objectAtIndex:index]; - if ([pdfFW isRegularFile] == NO) - pdfFW = nil; + NSString *path = [absoluteURL path]; + NSString *pdfFile = [[NSFileManager defaultManager] subfileWithExtension:@"pdf" inPDFBundleAtPath:path]; + if (pdfFile) { + NSURL *pdfURL = [NSURL fileURLWithPath:[path stringByAppendingPathComponent:pdfFile]]; + if ((data = [[NSData alloc] initWithContentsOfURL:pdfURL options:NSUncachedRead error:&error]) && + (pdfDoc = [[PDFDocument alloc] initWithURL:pdfURL])) { + NSString *skimFile = [[NSFileManager defaultManager] subfileWithExtension:@"skim" inPDFBundleAtPath:path]; + if (skimFile) { + NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:[path stringByAppendingPathComponent:skimFile]]; + if (array) + [self setNoteDicts:array]; } } - if (skimFW == nil) { - index = [extensions indexOfObject:@"skim"]; - if (index != NSNotFound) { - skimFW = [fws objectAtIndex:index]; - if ([skimFW isRegularFile] == NO) - skimFW = nil; - } - } } - if (pdfFW) { - data = [[pdfFW regularFileContents] retain]; - pdfDoc = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:[[absoluteURL path] stringByAppendingPathComponent:[pdfFW filename]]]]; - } - if (skimFW) { - if (noteArray = [NSKeyedUnarchiver unarchiveObjectWithData:[skimFW regularFileContents]]) - [self setNoteDicts:noteArray]; - } - [fileWrapper release]; } else if ([docType isEqualToString:SKPostScriptDocumentType]) { if (data = [NSData dataWithContentsOfURL:absoluteURL options:NSUncachedRead error:&error]) { SKPSProgressController *progressController = [[SKPSProgressController alloc] init]; @@ -1036,16 +1025,9 @@ if (theUTI && UTTypeConformsTo((CFStringRef)theUTI, CFSTR("application/x-dvi"))) { return; } if (theUTI && UTTypeConformsTo((CFStringRef)theUTI, CFSTR("net.sourceforge.skim-app.pdfd"))) { - NSString *pdfFile = [fileName stringByAppendingPathComponent:@"data.pdf"]; - if ([[NSFileManager defaultManager] fileExistsAtPath:pdfFile]) { - fileName = pdfFile; - } else { - NSArray *subfiles = [[NSFileManager defaultManager] subpathsAtPath:fileName]; - unsigned int index = [[subfiles valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"]; - if (index == NSNotFound) - return; - fileName = [fileName stringByAppendingPathComponent:[subfiles objectAtIndex:index]]; - } + NSString *pdfFile = [[NSFileManager defaultManager] subfileWithExtension:@"pdf" inPDFBundleAtPath:fileName]; + if (pdfFile == nil) return; + fileName = [fileName stringByAppendingPathComponent:pdfFile]; } } @@ -1355,19 +1337,22 @@ } - (NSString *)notesFDFString { - NSString *filename = [[[self fileURL] path] lastPathComponent]; + NSString *filePath = [[self fileURL] path]; + NSString *filename = [filePath lastPathComponent]; + if (filename && [[self fileType] isEqualToString:SKPDFBundleDocumentType]) { + NSString *pdfFile = [[NSFileManager defaultManager] subfileWithExtension:@"pdf" inPDFBundleAtPath:filePath]; + filename = pdfFile ? [filename stringByAppendingPathComponent:pdfFile] : nil; + } + return [self notesFDFStringForFile:filename]; +} + +- (NSString *)notesFDFStringForFile:(NSString *)filename { NSString *fileIDString = [self fileIDString]; int i, count = [[self notes] count]; NSMutableString *string = [NSMutableString stringWithFormat:@"%%FDF-1.2\n%%%C%C%C%C\n1 0 obj<</FDF<<", 0xe2, 0xe3, 0xcf, 0xd3]; [string appendString:@"/Annots["]; for (i = 0; i < count; i++) [string appendFormat:@"%i 0 R ", i + 2]; - if (filename && [[self fileType] isEqualToString:SKPDFBundleDocumentType]) { - NSArray *files = [[NSFileManager defaultManager] subpathsAtPath:[[self fileURL] path]]; - unsigned index = [[files valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:@"pdf"]; - if (index != NSNotFound) - filename = [filename stringByAppendingPathComponent:[files objectAtIndex:index]]; - } [string appendFormat:@"]/F(%@)", filename ? [filename stringByEscapingParenthesis] : @""]; if (fileIDString) [string appendFormat:@"/ID[%@]", fileIDString]; @@ -1747,3 +1732,23 @@ } @end + + +@implementation NSFileManager (SKDocumentExtensions) + +- (NSString *)subfileWithExtension:(NSString *)extension inPDFBundleAtPath:(NSString *)path { + NSArray *subfiles = [self subpathsAtPath:path]; + NSString *fileName = [[[path stringByDeletingLastPathComponent] stringByDeletingPathExtension] stringByAppendingPathExtension:extension]; + NSString *pdfFile = nil; + + if ([subfiles containsObject:fileName]) { + pdfFile = fileName; + } else { + unsigned int index = [[subfiles valueForKeyPath:@"pathExtension.lowercaseString"] indexOfObject:extension]; + if (index == NSNotFound) + pdfFile = [subfiles objectAtIndex:index]; + } + return pdfFile; +} + +@end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 18:11:46
|
Revision: 2862 http://skim-app.svn.sourceforge.net/skim-app/?rev=2862&view=rev Author: hofman Date: 2007-09-09 11:11:45 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Try to find the font from the FDF string. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 17:32:04 UTC (rev 2861) +++ trunk/SKFDFParser.m 2007-09-09 18:11:45 UTC (rev 2862) @@ -40,6 +40,7 @@ #import <Quartz/Quartz.h> #import "NSScanner_SKExtensions.h" #import "NSCharacterSet_SKExtensions.h" +#import "SKStringConstants.h" @interface SKFDFParser (SKPrivate) @@ -436,6 +437,31 @@ } else { success = NO; } + } else if ([key isEqualToString:@"DA"]) { + if (value = [self stringValue:value]) { + NSScanner *scanner = [NSScanner scannerWithString:value]; + NSString *fontName; + float fontSize; + if ([scanner scanUpToString:@"Tf" intoString:NULL] && [scanner isAtEnd] == NO) { + unsigned location = [scanner scanLocation]; + NSRange r = [value rangeOfString:@"/" options:NSBackwardsSearch range:NSMakeRange(0, location)]; + if (r.location != NSNotFound) { + [scanner setScanLocation:NSMaxRange(r)]; + if ([scanner scanCharactersFromSet:[NSCharacterSet nonWhitespaceAndNewlineCharacterSet] intoString:&fontName] && + [scanner scanFloat:&fontSize] && + [scanner scanString:@"Tf" intoString:NULL] && + [scanner scanLocation] == location + 2) { + NSFont *font = [NSFont fontWithName:fontName size:fontSize]; + if (font == nil) { + fontName = [[NSUserDefaults standardUserDefaults] stringForKey:SKTextNoteFontNameKey]; + font = [NSFont fontWithName:fontName size:fontSize]; + } + if (font) + [dictionary setObject:font forKey:@"font"]; + } + } + } + } } } return success ? dictionary : nil; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 17:32:05
|
Revision: 2861 http://skim-app.svn.sourceforge.net/skim-app/?rev=2861&view=rev Author: hofman Date: 2007-09-09 10:32:04 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Rewrite scanning to use a parser instance, so we don't need to pass the dictionary everywhere. Modified Paths: -------------- trunk/SKDocument.m trunk/SKFDFParser.h trunk/SKFDFParser.m Modified: trunk/SKDocument.m =================================================================== --- trunk/SKDocument.m 2007-09-09 16:54:30 UTC (rev 2860) +++ trunk/SKDocument.m 2007-09-09 17:32:04 UTC (rev 2861) @@ -684,7 +684,7 @@ } else { NSString *fdfString = [NSString stringWithContentsOfURL:notesURL encoding:NSISOLatin1StringEncoding error:NULL]; if (fdfString) - array = [SKFDFParser notesDictionariesFromFDFString:fdfString]; + array = [SKFDFParser noteDictionariesFromFDFString:fdfString]; } if (array) { Modified: trunk/SKFDFParser.h =================================================================== --- trunk/SKFDFParser.h 2007-09-09 16:54:30 UTC (rev 2860) +++ trunk/SKFDFParser.h 2007-09-09 17:32:04 UTC (rev 2861) @@ -39,7 +39,9 @@ #import <Cocoa/Cocoa.h> -@interface SKFDFParser : NSObject -+ (NSArray *)notesDictionariesFromFDFString:(NSString *)string; -+ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string; +@interface SKFDFParser : NSObject { + NSDictionary *fdfDictionary; + NSString *fdfString; +} ++ (NSArray *)noteDictionariesFromFDFString:(NSString *)string; @end Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 16:54:30 UTC (rev 2860) +++ trunk/SKFDFParser.m 2007-09-09 17:32:04 UTC (rev 2861) @@ -41,6 +41,20 @@ #import "NSScanner_SKExtensions.h" #import "NSCharacterSet_SKExtensions.h" + +@interface SKFDFParser (SKPrivate) +- (id)initWithString:(NSString *)aString; +- (BOOL)parseFDFString; +- (NSArray *)noteDictionaries; +- (NSDictionary *)noteDictionary:(NSDictionary *)dict; +- (id)value:(id)value ofClass:(Class)aClass; +- (NSString *)stringValue:(id)value; +- (NSNumber *)numberValue:(id)value; +- (NSArray *)arrayValue:(id)value; +- (NSDictionary *)dictionaryValue:(id)value; +@end + + @interface NSScanner (SKFDFParserExtensions) - (BOOL)scanFDFObject:(id *)object; - (BOOL)scanFDFArray:(NSArray **)array; @@ -70,13 +84,166 @@ @implementation SKFDFParser -+ (id)value:(id)value ofClass:(Class)aClass lookup:(NSDictionary *)lookup { ++ (NSArray *)noteDictionariesFromFDFString:(NSString *)string { + NSArray *notes = nil; + SKFDFParser *parser = [[self alloc] initWithString:string]; + + if ([parser parseFDFString]) + notes = [parser noteDictionaries]; + [parser release]; + + return notes; +} + +- (id)initWithString:(NSString *)string { + if (self = [super init]) { + fdfString = [string retain]; + fdfDictionary = nil; + } + return self; +} + +- (void)dealloc { + [fdfString release]; + [fdfDictionary release]; + [super dealloc]; +} + +- (BOOL)parseFDFString { + NSMutableDictionary *fdfDict = [[NSMutableDictionary alloc] init]; + + NSDictionary *dictionary; + int objNumber, genNumber; + id object; + BOOL success = YES; + + NSScanner *scanner = [[NSScanner alloc] initWithString:fdfString]; + + // Scan the FDF header + [scanner scanString:@"%FDF-1.2" intoString:NULL]; + while ([scanner scanFDFComment:NULL]); + + // Scan the FDF body + while (success && [scanner scanInt:&objNumber]) { + while ([scanner scanFDFComment:NULL]); + if (success = [scanner scanInt:&genNumber]) { + while ([scanner scanFDFComment:NULL]); + if ([scanner scanString:@"obj" intoString:NULL]) { + if (success = [scanner scanFDFObject:&object]) { + if ([object isKindOfClass:[NSDictionary class]]) { + while ([scanner scanFDFComment:NULL]); + if ([scanner scanString:@"stream" intoString:NULL]) { + object = @""; + [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; + + if ([scanner scanUpToString:@"endstream" intoString:&object]) { + int end = [object length]; + unichar ch = end ? [object characterAtIndex:end - 1] : 0; + if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { + end--; + if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') + end--; + object = [object substringToIndex:end]; + } + } + [scanner scanString:@"endstream" intoString:NULL]; + } + [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; + while ([scanner scanFDFComment:NULL]); + success = [scanner scanString:@"endobj" intoString:NULL]; + while ([scanner scanFDFComment:NULL]); + } + } + } + } + } + + // Scan the FDF cross reference table, if present + if (success) { + while ([scanner scanString:@"xref" intoString:NULL]) { + while ([scanner scanFDFComment:NULL]); + while ([scanner scanInt:NULL]) { + while ([scanner scanFDFComment:NULL]); + } + } + } + + // Scan the FDF trailer + if (success = success && [scanner scanString:@"trailer" intoString:NULL]) { + while ([scanner scanFDFComment:NULL]); + if (success = [scanner scanFDFDictionary:&dictionary]) { + while ([scanner scanFDFComment:NULL]); + [fdfDict setObject:dictionary forKey:@"trailer"]; + [scanner scanString:@"%%EOF" intoString:NULL]; + } + } + + [scanner release]; + + if (success) + fdfDictionary = fdfDict; + else + [fdfDict release]; + + return success; +} + +- (NSArray *)noteDictionaries { + NSMutableArray *array = nil; + NSDictionary *trailer; + SKIndirectObject *root; + NSDictionary *rootDict; + NSDictionary *fdfDict; + NSArray *annots; + + if ((trailer = [fdfDictionary objectForKey:@"trailer"]) && + ([trailer isKindOfClass:[NSDictionary class]]) && + (root = [trailer objectForKey:@"Root"]) && + ([root isKindOfClass:[SKIndirectObject class]]) && + (rootDict = [fdfDictionary objectForKey:root]) && + ([rootDict isKindOfClass:[NSDictionary class]]) && + (fdfDict = [rootDict objectForKey:@"FDF"]) && + ([fdfDict isKindOfClass:[NSDictionary class]]) && + (annots = [fdfDict objectForKey:@"Annots"]) && + ([annots isKindOfClass:[NSArray class]])) { + + NSEnumerator *annotEnum = [annots objectEnumerator]; + NSDictionary *dict; + + array = [NSMutableArray array]; + while (dict = [annotEnum nextObject]) { + if ((dict = [self dictionaryValue:dict]) && + (dict = [self noteDictionary:dict])) + [array addObject:dict]; + } + } + + return array; +} + +- (id)value:(id)value ofClass:(Class)aClass { while ([value isKindOfClass:[SKIndirectObject class]]) - value = [lookup objectForKey:value]; - return ([value isKindOfClass:aClass]) ? value : nil; + value = [fdfDictionary objectForKey:value]; + return (aClass == Nil || [value isKindOfClass:aClass]) ? value : nil; } -+ (NSDictionary *)noteDictionary:(NSDictionary *)dict lookup:(NSDictionary *)lookup { +- (NSString *)stringValue:(id)value { + return [self value:value ofClass:[NSString class]]; +} + +- (NSNumber *)numberValue:(id)value { + return [self value:value ofClass:[NSNumber class]]; +} + +- (NSArray *)arrayValue:(id)value { + return [self value:value ofClass:[NSArray class]]; +} + +- (NSDictionary *)dictionaryValue:(id)value { + return [self value:value ofClass:[NSDictionary class]]; +} + +- (NSDictionary *)noteDictionary:(NSDictionary *)dict { NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; NSSet *validTypes = [NSSet setWithObjects:@"FreeText", @"Note", @"Circle", @"Square", @"Highlight", @"Underline", @"StrikeOut", @"Line", nil]; NSEnumerator *keyEnum = [dict keyEnumerator]; @@ -87,7 +254,7 @@ id value = [dict valueForKey:key]; if ([key isEqualToString:@"Type"]) { - if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + if (value = [self stringValue:value]) { if ([value isEqualToString:@"Annot"] == NO) { success = NO; } @@ -95,7 +262,7 @@ success = NO; } } else if ([key isEqualToString:@"Subtype"]) { - if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + if (value = [self stringValue:value]) { if ([value isEqualToString:@"Text"]) value = @"Note"; if ([validTypes containsObject:value]) { @@ -107,17 +274,17 @@ success = NO; } } else if ([key isEqualToString:@"Contents"]) { - if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + if (value = [self stringValue:value]) { [dictionary setObject:value forKey:@"contents"]; } else { success = NO; } } else if ([key isEqualToString:@"Rect"]) { - if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 4) { - NSNumber *l = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *b = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *r = [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *t = [self value:[value objectAtIndex:3] ofClass:[NSNumber class] lookup:lookup]; + if ((value = [self arrayValue:value]) && [value count] == 4) { + NSNumber *l = [self numberValue:[value objectAtIndex:0]]; + NSNumber *b = [self numberValue:[value objectAtIndex:1]]; + NSNumber *r = [self numberValue:[value objectAtIndex:2]]; + NSNumber *t = [self numberValue:[value objectAtIndex:3]]; if (l && b && r && t) { NSRect rect; rect.origin.x = [l floatValue]; @@ -132,16 +299,16 @@ success = NO; } } else if ([key isEqualToString:@"Page"]) { - if (value = [self value:value ofClass:[NSNumber class] lookup:lookup]) { + if (value = [self numberValue:value]) { [dictionary setObject:value forKey:@"pageIndex"]; } else { success = NO; } } else if ([key isEqualToString:@"C"]) { - if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { - NSNumber *r = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *g = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *b = [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup]; + if ((value = [self arrayValue:value]) && [value count] == 3) { + NSNumber *r = [self numberValue:[value objectAtIndex:0]]; + NSNumber *g = [self numberValue:[value objectAtIndex:1]]; + NSNumber *b = [self numberValue:[value objectAtIndex:2]]; if (r && g && b) { [dictionary setObject:[NSColor colorWithCalibratedRed:[r floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0] forKey:@"color"]; } else { @@ -151,10 +318,10 @@ success = NO; } } else if ([key isEqualToString:@"BS"]) { - if (value = [self value:value ofClass:[NSDictionary class] lookup:lookup]) { - NSNumber *width = [self value:[value objectForKey:@"W"] ofClass:[NSNumber class] lookup:lookup]; - NSString *s = [self value:[value objectForKey:@"S"] ofClass:[NSString class] lookup:lookup]; - NSArray *dashPattern = [self value:[value objectForKey:@"D"] ofClass:[NSArray class] lookup:lookup]; + if (value = [self dictionaryValue:value]) { + NSNumber *width = [self numberValue:[value objectForKey:@"W"]]; + NSString *s = [self stringValue:[value objectForKey:@"S"]]; + NSArray *dashPattern = [self arrayValue:[value objectForKey:@"D"]]; int style = kPDFBorderStyleSolid; if ([s isEqualToString:@"S"]) style = kPDFBorderStyleSolid; @@ -180,8 +347,8 @@ success = NO; break; } - NSNumber *width = [value count] > 2 ? [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup] : nil; - NSArray *dashPattern = [value count] > 3 ? [self value:[value objectAtIndex:2] ofClass:[NSArray class] lookup:lookup] : nil; + NSNumber *width = [value count] > 2 ? [self numberValue:[value objectAtIndex:2]] : nil; + NSArray *dashPattern = [value count] > 3 ? [self arrayValue:[value objectAtIndex:2]] : nil; if (width && [width floatValue] > 0.0) { [dictionary setObject:width forKey:@"lineWidth"]; [dictionary setObject:[NSNumber numberWithInt:dashPattern ? kPDFBorderStyleDashed : kPDFBorderStyleSolid] forKey:@"borderStyle"]; @@ -189,7 +356,7 @@ [dictionary setObject:dashPattern forKey:@"dashPattern"]; } } else if ([key isEqualToString:@"Name"]) { - if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { + if (value = [self stringValue:value]) { int icon = kPDFTextAnnotationIconNote; if ([value isEqualToString:@"Comment"]) icon = kPDFTextAnnotationIconComment; @@ -208,10 +375,10 @@ success = NO; } } else if ([key isEqualToString:@"IC"]) { - if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { - NSNumber *r = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *g = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; - NSNumber *b = [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup]; + if ((value = [self arrayValue:value]) && [value count] == 3) { + NSNumber *r = [self numberValue:[value objectAtIndex:0]]; + NSNumber *g = [self numberValue:[value objectAtIndex:1]]; + NSNumber *b = [self numberValue:[value objectAtIndex:2]]; if (r && g && b) { [dictionary setObject:[NSColor colorWithCalibratedRed:[r floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0] forKey:@"interiorColor"]; } else { @@ -221,9 +388,9 @@ success = NO; } } else if ([key isEqualToString:@"LE"]) { - if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 2) { - NSString *start = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; - NSString *end = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; + if ((value = [self arrayValue:value]) && [value count] == 2) { + NSString *start = [self stringValue:[value objectAtIndex:0]]; + NSString *end = [self stringValue:[value objectAtIndex:1]]; int startStyle = kPDFLineStyleNone; int endStyle = kPDFLineStyleNone; if ([start isEqualToString:@"None"]) @@ -256,7 +423,7 @@ success = NO; } } else if ([key isEqualToString:@"QuadPoints"]) { - if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] % 8 == 0) { + if ((value = [self arrayValue:value]) && [value count] % 8 == 0) { NSMutableArray *quadPoints = [NSMutableArray array]; int i, count = [value count]; for (i = 0; i < count; i++) { @@ -274,116 +441,6 @@ return success ? dictionary : nil; } -+ (NSArray *)notesDictionariesFromFDFString:(NSString *)string { - NSMutableArray *array = nil; - NSDictionary *fdfDict; - NSDictionary *trailer; - SKIndirectObject *root; - NSDictionary *rootDict; - NSDictionary *rootFDFDict; - NSArray *annots; - - if ((fdfDict = [self fdfObjectsFromFDFString:string]) && - (trailer = [fdfDict objectForKey:@"trailer"]) && - ([trailer isKindOfClass:[NSDictionary class]]) && - (root = [trailer objectForKey:@"Root"]) && - ([root isKindOfClass:[SKIndirectObject class]]) && - (rootDict = [fdfDict objectForKey:root]) && - ([rootDict isKindOfClass:[NSDictionary class]]) && - (rootFDFDict = [rootDict objectForKey:@"FDF"]) && - ([rootFDFDict isKindOfClass:[NSDictionary class]]) && - (annots = [rootFDFDict objectForKey:@"Annots"]) && - ([annots isKindOfClass:[NSArray class]])) { - - NSEnumerator *annotEnum = [annots objectEnumerator]; - NSDictionary *dict; - - array = [NSMutableArray array]; - while (dict = [annotEnum nextObject]) { - while ([dict isKindOfClass:[SKIndirectObject class]]) - dict = [fdfDict objectForKey:dict]; - if ([dict isKindOfClass:[NSDictionary class]] == NO) - return nil; - if (dict = [self noteDictionary:dict lookup:fdfDict]) - [array addObject:dict]; - } - } - - return array; -} - -+ (NSDictionary *)fdfObjectsFromFDFString:(NSString *)string { - NSMutableDictionary *fdfDict = [NSMutableDictionary dictionary]; - - NSDictionary *dictionary; - int objNumber, genNumber; - id object; - BOOL success = YES; - - NSScanner *scanner = [NSScanner scannerWithString:string]; - - // Scan the FDF header - [scanner scanString:@"%FDF-1.2" intoString:NULL]; - while ([scanner scanFDFComment:NULL]); - - // Scan the FDF body - while (success && [scanner scanInt:&objNumber]) { - while ([scanner scanFDFComment:NULL]); - if (success = [scanner scanInt:&genNumber]) { - while ([scanner scanFDFComment:NULL]); - if ([scanner scanString:@"obj" intoString:NULL]) { - if (success = [scanner scanFDFObject:&object]) { - if ([object isKindOfClass:[NSDictionary class]]) { - while ([scanner scanFDFComment:NULL]); - if ([scanner scanString:@"stream" intoString:NULL]) { - object = @""; - [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; - - if ([scanner scanUpToString:@"endstream" intoString:&object]) { - int end = [object length]; - unichar ch = end ? [object characterAtIndex:end - 1] : 0; - if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { - end--; - if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') - end--; - object = [object substringToIndex:end]; - } - } - [scanner scanString:@"endstream" intoString:NULL]; - } - [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; - while ([scanner scanFDFComment:NULL]); - success = [scanner scanString:@"endobj" intoString:NULL]; - while ([scanner scanFDFComment:NULL]); - } - } - } - } - } - - // Scan the FDF cross reference table, if present - if (success) { - while ([scanner scanString:@"xref" intoString:NULL]) { - while ([scanner scanFDFComment:NULL]); - while ([scanner scanInt:NULL]) { - while ([scanner scanFDFComment:NULL]); - } - } - } - - // Scan the FDF trailer - if (success = success && [scanner scanString:@"trailer" intoString:NULL]) { - while ([scanner scanFDFComment:NULL]); - if (success = [scanner scanFDFDictionary:&dictionary]) { - while ([scanner scanFDFComment:NULL]); - [fdfDict setObject:dictionary forKey:@"trailer"]; - [scanner scanString:@"%%EOF" intoString:NULL]; - } - } - - return success ? fdfDict : nil; -} - @end #pragma mark - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 16:54:33
|
Revision: 2860 http://skim-app.svn.sourceforge.net/skim-app/?rev=2860&view=rev Author: hofman Date: 2007-09-09 09:54:30 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Skip whitespace and newline in FDF parsing, except for strings and names. Scan booleans. Scan and ignore comments. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 14:31:30 UTC (rev 2859) +++ trunk/SKFDFParser.m 2007-09-09 16:54:30 UTC (rev 2860) @@ -49,7 +49,9 @@ - (BOOL)scanFDFHexString:(NSString **)string; - (BOOL)scanFDFName:(NSString **)string; - (BOOL)scanFDFNumber:(NSNumber **)number; +- (BOOL)scanFDFBoolean:(id *)boolNumber; - (BOOL)scanFDFIndirectObject:(id *)object; +- (BOOL)scanFDFComment:(NSString **)comment; @end #pragma mark - @@ -320,67 +322,63 @@ NSScanner *scanner = [NSScanner scannerWithString:string]; - [scanner setCharactersToBeSkipped:nil]; - // Scan the FDF header [scanner scanString:@"%FDF-1.2" intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - if ([scanner scanString:@"%" intoString:NULL]) - [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + while ([scanner scanFDFComment:NULL]); // Scan the FDF body while (success && [scanner scanInt:&objNumber]) { - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + while ([scanner scanFDFComment:NULL]); if (success = [scanner scanInt:&genNumber]) { - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL]; + while ([scanner scanFDFComment:NULL]); if ([scanner scanString:@"obj" intoString:NULL]) { - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; if (success = [scanner scanFDFObject:&object]) { - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - - if ([object isKindOfClass:[NSDictionary class]] && [scanner scanString:@"stream" intoString:NULL]) { - object = @""; - [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; - - if ([scanner scanUpToString:@"endstream" intoString:&object]) { - int end = [object length]; - unichar ch = end ? [object characterAtIndex:end - 1] : 0; - if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { - end--; - if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') + if ([object isKindOfClass:[NSDictionary class]]) { + while ([scanner scanFDFComment:NULL]); + if ([scanner scanString:@"stream" intoString:NULL]) { + object = @""; + [scanner scanString:@"\n" intoString:NULL] || [scanner scanString:@"\r\n" intoString:NULL]; + + if ([scanner scanUpToString:@"endstream" intoString:&object]) { + int end = [object length]; + unichar ch = end ? [object characterAtIndex:end - 1] : 0; + if ([[NSCharacterSet newlineCharacterSet] characterIsMember:ch]) { end--; - object = [object substringToIndex:end]; + if (end && ch == '\n' && [object characterAtIndex:end - 1] == '\r') + end--; + object = [object substringToIndex:end]; + } } + [scanner scanString:@"endstream" intoString:NULL]; } - [scanner scanString:@"endstream" intoString:NULL]; + [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; + while ([scanner scanFDFComment:NULL]); + success = [scanner scanString:@"endobj" intoString:NULL]; + while ([scanner scanFDFComment:NULL]); } - [fdfDict setObject:object forKey:[SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - success = [scanner scanString:@"endobj" intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; } } } } // Scan the FDF cross reference table, if present - while (success && [scanner scanString:@"xref" intoString:NULL]) { - [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - while ([scanner scanInt:NULL]) { - [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:NULL]; - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; + if (success) { + while ([scanner scanString:@"xref" intoString:NULL]) { + while ([scanner scanFDFComment:NULL]); + while ([scanner scanInt:NULL]) { + while ([scanner scanFDFComment:NULL]); + } } } // Scan the FDF trailer if (success = success && [scanner scanString:@"trailer" intoString:NULL]) { - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL]; - if (success = [scanner scanFDFDictionary:&dictionary] && - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:NULL] && - [scanner scanString:@"%%EOF" intoString:NULL]) + while ([scanner scanFDFComment:NULL]); + if (success = [scanner scanFDFDictionary:&dictionary]) { + while ([scanner scanFDFComment:NULL]); [fdfDict setObject:dictionary forKey:@"trailer"]; + [scanner scanString:@"%%EOF" intoString:NULL]; + } } return success ? fdfDict : nil; @@ -394,15 +392,20 @@ - (BOOL)scanFDFObject:(id *)object { id tmpObject = nil; - BOOL success = [self scanFDFName:&tmpObject] || - [self scanFDFArray:&tmpObject] || - [self scanFDFDictionary:&tmpObject] || - [self scanFDFString:&tmpObject] || - [self scanFDFHexString:&tmpObject] || - [self scanFDFIndirectObject:&tmpObject] || - [self scanFDFNumber:&tmpObject] || - [self scanString:@"null" intoString:NULL]; + BOOL success = YES; + do { + success = [self scanFDFName:&tmpObject] || + [self scanFDFArray:&tmpObject] || + [self scanFDFDictionary:&tmpObject] || + [self scanFDFString:&tmpObject] || + [self scanFDFHexString:&tmpObject] || + [self scanFDFIndirectObject:&tmpObject] || + [self scanFDFNumber:&tmpObject] || + [self scanFDFBoolean:&tmpObject] || + [self scanString:@"null" intoString:NULL]; + } while (success == NO && [self isAtEnd] == NO && [self scanFDFComment:NULL]); + if (success && object) *object = tmpObject; @@ -474,55 +477,63 @@ NSMutableString *tmpString = [NSMutableString string]; NSString *s; unichar ch; - BOOL success = [self scanString:@"(" intoString:NULL]; + BOOL success; - while (success) { - if ([self scanUpToCharactersFromSet:specialCharSet intoString:&s]) - [tmpString appendString:s]; - if ([self scanCharacter:&ch]) { - if (ch == ')') { - break; - } else if (ch == '\\') { - if ([self scanCharacter:&ch]) { - if (ch == 'n') { - [tmpString appendString:@"\n"]; - } else if (ch == 'r') { - [tmpString appendString:@"\r"]; - } else if (ch == 't') { - [tmpString appendString:@"\r"]; - } else if (ch == 'b') { - [tmpString appendString:@"\b"]; - } else if (ch == 'f') { - [tmpString appendString:@"\f"]; - } else if (ch == '(') { - [tmpString appendString:@"("]; - } else if (ch == ')') { - [tmpString appendString:@")"]; - } else if (ch == '\\') { - [tmpString appendString:@"\\"]; - } else if ([octalCharSet characterIsMember:ch]) { - char octal = ch; - if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { - [self scanCharacter:NULL]; - octal = 8 * octal + ch; + if (success = [self scanString:@"(" intoString:NULL]) { + NSCharacterSet *skipChars = [[self charactersToBeSkipped] retain]; + [self setCharactersToBeSkipped:nil]; + + while (success) { + if ([self scanUpToCharactersFromSet:specialCharSet intoString:&s]) + [tmpString appendString:s]; + if ([self scanCharacter:&ch]) { + if (ch == ')') { + break; + } else if (ch == '\\') { + if ([self scanCharacter:&ch]) { + if (ch == 'n') { + [tmpString appendString:@"\n"]; + } else if (ch == 'r') { + [tmpString appendString:@"\r"]; + } else if (ch == 't') { + [tmpString appendString:@"\r"]; + } else if (ch == 'b') { + [tmpString appendString:@"\b"]; + } else if (ch == 'f') { + [tmpString appendString:@"\f"]; + } else if (ch == '(') { + [tmpString appendString:@"("]; + } else if (ch == ')') { + [tmpString appendString:@")"]; + } else if (ch == '\\') { + [tmpString appendString:@"\\"]; + } else if ([octalCharSet characterIsMember:ch]) { + char octal = ch; if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { [self scanCharacter:NULL]; octal = 8 * octal + ch; + if ([self peekCharacter:&ch] && [octalCharSet characterIsMember:ch]) { + [self scanCharacter:NULL]; + octal = 8 * octal + ch; + } } - } - NSString *s = [[NSString alloc] initWithBytes:&octal length:1 encoding:NSISOLatin1StringEncoding]; - if (success = s != nil) - [tmpString appendString:s]; - [s release]; - } else + NSString *s = [[NSString alloc] initWithBytes:&octal length:1 encoding:NSISOLatin1StringEncoding]; + if (success = s != nil) + [tmpString appendString:s]; + [s release]; + } else + success = NO; + } else { success = NO; - } else { - success = NO; + } } + } else { + success = NO; } - } else { - success = NO; } + + [self setCharactersToBeSkipped:skipChars]; + [skipChars release]; } if (success && string) @@ -603,7 +614,18 @@ whitespaceOrDelimiterCharSet = [tmpSet copy]; [tmpSet release]; } - return [self scanString:@"/" intoString:NULL] && [self scanUpToCharactersFromSet:whitespaceOrDelimiterCharSet intoString:string]; + + BOOL success; + + if (success = [self scanString:@"/" intoString:NULL]) { + NSCharacterSet *skipChars = [[self charactersToBeSkipped] retain]; + [self setCharactersToBeSkipped:nil]; + success = [self scanUpToCharactersFromSet:whitespaceOrDelimiterCharSet intoString:string]; + [self setCharactersToBeSkipped:skipChars]; + [skipChars release]; + } + + return success; } - (BOOL)scanFDFNumber:(NSNumber **)number { @@ -616,19 +638,32 @@ return success; } +- (BOOL)scanFDFBoolean:(id *)boolNumber { + NSNumber *tmpBoolNumber = nil; + BOOL success; + + if (success = [self scanString:@"true" intoString:NULL]) + tmpBoolNumber = [NSNumber numberWithBool:YES]; + else if (success = [self scanString:@"false" intoString:NULL]) + tmpBoolNumber = [NSNumber numberWithBool:NO]; + + if (success && boolNumber) + *boolNumber = tmpBoolNumber; + + return success; +} + - (BOOL)scanFDFIndirectObject:(id *)object { int rewindLoc = [self scanLocation]; id tmpObject; int objNumber, genNumber; BOOL success; - if (success = [self scanInt:&objNumber] && [self scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL] && - [self scanInt:&genNumber] && [self scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL] && - [self scanString:@"R" intoString:NULL]) + if (success = [self scanInt:&objNumber] && [self scanInt:&genNumber] && [self scanString:@"R" intoString:NULL]) { tmpObject = [SKIndirectObject indirectObjectWithNumber:objNumber generation:genNumber]; - - if (success == NO) + } else { [self setScanLocation:rewindLoc]; + } if (success && object) *object = tmpObject; @@ -636,6 +671,24 @@ return success; } +- (BOOL)scanFDFComment:(NSString **)comment { + NSString *tmpComment = @""; + BOOL success; + + if (success = [self scanString:@"%" intoString:NULL]) { + NSCharacterSet *skipChars = [[self charactersToBeSkipped] retain]; + [self setCharactersToBeSkipped:[NSCharacterSet whitespaceCharacterSet]]; + [self scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] intoString:&tmpComment]; + [self setCharactersToBeSkipped:skipChars]; + [skipChars release]; + } + + if (success && comment) + *comment = tmpComment; + + return success; +} + @end #pragma mark - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 14:31:31
|
Revision: 2859 http://skim-app.svn.sourceforge.net/skim-app/?rev=2859&view=rev Author: hofman Date: 2007-09-09 07:31:30 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Fix more parsing bugs in FDF parser. Modified Paths: -------------- trunk/SKFDFParser.m Modified: trunk/SKFDFParser.m =================================================================== --- trunk/SKFDFParser.m 2007-09-09 14:11:13 UTC (rev 2858) +++ trunk/SKFDFParser.m 2007-09-09 14:31:30 UTC (rev 2859) @@ -86,8 +86,9 @@ if ([key isEqualToString:@"Type"]) { if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { - if ([value isEqualToString:@"Annot"] == NO) + if ([value isEqualToString:@"Annot"] == NO) { success = NO; + } } else { success = NO; } @@ -95,62 +96,64 @@ if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { if ([value isEqualToString:@"Text"]) value = @"Note"; - if ([validTypes containsObject:value]) + if ([validTypes containsObject:value]) { [dictionary setObject:value forKey:@"type"]; - else + } else { success = NO; + } } else { success = NO; } } else if ([key isEqualToString:@"Contents"]) { - if (value = [self value:value ofClass:[NSString class] lookup:lookup]) + if (value = [self value:value ofClass:[NSString class] lookup:lookup]) { [dictionary setObject:value forKey:@"contents"]; - else + } else { success = NO; + } } else if ([key isEqualToString:@"Rect"]) { if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 4) { - NSRect rect; - rect.origin.x = [[value objectAtIndex:0] floatValue]; - rect.origin.y = [[value objectAtIndex:1] floatValue]; - rect.size.width = [[value objectAtIndex:2] floatValue] - NSMinX(rect); - rect.size.height = [[value objectAtIndex:3] floatValue] - NSMinY(rect); - [dictionary setObject:NSStringFromRect(rect) forKey:@"bounds"]; + NSNumber *l = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *b = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *r = [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *t = [self value:[value objectAtIndex:3] ofClass:[NSNumber class] lookup:lookup]; + if (l && b && r && t) { + NSRect rect; + rect.origin.x = [l floatValue]; + rect.origin.y = [b floatValue]; + rect.size.width = [r floatValue] - NSMinX(rect); + rect.size.height = [t floatValue] - NSMinY(rect); + [dictionary setObject:NSStringFromRect(rect) forKey:@"bounds"]; + } else { + success = NO; + } } else { success = NO; } } else if ([key isEqualToString:@"Page"]) { - if (value = [self value:value ofClass:[NSNumber class] lookup:lookup]) + if (value = [self value:value ofClass:[NSNumber class] lookup:lookup]) { [dictionary setObject:value forKey:@"pageIndex"]; - else{ - success = NO;} + } else { + success = NO; + } } else if ([key isEqualToString:@"C"]) { if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { - float r, g, b; - r = [[value objectAtIndex:0] floatValue]; - g = [[value objectAtIndex:1] floatValue]; - b = [[value objectAtIndex:2] floatValue]; - [dictionary setObject:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0] forKey:@"color"]; + NSNumber *r = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *g = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *b = [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup]; + if (r && g && b) { + [dictionary setObject:[NSColor colorWithCalibratedRed:[r floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0] forKey:@"color"]; + } else { + success = NO; + } } else { success = NO; } } else if ([key isEqualToString:@"BS"]) { if (value = [self value:value ofClass:[NSDictionary class] lookup:lookup]) { - NSNumber *width = [value objectForKey:@"W"]; - NSString *s = [value objectForKey:@"S"]; - NSArray *dashPattern = [value objectForKey:@"D"]; + NSNumber *width = [self value:[value objectForKey:@"W"] ofClass:[NSNumber class] lookup:lookup]; + NSString *s = [self value:[value objectForKey:@"S"] ofClass:[NSString class] lookup:lookup]; + NSArray *dashPattern = [self value:[value objectForKey:@"D"] ofClass:[NSArray class] lookup:lookup]; int style = kPDFBorderStyleSolid; - if (s && [s isKindOfClass:[NSString class]]) { - success = NO; - break; - } - if (dashPattern && [dashPattern isKindOfClass:[NSArray class]] == NO) { - success = NO; - break; - } - if (width && [width isKindOfClass:[NSNumber class]] == NO) { - success = NO; - break; - } if ([s isEqualToString:@"S"]) style = kPDFBorderStyleSolid; else if ([s isEqualToString:@"D"]) @@ -175,16 +178,8 @@ success = NO; break; } - NSNumber *width = [value count] > 2 ? [value objectAtIndex:2] : nil; - NSArray *dashPattern = [value count] > 3 ? [value objectAtIndex:3] : nil; - if (dashPattern && [dashPattern isKindOfClass:[NSArray class]] == NO) { - success = NO; - break; - } - if (width && [width isKindOfClass:[NSNumber class]] == NO) { - success = NO; - break; - } + NSNumber *width = [value count] > 2 ? [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup] : nil; + NSArray *dashPattern = [value count] > 3 ? [self value:[value objectAtIndex:2] ofClass:[NSArray class] lookup:lookup] : nil; if (width && [width floatValue] > 0.0) { [dictionary setObject:width forKey:@"lineWidth"]; [dictionary setObject:[NSNumber numberWithInt:dashPattern ? kPDFBorderStyleDashed : kPDFBorderStyleSolid] forKey:@"borderStyle"]; @@ -212,40 +207,47 @@ } } else if ([key isEqualToString:@"IC"]) { if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 3) { - float r, g, b; - r = [[value objectAtIndex:0] floatValue]; - g = [[value objectAtIndex:1] floatValue]; - b = [[value objectAtIndex:2] floatValue]; - [dictionary setObject:[NSColor colorWithCalibratedRed:r green:g blue:b alpha:1.0] forKey:@"interiorColor"]; + NSNumber *r = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *g = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; + NSNumber *b = [self value:[value objectAtIndex:2] ofClass:[NSNumber class] lookup:lookup]; + if (r && g && b) { + [dictionary setObject:[NSColor colorWithCalibratedRed:[r floatValue] green:[g floatValue] blue:[b floatValue] alpha:1.0] forKey:@"interiorColor"]; + } else { + success = NO; + } } else { success = NO; } } else if ([key isEqualToString:@"LE"]) { if ((value = [self value:value ofClass:[NSArray class] lookup:lookup]) && [value count] == 2) { - NSString *start = [value objectAtIndex:0]; - NSString *end = [value objectAtIndex:1]; + NSString *start = [self value:[value objectAtIndex:0] ofClass:[NSNumber class] lookup:lookup]; + NSString *end = [self value:[value objectAtIndex:1] ofClass:[NSNumber class] lookup:lookup]; int startStyle = kPDFLineStyleNone; int endStyle = kPDFLineStyleNone; - if (start && [start isKindOfClass:[NSNumber class]] == NO) { - success = NO; - break; - } - if (end && [end isKindOfClass:[NSNumber class]] == NO) { - success = NO; - break; - } + if ([start isEqualToString:@"None"]) + startStyle = kPDFLineStyleNone; + else if ([start isEqualToString:@"Square"]) + startStyle = kPDFLineStyleSquare; + else if ([start isEqualToString:@"Circle"]) + startStyle = kPDFLineStyleCircle; + else if ([start isEqualToString:@"Diamond"]) + startStyle = kPDFLineStyleDiamond; + else if ([start isEqualToString:@"OpenArrow"]) + startStyle = kPDFLineStyleOpenArrow; + else if ([start isEqualToString:@"ClosedArrow"]) + startStyle = kPDFLineStyleClosedArrow; if ([end isEqualToString:@"None"]) startStyle = kPDFLineStyleNone; else if ([end isEqualToString:@"Square"]) - startStyle = kPDFLineStyleSquare; + endStyle = kPDFLineStyleSquare; else if ([end isEqualToString:@"Circle"]) - startStyle = kPDFLineStyleCircle; + endStyle = kPDFLineStyleCircle; else if ([end isEqualToString:@"Diamond"]) - startStyle = kPDFLineStyleDiamond; + endStyle = kPDFLineStyleDiamond; else if ([end isEqualToString:@"OpenArrow"]) - startStyle = kPDFLineStyleOpenArrow; + endStyle = kPDFLineStyleOpenArrow; else if ([end isEqualToString:@"ClosedArrow"]) - startStyle = kPDFLineStyleClosedArrow; + endStyle = kPDFLineStyleClosedArrow; [dictionary setObject:[NSNumber numberWithInt:startStyle] forKey:@"startLineStyle"]; [dictionary setObject:[NSNumber numberWithInt:endStyle] forKey:@"endLineStyle"]; } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 14:11:14
|
Revision: 2858 http://skim-app.svn.sourceforge.net/skim-app/?rev=2858&view=rev Author: hofman Date: 2007-09-09 07:11:13 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Don't append nil string. Modified Paths: -------------- trunk/SKPDFAnnotationNote.m Modified: trunk/SKPDFAnnotationNote.m =================================================================== --- trunk/SKPDFAnnotationNote.m 2007-09-09 14:02:24 UTC (rev 2857) +++ trunk/SKPDFAnnotationNote.m 2007-09-09 14:11:13 UTC (rev 2858) @@ -232,7 +232,7 @@ [string appendString:@"/Type/Annot/Subtype/"]; [string appendString:[[self type] isEqualToString:@"Note"] ? @"Text" : [self type]]; [string appendString:@"/Contents("]; - [string appendString:[[self contents] stringByEscapingParenthesis]]; + [string appendString:[self contents] ? [[self contents] stringByEscapingParenthesis] : @""]; if ([self text]) { [string appendString:@"\n"]; [string appendString:[[[self text] string] stringByEscapingParenthesis]]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ho...@us...> - 2007-09-09 14:02:26
|
Revision: 2857 http://skim-app.svn.sourceforge.net/skim-app/?rev=2857&view=rev Author: hofman Date: 2007-09-09 07:02:24 -0700 (Sun, 09 Sep 2007) Log Message: ----------- Don't let reloading the outline change the current page. Modified Paths: -------------- trunk/SKMainWindowController.m Modified: trunk/SKMainWindowController.m =================================================================== --- trunk/SKMainWindowController.m 2007-09-09 13:26:40 UTC (rev 2856) +++ trunk/SKMainWindowController.m 2007-09-09 14:02:24 UTC (rev 2857) @@ -776,10 +776,11 @@ pdfOutline = [[pdfDoc outlineRoot] retain]; [pdfOutlineItems removeAllObjects]; if (pdfOutline) { + updatingOutlineSelection = YES; [outlineView reloadData]; - if ([outlineView numberOfRows] == 1) [outlineView expandItem: [outlineView itemAtRow: 0] expandChildren: NO]; + updatingOutlineSelection = NO; [self updateOutlineSelection]; } [leftSideButton setEnabled:pdfOutline != nil forSegment:SKOutlineSidePaneState]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |