Revision: 15285
          http://bibdesk.svn.sourceforge.net/bibdesk/?rev=15285&view=rev
Author:   amaxwell
Date:     2009-05-07 23:45:07 +0000 (Thu, 07 May 2009)

Log Message:
-----------
Ensure a non-nil attributed string before creating an image, so
the error message can be displayed.  Minor refactoring so the
error string is only created in one place, and assert a non-nil
string parameter in image creation methods.

Modified Paths:
--------------
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVCoreTextIcon.m
    trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVCoreTextIcon.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVCoreTextIcon.m  2009-05-07 
13:55:35 UTC (rev 15284)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVCoreTextIcon.m  2009-05-07 
23:45:07 UTC (rev 15285)
@@ -44,6 +44,7 @@
 
 - (CGImageRef)_newImageWithAttributedString:(NSMutableAttributedString 
*)attrString documentAttributes:(NSDictionary *)documentAttributes
 {
+    NSParameterAssert(attrString);
     CFMutableAttributedStringRef cfAttrString = 
(CFMutableAttributedStringRef)attrString;
     
     // set up page layout parameters
@@ -86,14 +87,6 @@
         [nsColor getRed:&backgroundComps[0] green:&backgroundComps[1] 
blue:&backgroundComps[2] alpha:&backgroundComps[3]];
     }
     
