X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6db1f43b6c914e0fc01631ffb75ca559a0c37cf6..b9efe021b554fa3967d1442cf758435c5cd5ae8f:/src/common/dcbase.cpp?ds=inline diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 88612bfdb1..9c9ba611e7 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -5,7 +5,7 @@ // Modified by: // Created: 05/25/99 // RCS-ID: $Id$ -// Copyright: (c) wxWindows team +// Copyright: (c) wxWidgets team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -30,9 +30,7 @@ #include "wx/dc.h" -#include - -// bool wxDCBase::sm_cacheing = FALSE; +// bool wxDCBase::sm_cacheing = false; // ============================================================================ // implementation @@ -291,7 +289,7 @@ static bool wx_spline_add_point(double x, double y) point->x = (int) x; point->y = (int) y; wx_spline_point_list.Append((wxObject*)point); - return TRUE; + return true; } static void wx_spline_draw_point_array(wxDCBase *dc) @@ -316,6 +314,10 @@ void wxDCBase::DoDrawSpline( wxList *points ) double x1, y1, x2, y2; wxList::compatibility_iterator node = points->GetFirst(); + if (node == wxList::compatibility_iterator()) + // empty list + return; + p = (wxPoint *)node->GetData(); x1 = p->x; @@ -370,27 +372,76 @@ void wxDCBase::DoDrawSpline( wxList *points ) // ---------------------------------------------------------------------------- -// Each element of the array will be the width of the string up to and -// including the coresoponding character in text. This is the generic +// Each element of the widths array will be the width of the string up to and +// including the corresponding character in text. This is the generic // implementation, the port-specific classes should do this with native APIs -// if available. +// if available and if faster. Note: pango_layout_index_to_pos is much slower +// than calling GetTextExtent!! + +#define FWC_SIZE 256 + +class FontWidthCache +{ +public: + FontWidthCache() : m_scaleX(1), m_widths(NULL) { } + ~FontWidthCache() { delete []m_widths; } + + void Reset() + { + if (!m_widths) + m_widths = new int[FWC_SIZE]; + + memset(m_widths, 0, sizeof(int)*FWC_SIZE); + } + + wxFont m_font; + double m_scaleX; + int *m_widths; +}; + +static FontWidthCache s_fontWidthCache; bool wxDCBase::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const { int totalWidth = 0; - size_t i; + size_t i, len = text.Length(); widths.Empty(); - widths.Add(0, text.Length()); - + widths.Add(0, len); + int w, h; + + // reset the cache if font or horizontal scale have changed + if (!s_fontWidthCache.m_widths || + (s_fontWidthCache.m_scaleX != m_scaleX) || + (s_fontWidthCache.m_font != GetFont())) + { + s_fontWidthCache.Reset(); + s_fontWidthCache.m_font = GetFont(); + s_fontWidthCache.m_scaleX = m_scaleX; + } + // Calculate the position of each character based on the widths of // the previous characters - for (i=0; iNext(), i++ ) { wxPoint *point = (wxPoint *)node->Data(); @@ -713,13 +764,13 @@ void wxDCBase::Rotate( wxList* points, double angle, wxPoint center ) { if( angle != 0.0 ) { - double pi(3.1415926536); + double pi(M_PI); double dSinA = -sin(angle*2.0*pi/360.0); double dCosA = cos(angle*2.0*pi/360.0); for ( wxNode* node = points->First(); node; node = node->Next() ) { wxPoint* point = (wxPoint*)node->Data(); - + // transform coordinates, if necessary if( center.x ) point->x -= center.x; if( center.y ) point->y -= center.y; @@ -736,12 +787,12 @@ void wxDCBase::Rotate( wxList* points, double angle, wxPoint center ) } } -void wxDCBase::CalculateEllipticPoints( wxList* points, - wxCoord xStart, wxCoord yStart, - wxCoord w, wxCoord h, +void wxDCBase::CalculateEllipticPoints( wxList* points, + wxCoord xStart, wxCoord yStart, + wxCoord w, wxCoord h, double sa, double ea ) { - double pi = 3.1415926535; + double pi = M_PI; double sar = 0; double ear = 0; int xsa = 0; @@ -758,9 +809,9 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, wxCoord b = h/2; // decrement 1 pixel if ellipse is smaller than 2*a, 2*b int decrX = 0; - if( 2*a == w ) decrX = 1; + if( 2*a == w ) decrX = 1; int decrY = 0; - if( 2*b == h ) decrY = 1; + if( 2*b == h ) decrY = 1; // center wxCoord xCenter = xStart + a; wxCoord yCenter = yStart + b; @@ -784,7 +835,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, ear = ea * pi / 180.0; // correct angle circle -> ellipse sar = atan( -a/(double)b * tan( sar ) ); - if ( sq == 1 || sq == 2 ) sar += pi; + if ( sq == 1 || sq == 2 ) sar += pi; ear = atan( -a/(double)b * tan( ear ) ); if ( eq == 1 || eq == 2 ) ear += pi; // coordinates of points @@ -823,7 +874,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, y2 = y2-y-y+1; --y; } - // old y now to big: set point with old y, old x + // old y now to big: set point with old y, old x if( bNewPoint && x>1) { int x1 = x - 1; @@ -834,7 +885,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, pointsarray[3].Append( (wxObject*) new wxPoint( xCenter + x1 - decrX, yCenter + y_old - decrY ) ); } // set point } // calculate point - + // Starting and/or ending points for the quadrants, first quadrant gets both. pointsarray[0].Insert( (wxObject*) new wxPoint( xCenter + a - decrX, yCenter ) ); pointsarray[0].Append( (wxObject*) new wxPoint( xCenter, yCenter - b ) ); @@ -858,12 +909,12 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, { // once: go to starting point in start quadrant if( !bStarted && - ( - ( (wxPoint*) node->Data() )->x < xsa+1 && q <= 1 - || + ( + ( (wxPoint*) node->Data() )->x < xsa+1 && q <= 1 + || ( (wxPoint*) node->Data() )->x > xsa-1 && q >= 2 ) - ) + ) { bStarted = true; } @@ -873,8 +924,8 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, { if( q != eq || bForceTurn || - ( (wxPoint*) node->Data() )->x > xea+1 && q <= 1 - || + ( (wxPoint*) node->Data() )->x > xea+1 && q <= 1 + || ( (wxPoint*) node->Data() )->x < xea-1 && q >= 2 ) { @@ -884,7 +935,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, } else if( q == eq && !bForceTurn || ( (wxPoint*) node->Data() )->x == xea) { - bReady = true; + bReady = true; } } } // for node @@ -903,8 +954,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, wxPoint *p = (wxPoint *)node->Data(); delete p; } - } - + } } else {