Fix size of text drawing using wxGraphicsContext when printing
When using both wxEnhMetaFileDC (used for print preview) and
wxPrinterDC, a global scale factor was applied to the graphics context
in wxGDIPlusPrintingContext ctor and this changes size of the text
rendered using size specified in point units.
To prevent this from happening, stop applying this scale factor in the
base class GetTextExtent() and apply it instead when setting fonts in
the derived wxGDIPlusPrintingContext only. This ensures that the results
are consistent between GetTextExtent() and DrawText() and also keeps
the font scale hack entirely in wxGDIPlusPrintingContext without
affecting the base class.
It's still not totally clear why do we have to do this at all even
although we specify the font sizes in UnitPoint units which ought to be
DPI-independent -- but somehow are not. But at least the output is
correct now and the code is arguably more clear than before.
This fixes a regression with text size when printing or previewing
introduced by d5020362ff
Closes #18338.
This commit is contained in:
@@ -336,6 +336,14 @@ public:
|
||||
REAL size,
|
||||
int style,
|
||||
const wxColour& col);
|
||||
|
||||
// This ctor takes ownership of the brush.
|
||||
wxGDIPlusFontData(wxGraphicsRenderer* renderer,
|
||||
const wxString& name,
|
||||
REAL size,
|
||||
int style,
|
||||
Brush* textBrush);
|
||||
|
||||
~wxGDIPlusFontData();
|
||||
|
||||
virtual Brush* GetGDIPlusBrush() { return m_textBrush; }
|
||||
@@ -347,7 +355,16 @@ private :
|
||||
void Init(const wxString& name,
|
||||
REAL size,
|
||||
int style,
|
||||
const wxColour& col);
|
||||
Brush* textBrush);
|
||||
|
||||
// Common part of ctors taking wxColour.
|
||||
void Init(const wxString& name,
|
||||
REAL size,
|
||||
int style,
|
||||
const wxColour& col)
|
||||
{
|
||||
Init(name, size, style, new SolidBrush(wxColourToColor(col)));
|
||||
}
|
||||
|
||||
Brush* m_textBrush;
|
||||
Font* m_font;
|
||||
@@ -432,9 +449,6 @@ public:
|
||||
Graphics* GetGraphics() const { return m_context; }
|
||||
|
||||
protected:
|
||||
|
||||
wxDouble m_fontScaleRatio;
|
||||
|
||||
// Used from ctors (including those in the derived classes) and takes
|
||||
// ownership of the graphics pointer that must be non-NULL.
|
||||
void Init(Graphics* graphics, int width, int height);
|
||||
@@ -507,7 +521,41 @@ class wxGDIPlusPrintingContext : public wxGDIPlusContext
|
||||
{
|
||||
public:
|
||||
wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer, const wxDC& dc );
|
||||
protected:
|
||||
|
||||
// Override to scale the font proportionally to the DPI.
|
||||
virtual void SetFont(const wxGraphicsFont& font) wxOVERRIDE
|
||||
{
|
||||
// The casts here are safe because we're only supposed to be passed
|
||||
// fonts created by this renderer.
|
||||
Font* const f = static_cast<wxGDIPlusFontData*>(font.GetRefData())->GetGDIPlusFont();
|
||||
Brush* const b = static_cast<wxGDIPlusFontData*>(font.GetRefData())->GetGDIPlusBrush();
|
||||
|
||||
// To scale the font, we need to create a new one which means
|
||||
// retrieving all the parameters originally used to create the font.
|
||||
FontFamily ffamily;
|
||||
f->GetFamily(&ffamily);
|
||||
|
||||
WCHAR familyName[LF_FACESIZE];
|
||||
ffamily.GetFamilyName(familyName);
|
||||
|
||||
wxGraphicsFont fontScaled;
|
||||
fontScaled.SetRefData(new wxGDIPlusFontData
|
||||
(
|
||||
GetRenderer(),
|
||||
familyName,
|
||||
f->GetSize() / m_fontScaleRatio,
|
||||
f->GetStyle(),
|
||||
b->Clone()
|
||||
));
|
||||
wxGDIPlusContext::SetFont(fontScaled);
|
||||
}
|
||||
|
||||
private:
|
||||
// This is logically const ratio between this context DPI and the standard
|
||||
// one which is used for scaling the fonts used with this context: without
|
||||
// this, the fonts wouldn't have the correct size, even though we
|
||||
// explicitly create them using UnitPoint units.
|
||||
wxDouble m_fontScaleRatio;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -982,7 +1030,7 @@ void
|
||||
wxGDIPlusFontData::Init(const wxString& name,
|
||||
REAL size,
|
||||
int style,
|
||||
const wxColour& col)
|
||||
Brush* textBrush)
|
||||
{
|
||||
#if wxUSE_PRIVATE_FONTS
|
||||
// If the user has registered any private fonts, they should be used in
|
||||
@@ -1014,7 +1062,7 @@ wxGDIPlusFontData::Init(const wxString& name,
|
||||
m_font = new Font(name.wc_str(), size, style, UnitPoint);
|
||||
}
|
||||
|
||||
m_textBrush = new SolidBrush(wxColourToColor(col));
|
||||
m_textBrush = textBrush;
|
||||
}
|
||||
|
||||
wxGDIPlusFontData::wxGDIPlusFontData( wxGraphicsRenderer* renderer,
|
||||
@@ -1045,6 +1093,16 @@ wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer,
|
||||
Init(name, size, style, col);
|
||||
}
|
||||
|
||||
wxGDIPlusFontData::wxGDIPlusFontData(wxGraphicsRenderer* renderer,
|
||||
const wxString& name,
|
||||
REAL size,
|
||||
int style,
|
||||
Brush* brush)
|
||||
: wxGraphicsObjectRefData(renderer)
|
||||
{
|
||||
Init(name, size, style, brush);
|
||||
}
|
||||
|
||||
wxGDIPlusFontData::~wxGDIPlusFontData()
|
||||
{
|
||||
delete m_textBrush;
|
||||
@@ -1686,7 +1744,6 @@ void wxGDIPlusContext::Init(Graphics* graphics, int width, int height)
|
||||
m_state2 = 0;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_fontScaleRatio = 1.0;
|
||||
|
||||
m_context->SetTextRenderingHint(TextRenderingHintSystemDefault);
|
||||
m_context->SetPixelOffsetMode(PixelOffsetModeHalf);
|
||||
@@ -2118,8 +2175,6 @@ void wxGDIPlusContext::GetTextExtent( const wxString &str, wxDouble *width, wxDo
|
||||
FontFamily ffamily ;
|
||||
f->GetFamily(&ffamily) ;
|
||||
|
||||
REAL factorY = m_fontScaleRatio;
|
||||
|
||||
// Notice that we must use the real font style or the results would be
|
||||
// incorrect for italic/bold fonts.
|
||||
const INT style = f->GetStyle();
|
||||
@@ -2130,11 +2185,11 @@ void wxGDIPlusContext::GetTextExtent( const wxString &str, wxDouble *width, wxDo
|
||||
REAL rHeight = ffamily.GetLineSpacing(style) * size / emHeight;
|
||||
|
||||
if ( height && str.empty() )
|
||||
*height = rHeight * factorY;
|
||||
*height = rHeight;
|
||||
if ( descent )
|
||||
*descent = rDescent * factorY;
|
||||
*descent = rDescent;
|
||||
if ( externalLeading )
|
||||
*externalLeading = (rHeight - rAscent - rDescent) * factorY;
|
||||
*externalLeading = rHeight - rAscent - rDescent;
|
||||
}
|
||||
|
||||
// measuring empty strings is not guaranteed, so do it by hand
|
||||
@@ -2277,7 +2332,7 @@ wxGDIPlusPrintingContext::wxGDIPlusPrintingContext( wxGraphicsRenderer* renderer
|
||||
|
||||
// We use this modifier when measuring fonts. It is needed because the
|
||||
// page scale is modified above.
|
||||
m_fontScaleRatio = context->GetDpiY() / 72.0;
|
||||
m_fontScaleRatio = context->GetDpiY() / 96.0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user