2014-10-22 8 views
3

я столкнулся с одной проблемой с текстами для рисования с помощью API DrawText вызова Windows, для шрифта Segoe UI:DrawText рисует текст шрифта Segoe UI неправильно

enter image description here

Это изображение демонстрирует проблему: указанный текст сместился немного справа в указанном прямоугольнике, так что последний символ обрезается (лучшим примером является цифра 0).

Наша программа рисования хорошо работает для других шрифтов, и проблема возникает только для пользовательского интерфейса Segoe.

Что это может быть и как его решить?

Выполнение этого в проекте VB6 OCX на Windows 8 Pro 64-бит, если это имеет значение.


соответствующего исходного кода кода является следующее:

' Only draws or measure text (if DT_CALCRECT is specified) 
' using the native WinAPI flags: 
Public Sub gpInternalDrawText(_ 
    ByVal lHDC As Long, _ 
    ByRef sText As String, _ 
    ByRef tR As RECT, _ 
    ByVal lFlags As Long _ 
) 
    ' Allows Unicode rendering of text under NT/2000/XP 
    If (g_bIsNt) Then 
    ' NT4 crashes with ptr = 0 
    If StrPtr(sText) <> 0 Then 
     DrawTextW lHDC, StrPtr(sText), -1, tR, lFlags 
    End If 
    Else 
    DrawTextA lHDC, sText, -1, tR, lFlags 
    End If 
End Sub 

' Draws the string in the specifed rectangle. 
' Should not be called to calculate text size 
' (with DT_CALCRECT flag - use gpInternalDrawText instead) 
Public Sub DrawText(_ 
    ByVal lHDC As Long, _ 
    ByRef sText As String, _ 
    ByRef rcText As RECT, _ 
    ByVal lFlags As Long, _ 
    Optional ByVal eAlignH As Long = 0, _ 
    Optional ByVal eAlignV As Long = 0 _ 
) 

    ' *** Automatically turns processing prefixes off (if required) 

    If (lFlags And &H200000) = 0 Then 
    lFlags = lFlags Or DT_NOPREFIX 
    Else 
    lFlags = lFlags Xor DT_PREFIXONLY 
    End If 


    ' *** We can modify rcText below, so do it with its copy 

    Dim rcDrawText As RECT 
    LSet rcDrawText = rcText 


    ' *** Getting the full set of API flags for our text 

    Select Case eAlignH 
    ' in fact don't need that as DT_LEFT=0: 
' Case igAlignHLeft 
'  lFlags = lFlags Or DT_LEFT 
    Case igAlignHCenter 
    lFlags = lFlags Or DT_CENTER 
    Case igAlignHRight 
    lFlags = lFlags Or DT_RIGHT 
    End Select 

    If (lFlags And DT_SINGLELINE) <> 0 Then 
    Select Case eAlignV 
    ' in fact don't need that as DT_TOP=0: 
    ' Case igAlignVTop 
    '  lFlags = lFlags Or DT_TOP 
    Case igAlignVCenter 
     lFlags = lFlags Or DT_VCENTER 
    Case igAlignVBottom 
     lFlags = lFlags Or DT_BOTTOM 
    End Select 
    Else 
    If eAlignV <> igAlignVTop Then 
     Dim rcCalcRect As RECT 
     LSet rcCalcRect = rcText 
     gpInternalDrawText lHDC, sText, rcCalcRect, lFlags Or DT_CALCRECT 
     Dim lTextHeight As Long 
     lTextHeight = rcCalcRect.Bottom - rcCalcRect.Top 
     Select Case eAlignV 
     Case igAlignVCenter 
      ' simplified (rcText.Top + rcText.Bottom)/2 - lTextHeight/2 
      ' should be integer division because of rounding erros in the case of "/" 
      rcDrawText.Top = (rcDrawText.Top + rcDrawText.Bottom - lTextHeight) \ 2 
     Case igAlignVBottom 
      rcDrawText.Top = rcDrawText.Bottom - lTextHeight 
     End Select 
    End If 
    End If 


    ' *** Finally draw the text 

    Const FIXED_PATH_ELLIPSIS_FLAGS As Long = DT_SINGLELINE Or DT_PATH_ELLIPSIS 
    If (lFlags And FIXED_PATH_ELLIPSIS_FLAGS) = FIXED_PATH_ELLIPSIS_FLAGS Then 
    DrawText_FixedPathEllipsis lHDC, sText, rcDrawText, lFlags 
    Else 
    gpInternalDrawText lHDC, sText, rcDrawText, lFlags 
    End If 

