git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@27071 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2004-05-03 09:19:05 +00:00
parent e964136c08
commit 2aaa050c33

View File

@@ -383,15 +383,15 @@ class FontWidthCache
public: public:
FontWidthCache() : m_scaleX(1), m_widths(NULL) { } FontWidthCache() : m_scaleX(1), m_widths(NULL) { }
~FontWidthCache() { delete []m_widths; } ~FontWidthCache() { delete []m_widths; }
void Reset() void Reset()
{ {
if (!m_widths) if (!m_widths)
m_widths = new int[FWC_SIZE]; m_widths = new int[FWC_SIZE];
memset(m_widths, 0, sizeof(int)*FWC_SIZE); memset(m_widths, 0, sizeof(int)*FWC_SIZE);
} }
wxFont m_font; wxFont m_font;
double m_scaleX; double m_scaleX;
int *m_widths; int *m_widths;
@@ -407,7 +407,7 @@ bool wxDCBase::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths)
widths.Empty(); widths.Empty();
widths.Add(0, len); widths.Add(0, len);
int w, h; int w, h;
// reset the cache if font or horizontal scale have changed // reset the cache if font or horizontal scale have changed
if (!s_fontWidthCache.m_widths || if (!s_fontWidthCache.m_widths ||
(s_fontWidthCache.m_scaleX != m_scaleX) || (s_fontWidthCache.m_scaleX != m_scaleX) ||
@@ -420,16 +420,16 @@ bool wxDCBase::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths)
// Calculate the position of each character based on the widths of // Calculate the position of each character based on the widths of
// the previous characters // the previous characters
for (i=0; i<len; i++) for (i=0; i<len; i++)
{ {
const wxChar c = text[i]; const wxChar c = text[i];
unsigned int c_int = (unsigned int)c; unsigned int c_int = (unsigned int)c;
if ((c_int < FWC_SIZE) && (s_fontWidthCache.m_widths[c_int] != 0)) if ((c_int < FWC_SIZE) && (s_fontWidthCache.m_widths[c_int] != 0))
{ {
w = s_fontWidthCache.m_widths[c_int]; w = s_fontWidthCache.m_widths[c_int];
} }
else else
{ {
GetTextExtent(c, &w, &h); GetTextExtent(c, &w, &h);
if (c_int < FWC_SIZE) if (c_int < FWC_SIZE)
@@ -439,7 +439,7 @@ bool wxDCBase::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths)
totalWidth += w; totalWidth += w;
widths[i] = totalWidth; widths[i] = totalWidth;
} }
return true; return true;
} }
@@ -683,19 +683,19 @@ DoDrawEllipticArcRot(...) is virtual, so it can be called from deeper
methods like (WinCE) wxDC::DoDrawArc(...). methods like (WinCE) wxDC::DoDrawArc(...).
CalculateEllipticPoints(...) fills a given list of wxPoints with some points CalculateEllipticPoints(...) fills a given list of wxPoints with some points
of an elliptic arc. The algorithm is pixel-based: In every row (in flat of an elliptic arc. The algorithm is pixel-based: In every row (in flat
parts) or every column (in steep parts) only one pixel is calculated. parts) or every column (in steep parts) only one pixel is calculated.
Trigonometric calculation (sin, cos, tan, atan) is only done if the Trigonometric calculation (sin, cos, tan, atan) is only done if the
starting angle is not equal to the ending angle. The calculation of the starting angle is not equal to the ending angle. The calculation of the
pixels is done using simple arithmetic only and should perform not too pixels is done using simple arithmetic only and should perform not too
bad even on devices without floating point processor. I didn't test this yet. bad even on devices without floating point processor. I didn't test this yet.
Rotate(...) rotates a list of point pixel-based, you will see rounding errors. Rotate(...) rotates a list of point pixel-based, you will see rounding errors.
For instance: an ellipse rotated 180 degrees is drawn For instance: an ellipse rotated 180 degrees is drawn
slightly different from the original. slightly different from the original.
The points are then moved to an array and used to draw a polyline and/or polygon The points are then moved to an array and used to draw a polyline and/or polygon
(with center added, the pie). (with center added, the pie).
The result looks quite similar to the native ellipse, only e few pixels differ. The result looks quite similar to the native ellipse, only e few pixels differ.
The performance on a desktop system (Athlon 1800, WinXP) is about 7 times The performance on a desktop system (Athlon 1800, WinXP) is about 7 times
@@ -703,7 +703,7 @@ slower as DrawEllipse(...), which calls the native API.
An rotated ellipse outside the clipping region takes nearly the same time, An rotated ellipse outside the clipping region takes nearly the same time,
while an native ellipse outside takes nearly no time to draw. while an native ellipse outside takes nearly no time to draw.
If you draw an arc with this new method, you will see the starting and ending angles If you draw an arc with this new method, you will see the starting and ending angles
are calculated properly. are calculated properly.
If you use DrawEllipticArc(...), you will see they are only correct for circles If you use DrawEllipticArc(...), you will see they are only correct for circles
and not properly calculated for ellipses. and not properly calculated for ellipses.
@@ -713,8 +713,8 @@ p.lenhard@t-online.de
*/ */
#ifdef __WXWINCE__ #ifdef __WXWINCE__
void wxDCBase::DoDrawEllipticArcRot( wxCoord x, wxCoord y, void wxDCBase::DoDrawEllipticArcRot( wxCoord x, wxCoord y,
wxCoord w, wxCoord h, wxCoord w, wxCoord h,
double sa, double ea, double angle ) double sa, double ea, double angle )
{ {
wxList list; wxList list;
@@ -729,7 +729,7 @@ void wxDCBase::DoDrawEllipticArcRot( wxCoord x, wxCoord y,
int n = list.Number(); int n = list.Number();
wxPoint *points = new wxPoint[n]; wxPoint *points = new wxPoint[n];
int i = 0; int i = 0;
wxNode* node = 0; wxNode* node = 0;
for ( node = list.First(); node; node = node->Next(), i++ ) for ( node = list.First(); node; node = node->Next(), i++ )
{ {
wxPoint *point = (wxPoint *)node->Data(); wxPoint *point = (wxPoint *)node->Data();
@@ -768,7 +768,7 @@ void wxDCBase::Rotate( wxList* points, double angle, wxPoint center )
for ( wxNode* node = points->First(); node; node = node->Next() ) for ( wxNode* node = points->First(); node; node = node->Next() )
{ {
wxPoint* point = (wxPoint*)node->Data(); wxPoint* point = (wxPoint*)node->Data();
// transform coordinates, if necessary // transform coordinates, if necessary
if( center.x ) point->x -= center.x; if( center.x ) point->x -= center.x;
if( center.y ) point->y -= center.y; if( center.y ) point->y -= center.y;
@@ -785,9 +785,9 @@ void wxDCBase::Rotate( wxList* points, double angle, wxPoint center )
} }
} }
void wxDCBase::CalculateEllipticPoints( wxList* points, void wxDCBase::CalculateEllipticPoints( wxList* points,
wxCoord xStart, wxCoord yStart, wxCoord xStart, wxCoord yStart,
wxCoord w, wxCoord h, wxCoord w, wxCoord h,
double sa, double ea ) double sa, double ea )
{ {
double pi = 3.1415926535; double pi = 3.1415926535;
@@ -807,9 +807,9 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
wxCoord b = h/2; wxCoord b = h/2;
// decrement 1 pixel if ellipse is smaller than 2*a, 2*b // decrement 1 pixel if ellipse is smaller than 2*a, 2*b
int decrX = 0; int decrX = 0;
if( 2*a == w ) decrX = 1; if( 2*a == w ) decrX = 1;
int decrY = 0; int decrY = 0;
if( 2*b == h ) decrY = 1; if( 2*b == h ) decrY = 1;
// center // center
wxCoord xCenter = xStart + a; wxCoord xCenter = xStart + a;
wxCoord yCenter = yStart + b; wxCoord yCenter = yStart + b;
@@ -833,7 +833,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
ear = ea * pi / 180.0; ear = ea * pi / 180.0;
// correct angle circle -> ellipse // correct angle circle -> ellipse
sar = atan( -a/(double)b * tan( sar ) ); 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 ) ); ear = atan( -a/(double)b * tan( ear ) );
if ( eq == 1 || eq == 2 ) ear += pi; if ( eq == 1 || eq == 2 ) ear += pi;
// coordinates of points // coordinates of points
@@ -872,7 +872,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
y2 = y2-y-y+1; y2 = y2-y-y+1;
--y; --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) if( bNewPoint && x>1)
{ {
int x1 = x - 1; int x1 = x - 1;
@@ -883,7 +883,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
pointsarray[3].Append( (wxObject*) new wxPoint( xCenter + x1 - decrX, yCenter + y_old - decrY ) ); pointsarray[3].Append( (wxObject*) new wxPoint( xCenter + x1 - decrX, yCenter + y_old - decrY ) );
} // set point } // set point
} // calculate point } // calculate point
// Starting and/or ending points for the quadrants, first quadrant gets both. // Starting and/or ending points for the quadrants, first quadrant gets both.
pointsarray[0].Insert( (wxObject*) new wxPoint( xCenter + a - decrX, yCenter ) ); pointsarray[0].Insert( (wxObject*) new wxPoint( xCenter + a - decrX, yCenter ) );
pointsarray[0].Append( (wxObject*) new wxPoint( xCenter, yCenter - b ) ); pointsarray[0].Append( (wxObject*) new wxPoint( xCenter, yCenter - b ) );
@@ -907,12 +907,12 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
{ {
// once: go to starting point in start quadrant // once: go to starting point in start quadrant
if( !bStarted && 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 ( (wxPoint*) node->Data() )->x > xsa-1 && q >= 2
) )
) )
{ {
bStarted = true; bStarted = true;
} }
@@ -922,8 +922,8 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
{ {
if( q != eq || bForceTurn 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 ( (wxPoint*) node->Data() )->x < xea-1 && q >= 2
) )
{ {
@@ -933,7 +933,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
} }
else if( q == eq && !bForceTurn || ( (wxPoint*) node->Data() )->x == xea) else if( q == eq && !bForceTurn || ( (wxPoint*) node->Data() )->x == xea)
{ {
bReady = true; bReady = true;
} }
} }
} // for node } // for node
@@ -952,8 +952,7 @@ void wxDCBase::CalculateEllipticPoints( wxList* points,
wxPoint *p = (wxPoint *)node->Data(); wxPoint *p = (wxPoint *)node->Data();
delete p; delete p;
} }
} }
} }
else else
{ {