X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/12bdd77c85888f29ed94e23ba28d31d99a522598..068b764a5a7cc2929b1fd8ea5643f43b5cbc8762:/src/common/dcbase.cpp diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index 73653ffc7d..1beb8edcae 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 @@ -106,6 +104,49 @@ void wxDCBase::DrawPolygon(const wxList *list, delete [] points; } +void +wxDCBase::DoDrawPolyPolygon(int n, + int count[], + wxPoint points[], + wxCoord xoffset, wxCoord yoffset, + int fillStyle) +{ + if ( n == 1 ) + { + DoDrawPolygon(count[0], points, xoffset, yoffset, fillStyle); + return; + } + + int i, j, lastOfs; + wxPoint* pts; + wxPen pen; + + for (i = j = lastOfs = 0; i < n; i++) + { + lastOfs = j; + j += count[i]; + } + pts = new wxPoint[j+n-1]; + for (i = 0; i < j; i++) + pts[i] = points[i]; + for (i = 2; i <= n; i++) + { + lastOfs -= count[n-i]; + pts[j++] = pts[lastOfs]; + } + + pen = GetPen(); + SetPen(wxPen(*wxBLACK, 0, wxTRANSPARENT)); + DoDrawPolygon(j, pts, xoffset, yoffset, fillStyle); + SetPen(pen); + for (i = j = 0; i < n; i++) + { + DoDrawLines(count[i], pts+j, xoffset, yoffset); + j += count[i]; + } + delete[] pts; +} + // ---------------------------------------------------------------------------- // splines // ---------------------------------------------------------------------------- @@ -248,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) @@ -273,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; @@ -322,6 +367,85 @@ void wxDCBase::DoDrawSpline( wxList *points ) #endif // wxUSE_SPLINES +// ---------------------------------------------------------------------------- +// Partial Text Extents +// ---------------------------------------------------------------------------- + + +// Each element of the widths array will be the width of the string up to and +// including the coresponding character in text. This is the generic +// implementation, the port-specific classes should do this with native APIs +// 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, len = text.Length(); + widths.Empty(); + 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(); @@ -617,7 +741,7 @@ void wxDCBase::DoDrawEllipticArcRot( wxCoord x, wxCoord y, } // first draw the pie without pen, if necessary - if( GetBrush() != *wxTRANSPARENT_BRUSH ) + if( GetBrush() != *wxTRANSPARENT_BRUSH ) { wxPen tempPen( GetPen() ); SetPen( *wxTRANSPARENT_PEN ); @@ -626,7 +750,7 @@ void wxDCBase::DoDrawEllipticArcRot( wxCoord x, wxCoord y, } // then draw the arc without brush, if necessary - if( GetPen() != *wxTRANSPARENT_PEN ) + if( GetPen() != *wxTRANSPARENT_PEN ) { // without center DoDrawLines( n-1, points, 0, 0 ); @@ -640,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; @@ -663,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; @@ -685,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; @@ -711,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 @@ -750,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; @@ -761,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 ) ); @@ -785,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; } @@ -800,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 ) { @@ -811,7 +935,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, } else if( q == eq && !bForceTurn || ( (wxPoint*) node->Data() )->x == xea) { - bReady = true; + bReady = true; } } } // for node @@ -830,8 +954,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points, wxPoint *p = (wxPoint *)node->Data(); delete p; } - } - + } } else {