-    if (NULL == cfAttrString) {
-        // display a mildly unhelpful error message
-        NSBundle *bundle = [NSBundle bundleForClass:[FVCoreTextIcon class]];
-        
-        NSString *err = [NSLocalizedStringFromTableInBundle(@"Unable to read 
text file ", @"FileView", bundle, @"error message with single trailing space") 
stringByAppendingString:[_fileURL path]];
-        cfAttrString = 
(CFMutableAttributedStringRef)[[[NSMutableAttributedString alloc] 
initWithString:err] autorelease];
-    }  
-    
     CGContextSetTextMatrix(ctxt, CGAffineTransformIdentity);
     CGContextSetRGBFillColor(ctxt, backgroundComps[0], backgroundComps[1], 
backgroundComps[2], backgroundComps[3]);
     CGContextFillRect(ctxt, paperRect);
@@ -107,7 +100,9 @@
     CFRelease(framesetter);
     
     /*
-     NSGraphicsContext is required for NSColor attributes.  See 
http://lists.apple.com/archives/Quartz-dev/2008/Jun/msg00043.html  
Unfortunately, colored underlines apparently aren't supported by CT; 
CTStringAttributes.h says that the color of those attributes is taken from the 
foreground text color, which is kind of lame.  Strikethrough apparently isn't 
supported at all.
+     NSGraphicsContext is required for NSColor attributes.  See 
http://lists.apple.com/archives/Quartz-dev/2008/Jun/msg00043.html  
+     Unfortunately, colored underlines apparently aren't supported by CT; 
CTStringAttributes.h says that the color of those 
+     attributes is taken from the foreground text color, which is kind of 
lame.  Strikethrough apparently isn't supported at all.
      */
     [NSGraphicsContext saveGraphicsState];
     [NSGraphicsContext setCurrentContext:[NSGraphicsContext 
graphicsContextWithGraphicsPort:ctxt flipped:NO]];

Modified: trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m
===================================================================
--- trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m      2009-05-07 
13:55:35 UTC (rev 15284)
+++ trunk/bibdesk_vendorsrc/amaxwell/FileView/FVTextIcon.m      2009-05-07 
23:45:07 UTC (rev 15285)
@@ -69,10 +69,7 @@
 {
     FVINITIALIZE(FVTextIcon);
     
-    FVAPIParameterAssert(pthread_main_np() != 0);
-    
     FVTextIconClass = self;
-    
     // make sure we compare with pointer equality; all I really want is a bag
     _cachedTextSystems = (NSMutableSet *)CFSetCreateMutable(NULL, 
MAX_CACHED_TEXT_SYSTEMS, &FVNSObjectPointerSetCallBacks);
 }
@@ -320,8 +317,8 @@
 
 - (CGImageRef)_newImageWithAttributedString:(NSMutableAttributedString 
*)attrString documentAttributes:(NSDictionary *)documentAttributes
 {
+    NSParameterAssert(attrString);
     FVBitmapContextRef ctxt = 
FVIconBitmapContextCreateWithSize(FVDefaultPaperSize.width, 
FVDefaultPaperSize.height);    
-    NSTextStorage *textStorage = [FVTextIcon popTextStorage];
 
     // set up default page layout parameters
     CGAffineTransform t1 = CGAffineTransformMakeTranslation(FVSideMargin, 
FVDefaultPaperSize.height - FVTopMargin);
@@ -334,48 +331,33 @@
     CGFloat backgroundComps[4] = { 1.0, 1.0, 1.0, 1.0 };
 
     // use a monospaced font for plain text
-    if (nil != attrString) {
-        if (nil == documentAttributes || [[documentAttributes 
objectForKey:NSDocumentTypeDocumentAttribute] 
isEqualToString:NSPlainTextDocumentType]) {
-            NSFont *plainFont = [NSFont userFixedPitchFontOfSize:10.0f];
-            [attrString addAttribute:NSFontAttributeName value:plainFont 
range:NSMakeRange(0, [attrString length])];
-        }
-        else if (nil != documentAttributes) {
-            
-            CGFloat left, right, top, bottom;
-            
-            left = [[documentAttributes 
objectForKey:NSLeftMarginDocumentAttribute] floatValue];
-            right = [[documentAttributes 
objectForKey:NSRightMarginDocumentAttribute] floatValue];
-            top = [[documentAttributes 
objectForKey:NSTopMarginDocumentAttribute] floatValue];
-            bottom = [[documentAttributes 
objectForKey:NSBottomMarginDocumentAttribute] floatValue];
-            paperSize = [[documentAttributes 
objectForKey:NSPaperSizeDocumentAttribute] sizeValue];
-            
-            t1 = CGAffineTransformMakeTranslation(0, paperSize.height);
-            t2 = CGAffineTransformMakeScale(1, -1);
-            pageTransform = CGAffineTransformConcat(t2, t1);
-            t1 = CGAffineTransformMakeTranslation(left, -bottom);
-            pageTransform = CGAffineTransformConcat(pageTransform, t1);
-            containerSize.width = paperSize.width - left - right;
-            containerSize.height = paperSize.height - top - bottom;
-            
-            NSColor *nsColor = [documentAttributes 
objectForKey:NSBackgroundColorDocumentAttribute];
-            nsColor = [nsColor 
colorUsingColorSpaceName:NSDeviceRGBColorSpace];  
-            [nsColor getRed:&backgroundComps[0] green:&backgroundComps[1] 
blue:&backgroundComps[2] alpha:&backgroundComps[3]];
-        }
+    if (nil == documentAttributes || [[documentAttributes 
objectForKey:NSDocumentTypeDocumentAttribute] 
isEqualToString:NSPlainTextDocumentType]) {
+        NSFont *plainFont = [NSFont userFixedPitchFontOfSize:10.0f];
+        [attrString addAttribute:NSFontAttributeName value:plainFont 
range:NSMakeRange(0, [attrString length])];
     }
-    
-    [textStorage beginEditing];
-    if (attrString) {
-        [textStorage setAttributedString:attrString];
+    else if (nil != documentAttributes) {
+        
+        CGFloat left, right, top, bottom;
+        
+        left = [[documentAttributes 
objectForKey:NSLeftMarginDocumentAttribute] floatValue];
+        right = [[documentAttributes 
objectForKey:NSRightMarginDocumentAttribute] floatValue];
+        top = [[documentAttributes objectForKey:NSTopMarginDocumentAttribute] 
floatValue];
+        bottom = [[documentAttributes 
objectForKey:NSBottomMarginDocumentAttribute] floatValue];
+        paperSize = [[documentAttributes 
objectForKey:NSPaperSizeDocumentAttribute] sizeValue];
+        
+        t1 = CGAffineTransformMakeTranslation(0, paperSize.height);
+        t2 = CGAffineTransformMakeScale(1, -1);
+        pageTransform = CGAffineTransformConcat(t2, t1);
+        t1 = CGAffineTransformMakeTranslation(left, -bottom);
+        pageTransform = CGAffineTransformConcat(pageTransform, t1);
+        containerSize.width = paperSize.width - left - right;
+        containerSize.height = paperSize.height - top - bottom;
+        
+        NSColor *nsColor = [documentAttributes 
objectForKey:NSBackgroundColorDocumentAttribute];
+        nsColor = [nsColor colorUsingColorSpaceName:NSDeviceRGBColorSpace];  
+        [nsColor getRed:&backgroundComps[0] green:&backgroundComps[1] 
blue:&backgroundComps[2] alpha:&backgroundComps[3]];
     }
-    else {
-        // avoid setting the text storage to nil, and display a mildly 
unhelpful error message
-        NSBundle *bundle = [NSBundle bundleForClass:[FVTextIcon class]];
         
-        NSString *err = [NSLocalizedStringFromTableInBundle(@"Unable to read 
text file ", @"FileView", bundle, @"error message with single trailing space") 
stringByAppendingString:[_fileURL path]];
-        [[textStorage mutableString] setString:err];
-    }  
-    [textStorage endEditing];
-    
     NSRect stringRect = NSZeroRect;
     stringRect.size = paperSize;
     
@@ -393,15 +375,16 @@
     [NSGraphicsContext saveGraphicsState];
     [NSGraphicsContext setCurrentContext:nsCtxt];
     
+    NSTextStorage *textStorage = [FVTextIcon popTextStorage];
+    [textStorage setAttributedString:attrString];
+    
     // objectAtIndex:0 is safe, since we added these to the text storage (so 
there's at least one)
     NSLayoutManager *lm = [[textStorage layoutManagers] objectAtIndex:0];
     NSTextContainer *tc = [[lm textContainers] objectAtIndex:0];
     [tc setContainerSize:containerSize];
-    
-    NSRange glyphRange;
-    
+        
     // we now have a properly flipped graphics context, so force layout and 
then draw the text
-    glyphRange = [lm glyphRangeForBoundingRect:stringRect inTextContainer:tc];
+    NSRange glyphRange = [lm glyphRangeForBoundingRect:stringRect 
inTextContainer:tc];
     NSRect usedRect = [lm usedRectForTextContainer:tc];
     
     // NSRunStorage raises if we try drawing a zero length range (happens if 
you have an empty text file)
@@ -410,6 +393,9 @@
         [lm drawGlyphsForGlyphRange:glyphRange atPoint:usedRect.origin];
     }
     
+    // text is drawn, so we're done with this
+    [FVTextIcon pushTextStorage:textStorage];
+    textStorage = nil;
     
     // restore the previous context
     [NSGraphicsContext restoreGraphicsState];
@@ -417,9 +403,6 @@
     // restore the bitmap context's state (although it's gone after this 
operation)
     CGContextRestoreGState(ctxt);
     
-    [FVTextIcon pushTextStorage:textStorage];
-    textStorage = nil;
-    
     CGImageRef image = CGBitmapContextCreateImage(ctxt);
     FVIconBitmapContextRelease(ctxt);
     
@@ -468,7 +451,11 @@
         }
     }
 
