Factor out text measurement from wxDC and wxWindow into wxTextMeasure.
Add a new private wxTextMeasure class implementing methods for measuring text and move the often duplicated (but not always identically) code for doing the same from wxDC and wxWindow into it. Currently this class is only really implemented in wxMSW and wxGTK. Also extend the test for text measuring functions and rename it to MeasuringTextTestCase from MeasuringContextTestCase as it's not wxGC-specific any more. Closes #14705. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72699 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
178
src/common/textmeasurecmn.cpp
Normal file
178
src/common/textmeasurecmn.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/common/textmeasurecmn.cpp
|
||||
// Purpose: wxTextMeasureBase implementation
|
||||
// Author: Manuel Martin
|
||||
// Created: 2012-10-05
|
||||
// Copyright: (c) 1997-2012 wxWidgets team
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// for compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/dc.h"
|
||||
#include "wx/window.h"
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/private/textmeasure.h"
|
||||
|
||||
// ============================================================================
|
||||
// wxTextMeasureBase implementation
|
||||
// ============================================================================
|
||||
|
||||
wxTextMeasureBase::wxTextMeasureBase(const wxDC *dc, const wxFont *theFont)
|
||||
: m_dc(dc),
|
||||
m_win(NULL),
|
||||
m_font(theFont)
|
||||
{
|
||||
wxASSERT_MSG( dc, wxS("wxTextMeasure needs a valid wxDC") );
|
||||
}
|
||||
|
||||
wxTextMeasureBase::wxTextMeasureBase(const wxWindow *win, const wxFont *theFont)
|
||||
: m_dc(NULL),
|
||||
m_win(win),
|
||||
m_font(theFont)
|
||||
{
|
||||
wxASSERT_MSG( win, wxS("wxTextMeasure needs a valid wxWindow") );
|
||||
}
|
||||
|
||||
void wxTextMeasureBase::GetTextExtent(const wxString& string,
|
||||
wxCoord *width,
|
||||
wxCoord *height,
|
||||
wxCoord *descent,
|
||||
wxCoord *externalLeading)
|
||||
{
|
||||
// To make the code simpler, make sure that the width and height pointers
|
||||
// are always valid, even if they point to dummy variables.
|
||||
int unusedWidth, unusedHeight;
|
||||
if ( !width )
|
||||
width = &unusedWidth;
|
||||
if ( !height )
|
||||
height = &unusedHeight;
|
||||
|
||||
if ( string.empty() )
|
||||
{
|
||||
*width =
|
||||
*height = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
MeasuringGuard guard(*this);
|
||||
|
||||
DoGetTextExtent(string, width, height, descent, externalLeading);
|
||||
}
|
||||
|
||||
void wxTextMeasureBase::GetMultiLineTextExtent(const wxString& text,
|
||||
wxCoord *width,
|
||||
wxCoord *height,
|
||||
wxCoord *heightOneLine)
|
||||
{
|
||||
MeasuringGuard guard(*this);
|
||||
|
||||
wxCoord widthTextMax = 0, widthLine,
|
||||
heightTextTotal = 0, heightLineDefault = 0, heightLine = 0;
|
||||
|
||||
wxString curLine;
|
||||
for ( wxString::const_iterator pc = text.begin(); ; ++pc )
|
||||
{
|
||||
if ( pc == text.end() || *pc == wxS('\n') )
|
||||
{
|
||||
if ( curLine.empty() )
|
||||
{
|
||||
// we can't use GetTextExtent - it will return 0 for both width
|
||||
// and height and an empty line should count in height
|
||||
// calculation
|
||||
|
||||
// assume that this line has the same height as the previous
|
||||
// one
|
||||
if ( !heightLineDefault )
|
||||
heightLineDefault = heightLine;
|
||||
|
||||
if ( !heightLineDefault )
|
||||
{
|
||||
// but we don't know it yet - choose something reasonable
|
||||
DoGetTextExtent(wxS("W"), NULL, &heightLineDefault);
|
||||
}
|
||||
|
||||
heightTextTotal += heightLineDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
DoGetTextExtent(curLine, &widthLine, &heightLine);
|
||||
if ( widthLine > widthTextMax )
|
||||
widthTextMax = widthLine;
|
||||
heightTextTotal += heightLine;
|
||||
}
|
||||
|
||||
if ( pc == text.end() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else // '\n'
|
||||
{
|
||||
curLine.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curLine += *pc;
|
||||
}
|
||||
}
|
||||
|
||||
if ( width )
|
||||
*width = widthTextMax;
|
||||
if ( height )
|
||||
*height = heightTextTotal;
|
||||
if ( heightOneLine )
|
||||
*heightOneLine = heightLine;
|
||||
}
|
||||
|
||||
void wxTextMeasureBase::GetLargestStringExtent(const wxVector<wxString>& strings,
|
||||
wxCoord *width,
|
||||
wxCoord *height)
|
||||
{
|
||||
MeasuringGuard guard(*this);
|
||||
|
||||
wxCoord w, h, widthMax = 0, heightMax = 0;
|
||||
for ( wxVector<wxString>::const_iterator i = strings.begin();
|
||||
i != strings.end();
|
||||
++i )
|
||||
{
|
||||
DoGetTextExtent(*i, &w, &h);
|
||||
|
||||
if ( w > widthMax )
|
||||
widthMax = w;
|
||||
if ( h > heightMax )
|
||||
heightMax = h;
|
||||
}
|
||||
|
||||
if ( width )
|
||||
*width = widthMax;
|
||||
if ( height )
|
||||
*height = heightMax;
|
||||
}
|
||||
|
||||
bool wxTextMeasureBase::GetPartialTextExtents(const wxString& text,
|
||||
wxArrayInt& widths,
|
||||
double scaleX)
|
||||
{
|
||||
widths.Empty();
|
||||
if ( text.empty() )
|
||||
return true;
|
||||
|
||||
MeasuringGuard guard(*this);
|
||||
|
||||
widths.Add(0, text.length());
|
||||
|
||||
return DoGetPartialTextExtents(text, widths, scaleX);
|
||||
}
|
Reference in New Issue
Block a user