diff --git a/docs/changes.txt b/docs/changes.txt index 22439c6db6..b28f85a2b4 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -100,6 +100,9 @@ All (Unix): - Return false from wxSingleInstanceChecker::IsAnotherRunning() if an error occurred while opening or reading the lock file (Lauri Nurmi). +wxGTK: + +- Fixed printing to use fonts sizes adjustment consistent with wxMSW. 2.8.9 ----- diff --git a/include/wx/dc.h b/include/wx/dc.h index 0273c4de76..302838ae24 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -466,7 +466,6 @@ public: bool GetPartialTextExtents(const wxString& text, wxArrayInt& widths) const { return DoGetPartialTextExtents(text, widths); } - // size and resolution // ------------------- @@ -793,6 +792,13 @@ protected: virtual void DoDrawSpline(wxList *points); #endif +#if wxABI_VERSION >= 20810 + // returns adjustment factor for converting wxFont "point size"; in wx + // it is point size on screen and needs to be multiplied by this value + // for rendering on higher-resolution DCs such as printer ones + static float GetFontPointSizeAdjustment(float dpi); +#endif + protected: // unset clipping variables (after clipping region was destroyed) void ResetClipping() diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 5785668250..8ff7a8b302 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -1157,3 +1157,18 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, } // CalculateEllipticPoints #endif + + +float wxDCBase::GetFontPointSizeAdjustment(float dpi) +{ + // wxMSW has long-standing bug where wxFont point size is interpreted as + // "pixel size corresponding to given point size *on screen*". In other + // words, on a typical 600dpi printer and a typical 96dpi screen, fonts + // are ~6 times smaller when printing. Unfortunately, this bug is so severe + // that *all* printing code has to account for it and consequently, other + // ports need to emulate this bug too: + const wxSize screenPixels = wxGetDisplaySize(); + const wxSize screenMM = wxGetDisplaySizeMM(); + const int screenPPI_y = (screenPixels.y * 25.4) / screenMM.y; + return float(screenPPI_y) / dpi; +} diff --git a/src/generic/dcpsg.cpp b/src/generic/dcpsg.cpp index 77cf30e876..0ee8f72d50 100644 --- a/src/generic/dcpsg.cpp +++ b/src/generic/dcpsg.cpp @@ -987,8 +987,11 @@ void wxPostScriptDC::SetFont( const wxFont& font ) PsPrint( name ); PsPrint( " findfont\n" ); + float size = float(m_font.GetPointSize()); + size = size * GetFontPointSizeAdjustment(GetResolution()); + char buffer[100]; - sprintf( buffer, "%f scalefont setfont\n", LogicalToDeviceYRel(m_font.GetPointSize() * 1000) / 1000.0F); + sprintf( buffer, "%f scalefont setfont\n", size * m_scaleX); // this is a hack - we must scale font size (in pts) according to m_scaleY but // LogicalToDeviceYRel works with wxCoord type (int or longint). Se we first convert font size // to 1/1000th of pt and then back. @@ -1840,7 +1843,8 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string, if (!fontToUse) fontToUse = (wxFont*) &m_font; - wxCHECK_RET( fontToUse, wxT("GetTextExtent: no font defined") ); + const float fontSize = + fontToUse->GetPointSize() * GetFontPointSizeAdjustment(72.0); if (string.empty()) { @@ -1860,15 +1864,10 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string, * Produces accurate results for mono-spaced font * such as Courier (aka wxMODERN) */ - int height = 12; - if (fontToUse) - { - height = fontToUse->GetPointSize(); - } if ( x ) - *x = strlen (strbuf) * height * 72 / 120; + *x = strlen (strbuf) * fontSize * 72.0 / 120.0; if ( y ) - *y = (wxCoord) (height * 1.32); /* allow for descender */ + *y = (wxCoord) (fontSize * 1.32); /* allow for descender */ if (descent) *descent = 0; if (externalLeading) *externalLeading = 0; #else @@ -2135,9 +2134,9 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string, // VS: dirty, but is there any better solution? double *pt; pt = (double*) &m_underlinePosition; - *pt = LogicalToDeviceYRel((wxCoord)(UnderlinePosition * fontToUse->GetPointSize())) / 1000.0f; + *pt = LogicalToDeviceYRel((wxCoord)(UnderlinePosition * fontSize)) / 1000.0f; pt = (double*) &m_underlineThickness; - *pt = LogicalToDeviceYRel((wxCoord)(UnderlineThickness * fontToUse->GetPointSize())) / 1000.0f; + *pt = LogicalToDeviceYRel((wxCoord)(UnderlineThickness * fontSize)) / 1000.0f; } @@ -2147,7 +2146,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string, / string. they are given in 1/1000 of the size! */ long sum=0; - wxCoord height=Size; /* by default */ + float height=fontSize; /* by default */ unsigned char *p; for(p=(unsigned char *)wxMBSTRINGCAST strbuf; *p; p++) { @@ -2163,7 +2162,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string, } double widthSum = sum; - widthSum *= Size; + widthSum *= fontSize; widthSum /= 1000.0F; /* add descender to height (it is usually a negative value) */ @@ -2178,14 +2177,14 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string, if ( x ) *x = (wxCoord)widthSum; if ( y ) - *y = height; + *y = (wxCoord)height; /* return other parameters */ if (descent) { if(lastDescender!=INT_MIN) { - *descent = (wxCoord)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */ + *descent = (wxCoord)(((-lastDescender)/1000.0F) * fontSize); /* MATTHEW: forgot scale */ } else { diff --git a/src/gtk/gnome/gprint.cpp b/src/gtk/gnome/gprint.cpp index 927aa1afc3..2e06055a50 100644 --- a/src/gtk/gnome/gprint.cpp +++ b/src/gtk/gnome/gprint.cpp @@ -1507,8 +1507,8 @@ void wxGnomePrintDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y ) void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle) { - x = XLOG2DEV(x); - y = YLOG2DEV(y); + double xx = XLOG2DEV(x); + double yy = YLOG2DEV(y); bool underlined = m_font.Ok() && m_font.GetUnderlined(); @@ -1555,76 +1555,31 @@ void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord } } +#if 0 + if ( m_backgroundMode == wxSOLID ) + { + gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor()); + gdk_draw_rectangle(m_window, m_textGC, TRUE, xx, yy, w, h); + gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor()); + } +#endif + + // Draw layout. + gs_lgp->gnome_print_moveto (m_gpc, xx, yy); + + gs_lgp->gnome_print_gsave( m_gpc ); + + gs_lgp->gnome_print_scale( m_gpc, m_scaleX, m_scaleY ); + + if (fabs(angle) > 0.00001) + gs_lgp->gnome_print_rotate( m_gpc, angle ); + + gs_lgp->gnome_print_pango_layout( m_gpc, m_layout ); + int w,h; + pango_layout_get_pixel_size( m_layout, &w, &h ); - if (fabs(m_scaleY - 1.0) > 0.00001) - { - // If there is a user or actually any scale applied to - // the device context, scale the font. - - // scale font description - gint oldSize = pango_font_description_get_size( m_fontdesc ); - double size = oldSize; - size = size * m_scaleY; - pango_font_description_set_size( m_fontdesc, (gint)size ); - - // actually apply scaled font - pango_layout_set_font_description( m_layout, m_fontdesc ); - - pango_layout_get_pixel_size( m_layout, &w, &h ); -#if 0 - if ( m_backgroundMode == wxSOLID ) - { - gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor()); - gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h); - gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor()); - } -#endif - // Draw layout. - gs_lgp->gnome_print_moveto (m_gpc, x, y); - if (fabs(angle) > 0.00001) - { - gs_lgp->gnome_print_gsave( m_gpc ); - gs_lgp->gnome_print_rotate( m_gpc, angle ); - gs_lgp->gnome_print_pango_layout( m_gpc, m_layout ); - gs_lgp->gnome_print_grestore( m_gpc ); - } - else - { - gs_lgp->gnome_print_pango_layout( m_gpc, m_layout ); - } - - // reset unscaled size - pango_font_description_set_size( m_fontdesc, oldSize ); - - // actually apply unscaled font - pango_layout_set_font_description( m_layout, m_fontdesc ); - } - else - { - pango_layout_get_pixel_size( m_layout, &w, &h ); -#if 0 - if ( m_backgroundMode == wxSOLID ) - { - gdk_gc_set_foreground(m_textGC, m_textBackgroundColour.GetColor()); - gdk_draw_rectangle(m_window, m_textGC, TRUE, x, y, w, h); - gdk_gc_set_foreground(m_textGC, m_textForegroundColour.GetColor()); - } -#endif - // Draw layout. - gs_lgp->gnome_print_moveto (m_gpc, x, y); - if (fabs(angle) > 0.00001) - { - gs_lgp->gnome_print_gsave( m_gpc ); - gs_lgp->gnome_print_rotate( m_gpc, angle ); - gs_lgp->gnome_print_pango_layout( m_gpc, m_layout ); - gs_lgp->gnome_print_grestore( m_gpc ); - } - else - { - gs_lgp->gnome_print_pango_layout( m_gpc, m_layout ); - } - } + gs_lgp->gnome_print_grestore( m_gpc ); if (underlined) { @@ -1632,7 +1587,8 @@ void wxGnomePrintDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord pango_layout_set_attributes(m_layout, NULL); } - CalcBoundingBox (x + w, y + h); + CalcBoundingBox(x, y); + CalcBoundingBox(x + w, y + h); } void wxGnomePrintDC::Clear() @@ -1650,6 +1606,10 @@ void wxGnomePrintDC::SetFont( const wxFont& font ) m_fontdesc = pango_font_description_copy( m_font.GetNativeFontInfo()->description ); + float size = pango_font_description_get_size( m_fontdesc ); + size = size * GetFontPointSizeAdjustment(72.0); + pango_font_description_set_size( m_fontdesc, (gint)size ); + pango_layout_set_font_description( m_layout, m_fontdesc ); } } @@ -1871,26 +1831,24 @@ void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxC return; } - PangoFontDescription *desc = (theFont) ? theFont->GetNativeFontInfo()->description : m_fontdesc; + gint oldSize; + if ( theFont ) + { + // scale the font and apply it + PangoFontDescription *desc = theFont->GetNativeFontInfo()->description; + float size = pango_font_description_get_size(desc); + size = size * GetFontPointSizeAdjustment(72.0); + pango_font_description_set_size(desc, (gint)size); - gint oldSize = pango_font_description_get_size( desc ); - double size = oldSize; - size = size * m_scaleY; - pango_font_description_set_size( desc, (gint)size ); - - // apply scaled font - pango_layout_set_font_description( m_layout, desc ); + pango_layout_set_font_description(m_layout, desc); + } pango_layout_set_text( m_layout, dataUTF8, strlen(dataUTF8) ); - int w, h; - pango_layout_get_pixel_size( m_layout, &w, &h ); - - - if (width) - *width = (wxCoord)(w / m_scaleX); - if (height) - *height = (wxCoord)(h / m_scaleY); + int h; + pango_layout_get_pixel_size( m_layout, width, &h ); + if ( height ) + *height = h; if (descent) { @@ -1900,11 +1858,14 @@ void wxGnomePrintDC::DoGetTextExtent(const wxString& string, wxCoord *width, wxC *descent = h - PANGO_PIXELS(baseline); } - // reset unscaled size - pango_font_description_set_size( desc, oldSize ); + if ( theFont ) + { + // restore font and reset font's size back + pango_layout_set_font_description(m_layout, m_fontdesc); - // reset unscaled font - pango_layout_set_font_description( m_layout, m_fontdesc ); + PangoFontDescription *desc = theFont->GetNativeFontInfo()->description; + pango_font_description_set_size(desc, oldSize); + } } void wxGnomePrintDC::DoGetSize(int* width, int* height) const diff --git a/version-script.in b/version-script.in index a6db3de926..c6323327f9 100644 --- a/version-script.in +++ b/version-script.in @@ -23,15 +23,19 @@ # released with the generic branch version due to the final wildcard below, # and once released its version cannot be changed. +# public symbols added in 2.8.10 (please keep in alphabetical order): +@WX_VERSION_TAG@.10 { + *wxDCBase*GetFontPointSizeAdjustment*; +}; # public symbols added in 2.8.9 (please keep in alphabetical order): -# public symbols added in 2.8.8 (please keep in alphabetical order): @WX_VERSION_TAG@.9 { *wxAuiTabCtrl*OnCaptureLost*; *wxAuiToolBar*; *wxWindow*UnsetToolTip*; }; +# public symbols added in 2.8.8 (please keep in alphabetical order): @WX_VERSION_TAG@.8 { global: *TimeZone*Make*;