Рисование текста с использованием базовой графики - PullRequest
8 голосов
/ 08 декабря 2010

Мне нужно нарисовать центрированный текст в CGContext.

Я начал с подхода Какао.Я создал NSCell с текстом и попытался нарисовать его так:

NSGraphicsContext* newCtx = [NSGraphicsContext
     graphicsContextWithGraphicsPort:bitmapContext flipped:true];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:newCtx];
[pCell setFont:font];
[pCell drawWithFrame:rect inView:nil];
[NSGraphicsContext restoreGraphicsState];

Но, похоже, на CGBitmapContext текст не отображается.Возможно, потому что мне нужно передать nil для параметра inView:

. Итак, я попытался переключить рендеринг текста в Core Graphics:

Кажется, что самым простым способом является использование CGContextSelectFont для выбора шрифта, используя егоимя постскриптума и размер точки, но CGContextShowTextAtPoint принимает только символы, отличные от Юникода, и нет никакого очевидного способа разместить текст в прямоугольнике: или вычислить экстенты строки текста, чтобы вручную расположить прямоугольник.

Затем существует CGFont, который можно создать, и установите cia CGContextSetFont.Для рисования этого текста требуется CGContextShowGlyphsAtPoint, но, опять же, в CGContext, похоже, отсутствуют функции для вычисления ограничивающего прямоугольника сгенерированного текста или для переноса текста в прямоугольник.Плюс, как преобразовать строку в массив CGGlyphs не очевидно.

Следующий вариант - попытаться использовать CoreText для рендеринга строки.Но классы Core Text чрезвычайно сложны, и хотя есть примеры, которые показывают, как отображать текст указанным шрифтом в прямоугольнике, нет примеров, демонстрирующих, как вычислять ограничивающий прямоугольник строки CoreText.

Итак:

  • С учетом CGFont CGContext, как мне вычислить ограничивающий прямоугольник некоторого текста и как преобразовать текстовую строку в массив CGGlyphs?
  • Учитываястрока, CGContext и имя и размер постскриптума, какие объекты Core Text мне нужно создать, чтобы вычислить ограничивающий прямоугольник строки и / или нарисовать строку, обернутую в прямоугольник CGContext.
  • Заданная строка и NSFont - как мне отрендерить строку в CGBitmapContext?Я уже знаю, как получить его экстенты.

Ответы [ 2 ]

7 голосов
/ 10 февраля 2011

Мне наконец удалось найти ответы после 4 дней поиска. Я действительно хочу, чтобы Apple сделала лучшую документацию. Итак, мы идем

Полагаю, у вас уже есть CGFontRef. Если нет, дайте мне знать, я расскажу вам, как загрузить ttf из комплекта ресурсов в CgFontRef.

Ниже приведен фрагмент кода для вычисления границ любой строки с любым CGFontref

        int charCount = [string length];
        CGGlyph glyphs[charCount];
        CGRect rects[charCount];

        CTFontGetGlyphsForCharacters(theCTFont, (const unichar*)[string cStringUsingEncoding:NSUnicodeStringEncoding], glyphs, charCount);
        CTFontGetBoundingRectsForGlyphs(theCTFont, kCTFontDefaultOrientation, glyphs, rects, charCount);

        int totalwidth = 0, maxheight = 0;
        for (int i=0; i < charCount; i++)
        {
            totalwidth += rects[i].size.width;
            maxheight = maxheight < rects[i].size.height ? rects[i].size.height : maxheight;
        }

        dim = CGSizeMake(totalwidth, maxheight);

Повторно используйте ту же функцию CTFontGetGlyphsForCharacters, чтобы получить глифы. Чтобы получить CTFontRef из CGFontRef, используйте функцию CTFontCreateWithGraphicsFont ()

Также помните, что NSFont и CGFontRef являются бесплатными мостовыми соединениями, что означает, что они могут быть объединены друг с другом и будут работать без каких-либо дополнительных действий.

7 голосов
/ 09 декабря 2010

Я бы продолжил ваш вышеуказанный подход, но вместо этого использовал бы NSAttributedString.

NSGraphicsContext* newCtx = [NSGraphicsContext graphicsContextWithGraphicsPort:bitmapContext flipped:true];
[NSGraphicsContext saveGraphicsState];
[NSGraphicsContext setCurrentContext:newCtx];
NSAttributedString *string = /* make a string with all of the desired attributes */;
[string drawInRect:locationToDraw];
[NSGraphicsContext restoreGraphicsState];
...