Какао: вставка форматированного текста в текущий шрифт? - PullRequest
4 голосов
/ 05 октября 2009

Когда я помещаю отформатированный текст в монтажную панель (NSRTFPboardType), он вставляется с сохранением всего форматирования. Но то, что я действительно хотел бы, это отбросить информацию о размере и размере шрифта, сохранив при этом вес, цвет и т. Д.

Согласно документам, NSAttributedString без информации о шрифтах по умолчанию будет иметь значение Helvetica 12. Это выглядит как тупик.

Я также могу генерировать текст по требованию, поэтому, если бы я мог найти шрифт в текущем элементе пользовательского интерфейса, я мог бы изменить текст, прежде чем он попадет в монтажную область. Я надеялся, что 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 ]

1 голос
/ 06 октября 2009

Не существует общесистемного или даже обще-прикладного понятия «текущий шрифт». Самое близкое, что вы можете получить, это атрибуты набора текста активного в настоящий момент NSTextView; если ни один не активен, то нет ничего похожего на текущий шрифт.

С учетом вышесказанного вы могли бы пообещать данные RTF для монтажной панели, а при запросе отправлять текущему активному приложению команду копирования AppleEvent, ждать ответа, извлекать любой расширенный текст из монтажной панели и захватывать его шрифт. атрибутов. Если нет расширенного текста, придерживайтесь текущего шрифта и размера. Я понятия не имею, насколько хорошо эта эвристика работает на практике, но я не могу придумать лучшего подхода.

Если я попытаюсь сгенерировать самые простые необработанные RTF-данные, которые я смогу, без информации о шрифтах, они все равно будут вставлены в Helvetica 12!

В качестве шрифта по умолчанию используется Helvetica-12, если информация о шрифте не указана, поскольку весь рисуемый текст должен иметь размер некоторый , размер , некоторый . Helvetica-12 должна была показаться читабельной и достаточно безобидной, чтобы быть выбранной по умолчанию. (Конечно, победит Comic Sans-72!)

0 голосов
/ 05 октября 2009

изменение скопированного текста, чтобы оно отличалось от того, что скопировал пользователь, противоречило бы идее копирования и вставки, не так ли?

0 голосов
/ 05 октября 2009

NSAttributedString является неизменным. Я думаю, возможно, что вам нужно это NSMutableAttributedString . В этом руководстве есть пример того, как что-то изменить. Вы должны иметь возможность создать новую NSMutableAttributedString в качестве копии NSAttributedString, а затем внести в нее изменения, прежде чем передавать ее на монтажную панель.

EDIT:

Я не совсем уверен, что тебе делать. Вы говорите, что хотите сохранить некоторое форматирование и удалить другое форматирование, и кажется, что вы понимаете, как манипулировать атрибутами 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));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...