Core Text in Cocoa app

感情迁移 提交于 2019-12-22 09:24:13

问题


I have the following sample code which works on iPhone. It draws the text "Hello World!" on the screen using Core Text.

Dropping this code into a cocoa project in an NSView produces different results. The font size is scaled much bigger and the letters are drawn on top of each other. How do I have the text draw the same in the cocoa app?

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);

    CFStringRef font_name = CFStringCreateWithCString(NULL, "Courier", kCFStringEncodingMacRoman);

    CTFontRef font = CTFontCreateWithName(font_name, 36.0, NULL);

    CFStringRef keys[] = { kCTFontAttributeName };

    CFTypeRef values[] = { font };

    CFDictionaryRef font_attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFRelease(font_name);

    CFRelease(font);

    int x = 10;
    int y = 10;
    const char *text = "Hello World!";

    CFStringRef string = CFStringCreateWithCString(NULL, text, kCFStringEncodingMacRoman);

    CFAttributedStringRef attr_string = CFAttributedStringCreate(NULL, string, font_attributes);

    CTLineRef line = CTLineCreateWithAttributedString(attr_string);

    CGContextSetTextPosition(context, x, y);

    // Core Text uses a reference coordinate system with the origin on the bottom-left
    // flip the coordinate system before drawing or the text will appear upside down
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    CTLineDraw(line, context);

    CFRelease(line);

    CFRelease(string);

    CFRelease(attr_string);

    CGContextRestoreGState(context);
}

iPhone in UIView (Expected Result)

Mac in NSView (Unexpected Result)


回答1:


As @matt has noted, this is not the Cocoa code, the origin of the coordinate system is "bottom-left" on Cocoa, and UIGraphicsGetCurrentContext() does not exist…

Anyway you need to set the text matrix of the context at least to CGAffineTransformIdentity. But as CGContextSetTextPosition don't set the position for CTDrawLine, you need to translate the text matrix to your desired position.

- (void)drawRect:(NSRect)dirtyRect
{
    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
    CGContextSaveGState(context);

    CFStringRef font_name = CFStringCreateWithCString(NULL, "Courier", kCFStringEncodingMacRoman);

    CTFontRef font = CTFontCreateWithName(font_name, 36.0, NULL);

    CFStringRef keys[] = { kCTFontAttributeName };
    CFTypeRef values[] = { font };

    CFDictionaryRef font_attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)&keys, (const void **)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFRelease(font_name);

    CFRelease(font);

    int x = 10;
    int y = 10;

    CFAttributedStringRef attr_string = CFAttributedStringCreate(NULL, CFSTR("Hello World!"), font_attributes);

    CTLineRef line = CTLineCreateWithAttributedString(attr_string);

    // You need to set the text matrix at least to CGAffineTransformIdentity 
    // Here we translate to the desired position
    CGContextSetTextMatrix(context, CGAffineTransformMakeTranslation(x,y));

    CTLineDraw(line, context);

    CFRelease(line);

    CFRelease(attr_string);

    CGContextRestoreGState(context);
}


来源:https://stackoverflow.com/questions/22515480/core-text-in-cocoa-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!