From ba5d07f4b4c551bb6dfb43af30d17136d28ad910 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Fri, 27 Jan 2017 22:42:31 +0100 Subject: [PATCH] Fix underline length for underlined text (wxPostScriptDC) Draw underline relatively to the baseline and obtain line parameters using 'stringwidth' operator instead of calculating them manually based on the parameters returned by DoGetTextExtent(), which are not always accurate (e.g. if no AFM files are available). Closes #17788. --- docs/changes.txt | 1 + src/generic/dcpsg.cpp | 64 +++++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 6f3e9c0910..99fc162458 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -120,6 +120,7 @@ All (GUI): - Improve wxImage::Scale() handling of pixels with alpha channel (Tim Kosse). - Fix parsing of RGBA strings in wxColour (Laurent Poujoulat). - Refactor code in wxQuantize() for MSVC to avoid crash. +- Fix drawing rotated and/or underlined text on wxPostScriptDC. wxGTK: diff --git a/src/generic/dcpsg.cpp b/src/generic/dcpsg.cpp index 1bb1ce14f4..ac5fce3a40 100644 --- a/src/generic/dcpsg.cpp +++ b/src/generic/dcpsg.cpp @@ -1354,9 +1354,9 @@ void wxPostScriptDCImpl::DoDrawText( const wxString& text, wxCoord x, wxCoord y } } - wxCoord text_w, text_h, text_descent; + wxCoord text_descent; - GetOwner()->GetTextExtent(text, &text_w, &text_h, &text_descent); + GetOwner()->GetTextExtent(text, NULL, NULL, &text_descent); int size = m_font.GetPointSize(); @@ -1392,25 +1392,30 @@ void wxPostScriptDCImpl::DoDrawText( const wxString& text, wxCoord x, wxCoord y } } - PsPrint( ") show\n" ); + PsPrint( ")\n" ); if (m_font.GetUnderlined()) { - wxCoord uy = (wxCoord)(y + size - m_underlinePosition); - + // We need relative underline position + // with reference to the baseline: + // uy = y + size - m_underlinePosition => + // uy = by + text_descent - m_underlinePosition => + // dy = -(text_descent - m_underlinePosition) + // It's negated due to the orientation of Y-axis. buffer.Printf( "gsave\n" - "%f %f moveto\n" + "0.0 %f rmoveto\n" "%f setlinewidth\n" - "%f %f lineto\n" + "dup stringwidth rlineto\n" "stroke\n" "grestore\n", - XLOG2DEV(x), YLOG2DEV(uy), - m_underlineThickness, - XLOG2DEV(x + text_w), YLOG2DEV(uy) ); + -YLOG2DEVREL(text_descent - m_underlinePosition), + m_underlineThickness ); buffer.Replace( ",", "." ); PsPrint( buffer ); } + PsPrint("show\n"); + CalcBoundingBox( x, y ); CalcBoundingBox( x + size * text.length() * 2/3 , y ); } @@ -1507,32 +1512,33 @@ void wxPostScriptDCImpl::DoDrawRotatedText( const wxString& text, wxCoord x, wxC } } - PsPrint( ") show\n" ); - - buffer.Printf( "%f rotate\n", -angle ); - buffer.Replace( ",", "." ); - PsPrint( buffer ); + PsPrint( ")\n" ); if (m_font.GetUnderlined()) { - wxCoord uy = (wxCoord)(y + size - m_underlinePosition); - wxCoord w, h; - GetOwner()->GetTextExtent(text, &w, &h); - - buffer.Printf( - "gsave\n" - "%f %f moveto\n" - "%f setlinewidth\n" - "%f %f lineto\n" - "stroke\n" - "grestore\n", - XLOG2DEV(x), YLOG2DEV(uy), - m_underlineThickness, - XLOG2DEV(x + w), YLOG2DEV(uy) ); + // We need relative underline position with reference + // to the baseline in rotated coordinate system: + // uy = y + size - m_underlinePosition => + // uy = by + text_descent - m_underlinePosition => + // dy = -(text_descent - m_underlinePosition) + // It's negated due to the orientation of Y-axis. + buffer.Printf( "gsave\n" + "0.0 %f rmoveto\n" + "%f setlinewidth\n" + "dup stringwidth rlineto\n" + "stroke\n" + "grestore\n", + -YLOG2DEVREL(text_descent - m_underlinePosition), + m_underlineThickness ); buffer.Replace( ",", "." ); PsPrint( buffer ); } + PsPrint("show\n"); + buffer.Printf( "%f rotate\n", -angle ); + buffer.Replace( ",", "." ); + PsPrint( buffer ); + CalcBoundingBox( x, y ); CalcBoundingBox( x + size * text.length() * 2/3 , y ); }