From 66815259f590d8a88cab69e0a813bc6e8c6029cc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 15 Sep 2012 23:19:35 +0000 Subject: [PATCH] Fix text origin and bounding box computations in wxSVGFileDC. Text origin was calculated incorrectly for the rotated text and the bounding box was wrong even in non-rotated case. Fix this by using correct definition of the text anchor according to the SVG specification and add a test to the svg sample demonstrating this. Closes #14489. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72494 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + samples/svg/svgtest.cpp | 48 ++++++++++++++++++++++++++++++++++++++++- src/common/dcsvg.cpp | 11 ++++++---- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index a46dd90547..20aa862f3c 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -551,6 +551,7 @@ All (GUI): - Add wxBitmapButton::NewCloseButton(). - Add wxTextEntry::SelectNone() (troelsk). - Restore the original wxGrid col/row size when unhiding it (Michael Richards). +- Fix text origin and extent computations in wxSVGFileDC (Neil Chittenden). wxGTK: diff --git a/samples/svg/svgtest.cpp b/samples/svg/svgtest.cpp index 8e792daa71..ba6561bd06 100644 --- a/samples/svg/svgtest.cpp +++ b/samples/svg/svgtest.cpp @@ -40,6 +40,8 @@ #include "../sample.xpm" #endif +#include + class MyChild; class MyCanvas; @@ -321,7 +323,7 @@ MyCanvas::MyCanvas(MyChild *parent, const wxPoint& pos, const wxSize& size) SetBackgroundColour(wxColour(wxT("WHITE"))); m_child = parent; - m_index = m_child->GetFrame()->GetCountOfChildren() % 7; + m_index = m_child->GetFrame()->GetCountOfChildren() % 8; } // Define the repainting behaviour @@ -493,6 +495,50 @@ void MyCanvas::OnDraw(wxDC& dc) #endif // wxUSE_STATUSBAR break; + case 7: + wxString txtStr; + wxCoord txtX, txtY, txtW, txtH, txtDescent, txtEL; + wxCoord txtPad = 0; + + wP = *wxRED_PEN; + dc.SetPen(wP); + //dc.SetBackgroundMode(wxBRUSHSTYLE_SOLID); + //dc.SetTextBackground(*wxBLUE); + + // Horizontal text + txtStr = wxT("Horizontal string"); + dc.GetTextExtent(txtStr, &txtW, &txtH, &txtDescent, &txtEL); + txtX = 50; + txtY = 300; + dc.DrawRectangle(txtX, txtY, txtW + 2*txtPad, txtH + 2*txtPad); + dc.DrawText(txtStr, txtX + txtPad, txtY + txtPad); + + // Vertical text + txtStr = wxT("Vertical string"); + dc.GetTextExtent(txtStr, &txtW, &txtH, &txtDescent, &txtEL); + txtX = 50; + txtY = 250; + dc.DrawRectangle(txtX, txtY - (txtW + 2*txtPad), txtH + 2*txtPad, txtW + 2*txtPad); + dc.DrawRotatedText(txtStr, txtX + txtPad, txtY - txtPad, 90); + + // 45 degree text + txtStr = wxT("45 deg string"); + dc.GetTextExtent(txtStr, &txtW, &txtH, &txtDescent, &txtEL); + double lenW = (double)(txtW + 2*txtPad) / sqrt(2.0); + double lenH = (double)(txtH + 2*txtPad) / sqrt(2.0); + double padding = (double)txtPad / sqrt(2.0); + txtX = 150; + txtY = 200; + dc.DrawLine(txtX - padding, txtY, txtX + lenW, txtY - lenW); // top + dc.DrawLine(txtX + lenW, txtY - lenW, txtX - padding + lenH + lenW, txtY + (lenH - lenW)); + dc.DrawLine(txtX - padding, txtY, txtX - padding + lenH, txtY + lenH); + dc.DrawLine(txtX - padding + lenH, txtY + lenH, txtX - padding + lenH + lenW, txtY + (lenH - lenW)); // bottom + dc.DrawRotatedText(txtStr, txtX, txtY, 45); +#if wxUSE_STATUSBAR + s = wxT("Text position test page"); +#endif // wxUSE_STATUSBAR + break; + } #if wxUSE_STATUSBAR m_child->SetStatusText(s); diff --git a/src/common/dcsvg.cpp b/src/common/dcsvg.cpp index 6d922b3fae..494d78b519 100644 --- a/src/common/dcsvg.cpp +++ b/src/common/dcsvg.cpp @@ -253,23 +253,26 @@ void wxSVGFileDCImpl::DoDrawRotatedText(const wxString& sText, wxCoord x, wxCoor CalcBoundingBox((wxCoord)(x + w*cos(rad)), (wxCoord)(y - h*sin(rad))); // wxT("bottom left") and wxT("bottom right") - x += (wxCoord)(h*sin(rad)); - y += (wxCoord)(h*cos(rad)); - CalcBoundingBox(x, y); CalcBoundingBox((wxCoord)(x + h*sin(rad)), (wxCoord)(y + h*cos(rad))); + CalcBoundingBox((wxCoord)(x + h*sin(rad) + w*cos(rad)), (wxCoord)(y + h*cos(rad) - w*sin(rad))); if (m_backgroundMode == wxBRUSHSTYLE_SOLID) { // draw background first // just like DoDrawRectangle except we pass the text color to it and set the border to a 1 pixel wide text background - sTmp.Printf ( wxT(" "), NumStr(-angle), x,y ); s += sTmp + wxT("\n"); write(s); } + + // convert x,y to SVG text x,y (the coordinates of the text baseline) + x = (wxCoord)(x + (h-desc)*sin(rad)); + y = (wxCoord)(y + (h-desc)*cos(rad)); + //now do the text itself s.Printf (wxT("