Я обрабатываю текст в Direct2D/DirectWrite, но вызов SetLineSpacing()
на TextFormat или TextLayout кажется неэффективным. Кто-нибудь знает, почему?SetLineSpacing() не работает в DirectWrite - почему?
ответ
Я на 99% уверен, что это ошибка. В последнее время я немного поиграл с Direct2D, а также имел проблему с SetLineSpacing()
на TextLayout, думаю, что это то же самое, что и вы описываете, в этом случае я могу подтвердить, что это не только вы. Повторно откройте отчет об ошибке в MS Connect, он был закрыт.
Я не знаю, действительно ли это не работает в 2009 году, но по крайней мере теперь вызов 'SetLineSpacing()' работает так, как ожидалось. Проблема заключается в том, что при указании 'DWRITE_LINE_SPACING_METHOD_DEFAULT', два значения float игнорируются, поскольку в этом контексте они не имеют смысла. Межстрочный интервал по умолчанию означает «получить интервал между используемыми шрифтами и встроенными объектами». См. Мой ответ ниже для получения дополнительной информации. – Pepor
Я что-то не хватает?
Ни IDWriteTextFormat ни IDWriteTextLayout имеет функцию SetLineHeight ...
Я имел в виду 'SetLineSpacing()', извините. –
Вы проверили код HRESULT
ошибки, возвращаемый SetLineSpacing()
?
Подсказка: если вы используете Visual Studio, просто введите eax,hr
в одном из окон отладки Watch, чтобы увидеть любой возможный код ошибки сразу после вызова.
Да, и это S_OK –
Минимальный поддерживаемый клиент: Windows 7, Windows Vista с пакетом обновления 2 и обновления платформы для Windows Vista.
Вы используете любую из вышеперечисленных версий окон? Я верю, что причина, по которой вы не видите никаких изменений, связана с тем, что любая версия ниже указанных выше не поддерживает SetLineSpacing() в DirectWrite.
Тот факт, что я запускаю его, будет означать, что я на самом деле использую поддерживаемую операционную систему, в данном случае 2008R2. –
У меня даже такая же проблема, как сказал Дмитрий Нестерук.
Тем не менее, я выясню, что если вы установили lineSpacing «после CreateTextLayout», SetLineSpacing не сможет работать.
В противном случае, если вы установите LineSpacing перед CreateTextLayout, , он может работать сейчас.
Возможно, вы сможете попробовать этот солон.
PS: My env. находится в Windows Vista SP2.
Большое спасибо.
К сожалению, вы не указали код, показывающий, что вы пытаетесь сделать. Я предполагаю, что вы пытаетесь установить межстрочный интервал, как это:
pTextLayout->SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, lineSpacing, baseline);
документация на MSDN не очень четкое представление о различных методах межстрочного интервала. Метод по умолчанию заставляет интервал для каждой строки выводиться из используемого шрифта и встроенных объектов, если таковые имеются, поэтому каждая строка - это высота, которая должна быть в соответствии с ее содержимым. В этом случае два параметра, lineSpacing
и baseline
, игнорируются.
Если у вас есть текстовый формат, в котором используется один шрифт (и размер шрифта) и нет встроенных объектов (или встроенных объектов, которые не превышают текст), вы можете указать равномерный интервал между строками. Это то, что для DWRITE_LINE_SPACING_METHOD_UNIFORM
. Я только что попробовал, и вызов SetLineSpacing()
с помощью этого метода приводит к равномерному интервалу между строками в соответствии с переданными аргументами.
Начиная с Windows 10 существует третий способ межстрочного интервала, DWRITE_LINE_SPACING_METHOD_PROPORTIONAL
, который может использоваться для достижения межстрочного интервала, который соответствует типу шрифтов и встроенных объектов. Тем не менее, это поддерживается только в Windows 10.
Самая ошибочная часть, по моему опыту, заключается в том, что вызов SetLineSpacing(DWRITE_LINE_SPACING_METHOD_DEFAULT, x, y)
преуспевает без ошибки и после этого извлекает параметры интервала между линиями, используя метод , возвращает значения, которые были (пока они ничего не добиваются). API является внутренне непротиворечивым в этом отношении, не отбрасывая указанные значения, даже если они не достигают ничего полезного. Кроме того, когда вы вызываете GetLineSpacing()
на вновь созданный экземпляр IDWriteTextFormat
или IDWriteTextLayout
, значения возвращаются как ноль (это правильно, потому что метод межстрочного интервала DWRITE_LINE_SPACING_METHOD_DEFAULT
). Чтобы иметь возможность сделать что-нибудь полезное, вам нужно определить интервал между строками по умолчанию для используемого шрифта. Вы можете достичь этого, вызвав IDWriteFont::GetMetrics()
на шрифт, который вы используете. Интервал между строками по умолчанию представляет собой сумму значений ascent
, descent
и lineGap
.
Charles Petzold написал об этом в статье около Pagination With DirectWrite.
Это может быть ошибка: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=507456 – Kredns
Я разместил эту ошибку, но подумал, что было бы разумно спросить здесь, на всякий случай «Я делаю что-то неправильно. –
Покажите нам свой код. – Goz