Cocoa:用当前字体粘贴格式化文本?

时间:2009-10-05 17:22:51

标签: objective-c cocoa

当我将格式化文本放入粘贴板(NSRTFPboardType)时,它会粘贴保留的所有格式。但我真正喜欢的是丢弃字体和大小信息,同时保留重量,颜色等。

根据文档,没有字体信息的NSAttributedString默认为Helvetica 12,所以这看起来像死路一条。

我也可以按需生成文本,所以如果我能找到当前UI元素中的字体,我可以在文本进入粘贴板之前修改它。我希望辅助功能API可以帮助解决这个问题,但是我在UIElementInspector中找不到的任何属性似乎都没有处理格式化。

有什么想法吗?

这是一个测试案例。它粘贴在Helvetica 12中,即使唯一的属性是绿色:

// Create the string with no attributes, and strip the font just in case.
NSMutableAttributedString *s = [[[NSMutableAttributedString alloc] initWithString:@"Hello green world!"] autorelease];
[s removeAttribute:NSFontAttributeName range:NSMakeRange(0, [s length])];

// Add a test attribute
[s addAttribute:NSForegroundColorAttributeName value:[NSColor greenColor] range:NSMakeRange(6, 5)];

// Generate RTF data 
NSData *rtf = [s RTFFromRange:NSMakeRange(0, [s length]) documentAttributes:nil];

// Copy to pasteboard
NSPasteboard *pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObject:NSRTFPboardType] owner:nil];
[pb setData:rtf forType:NSRTFPboardType];

这里有一些有趣的东西。如果我尝试生成最简单的原始RTF数据,我可以使用绝对没有字体信息,它仍然粘贴在Helvetica 12中!

char *rawrtf = "{\\rtf1\\ansi\\ansicpg1252\n"
               "Hello world.}";
NSData *rtf = [NSData dataWithBytes:rawrtf length:strlen(rawrtf)];

因此,如果这是可能的,我认为只有通过查询当前运行的应用程序才能获得当前字体。

3 个答案:

答案 0 :(得分:1)

“当前字体”没有系统范围甚至应用程序范围的概念。您可以获得的最接近的是当前有效NSTextView的输入属性;如果没有活动,则没有像当前字体那样的东西。

话虽如此,您可以将RTF数据保证到粘贴板,并在它请求时,向当前活动的应用程序发送AppleEvent命令副本,等待响应,从粘贴板中提取任何富文本,然后抓取其字体属性。如果没有可用的富文本,请坚持使用当前的字体和大小。我不知道这种启发式在实践中的效果如何,但我想不出更好的方法。

  

如果我尝试生成最简单的原始RTF数据,我绝对没有字体信息,它仍然粘贴在Helvetica 12中!

当没有提供字体信息时,字体默认为Helvetica-12,因为所有正在绘制的文本必须是部分字体 大小。 Helvetica-12必须具有可读性和足够的无害性才能被选为默认值。 (肯定比Comic Sans-72好!)

答案 1 :(得分:0)

NSAttributedString是不可变的。我想也许你需要的是NSMutableAttributedStringThis guide有一个如何改变事物的例子。您应该能够创建一个新的NSMutableAttributedString作为NSAttributedString的副本,然后在将其传递给粘贴板之前对其进行修改。

编辑:

我不太清楚你该做什么。您说要保留一些格式,并删除其他格式,似乎您了解如何操作NSMutableAttributedString属性,那么问题是什么?创建一个新的属性字符串,询问旧的字符串,并将所需的任何属性应用于新的属性,如果您不喜欢默认字体,请更改它。我不明白这个问题在哪里。

EDIT2:

使用initWithAttributedString:应该复制字体属性,但如果没有,您应该可以使用enumerateAttributesInRange:options:usingBlock:来查询原始的NSAttributedString

EDIT3:

NSAttributedString *attrStr;
NSRange limitRange;
NSRange effectiveRange;
id attributeValue;

limitRange = NSMakeRange(0, [attrStr length]);

while (limitRange.length > 0) {
    attributeValue = [attrStr attribute:NSFontAttributeName
        atIndex:limitRange.location longestEffectiveRange:&effectiveRange
        inRange:limitRange];

    // apply attributeValue to the other mutable attributed string range here

    limitRange = NSMakeRange(NSMaxRange(effectiveRange),
        NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
}

答案 2 :(得分:0)

更改复制文本以使其与用户复制的内容不同会违背复制和粘贴的想法,不是吗?

相关问题