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
This commit is contained in:
Vadim Zeitlin 2012-09-15 23:19:35 +00:00
parent c9848e6318
commit 66815259f5
3 changed files with 55 additions and 5 deletions

View File

@ -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:

View File

@ -40,6 +40,8 @@
#include "../sample.xpm"
#endif
#include <math.h>
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);

View File

@ -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(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x,y+desc-h, w, h );
sTmp.Printf ( wxT(" <rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" "), x, y, w, h );
s = sTmp + wxT("style=\"") + wxBrushString(m_textBackgroundColour);
s += wxT("stroke-width:1; ") + wxPenString(m_textBackgroundColour);
sTmp.Printf ( wxT("\" transform=\"rotate( %s %d %d ) \" />"), 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(" <text x=\"%d\" y=\"%d\" "),x,y );