-    // At this point, neither icon should be present, unless ImageIO failed 
previously or caching failed.  However, if multiple views are caching icons at 
the same time, we can end up here with a thumbnail but no full image.  Make 
sure we don't leak in that case.
+    /*
+     At this point, neither icon should be present, unless ImageIO failed 
previously or caching failed.  
+     However, if multiple views are caching icons at the same time, we can end 
up here with a thumbnail 
+     but no full image.
+     */
     NSParameterAssert(NULL == _fullImage);
         
     // originally kept the attributed string as an ivar, but it's not worth it 
in most cases
@@ -477,7 +464,12 @@
     NSDictionary *documentAttributes = nil;
     NSMutableAttributedString *attrString = nil;
     
-        // This is a minor optimization: NSAttributedString creates a bunch of 
temporary objects for pasteboard translation when reading a file, but we avoid 
that by loading with NSString directly.  Interestingly, this also appears to be 
at least a partial workaround for rdar://problem/5775728 (CoreGraphics memory 
leaks), since Instruments shows I'm only leaking a single 
NSConcreteAttributedString here now.
+    /* 
+     This is a minor optimization: NSAttributedString creates a bunch of 
temporary objects for pasteboard 
+     translation when reading a file, but we avoid that by loading with 
NSString directly.  Interestingly, 
+     this also appears to be at least a partial workaround for 
rdar://problem/5775728 (CoreGraphics memory leaks), 
+     since Instruments shows I'm only leaking a single 
NSConcreteAttributedString here now.
+     */
     if (_isPlainText) {
         NSStringEncoding enc;
         NSString *text = [[NSString allocWithZone:[self zone]] 
initWithContentsOfURL:_fileURL usedEncoding:&enc error:NULL];
@@ -490,8 +482,12 @@
         }
     }
 
+    // not plain text, so try to load with NSAttributedString
     if (nil == attrString) {
-        // Occasionally NSAttributedString might end up calling 
NSHTMLReader/WebKit to load a file, which raises an exception and crashes on 
10.4.  The workaround is to always load on the main thread on 10.4.
+        /*
+         Occasionally NSAttributedString might end up calling 
NSHTMLReader/WebKit to load a file, which raises 
+         an exception and crashes on 10.4.  The workaround is to always load 
on the main thread on 10.4.
+         */
         if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) {
             [attrString release];
             _FVAttributedStringOperation *operation = 
[[_FVAttributedStringOperation allocWithZone:[self zone]] initWithURL:_fileURL];
@@ -507,15 +503,18 @@
         }
     }
     
-    CGImageRelease(_fullImage);
-    if (attrString) {
-        _fullImage = [self _newImageWithAttributedString:attrString 
documentAttributes:documentAttributes];
-        [attrString release];
+    // plain text failed and so did NSAttributedString, so display a mildly 
unhelpful error message
+    if (nil == attrString) {
+        NSBundle *bundle = [NSBundle bundleForClass:[FVTextIcon class]];       
 
+        NSString *err = [NSLocalizedStringFromTableInBundle(@"Unable to read 
text file ", @"FileView", bundle, @"error message with single trailing space") 
stringByAppendingString:[_fileURL path]];
+        attrString = [[NSMutableAttributedString alloc] initWithString:err];
     }
-    else {
-        _fullImage = NULL;
-    }
+    FVAPIParameterAssert(nil != attrString);
     
+    CGImageRelease(_fullImage);
+    _fullImage = [self _newImageWithAttributedString:attrString 
documentAttributes:documentAttributes];
+    [attrString release];
+        
     if (NULL != _fullImage) {        
         // reset size while we have the lock, since it may be different now 
that we've read the string
         _fullSize = FVCGImageSize(_fullImage);


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to