2010-12-17 19 views
12

我一直在使用NSStrokeWidthAttributeName上的NSAttributedString對象來繪製一個圍繞文本的輪廓。問題在於筆畫在文本的填充區域內。當文字很小(例如1像素厚)時,筆觸會使文字難以閱讀。我真正想要的是在外面中風。有沒有辦法做到這一點?你如何描述NSAttributedString的_outside_?

我試過NSShadow沒有偏移和模糊,但它太模糊,很難看。如果有一種方法可以不加模糊地增加陰影的大小,那也可以。

回答

31

儘管可能有其他方法,但實現此目的的一種方法是首先僅用一個筆劃繪製字符串,然後僅用填充繪製字符串,直接繪製之前繪製的字符串。 (Adobe InDesign實際上具有這種內置的功能,它似乎只將字筆應用於字母外,這有助於提高可讀性)。

這僅僅是一個示例圖,顯示瞭如何實現這一點(由http://developer.apple.com/library/mac/#qa/qa2008/qa1531.html啓發):

首先設置的屬性:

@implementation MDInDesignTextView 

static NSMutableDictionary *regularAttributes = nil; 
static NSMutableDictionary *indesignBackgroundAttributes = nil; 
static NSMutableDictionary *indesignForegroundAttributes = nil; 

- (void)drawRect:(NSRect)frame { 
    NSString *string = @"Got stroke?"; 
    if (regularAttributes == nil) { 
     regularAttributes = [[NSMutableDictionary 
    dictionaryWithObjectsAndKeys: 
     [NSFont systemFontOfSize:64.0],NSFontAttributeName, 
     [NSColor whiteColor],NSForegroundColorAttributeName, 
     [NSNumber numberWithFloat:-5.0],NSStrokeWidthAttributeName, 
     [NSColor blackColor],NSStrokeColorAttributeName, nil] retain]; 
    } 

    if (indesignBackgroundAttributes == nil) { 
     indesignBackgroundAttributes = [[NSMutableDictionary 
     dictionaryWithObjectsAndKeys: 
     [NSFont systemFontOfSize:64.0],NSFontAttributeName, 
     [NSNumber numberWithFloat:-5.0],NSStrokeWidthAttributeName, 
     [NSColor blackColor],NSStrokeColorAttributeName, nil] retain]; 
    } 

    if (indesignForegroundAttributes == nil) { 
     indesignForegroundAttributes = [[NSMutableDictionary 
     dictionaryWithObjectsAndKeys: 
     [NSFont systemFontOfSize:64.0],NSFontAttributeName, 
     [NSColor whiteColor],NSForegroundColorAttributeName, nil] retain]; 
    } 

    [[NSColor grayColor] set]; 
    [NSBezierPath fillRect:frame]; 

    // draw top string 
    [string drawAtPoint: 
     NSMakePoint(frame.origin.x + 200.0, frame.origin.y + 200.0) 
     withAttributes:regularAttributes]; 

    // draw bottom string in two passes 
    [string drawAtPoint: 
     NSMakePoint(frame.origin.x + 200.0, frame.origin.y + 140.0) 
     withAttributes:indesignBackgroundAttributes]; 
    [string drawAtPoint: 
     NSMakePoint(frame.origin.x + 200.0, frame.origin.y + 140.0) 
     withAttributes:indesignForegroundAttributes]; 
} 

@end 

這將產生以下輸出:

alt text

alt text

現在,這並不完美,因爲字形有時會落在分界線上,但它看起來肯定比默認的要好。

如果性能是一個問題,你總是可以考慮下降到一個稍低的水平,如CoreGraphics或CoreText。

+0

謝謝。作品一種享受。 – 2010-12-19 03:08:38

+0

好的,詳細的答案。感謝您投入時間! – epologee 2012-04-23 08:32:37

+1

簡單。輝煌。 ...應該是完全沒有必要的...(支持應該已經存在) – u2Fan 2014-08-06 15:06:49