2015-10-15 43 views
2

我正在嘗試構建this question的測試用例。要做到這一點,我需要繪製一個與預設值不同的大寫和連接虛線;例如,用圓線帽。用Gelfman和Laden的書籍Quartz編寫的說我應該能夠;第125頁談了很多關於用不同的上限和下劃線繪製虛線,甚至有一個圖顯示不同上限的虛線。爲什麼我不能在使用Quartz的OS X上繪製不同線蓋/連線的虛線?

然而,當我運行

CGFloat lengths[2] = { 5, 3 }; 
CGContextMoveToPoint(c, 50, 50); 
CGContextAddLineToPoint(c, 100, 30); 
CGContextAddLineToPoint(c, 150, 70); 
CGContextAddLineToPoint(c, 200, 50); 
CGContextSetLineWidth(c, 10); 
CGContextSetLineJoin(c, kCGLineJoinBevel); 
CGContextSetLineCap(c, kCGLineCapRound); 
CGContextSetLineDash(c, 0, lengths, 2); 
CGContextSetRGBStrokeColor(c, 0, 0, 0, 1); 
CGContextStrokePath(c); 

我看到的實線,沒有虛線。如果我註釋掉以下兩行:

CGContextSetLineJoin(c, kCGLineJoinBevel); 
CGContextSetLineCap(c, kCGLineCapRound); 

然後我看到我的瀟灑。其中一條線本身會使繪圖恢復爲實線。

我不知道發生了什麼事情。提供了一個示例程序。這在OS X 10.10上;我需要追溯到10.7。

這是針對OS X而非iOS的。

謝謝。

// 15 october 2015 
#import <Cocoa/Cocoa.h> 

@interface dashStrokeView : NSView 
@end 

void putstr(CGContextRef c, const char *str, double x, double y) 
{ 
    NSFont *sysfont; 
    CFStringRef string; 
    CTFontRef font; 
    CFStringRef keys[1]; 
    CFTypeRef values[1]; 
    CFDictionaryRef attrs; 
    CFAttributedStringRef attrstr; 
    CTLineRef line; 

    sysfont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]; 
    font = (CTFontRef) sysfont;  // toll-free bridge 

    string = CFStringCreateWithCString(kCFAllocatorDefault, 
     str, kCFStringEncodingUTF8); 
    keys[0] = kCTFontAttributeName; 
    values[0] = font; 
    attrs = CFDictionaryCreate(kCFAllocatorDefault, 
     keys, values, 
     1, 
     &kCFTypeDictionaryKeyCallBacks, 
     &kCFTypeDictionaryValueCallBacks); 
    attrstr = CFAttributedStringCreate(kCFAllocatorDefault, string, attrs); 

    line = CTLineCreateWithAttributedString(attrstr); 
    CGContextSetTextPosition(c, x, y); 
    CTLineDraw(line, c); 

    CFRelease(line); 
    CFRelease(attrstr); 
    CFRelease(attrs); 
    CFRelease(string); 
} 

@implementation dashStrokeView 

- (void)drawRect:(NSRect)r 
{ 
    CGContextRef c; 
    CGFloat lengths[2] = { 5, 3 }; 
    CGMutablePathRef buildpath; 
    CGPathRef copy, copy2; 

    c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; 

    CGContextSaveGState(c); 

    putstr(c, "Dash + Stroke With CGContext Functions", 10, 10); 
    CGContextMoveToPoint(c, 50, 50); 
    CGContextAddLineToPoint(c, 100, 30); 
    CGContextAddLineToPoint(c, 150, 70); 
    CGContextAddLineToPoint(c, 200, 50); 
    CGContextSetLineWidth(c, 10); 
    CGContextSetLineJoin(c, kCGLineJoinBevel); 
    CGContextSetLineCap(c, kCGLineCapRound); 
    CGContextSetLineDash(c, 0, lengths, 2); 
    CGContextSetRGBStrokeColor(c, 0, 0, 0, 1); 
    CGContextStrokePath(c); 

    CGContextTranslateCTM(c, 0, 100); 
    putstr(c, "Dash With CGPath Functions", 10, 10); 

    CGContextTranslateCTM(c, 0, 100); 
    putstr(c, "Dash + Stroke With CGPath Functions", 10, 10); 

    CGContextRestoreGState(c); 
} 

- (BOOL)isFlipped 
{ 
    return YES; 
} 

@end 

@interface appDelegate : NSObject<NSApplicationDelegate> 
@end 

@implementation appDelegate 

- (void)applicationDidFinishLaunching:(NSNotification *)note 
{ 
    NSWindow *mainwin; 
    NSView *contentView; 
    dashStrokeView *view; 
    NSDictionary *views; 
    NSArray *constraints; 

    mainwin = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, 320, 240) 
     styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) 
     backing:NSBackingStoreBuffered 
     defer:YES]; 
    [mainwin setTitle:@"Dash/Stroke Example"]; 
    contentView = [mainwin contentView]; 

    view = [[dashStrokeView alloc] initWithFrame:NSZeroRect]; 
    [view setTranslatesAutoresizingMaskIntoConstraints:NO]; 
    [contentView addSubview:view]; 

    views = NSDictionaryOfVariableBindings(view); 
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[view]-|" 
     options:0 
     metrics:nil 
     views:views]; 
    [contentView addConstraints:constraints]; 
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[view]-|" 
     options:0 
     metrics:nil 
     views:views]; 
    [contentView addConstraints:constraints]; 

    [mainwin cascadeTopLeftFromPoint:NSMakePoint(20, 20)]; 
    [mainwin makeKeyAndOrderFront:nil]; 
} 

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app 
{ 
    return YES; 
} 

@end 

int main(void) 
{ 
    NSApplication *app; 

    app = [NSApplication sharedApplication]; 
    [app setActivationPolicy:NSApplicationActivationPolicyRegular]; 
    [app setDelegate:[appDelegate new]]; 
    [app run]; 
    return 0; 
} 

回答

3

的問題是,CGFloat的lengths不是一個足夠大的值是明顯的,從它的路徑。增加浮點值將允許斜面和上限,以更充分地間隔:

CGFloat lengths[2] = { 10, 13 }; 

你已經有了,現在實際上是繪製(未恢復)的方式,雖然它是如此微不足道,它的重疊本身,這實質上創建一條實線。

+0

是的,就是這樣。圓線帽太大,所以它們重疊= P謝謝! – andlabs

+0

@andlabs:不客氣!你可能考慮的另一件事是使用'kCGLineJoinRound'而不是'kCGLineJoinBevel',因爲它可能會給你一個更平滑的邊緣。 –

+0

這只是一個示範;我選擇了斜角連接以便從帽子看起來有一個獨特的外觀。示範完成;你可以看到我的結果[這裏](http://stackoverflow.com/a/33171188/3408572)。 – andlabs