2009-11-03 2 views
4

Я обрабатываю текст в Direct2D/DirectWrite, но вызов SetLineSpacing() на TextFormat или TextLayout кажется неэффективным. Кто-нибудь знает, почему?SetLineSpacing() не работает в DirectWrite - почему?

+0

Это может быть ошибка: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=507456 – Kredns

+1

Я разместил эту ошибку, но подумал, что было бы разумно спросить здесь, на всякий случай «Я делаю что-то неправильно. –

+1

Покажите нам свой код. – Goz

ответ

5

Я на 99% уверен, что это ошибка. В последнее время я немного поиграл с Direct2D, а также имел проблему с SetLineSpacing() на TextLayout, думаю, что это то же самое, что и вы описываете, в этом случае я могу подтвердить, что это не только вы. Повторно откройте отчет об ошибке в MS Connect, он был закрыт.

+0

Я не знаю, действительно ли это не работает в 2009 году, но по крайней мере теперь вызов 'SetLineSpacing()' работает так, как ожидалось. Проблема заключается в том, что при указании 'DWRITE_LINE_SPACING_METHOD_DEFAULT', два значения float игнорируются, поскольку в этом контексте они не имеют смысла. Межстрочный интервал по умолчанию означает «получить интервал между используемыми шрифтами и встроенными объектами». См. Мой ответ ниже для получения дополнительной информации. – Pepor

0

Вы проверили код HRESULT ошибки, возвращаемый SetLineSpacing()?

Подсказка: если вы используете Visual Studio, просто введите eax,hr в одном из окон отладки Watch, чтобы увидеть любой возможный код ошибки сразу после вызова.

+0

Да, и это S_OK –

-2

Source

Минимальный поддерживаемый клиент: Windows 7, Windows Vista с пакетом обновления 2 и обновления платформы для Windows Vista.

Вы используете любую из вышеперечисленных версий окон? Я верю, что причина, по которой вы не видите никаких изменений, связана с тем, что любая версия ниже указанных выше не поддерживает SetLineSpacing() в DirectWrite.

+0

Тот факт, что я запускаю его, будет означать, что я на самом деле использую поддерживаемую операционную систему, в данном случае 2008R2. –

2

У меня даже такая же проблема, как сказал Дмитрий Нестерук.

Тем не менее, я выясню, что если вы установили lineSpacing «после CreateTextLayout», SetLineSpacing не сможет работать.

В противном случае, если вы установите LineSpacing перед CreateTextLayout, , он может работать сейчас.

Возможно, вы сможете попробовать этот солон.

PS: My env. находится в Windows Vista SP2.

Большое спасибо.

1

К сожалению, вы не указали код, показывающий, что вы пытаетесь сделать. Я предполагаю, что вы пытаетесь установить межстрочный интервал, как это:

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.