Replace STROKE_FONT performance fix, this time with correct type.

Also this time with a fixed Cairo implementation and an implemented
BASIC_GAL implementation.

Fixes https://gitlab.com/kicad/code/kicad/issues/6447
This commit is contained in:
Jeff Young 2020-11-20 10:21:59 +00:00
parent e5daac97c2
commit 0a7ef25453
4 changed files with 57 additions and 28 deletions

View File

@ -44,6 +44,7 @@ KIGFX::GAL_DISPLAY_OPTIONS basic_displayOptions;
// the basic GAL doesn't get an external display option object // the basic GAL doesn't get an external display option object
BASIC_GAL basic_gal( basic_displayOptions ); BASIC_GAL basic_gal( basic_displayOptions );
const VECTOR2D BASIC_GAL::transform( const VECTOR2D& aPoint ) const const VECTOR2D BASIC_GAL::transform( const VECTOR2D& aPoint ) const
{ {
VECTOR2D point = aPoint + m_transform.m_moveOffset - m_transform.m_rotCenter; VECTOR2D point = aPoint + m_transform.m_moveOffset - m_transform.m_rotCenter;
@ -51,57 +52,77 @@ const VECTOR2D BASIC_GAL::transform( const VECTOR2D& aPoint ) const
return point; return point;
} }
void BASIC_GAL::DrawPolyline( const std::deque<VECTOR2D>& aPointList )
// Draws a polyline given a list of points already transformed into the local coordinate
// system.
void BASIC_GAL::doDrawPolyline( const std::vector<wxPoint>& aLocalPointList )
{ {
if( aPointList.empty() )
return;
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
std::vector <wxPoint> polyline_corners;
for( ; it != aPointList.end(); ++it )
{
VECTOR2D corner = transform(*it);
polyline_corners.emplace_back( corner.x, corner.y );
}
if( m_DC ) if( m_DC )
{ {
if( isFillEnabled ) if( isFillEnabled )
{ {
GRPoly( m_isClipped ? &m_clipBox : NULL, m_DC, polyline_corners.size(), GRPoly( m_isClipped ? &m_clipBox : NULL, m_DC, aLocalPointList.size(),
&polyline_corners[0], 0, GetLineWidth(), m_Color, m_Color ); &aLocalPointList[0], 0, GetLineWidth(), m_Color, m_Color );
} }
else else
{ {
for( unsigned ii = 1; ii < polyline_corners.size(); ++ii ) for( unsigned ii = 1; ii < aLocalPointList.size(); ++ii )
{ {
GRCSegm( m_isClipped ? &m_clipBox : NULL, m_DC, polyline_corners[ii-1], GRCSegm( m_isClipped ? &m_clipBox : NULL, m_DC, aLocalPointList[ ii - 1],
polyline_corners[ii], GetLineWidth(), m_Color ); aLocalPointList[ii], GetLineWidth(), m_Color );
} }
} }
} }
else if( m_plotter ) else if( m_plotter )
{ {
m_plotter->MoveTo( polyline_corners[0] ); m_plotter->MoveTo( aLocalPointList[0] );
for( unsigned ii = 1; ii < polyline_corners.size(); ii++ ) for( unsigned ii = 1; ii < aLocalPointList.size(); ii++ )
{ {
m_plotter->LineTo( polyline_corners[ii] ); m_plotter->LineTo( aLocalPointList[ii] );
} }
m_plotter->PenFinish(); m_plotter->PenFinish();
} }
else if( m_callback ) else if( m_callback )
{ {
for( unsigned ii = 1; ii < polyline_corners.size(); ii++ ) for( unsigned ii = 1; ii < aLocalPointList.size(); ii++ )
{ {
m_callback( polyline_corners[ii-1].x, polyline_corners[ii-1].y, m_callback( aLocalPointList[ ii - 1].x, aLocalPointList[ ii - 1].y,
polyline_corners[ii].x, polyline_corners[ii].y, m_callbackData ); aLocalPointList[ii].x, aLocalPointList[ii].y, m_callbackData );
} }
} }
} }
void BASIC_GAL::DrawPolyline( const std::deque<VECTOR2D>& aPointList )
{
if( aPointList.size() < 2 )
return;
std::vector<wxPoint> polyline_corners;
for( const VECTOR2D& pt : aPointList )
polyline_corners.emplace_back( (wxPoint) transform( pt ) );
doDrawPolyline( polyline_corners );
}
void BASIC_GAL::DrawPolyline( const VECTOR2D aPointList[], int aListSize )
{
if( aListSize < 2 )
return;
std::vector<wxPoint> polyline_corners;
for( int ii = 0; ii < aListSize; ++ii )
polyline_corners.emplace_back( (wxPoint) transform( aPointList[ ii ] ) );
doDrawPolyline( polyline_corners );
}
void BASIC_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) void BASIC_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{ {
VECTOR2D startVector = transform( aStartPoint ); VECTOR2D startVector = transform( aStartPoint );

View File

@ -1155,7 +1155,7 @@ void CAIRO_GAL_BASE::drawPoly( const VECTOR2D aPointList[], int aListSize )
const auto p = roundp( xform( ptr->x, ptr->y ) ); const auto p = roundp( xform( ptr->x, ptr->y ) );
cairo_move_to( currentContext, p.x, p.y ); cairo_move_to( currentContext, p.x, p.y );
for( int i = 0; i < aListSize; ++i ) for( int i = 1; i < aListSize; ++i )
{ {
++ptr; ++ptr;
const auto p2 = roundp( xform( ptr->x, ptr->y ) ); const auto p2 = roundp( xform( ptr->x, ptr->y ) );

View File

@ -332,6 +332,9 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
bool in_super_or_subscript = false; bool in_super_or_subscript = false;
VECTOR2D glyphSize = baseGlyphSize; VECTOR2D glyphSize = baseGlyphSize;
// Allocate only once (for performance)
std::vector<VECTOR2D> ptListScaled;
yOffset = 0; yOffset = 0;
for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt ) for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt )
@ -456,7 +459,8 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
for( const std::vector<VECTOR2D>* ptList : *glyph ) for( const std::vector<VECTOR2D>* ptList : *glyph )
{ {
std::deque<VECTOR2D> ptListScaled; int ptCount = 0;
ptListScaled.clear();
for( const VECTOR2D& pt : *ptList ) for( const VECTOR2D& pt : *ptList )
{ {
@ -473,9 +477,10 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
} }
ptListScaled.push_back( scaledPt ); ptListScaled.push_back( scaledPt );
ptCount++;
} }
m_gal->DrawPolyline( ptListScaled ); m_gal->DrawPolyline( &ptListScaled[0], ptCount );
} }
xOffset += glyphSize.x * bbox.GetEnd().x; xOffset += glyphSize.x * bbox.GetEnd().x;

View File

@ -111,13 +111,14 @@ public:
m_transformHistory.pop(); m_transformHistory.pop();
} }
/** /**
* @brief Draw a polyline * @brief Draw a polyline
* @param aPointList is a list of 2D-Vectors containing the polyline points. * @param aPointList is a list of 2D-Vectors containing the polyline points.
*/ */
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) override; virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) override;
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) override;
/** Start and end points are defined as 2D-Vectors. /** Start and end points are defined as 2D-Vectors.
* @param aStartPoint is the start point of the line. * @param aStartPoint is the start point of the line.
* @param aEndPoint is the end point of the line. * @param aEndPoint is the end point of the line.
@ -146,6 +147,8 @@ public:
} }
private: private:
void doDrawPolyline( const std::vector<wxPoint>& aLocalPointList );
// Apply the roation/translation transform to aPoint // Apply the roation/translation transform to aPoint
const VECTOR2D transform( const VECTOR2D& aPoint ) const; const VECTOR2D transform( const VECTOR2D& aPoint ) const;