Add wxDC::GetFontMetrics() and implement it for wxMSW.

Add a new wxDC method allowing to retrieve the font characteristics not
available from GetTextExtent(), notably the internal leading (and also the
average font width).

Currently this is implemented for wxMSW only, the internal leading is always 0
in the other ports.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67063 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2011-02-27 12:48:13 +00:00
parent f5bdfc69a5
commit e29bf4b056
5 changed files with 132 additions and 7 deletions

View File

@ -114,6 +114,27 @@ enum wxMappingMode
wxMM_POINTS
};
// Description of text characteristics.
struct wxFontMetrics
{
wxFontMetrics()
{
height =
ascent =
descent =
internalLeading =
externalLeading =
averageWidth = 0;
}
int height, // Total character height.
ascent, // Part of the height above the baseline.
descent, // Part of the height below the baseline.
internalLeading, // Intra-line spacing.
externalLeading, // Inter-line spacing.
averageWidth; // Average font width, a.k.a. "x-width".
};
#if WXWIN_COMPATIBILITY_2_8
//-----------------------------------------------------------------------------
@ -375,6 +396,18 @@ public:
virtual wxCoord GetCharHeight() const = 0;
virtual wxCoord GetCharWidth() const = 0;
// The derived classes should really override DoGetFontMetrics() to return
// the correct values in the future but for now provide a default
// implementation in terms of DoGetTextExtent() to avoid breaking the
// compilation of all other ports as wxMSW is the only one to implement it.
virtual void DoGetFontMetrics(int *height,
int *ascent,
int *descent,
int *internalLeading,
int *externalLeading,
int *averageWidth) const;
virtual void DoGetTextExtent(const wxString& string,
wxCoord *x, wxCoord *y,
wxCoord *descent = NULL,
@ -840,6 +873,15 @@ public:
wxCoord GetCharWidth() const
{ return m_pimpl->GetCharWidth(); }
wxFontMetrics GetFontMetrics() const
{
wxFontMetrics fm;
m_pimpl->DoGetFontMetrics(&fm.height, &fm.ascent, &fm.descent,
&fm.internalLeading, &fm.externalLeading,
&fm.averageWidth);
return fm;
}
void GetTextExtent(const wxString& string,
wxCoord *x, wxCoord *y,
wxCoord *descent = NULL,

View File

@ -165,6 +165,12 @@ protected:
void RealizeScaleAndOrigin();
public:
virtual void DoGetFontMetrics(int *height,
int *ascent,
int *descent,
int *internalLeading,
int *externalLeading,
int *averageWidth) const;
virtual void DoGetTextExtent(const wxString& string,
wxCoord *x, wxCoord *y,
wxCoord *descent = NULL,

View File

@ -79,6 +79,28 @@ enum wxMappingMode
wxMM_POINTS
};
/**
Simple collection of various font metrics.
This object is returned by wxDC::GetFontMetrics().
@since 2.9.2
@library{wxcore}
@category{dc,gdi}
*/
struct wxFontMetrics
{
/// Constructor initializes all fields to 0.
wxFontMetrics();
int height, ///< Total character height.
ascent, ///< Part of the height above the baseline.
descent, ///< Part of the height below the baseline.
internalLeading, ///< Intra-line spacing.
externalLeading, ///< Inter-line spacing.
averageWidth; ///< Average font width, a.k.a. "x-width".
};
/**
@ -773,6 +795,21 @@ public:
*/
wxCoord GetCharWidth() const;
/**
Returns the various font characteristics.
This method allows to retrieve some of the font characteristics not
returned by GetTextExtent(), notably internal leading and average
character width.
Currently this method returns correct results only under wxMSW, in the
other ports the internal leading will always be 0 and the average
character width will be computed as the width of the character 'x'.
@since 2.9.2
*/
wxFontMetrics GetFontMetrics() const;
/**
Gets the dimensions of the string using the currently selected font.
@a string is the text string to measure, @e heightLine, if non @NULL,

View File

@ -1134,6 +1134,27 @@ void wxDCImpl::InheritAttributes(wxWindow *win)
SetLayoutDirection(win->GetLayoutDirection());
}
void wxDCImpl::DoGetFontMetrics(int *height,
int *ascent,
int *descent,
int *internalLeading,
int *externalLeading,
int *averageWidth) const
{
// Average width is typically the same as width of 'x'.
wxCoord h, d;
DoGetTextExtent("x", averageWidth, &h, &d, externalLeading);
if ( height )
*height = h;
if ( ascent )
*ascent = h - d;
if ( descent )
*descent = d;
if ( internalLeading )
*internalLeading = 0;
}
//-----------------------------------------------------------------------------
// wxDC
//-----------------------------------------------------------------------------

View File

@ -1722,6 +1722,31 @@ wxCoord wxMSWDCImpl::GetCharWidth() const
return lpTextMetric.tmAveCharWidth;
}
void wxMSWDCImpl::DoGetFontMetrics(int *height,
int *ascent,
int *descent,
int *internalLeading,
int *externalLeading,
int *averageWidth) const
{
TEXTMETRIC tm;
GetTextMetrics(GetHdc(), &tm);
if ( height )
*height = tm.tmHeight;
if ( ascent )
*ascent = tm.tmAscent;
if ( descent )
*descent = tm.tmDescent;
if ( internalLeading )
*internalLeading = tm.tmInternalLeading;
if ( externalLeading )
*externalLeading = tm.tmExternalLeading;
if ( averageWidth )
*averageWidth = tm.tmAveCharWidth;
}
void wxMSWDCImpl::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y,
wxCoord *descent, wxCoord *externalLeading,
const wxFont *font) const
@ -1791,13 +1816,7 @@ void wxMSWDCImpl::DoGetTextExtent(const wxString& string, wxCoord *x, wxCoord *y
if ( descent || externalLeading )
{
TEXTMETRIC tm;
::GetTextMetrics(GetHdc(), &tm);
if (descent)
*descent = tm.tmDescent;
if (externalLeading)
*externalLeading = tm.tmExternalLeading;
DoGetFontMetrics(NULL, NULL, descent, NULL, externalLeading, NULL);
}
if ( hfontOld )