End Sub 

Шрифт для UserControl DC устанавливается с помощью этого кода:

Public Function FontHandle(fnt As IFont) As Long 
    FontHandle = fnt.hFont 
End Function 

Private Sub pApplyFont() 
    If (m_hFntDC <> 0) Then 
     If (m_hDC <> 0) Then 
     If (m_hFntOldDC <> 0) Then 
      SelectObject m_hDC, m_hFntOldDC 
     End If 
     End If 
    End If 

    m_hFntDC = FontHandle(UserControl.Font) 
    If (m_hDC <> 0) Then 
     m_hFntOldDC = SelectObject(m_hDC, m_hFntDC) 
    End If 
End Sub 

, где

m_hDC = CreateCompatibleDC(UserControl.hdc) 
+0

Мы не можем видеть любой код. Поэтому мы не знаем, что вы сделали. Пожалуйста, покажите код. –

+0

@DavidHeffernan, я добавил код. – TecMan

+0

Там нет ничего относительно шрифта. Где вы создаете шрифт и выбираете его в DC? Я могу догадаться, что происходит, но было бы лучше, если бы мы сказали это прямо. –

ответ

5

Проблема заключается в выходе качество, которое вы используете. Вы используете ANTIALIASED_QUALITY. Интерфейс Segoe UI разработан для четкого типа. Он отлично выглядит с четким типом, но ужасным со стандартным сглаживанием. Переключитесь на тип очистки (установите lqQuality на CLEARTYPE_QUALITY), и вы получите гораздо лучшие результаты.

Это изображение демонстрирует рендеринг 10pt Segoe UI с двумя вариантами качества, описанными выше.

enter image description here

+0

Я не создаю объект шрифта API - я использую существующий объект Font из UserControl (тип StdFont). Я добавил больше кода на этот вопрос, чтобы продемонстрировать это. Могу ли я установить требуемое качество шрифта для существующего шрифта API или сделать это для DC? – TecMan

+1

Ну, теперь мы находимся в пользовательских элементах управления VB6, которые не являются моей сумкой. Я почти уверен, что проблема в том, что я сказал. Интересно, почему вы не выбираете четкий тип. Вы отключили его на своей машине? Я бы ожидал, что структура VB6 будет использовать 'DEFAULT_QUALITY', которая даст вам качество системы. По умолчанию это чистый тип. Я думаю, что вам в первую очередь нужно решить, почему вы не используете четкий тип. Я не думаю, что я могу ответить на это за вас. –

1

Да, Дэвид Heffernan был прав - мне нужно, чтобы включить настройки ClearType для всей операционной системы на:

enter image description here

+0

Пожалуйста, используйте ссылку для редактирования по вашему вопросу, чтобы добавить дополнительную информацию.Кнопка «Ответ на сообщение» должна использоваться только для полных ответов на вопрос. – apomene

+0

@apomene: на самом деле это форма ответа. Проблема была решена путем «включения параметра ClearType в настройках ОС». – quetzalcoatl

+0

@ apomene, @ quetzalcoatl: да, это была форма, чтобы опубликовать ответ на мой вопрос, поскольку я не нашел другого лучшего способа. – TecMan

 Смежные вопросы

  • Нет связанных вопросов^_^