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
BASIC_GAL basic_gal( basic_displayOptions );
const VECTOR2D BASIC_GAL::transform( const VECTOR2D& aPoint ) const
{
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;
}
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( isFillEnabled )
{
GRPoly( m_isClipped ? &m_clipBox : NULL, m_DC, polyline_corners.size(),
&polyline_corners[0], 0, GetLineWidth(), m_Color, m_Color );
GRPoly( m_isClipped ? &m_clipBox : NULL, m_DC, aLocalPointList.size(),
&aLocalPointList[0], 0, GetLineWidth(), m_Color, m_Color );
}
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],
polyline_corners[ii], GetLineWidth(), m_Color );
GRCSegm( m_isClipped ? &m_clipBox : NULL, m_DC, aLocalPointList[ ii - 1],
aLocalPointList[ii], GetLineWidth(), m_Color );
}
}
}
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();
}
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,
polyline_corners[ii].x, polyline_corners[ii].y, m_callbackData );
m_callback( aLocalPointList[ ii - 1].x, aLocalPointList[ ii - 1].y,
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 )
{
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 ) );
cairo_move_to( currentContext, p.x, p.y );
for( int i = 0; i < aListSize; ++i )
for( int i = 1; i < aListSize; ++i )
{
++ptr;
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;
VECTOR2D glyphSize = baseGlyphSize;
// Allocate only once (for performance)
std::vector<VECTOR2D> ptListScaled;
yOffset = 0;
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 )
{
std::deque<VECTOR2D> ptListScaled;
int ptCount = 0;
ptListScaled.clear();
for( const VECTOR2D& pt : *ptList )
{
@ -473,9 +477,10 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
}
ptListScaled.push_back( scaledPt );
ptCount++;
}
m_gal->DrawPolyline( ptListScaled );
m_gal->DrawPolyline( &ptListScaled[0], ptCount );
}
xOffset += glyphSize.x * bbox.GetEnd().x;

View File

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