Плохой рендеринг текста с Core Animation - PullRequest
9 голосов
/ 13 августа 2011

Прежде всего, я знаю, что эта тема поднималась несколько раз раньше, но я публикую этот вопрос, потому что ни одно из "решений", которые я использовал в прошлом, не работало в этом конкретном случае.Я рисую некоторый текст на CALayer, который размещается в представлении внутри моего NSToolbar.Вот как выглядит текст:

Font smoothing on

Я попытался использовать предложение из этого сообщения StackOverflow, которое должно вызвать CGContextSetShouldSmoothFonts(ctx, false) для отключения субпиксельного сглаживанияпрежде чем рисовать в контексте.Это решение, которое дало мне приемлемые результаты в прошлом, но в этом случае кажется, что текст выглядел еще хуже:

Font smoothing off

Другое решение, упомянутое в этомсообщение должно заполнить прямоугольник непрозрачным цветом фона перед рисованием, что просто невозможно в этом случае, потому что фон панели инструментов является градиентом.Могу ли я что-нибудь сделать, чтобы этот текст выглядел так же красиво, как текст, нарисованный в простой NSView?

Ответы [ 3 ]

7 голосов
/ 13 августа 2011

Причина, по которой субпиксельное сглаживание невозможно, заключается в том, что за кадром CALayers, по сути, являются просто текстурами OpenGL.

Это означает, что они являются растровыми изображениями, обрабатываемыми и визуализируемыми непосредственно графическим процессором. Графический процессор ничего не знает о тексте и поэтому не может применять субпиксельное сглаживание.

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

Причина, по которой текст на непрозрачных фонах может использовать SPAA, заключается в том, что текст предварительно визуализируется с субпиксельным сглаживанием перед сохранением текстуры слоя в графическом процессоре. Это невозможно, если фон текста прозрачный.

Вам придется жить с этим ограничением. К счастью, это больше не будет проблемой, когда все мы в конечном итоге получим дисплеи HiDPI ... взгляните на iPhone, который вообще не выполняет субпиксельное сглаживание. На iPhone текст выглядит просто отлично благодаря высокому разрешению экрана.

5 голосов
/ 13 августа 2011

К сожалению, нет волшебного исправления. В конце дня текст должен быть нарисован на непрозрачном фоне, чтобы получить SPAA. Это отстой, но это имеет большой смысл, учитывая, как работают слои. И, честно говоря, я не вижу, чтобы Apple когда-либо «исправляла» это. Я думаю, что по этой причине они так долго придерживаются старой модели компоновки программного обеспечения. Это сложная проблема, и они надеются проигнорировать ее, выбрав высокое разрешение.

Но в любом случае, есть несколько способов получить SPAA в вашем конкретном случае.

Вы можете попытаться воссоздать градиент и нарисовать его самостоятельно, когда будете рисовать текст. Но очевидно, что это хрупко, если в обновлении ОС изменяется градиент панели инструментов, и может быть трудно заставить градиент точно соответствовать.

Или вы можете попытаться получить изображение фона панели инструментов во время выполнения или заранее и нарисовать его в качестве фона.

0 голосов
/ 25 января 2014

У меня хороший опыт работы с OpenGL, анимацией, прокруткой текста в реальном времени, рендерингом текстур с использованием мультисэмпла AAТекстура 4 байта с альфа-каналом не заботится о том, является ли фон прозрачным или нет.OpenGL отображает эту прозрачную текстуру в реальном времени.А переделка текстуры при любом небольшом изменении глифов - это вопрос микросекунд.Apple может это исправить.

...