Avoid 1px gaps between consecutive underlined words in wxHTML

At least when using standard fonts under MSW, the underlines under the
consecutive words didn't overlap, resulting in ugly gaps between them when
using more than one word as the link text, for example.

Work around this by drawing an extra, slightly offset, underlined space when
the previous cell was drawn underlined.
This commit is contained in:
Vadim Zeitlin
2015-12-03 03:55:52 +01:00
parent 9f15ca5f53
commit 0dc57e9e23
3 changed files with 30 additions and 1 deletions

View File

@@ -103,6 +103,7 @@ All (GUI):
- XRC handler for wxAuiToolBar added (Kinaou Hervé, David Hart). - XRC handler for wxAuiToolBar added (Kinaou Hervé, David Hart).
- Improve wxLIST_AUTOSIZE_XXX support in generic wxListCtrl (Kinaou Hervé). - Improve wxLIST_AUTOSIZE_XXX support in generic wxListCtrl (Kinaou Hervé).
- Support "color", "size" and "font" CSS for fonts in wxHTML (Kinaou Hervé). - Support "color", "size" and "font" CSS for fonts in wxHTML (Kinaou Hervé).
- Fix one pixel gaps between consecutive underlined words in wxHTML.
- Add wxCursor::GetHotSpot(). - Add wxCursor::GetHotSpot().
- Add wxFD_NO_FOLLOW style for wxFileDialog (Luca Bacci). - Add wxFD_NO_FOLLOW style for wxFileDialog (Luca Bacci).
- Add support for embedding bitmaps in generated SVG in wxSVGFileDC (iwbnwif). - Add support for embedding bitmaps in generated SVG in wxSVGFileDC (iwbnwif).

View File

@@ -125,7 +125,12 @@ public:
class WXDLLIMPEXP_HTML wxHtmlRenderingInfo class WXDLLIMPEXP_HTML wxHtmlRenderingInfo
{ {
public: public:
wxHtmlRenderingInfo() : m_selection(NULL), m_style(NULL) {} wxHtmlRenderingInfo()
: m_selection(NULL),
m_style(NULL),
m_prevUnderlined(false)
{
}
void SetSelection(wxHtmlSelection *s) { m_selection = s; } void SetSelection(wxHtmlSelection *s) { m_selection = s; }
wxHtmlSelection *GetSelection() const { return m_selection; } wxHtmlSelection *GetSelection() const { return m_selection; }
@@ -133,12 +138,16 @@ public:
void SetStyle(wxHtmlRenderingStyle *style) { m_style = style; } void SetStyle(wxHtmlRenderingStyle *style) { m_style = style; }
wxHtmlRenderingStyle& GetStyle() { return *m_style; } wxHtmlRenderingStyle& GetStyle() { return *m_style; }
void SetCurrentUnderlined(bool u) { m_prevUnderlined = u; }
bool WasPreviousUnderlined() const { return m_prevUnderlined; }
wxHtmlRenderingState& GetState() { return m_state; } wxHtmlRenderingState& GetState() { return m_state; }
protected: protected:
wxHtmlSelection *m_selection; wxHtmlSelection *m_selection;
wxHtmlRenderingStyle *m_style; wxHtmlRenderingStyle *m_style;
wxHtmlRenderingState m_state; wxHtmlRenderingState m_state;
bool m_prevUnderlined;
}; };

View File

@@ -480,6 +480,25 @@ void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
wxHtmlSelectionState selstate = info.GetState().GetSelectionState(); wxHtmlSelectionState selstate = info.GetState().GetSelectionState();
// Not changing selection state, draw the word in single mode: // Not changing selection state, draw the word in single mode:
SwitchSelState(dc, info, selstate != wxHTML_SEL_OUT); SwitchSelState(dc, info, selstate != wxHTML_SEL_OUT);
// This is a quite horrible hack but it fixes a nasty user-visible
// problem: when drawing underlined text, which is common in wxHTML as
// all links are underlined, there is a 1 pixel gap between the
// underlines because we draw separate words in separate DrawText()
// calls. The right thing to do would be to draw all of them appearing
// on the same line at once (this would probably be more efficient as
// well), but this doesn't seem simple to do, so instead we just draw
// an extra space at a negative offset to ensure that the underline
// spans the previous pixel and so overlaps the one from the previous
// word, if any.
const bool prevUnderlined = info.WasPreviousUnderlined();
const bool thisUnderlined = dc.GetFont().GetUnderlined();
if ( prevUnderlined && thisUnderlined )
{
dc.DrawText(wxS(" "), x + m_PosX - 1, y + m_PosY);
}
info.SetCurrentUnderlined(thisUnderlined);
dc.DrawText(m_Word, x + m_PosX, y + m_PosY); dc.DrawText(m_Word, x + m_PosX, y + m_PosY);
drawSelectionAfterCell = (selstate != wxHTML_SEL_OUT); drawSelectionAfterCell = (selstate != wxHTML_SEL_OUT);
} }