58using namespace std::placeholders;
 
   66#include <glsl_kicad_frag.h> 
   67#include <glsl_kicad_vert.h> 
   74    wxGLAttributes attribs;
 
   75    attribs.RGBA().DoubleBuffer().Depth( 8 ).EndList();
 
 
  124        glDeleteTextures( 1, &bitmap.second.id );
 
 
  130#ifndef DISABLE_BITMAP_CACHE 
  136        if( glIsTexture( it->second.id ) )
 
  138            it->second.accessTime = wxGetUTCTimeMillis().GetValue();
 
  139            return it->second.id;
 
  144            glDeleteTextures( 1, &it->second.id );
 
 
  172        return std::numeric_limits< GLuint >::max();
 
  174    const wxImage& imgData = *imgPtr;
 
  176    bmp.
w = imgData.GetSize().x;
 
  177    bmp.
h = imgData.GetSize().y;
 
  183        glGenTextures( 1, &textureID );
 
  191    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
 
  193    if( imgData.HasAlpha() || imgData.HasMask() )
 
  195        bmp.
size = bmp.
w * bmp.
h * 4;
 
  196        auto buf = std::make_unique<uint8_t[]>( bmp.
size );
 
  198        uint8_t* dstP = buf.get();
 
  199        uint8_t* srcP = imgData.GetData();
 
  201        long long pxCount = 
static_cast<long long>( bmp.
w ) * bmp.
h;
 
  203        if( imgData.HasAlpha() )
 
  205            uint8_t* srcAlpha = imgData.GetAlpha();
 
  207            for( 
long long px = 0; px < pxCount; px++ )
 
  209                memcpy( dstP, srcP, 3 );
 
  217        else if( imgData.HasMask() )
 
  219            uint8_t maskRed = imgData.GetMaskRed();
 
  220            uint8_t maskGreen = imgData.GetMaskGreen();
 
  221            uint8_t maskBlue = imgData.GetMaskBlue();
 
  223            for( 
long long px = 0; px < pxCount; px++ )
 
  225                memcpy( dstP, srcP, 3 );
 
  227                if( srcP[0] == maskRed && srcP[1] == maskGreen && srcP[2] == maskBlue )
 
  228                    dstP[3] = wxALPHA_TRANSPARENT;
 
  230                    dstP[3] = wxALPHA_OPAQUE;
 
  237        glBindTexture( GL_TEXTURE_2D, textureID );
 
  238        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.
w, bmp.
h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 
  243        bmp.
size = bmp.
w * bmp.
h * 3;
 
  245        uint8_t* srcP = imgData.GetData();
 
  247        glBindTexture( GL_TEXTURE_2D, textureID );
 
  248        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, bmp.
w, bmp.
h, 0, GL_RGB, GL_UNSIGNED_BYTE, srcP );
 
  251    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
 
  252    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
 
  254    long long currentTime = wxGetUTCTimeMillis().GetValue();
 
  259#ifndef DISABLE_BITMAP_CACHE 
  267        for( 
const auto& [kiid, cachedBmp] : 
m_bitmaps )
 
  269            const int cacheTimeoutMillis = 1000L;
 
  271            if( currentTime - cachedBmp.accessTime > cacheTimeoutMillis )
 
  285            toRemove = *toRemoveLru;
 
  291        glDeleteTextures( 1, &cachedBitmap.
id );
 
 
  309                        wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
 
  310                        const wxString& aName ) :
 
  311        GAL( aDisplayOptions ),
 
  333            throw std::runtime_error( 
"Could not create the main OpenGL context" );
 
  342            throw std::runtime_error( 
"Could not create a private OpenGL context" );
 
  387#if defined _WIN32 || defined _WIN64 
  394    SetSize( aParent->GetClientSize() );
 
  405    gluTessProperty( 
m_tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
 
 
  471    wxString retVal = wxEmptyString;
 
  473    wxFrame* testFrame = 
new wxFrame( 
nullptr, wxID_ANY, wxT( 
"" ), wxDefaultPosition,
 
  474                                      wxSize( 1, 1 ), wxFRAME_TOOL_WINDOW | wxNO_BORDER );
 
  489    catch( std::runtime_error& err )
 
  492        retVal = wxString( err.what() );
 
 
  550#ifdef KICAD_GAL_PROFILE 
  551    PROF_TIMER totalRealTime( 
"OPENGL_GAL::beginDrawing()", 
true );
 
  554    wxASSERT_MSG( 
m_isContextLocked, 
"GAL_DRAWING_CONTEXT RAII object should have locked context. " 
  555                                     "Calling GAL::beginDrawing() directly is not allowed." );
 
  557    wxASSERT_MSG( 
IsVisible(), 
"GAL::beginDrawing() must not be entered when GAL is not visible. " 
  558                               "Other drawing routines will expect everything to be initialized " 
  559                               "which will not be the case." );
 
  565    glMatrixMode( GL_PROJECTION );
 
  581        catch( 
const std::runtime_error& )
 
  583            wxLogVerbose( 
"Could not create a framebuffer for diff mode blending.\n" );
 
  590        catch( 
const std::runtime_error& )
 
  592            wxLogVerbose( 
"Could not create a framebuffer for overlays.\n" );
 
  602    glDisable( GL_TEXTURE_2D );
 
  604    glShadeModel( GL_FLAT );
 
  607    glEnable( GL_DEPTH_TEST );
 
  608    glDepthFunc( GL_LESS );
 
  611    glEnable( GL_BLEND );
 
  612    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
  614    glMatrixMode( GL_MODELVIEW );
 
  618    GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
 
  628    glLoadMatrixd( matrixData );
 
  647        const GLint FONT_TEXTURE_UNIT = 2;
 
  652            glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
 
  657            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
 
  658            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
 
  659            checkGlError( 
"loading bitmap font", __FILE__, __LINE__ );
 
  661            glActiveTexture( GL_TEXTURE0 );
 
  667            glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
 
  669            glActiveTexture( GL_TEXTURE0 );
 
  676        checkGlError( 
"setting bitmap font sampler as shader parameter", __FILE__, __LINE__ );
 
  686    double pixelSizeMultiplier = 
m_compositor->GetAntialiasSupersamplingFactor();
 
  689    renderingOffset.
x *= screenPixelSize.
x;
 
  690    renderingOffset.
y *= screenPixelSize.
y;
 
  697    glActiveTexture( GL_TEXTURE0 );
 
  702#ifdef KICAD_GAL_PROFILE 
  703    totalRealTime.
Stop();
 
  704    wxLogTrace( 
traceGalProfile, wxT( 
"OPENGL_GAL::beginDrawing(): %.1f ms" ),
 
  705                totalRealTime.
msecs() );
 
 
  728    PROF_TIMER cntEndNoncached( 
"gl-end-noncached" );
 
  738    cntEndNoncached.
Start();
 
  740    cntEndNoncached.
Stop();
 
  742    cntEndCached.
Start();
 
  746    cntEndOverlay.
Start();
 
  752    cntEndOverlay.
Stop();
 
  754    cntComposite.
Start();
 
  757    glColor4d( 1.0, 1.0, 1.0, 1.0 );
 
 
  794    wxASSERT_MSG( 
m_isContextLocked, 
"Context not locked.  A GAL_CONTEXT_LOCKER RAII object must " 
  795                                     "be stacked rather than making separate lock/unlock calls." );
 
  798                  "Context was locked by a different client. " 
  799                  "Should not be possible with RAII objects." );
 
 
  809    wxASSERT_MSG( 
m_isContextLocked, 
"GAL_UPDATE_CONTEXT RAII object should have locked context. " 
  810                                     "Calling this from anywhere else is not allowed." );
 
  812    wxASSERT_MSG( 
IsVisible(), 
"GAL::beginUpdate() must not be entered when GAL is not visible. " 
  813                               "Other update routines will expect everything to be initialized " 
  814                               "which will not be the case." );
 
 
  850    VECTOR2D startEndVector = aEndPoint - aStartPoint;
 
  857    float startX = 
static_cast<float>( aStartPoint.
x );
 
  858    float startY = 
static_cast<float>( aStartPoint.
y );
 
  859    float endX = 
static_cast<float>( aEndPoint.
x );
 
  860    float endY = 
static_cast<float>( aEndPoint.
y );
 
  862    if( startX == endX && startY == endY )
 
  864        drawCircle( aStartPoint, aWidth / 2, aReserve );
 
 
  999    double startAngle = aStartAngle.
AsRadians();
 
 1000    double endAngle = startAngle + aAngle.
AsRadians();
 
 1017        for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
 
 1023            alpha += alphaIncrement;
 
 1029        const VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
 
 1042        VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
 
 1044        unsigned int lineCount = 0;
 
 1046        for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
 
 1049        if( alpha != endAngle )
 
 1054        for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
 
 1056            VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
 
 1063        if( alpha != endAngle )
 
 1065            VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
 
 
 1076                                 double aWidth, 
double aMaxError )
 
 1087    double startAngle = aStartAngle.
AsRadians();
 
 1088    double endAngle = startAngle + aAngle.
AsRadians();
 
 1096    double alphaIncrement = 2.0 * 
M_PI / segCount360;
 
 1101    int seg_count = 
KiROUND( ( endAngle - startAngle ) / alphaIncrement );
 
 1103    if( seg_count % 2 != 0 )
 
 1107    if( seg_count == 0 )
 
 1109        VECTOR2D p_start( aCenterPoint.
x + cos( startAngle ) * aRadius,
 
 1110                          aCenterPoint.
y + sin( startAngle ) * aRadius );
 
 1112        VECTOR2D p_end( aCenterPoint.
x + cos( endAngle ) * aRadius,
 
 1113                        aCenterPoint.
y + sin( endAngle ) * aRadius );
 
 1120    alphaIncrement = ( endAngle - startAngle ) / seg_count;
 
 1130        double   width = aWidth / 2.0;
 
 1131        VECTOR2D startPoint( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
 
 1132        VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
 
 1137        VECTOR2D pOuter( cos( startAngle ) * ( aRadius + width ),
 
 1138                         sin( startAngle ) * ( aRadius + width ) );
 
 1140        VECTOR2D pInner( cos( startAngle ) * ( aRadius - width ),
 
 1141                         sin( startAngle ) * ( aRadius - width ) );
 
 1145        for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
 
 1147            VECTOR2D pNextOuter( cos( alpha ) * ( aRadius + width ),
 
 1148                                 sin( alpha ) * ( aRadius + width ) );
 
 1149            VECTOR2D pNextInner( cos( alpha ) * ( aRadius - width ),
 
 1150                                 sin( alpha ) * ( aRadius - width ) );
 
 1155            pOuter = pNextOuter;
 
 1156            pInner = pNextInner;
 
 1160        if( alpha != endAngle )
 
 1162            VECTOR2D pLastOuter( cos( endAngle ) * ( aRadius + width ),
 
 1163                                 sin( endAngle ) * ( aRadius + width ) );
 
 1164            VECTOR2D pLastInner( cos( endAngle ) * ( aRadius - width ),
 
 1165                                 sin( endAngle ) * ( aRadius - width ) );
 
 1177        VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
 
 1182        for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
 
 1188        if( alpha != endAngle )
 
 1195        for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
 
 1197            VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
 
 1204        if( alpha != endAngle )
 
 1206            VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
 
 
 1218    VECTOR2D diagonalPointA( aEndPoint.
x, aStartPoint.
y );
 
 1219    VECTOR2D diagonalPointB( aStartPoint.
x, aEndPoint.
y );
 
 1245        if( aStartPoint == aEndPoint )
 
 1251            std::deque<VECTOR2D> pointList;
 
 1253            pointList.push_back( aStartPoint );
 
 1254            pointList.push_back( diagonalPointA );
 
 1255            pointList.push_back( aEndPoint );
 
 1256            pointList.push_back( diagonalPointB );
 
 1257            pointList.push_back( aStartPoint );
 
 
 1269                return aPointList[idx];
 
 1271            aPointList.size(), aWidth );
 
 
 1285                return aLineChain.
CPoint( idx );
 
 1287            numPoints, aWidth );
 
 
 1296                return aPointList[idx];
 
 1298            aPointList.size() );
 
 
 1307                return aPointList[idx];
 
 1309            aPointList.size() );
 
 
 1318                return aPointList[idx];
 
 
 1334                return aLineChain.
CPoint( idx );
 
 
 1342    int lineQuadCount = 0;
 
 1344    for( 
const std::vector<VECTOR2D>& points : aPointList )
 
 1345        lineQuadCount += points.size() - 1;
 
 1349    for( 
const std::vector<VECTOR2D>& points : aPointList )
 
 1356                points.size(), 
false );
 
 
 1363    wxCHECK( aPointList.size() >= 2,  );
 
 1364    auto      points = std::unique_ptr<GLdouble[]>( 
new GLdouble[3 * aPointList.size()] );
 
 1365    GLdouble* ptr = points.get();
 
 1367    for( 
const VECTOR2D& p : aPointList )
 
 
 1380    wxCHECK( aListSize >= 2,  );
 
 1381    auto            points = std::unique_ptr<GLdouble[]>( 
new GLdouble[3 * aListSize] );
 
 1382    GLdouble*       target = points.get();
 
 1385    for( 
int i = 0; i < aListSize; ++i )
 
 
 1398                                          bool aStrokeTriangulation )
 
 1405        int totalTriangleCount = 0;
 
 1420            for( 
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
 
 1423                triPoly->GetTriangle( i, a, b, c );
 
 1435            const auto& poly = aPolySet.
Polygon( j );
 
 1437            for( 
const auto& lc : poly )
 
 1446        aStrokeTriangulation = 
true;
 
 1450    if( aStrokeTriangulation )
 
 1459            for( 
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
 
 1462                triPoly->GetTriangle( i, a, b, c );
 
 
 1494    std::unique_ptr<GLdouble[]> points( 
new GLdouble[3 * pointCount] );
 
 1495    GLdouble*                   ptr = points.get();
 
 1497    for( 
int i = 0; i < pointCount; ++i )
 
 
 1511                            double aFilterValue )
 
 1513    std::vector<VECTOR2D> output;
 
 1514    std::vector<VECTOR2D> pointCtrl;
 
 1516    pointCtrl.push_back( aStartPoint );
 
 1517    pointCtrl.push_back( aControlPointA );
 
 1518    pointCtrl.push_back( aControlPointB );
 
 1519    pointCtrl.push_back( aEndPoint );
 
 1522    converter.
GetPoly( output, aFilterValue );
 
 1524    if( output.size() == 1 )
 
 1525        output.push_back( output.front() );
 
 
 1533    GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
 
 1543    glm::vec4 v0 = xform * glm::vec4( -w / 2, -h / 2, 0.0, 0.0 );
 
 1544    glm::vec4 
v1 = xform * glm::vec4( w / 2, h / 2, 0.0, 0.0 );
 
 1545    glm::vec4 trans = xform[3];
 
 1549    if( !glIsTexture( texture_id ) ) 
 
 1552    glDepthFunc( GL_ALWAYS );
 
 1554    glAlphaFunc( GL_GREATER, 0.01f );
 
 1555    glEnable( GL_ALPHA_TEST );
 
 1557    glMatrixMode( GL_TEXTURE );
 
 1559    glTranslated( 0.5, 0.5, 0.5 );
 
 1561    glTranslated( -0.5, -0.5, -0.5 );
 
 1563    glMatrixMode( GL_MODELVIEW );
 
 1565    glTranslated( trans.x, trans.y, trans.z );
 
 1567    glEnable( GL_TEXTURE_2D );
 
 1568    glActiveTexture( GL_TEXTURE0 );
 
 1569    glBindTexture( GL_TEXTURE_2D, texture_id );
 
 1571    float texStartX = aBitmap.
IsMirroredX() ? 1.0 : 0.0;
 
 1572    float texEndX   = aBitmap.
IsMirroredX() ? 0.0 : 1.0;
 
 1573    float texStartY = aBitmap.
IsMirroredY() ? 1.0 : 0.0;
 
 1574    float texEndY   = aBitmap.
IsMirroredY() ? 0.0 : 1.0;
 
 1576    glBegin( GL_QUADS );
 
 1577    glColor4f( 1.0, 1.0, 1.0, alpha );
 
 1578    glTexCoord2f( texStartX, texStartY );
 
 1580    glColor4f( 1.0, 1.0, 1.0, alpha );
 
 1581    glTexCoord2f( texEndX,  texStartY);
 
 1583    glColor4f( 1.0, 1.0, 1.0, alpha );
 
 1584    glTexCoord2f( texEndX, texEndY);
 
 1586    glColor4f( 1.0, 1.0, 1.0, alpha );
 
 1587    glTexCoord2f( texStartX, texEndY);
 
 1591    glBindTexture( GL_TEXTURE_2D, 0 );
 
 1593#ifdef DISABLE_BITMAP_CACHE 
 1594    glDeleteTextures( 1, &texture_id );
 
 1599    glMatrixMode( GL_TEXTURE );
 
 1601    glMatrixMode( GL_MODELVIEW );
 
 1603    glDisable( GL_ALPHA_TEST );
 
 1605    glDepthFunc( GL_LESS );
 
 
 1614            || aText.Contains( wxT( 
"^{" ) )
 
 1615            || aText.Contains( wxT( 
"_{" ) )
 
 1616            || aText.Contains( wxT( 
"\n" ) ) )
 
 1627    double       overbarHeight = textSize.
y;
 
 1658        wxFAIL_MSG( wxT( 
"Indeterminate state legal only in dialogs." ) );
 
 1674        overbarHeight = -textSize.
y / 2.0;
 
 1678        wxFAIL_MSG( wxT( 
"Indeterminate state legal only in dialogs." ) );
 
 1682    int overbarLength = 0;
 
 1683    int overbarDepth = -1;
 
 1684    int braceNesting = 0;
 
 1686    auto iterateString =
 
 1687            [&]( 
const std::function<void( 
int aOverbarLength, 
int aOverbarHeight )>& overbarFn,
 
 1688                 const std::function<int( 
unsigned long aChar )>& bitmapCharFn )
 
 1692                    wxASSERT_MSG( *chIt != 
'\n' && *chIt != 
'\r',
 
 1693                                  "No support for multiline bitmap text yet" );
 
 1695                    if( *chIt == 
'~' && overbarDepth == -1 )
 
 1699                        if( ++lookahead != 
end && *lookahead == 
'{' )
 
 1702                            overbarDepth = braceNesting;
 
 1707                    else if( *chIt == 
'{' )
 
 1711                    else if( *chIt == 
'}' )
 
 1713                        if( braceNesting > 0 )
 
 1716                        if( braceNesting == overbarDepth )
 
 1718                            overbarFn( overbarLength, overbarHeight );
 
 1726                    if( overbarDepth != -1 )
 
 1727                        overbarLength += bitmapCharFn( *chIt );
 
 1729                        bitmapCharFn( *chIt );
 
 1736    int overbarsCount = 0;
 
 1739            [&overbarsCount]( 
int aOverbarLength, 
int aOverbarHeight )
 
 1743            [&charsCount]( 
unsigned long aChar ) -> 
int 
 1759            [&]( 
int aOverbarLength, 
int aOverbarHeight )
 
 1763            [&]( 
unsigned long aChar ) -> 
int 
 1771    if( overbarDepth != -1 && overbarLength > 0 )
 
 
 1786    float minorLineWidth = std::fmax( 1.0f,
 
 1788    float majorLineWidth = minorLineWidth * 2.0f;
 
 1832    glDisable( GL_DEPTH_TEST );
 
 1833    glDisable( GL_TEXTURE_2D );
 
 1837        glEnable( GL_STENCIL_TEST );
 
 1838        glStencilFunc( GL_ALWAYS, 1, 1 );
 
 1839        glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
 
 1840        glColor4d( 0.0, 0.0, 0.0, 0.0 );
 
 1852        for( 
int j = gridStartY; j <= gridEndY; j++ )
 
 1858            for( 
int i = gridStartX; i <= gridEndX; i++ )
 
 1861                SetLineWidth( ( ( tickX && tickY ) ? majorLineWidth : minorLineWidth ) );
 
 1875        for( 
int j = gridStartY; j <= gridEndY; j++ )
 
 1894            glStencilFunc( GL_NOTEQUAL, 0, 1 );
 
 1900        for( 
int i = gridStartX; i <= gridEndX; i++ )
 
 1917            glDisable( GL_STENCIL_TEST );
 
 1920    glEnable( GL_DEPTH_TEST );
 
 1921    glEnable( GL_TEXTURE_2D );
 
 
 1931    m_compositor->Resize( aWidth * scaleFactor, aHeight * scaleFactor );
 
 1934    wxGLCanvas::SetSize( aWidth, aHeight );
 
 
 1940    bool s = wxGLCanvas::Show( aShow );
 
 1943        wxGLCanvas::Raise();
 
 
 1961    glClearColor( 0, 0, 0, 1 );
 
 1962    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
 
 
 1968    GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
 
 1970    matrixData[0] = aTransformation.
m_data[0][0];
 
 1971    matrixData[1] = aTransformation.
m_data[1][0];
 
 1972    matrixData[2] = aTransformation.
m_data[2][0];
 
 1973    matrixData[4] = aTransformation.
m_data[0][1];
 
 1974    matrixData[5] = aTransformation.
m_data[1][1];
 
 1975    matrixData[6] = aTransformation.
m_data[2][1];
 
 1976    matrixData[12] = aTransformation.
m_data[0][2];
 
 1977    matrixData[13] = aTransformation.
m_data[1][2];
 
 1978    matrixData[14] = aTransformation.
m_data[2][2];
 
 1980    glMultMatrixd( matrixData );
 
 
 2018    std::shared_ptr<VERTEX_ITEM> newItem = std::make_shared<VERTEX_ITEM>( *
m_cachedManager );
 
 2020    m_groups.insert( std::make_pair( groupNumber, newItem ) );
 
 
 2163        glBlendEquation( GL_MAX );
 
 2165        glBlendEquation( GL_FUNC_ADD );
 
 2172        glBlendFunc( GL_SRC_ALPHA, GL_ONE );
 
 2174        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
 
 2187#if wxCHECK_VERSION( 3, 3, 0 ) 
 
 2199#if wxCHECK_VERSION( 3, 3, 0 ) 
 
 2218                               const bool aReserve )
 
 2236              * glm::vec4( aStartPoint.
x, aStartPoint.
y, 0.0, 0.0 );
 
 2238              * glm::vec4( aEndPoint.
x, aEndPoint.
y, 0.0, 0.0 );
 
 
 2322    double outerRadius = aRadius + ( 
m_lineWidth / 2 );
 
 
 2368        GLdouble* point = aPoints;
 
 2370        for( 
int i = 0; i < aPointCount; ++i )
 
 2388                    return VECTOR2D( aPoints[idx * 3], aPoints[idx * 3 + 1] );
 
 
 2398    wxCHECK( aPointCount > 0,  );
 
 2402    if( aPointCount == 1 )
 
 2404        drawLineQuad( aPointGetter( 0 ), aPointGetter( 0 ), aReserve );
 
 2413    for( 
int i = 1; i < aPointCount; ++i )
 
 2415        auto start = aPointGetter( i - 1 );
 
 2416        auto end = aPointGetter( i );
 
 
 2424                                   int aPointCount, 
double aWidth, 
bool aReserve )
 
 2426    wxCHECK( aPointCount >= 2,  );
 
 2432    for( 
int i = 1; i < aPointCount; ++i )
 
 2434        auto start = aPointGetter( i - 1 );
 
 2435        auto end = aPointGetter( i );
 
 2437        float startx = start.x;
 
 2438        float starty = start.y;
 
 2447        if( startx == endx && starty == endy )
 
 2459            vertices += 6 + 6 + 3 + 3; 
 
 2465    for( 
int i = 1; i < aPointCount; ++i )
 
 2467        auto start = aPointGetter( i - 1 );
 
 2468        auto end = aPointGetter( i );
 
 
 2487        double spaceWidth = g->
advance * 0.74;
 
 2505    const float XOFF = glyph->
minx;
 
 2508    const float round_adjust = ( glyph->
maxy - glyph->
miny )
 
 2511    const float YOFF = round_adjust + top_adjust;
 
 
 2560    const float H = glyph->
maxy - glyph->
miny;
 
 
 2590    float    commonOffset = std::numeric_limits<float>::max();
 
 2592    int      overbarDepth = -1;
 
 2593    int braceNesting = 0;
 
 2597        if( *chIt == 
'~' && overbarDepth == -1 )
 
 2601            if( ++lookahead != 
end && *lookahead == 
'{' )
 
 2604                overbarDepth = braceNesting;
 
 2609        else if( *chIt == 
'{' )
 
 2613        else if( *chIt == 
'}' )
 
 2615            if( braceNesting > 0 )
 
 2618            if( braceNesting == overbarDepth )
 
 2628            || *chIt == 
'-' || *chIt == 
'_' ) 
 
 2630            glyph = defaultGlyph;
 
 2637    textSize.
y = std::max<float>( textSize.
y, charHeight );
 
 2639    textSize.
y -= commonOffset;
 
 2641    return std::make_pair( textSize, commonOffset );
 
 
 2685        const int cursorSize = 80;
 
 2692    GLboolean depthTestEnabled = glIsEnabled( GL_DEPTH_TEST );
 
 2693    glDisable( GL_DEPTH_TEST );
 
 2695    glActiveTexture( GL_TEXTURE0 );
 
 2696    glDisable( GL_TEXTURE_2D );
 
 2697    glEnable( GL_BLEND );
 
 2698    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
 2703    glMatrixMode( GL_PROJECTION );
 
 2705    glTranslated( 0, 0, -0.5 );
 
 2707    glBegin( GL_LINES );
 
 2722        double offset1 = cy - cx;
 
 2723        VECTOR2D pos_start( screenTopLeft.
x, screenTopLeft.
x + offset1 );
 
 2724        VECTOR2D pos_end( screenBottomRight.
x, screenBottomRight.
x + offset1 );
 
 2727        glVertex2d( pos_start.
x, pos_start.
y );
 
 2728        glVertex2d( pos_end.
x, pos_end.
y );
 
 2731        double offset2 = cy + cx;
 
 2732        VECTOR2D neg_start( screenTopLeft.
x, offset2 - screenTopLeft.
x );
 
 2733        VECTOR2D neg_end( screenBottomRight.
x, offset2 - screenBottomRight.
x );
 
 2736        glVertex2d( neg_start.
x, neg_start.
y );
 
 2737        glVertex2d( neg_end.
x, neg_end.
y );
 
 2741        glVertex2d( cursorCenter.
x, cursorBegin.
y );
 
 2742        glVertex2d( cursorCenter.
x, cursorEnd.
y );
 
 2744        glVertex2d( cursorBegin.
x, cursorCenter.
y );
 
 2745        glVertex2d( cursorEnd.
x, cursorCenter.
y );
 
 2752    if( depthTestEnabled )
 
 2753        glEnable( GL_DEPTH_TEST );
 
 
 2759    wxASSERT_MSG( 
m_groups.size() < std::numeric_limits<unsigned int>::max(),
 
 2760                  wxT( 
"There are no free slots to store a group" ) );
 
 
 2771#ifndef KICAD_USE_EGL 
 2772    wxASSERT( IsShownOnScreen() );
 
 2775    wxASSERT_MSG( 
m_isContextLocked, 
"This should only be called from within a locked context." );
 
 2779        throw std::runtime_error( 
"Could not create the tesselator" );
 
 2780    GLenum err = glewInit();
 
 2784    for( 
int i = 0; i < 10; i++ )
 
 2786        if( GLEW_OK == err )
 
 2789        std::this_thread::sleep_for( std::chrono::milliseconds( 250 ) );
 
 2795    SetOpenGLInfo( (
const char*) glGetString( GL_VENDOR ), (
const char*) glGetString( GL_RENDERER ),
 
 2796                   (
const char*) glGetString( GL_VERSION ) );
 
 2798    if( GLEW_OK != err )
 
 2799        throw std::runtime_error( (
const char*) glewGetErrorString( err ) );
 
 2802    if( !GLEW_VERSION_2_1 )
 
 2803        throw std::runtime_error( 
"OpenGL 2.1 or higher is required!" );
 
 2805#if defined( __LINUX__ )  
 2807    if( GLEW_ARB_debug_output )
 
 2813    if( !GLEW_EXT_framebuffer_object )
 
 2814        throw std::runtime_error( 
"Framebuffer objects are not supported!" );
 
 2817    if( !GLEW_ARB_vertex_buffer_object )
 
 2818        throw std::runtime_error( 
"Vertex buffer objects are not supported!" );
 
 2823                                             BUILTIN_SHADERS::glsl_kicad_vert ) )
 
 2825        throw std::runtime_error( 
"Cannot compile vertex shader!" );
 
 2830                                             BUILTIN_SHADERS::glsl_kicad_frag ) )
 
 2832        throw std::runtime_error( 
"Cannot compile fragment shader!" );
 
 2836        throw std::runtime_error( 
"Cannot link the shaders!" );
 
 2843    glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
 
 2849        throw std::runtime_error( 
"Requested texture size is not supported" );
 
 
 2885    GLdouble*               vertex = 
static_cast<GLdouble*
>( aVertexPtr );
 
 2889    assert( vboManager );
 
 2890    vboManager->
Vertex( vertex[0], vertex[1], vertex[2] );
 
 
 2895                               GLdouble** dataOut, 
void* aData )
 
 2897    GLdouble*               vertex = 
new GLdouble[3];
 
 2903    param->
intersectPoints.emplace_back( vertex, std::default_delete<GLdouble[]>() );
 
 2905    memcpy( vertex, coords, 3 * 
sizeof( GLdouble ) );
 
 
 2943    return ( ceil( f / r ) - 0.5 ) * r;
 
 
 2976        outlineGlyph.Triangulate(
 
 
 2991    if( aGlyphs.empty() )
 
 2994    bool allGlyphsAreStroke = 
true;
 
 2995    bool allGlyphsAreOutline = 
true;
 
 2997    for( 
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
 
 2999        if( !glyph->IsStroke() )
 
 3001            allGlyphsAreStroke = 
false;
 
 3006    for( 
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
 
 3008        if( !glyph->IsOutline() )
 
 3010            allGlyphsAreOutline = 
false;
 
 3015    if( allGlyphsAreStroke )
 
 3018        int lineQuadCount = 0;
 
 3020        for( 
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
 
 3024            for( 
const std::vector<VECTOR2D>& points : strokeGlyph )
 
 3025                lineQuadCount += points.size() - 1;
 
 3030        for( 
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
 
 3034            for( 
const std::vector<VECTOR2D>& points : strokeGlyph )
 
 3041                        points.size(), 
false );
 
 3047    else if( allGlyphsAreOutline )
 
 3050        int triangleCount = 0;
 
 3052        for( 
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
 
 3056            for( 
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
 
 3059                        outlineGlyph.TriangulatedPolygon( i );
 
 3070        for( 
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
 
 3074            for( 
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
 
 3077                        outlineGlyph.TriangulatedPolygon( i );
 
 3094        for( 
size_t i = 0; i < aGlyphs.size(); i++ )
 
 3095            DrawGlyph( *aGlyphs[i], i, aGlyphs.size() );
 
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
void SetOpenGLInfo(const char *aVendor, const char *aRenderer, const char *aVersion)
A setter for OpenGL info when it's initialized.
 
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
 
Bezier curves to polygon converter.
 
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
 
This class handle bitmap images in KiCad.
 
const wxImage * GetOriginalImageData() const
 
VECTOR2I GetSizePixels() const
 
EDA_ANGLE Rotation() const
 
static const WX_CURSOR_TYPE GetCursor(KICURSOR aCursorType, bool aHiDPI=false)
Get a cursor bundle (wx 3.3+) or appropriate cursor (older versions)
 
void UnlockCtx(wxGLContext *aContext)
Allow other canvases to bind an OpenGL context.
 
void DestroyCtx(wxGLContext *aContext)
Destroy a managed OpenGL context.
 
void LockCtx(wxGLContext *aContext, wxGLCanvas *aCanvas)
Set a context as current and prevents other canvases from switching it.
 
wxGLContext * CreateCtx(wxGLCanvas *aCanvas, const wxGLContext *aOther=nullptr)
Create a managed OpenGL context.
 
static int SetSwapInterval(int aVal)
Attempt to set the OpenGL swap interval.
 
HIDPI_GL_CANVAS(const KIGFX::VC_SETTINGS &aSettings, wxWindow *aParent, const wxGLAttributes &aGLAttribs, wxWindowID aId=wxID_ANY, const wxPoint &aPos=wxDefaultPosition, const wxSize &aSize=wxDefaultSize, long aStyle=0, const wxString &aName=wxGLCanvasName, const wxPalette &aPalette=wxNullPalette)
 
virtual wxSize GetNativePixelSize() const
 
double GetScaleFactor() const
Get the current scale factor.
 
virtual bool IsStroke() const
 
virtual bool IsOutline() const
 
A color representation with 4 components: red, green, blue, alpha.
 
static const COLOR4D BLACK
 
bool IsTextMirrored() const
 
void SetGridColor(const COLOR4D &aGridColor)
Set the grid color.
 
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
 
bool IsCursorEnabled() const
Return information about cursor visibility.
 
friend class GAL_CONTEXT_LOCKER
 
MATRIX3x3D m_worldScreenMatrix
World transformation.
 
VECTOR2D GetVisibleGridSize() const
Return the visible grid size in x and y directions.
 
double m_layerDepth
The actual layer depth.
 
MATRIX3x3D m_screenWorldMatrix
Screen transformation.
 
friend class GAL_SCOPED_ATTRS
 
bool m_axesEnabled
Should the axes be drawn.
 
float m_gridLineWidth
Line width of the grid.
 
VECTOR2I m_screenSize
Screen size in screen (wx logical) coordinates.
 
GR_TEXT_H_ALIGN_T GetHorizontalJustify() const
 
void normalize(T &a, T &b)
Ensure that the first element is smaller than the second.
 
VECTOR2D m_depthRange
Range of the depth.
 
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
 
virtual bool SetNativeCursorStyle(KICURSOR aCursor, bool aHiDPI)
Set the cursor in the native panel.
 
GRID_STYLE m_gridStyle
Grid display style.
 
COLOR4D m_axesColor
Color of the axes.
 
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
 
float m_lineWidth
The line width.
 
void computeWorldScale()
Compute the scaling factor for the world->screen matrix.
 
virtual void SetLineWidth(float aLineWidth)
Set the line width.
 
VECTOR2D m_gridSize
The grid size.
 
COLOR4D getCursorColor() const
Get the actual cursor color to draw.
 
COLOR4D m_fillColor
The fill color.
 
double m_worldUnitLength
The unit length of the world coordinates [inch].
 
virtual bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions)
Handle updating display options.
 
void SetAxesColor(const COLOR4D &aAxesColor)
Set the axes color.
 
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
 
VECTOR2D m_cursorPosition
Current cursor position (world coordinates)
 
const VECTOR2I & GetGlyphSize() const
 
int m_gridTick
Every tick line gets the double width.
 
double m_worldScale
The scale factor world->screen.
 
VECTOR2D m_gridOrigin
The grid origin.
 
virtual void SetMinLineWidth(float aLineWidth)
Set the minimum line width in pixels.
 
KICURSOR m_currentNativeCursor
Current cursor.
 
bool m_globalFlipY
Flag for Y axis flipping.
 
float GetMinLineWidth() const
Get the minimum line width in pixels.
 
bool m_isFillEnabled
Is filling of graphic objects enabled ?
 
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
 
COLOR4D m_gridColor
Color of the grid.
 
COLOR4D m_strokeColor
The color of the outlines.
 
bool m_isStrokeEnabled
Are the outlines stroked ?
 
GAL_DISPLAY_OPTIONS & m_options
 
bool m_gridVisibility
Should the grid be shown.
 
virtual void BitmapText(const wxString &aText, const VECTOR2I &aPosition, const EDA_ANGLE &aAngle)
Draw a text using a bitmap font.
 
float GetLineWidth() const
Get the line width.
 
bool m_globalFlipX
Flag for X axis flipping.
 
GR_TEXT_V_ALIGN_T GetVerticalJustify() const
 
KIGFX::CROSS_HAIR_MODE m_crossHairMode
Crosshair drawing mode.
 
VECTOR2D m_lookAtPoint
Point to be looked at in world space.
 
GAL(GAL_DISPLAY_OPTIONS &aOptions)
 
GLuint cacheBitmap(const BITMAP_BASE *aBitmap)
 
const size_t m_cacheMaxElements
 
GLuint RequestBitmap(const BITMAP_BASE *aBitmap)
 
std::list< GLuint > m_freedTextureIds
 
const size_t m_cacheMaxSize
 
std::map< const KIID, CACHED_BITMAP > m_bitmaps
 
std::list< KIID > m_cacheLru
 
static const unsigned int DIRECT_RENDERING
 
OpenGL implementation of the Graphics Abstraction Layer.
 
void Transform(const MATRIX3x3D &aTransformation) override
Transform the context.
 
void drawPolygon(GLdouble *aPoints, int aPointCount)
Draw a filled polygon.
 
void ChangeGroupDepth(int aGroupNumber, int aDepth) override
Change the depth (Z-axis position) of the group.
 
void skipMouseEvent(wxMouseEvent &aEvent)
Skip the mouse event to the parent.
 
void drawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth, bool aReserve=true)
Internal method for segment drawing.
 
unsigned int m_groupCounter
Counter used for generating keys for groups.
 
void EndDiffLayer() override
Ends rendering of a differential layer.
 
VERTEX_MANAGER * m_overlayManager
Container for storing overlaid VERTEX_ITEMs.
 
void Scale(const VECTOR2D &aScale) override
Scale the context.
 
bool m_isInitialized
Basic initialization flag, has to be done when the window is visible.
 
VERTEX_MANAGER * m_currentManager
Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs).
 
void drawCircle(const VECTOR2D &aCenterPoint, double aRadius, bool aReserve=true)
Internal method for circle drawing.
 
std::deque< std::shared_ptr< GLdouble > > m_tessIntersects
 
void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius) override
Draw a circle using world coordinates.
 
void LockContext(int aClientCookie) override
Use GAL_CONTEXT_LOCKER RAII object unless you know what you're doing.
 
WX_CURSOR_TYPE m_currentwxCursor
wx cursor showing the current native cursor.
 
unsigned int m_mainBuffer
Main rendering target.
 
std::unique_ptr< GL_BITMAP_CACHE > m_bitmapCache
 
std::pair< VECTOR2D, float > computeBitmapTextSize(const UTF8 &aText) const
Compute a size of text drawn using bitmap font with current text setting applied.
 
void SetTarget(RENDER_TARGET aTarget) override
Set the target for rendering.
 
void blitCursor()
Blit cursor into the current screen.
 
static wxString CheckFeatures(GAL_DISPLAY_OPTIONS &aOptions)
Checks OpenGL features.
 
void ClearTarget(RENDER_TARGET aTarget) override
Clear the target for rendering.
 
void drawBitmapOverbar(double aLength, double aHeight, bool aReserve=true)
Draw an overbar over the currently drawn text.
 
void EndGroup() override
End the group.
 
bool m_isBitmapFontInitialized
Is the shader set to use bitmap fonts?
 
void drawSegmentChain(const std::function< VECTOR2D(int)> &aPointGetter, int aPointCount, double aWidth, bool aReserve=true)
Generic way of drawing a chain of segments stored in different containers.
 
void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle, double aWidth, double aMaxError) override
Draw an arc segment.
 
void BitmapText(const wxString &aText, const VECTOR2I &aPosition, const EDA_ANGLE &aAngle) override
Draw a text using a bitmap font.
 
bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions) override
Handle updating display options.
 
unsigned int m_overlayBuffer
Auxiliary rendering target (for menus etc.)
 
void PostPaint(wxPaintEvent &aEvent)
Post an event to #m_paint_listener.
 
OPENGL_COMPOSITOR * m_compositor
Handles multiple rendering targets.
 
VERTEX_MANAGER * m_cachedManager
Container for storing cached VERTEX_ITEMs.
 
void Translate(const VECTOR2D &aTranslation) override
Translate the context.
 
void DrawPolyline(const std::deque< VECTOR2D > &aPointList) override
Draw a polyline.
 
bool SetNativeCursorStyle(KICURSOR aCursor, bool aHiDPI) override
Set the cursor in the native panel.
 
void DrawCurve(const VECTOR2D &startPoint, const VECTOR2D &controlPointA, const VECTOR2D &controlPointB, const VECTOR2D &endPoint, double aFilterValue=0.0) override
Draw a cubic bezier spline.
 
void drawFilledSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a filled semicircle.
 
void onPaint(wxPaintEvent &aEvent)
This is the OnPaint event handler.
 
void DrawGroup(int aGroupNumber) override
Draw the stored group.
 
GLint ufm_minLinePixelWidth
 
void Restore() override
Restore the context.
 
void DrawSegmentChain(const std::vector< VECTOR2D > &aPointList, double aWidth) override
Draw a chain of rounded segments.
 
void drawStrokedSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle, bool aReserve=true)
Draw a stroked semicircle.
 
unsigned int getNewGroupNumber()
Return a valid key that can be used as a new group number.
 
void Flush() override
Force all remaining objects to be drawn.
 
GLint ufm_antialiasingOffset
 
void DeleteGroup(int aGroupNumber) override
Delete the group from the memory.
 
bool IsVisible() const override
Return true if the GAL canvas is visible on the screen.
 
wxEvtHandler * m_mouseListener
 
int m_swapInterval
Used to store swap interval information.
 
void ClearCache() override
Delete all data created during caching of graphic items.
 
double getWorldPixelSize() const
 
void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth) override
Draw a rounded segment.
 
GROUPS_MAP m_groups
Stores information about VBO objects (groups)
 
void endUpdate() override
 
void ClearScreen() override
Clear the screen.
 
void ResizeScreen(int aWidth, int aHeight) override
Resizes the canvas.
 
GLint ufm_fontTextureWidth
 
void DrawPolygon(const std::deque< VECTOR2D > &aPointList) override
Draw a polygon.
 
void drawTriangulatedPolyset(const SHAPE_POLY_SET &aPoly, bool aStrokeTriangulation)
Draw a set of polygons with a cached triangulation.
 
void DrawCursor(const VECTOR2D &aCursorPosition) override
Draw the cursor.
 
void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a rectangle.
 
VERTEX_MANAGER * m_nonCachedManager
Container for storing non-cached VERTEX_ITEMs.
 
int drawBitmapChar(unsigned long aChar, bool aReserve=true)
Draw a single character using bitmap font.
 
GLUtesselator * m_tesselator
 
wxEvtHandler * m_paintListener
 
void StartDiffLayer() override
Begins rendering of a differential layer.
 
bool m_isContextLocked
Used for assertion checking.
 
void Save() override
Save the context.
 
void DrawHoleWall(const VECTOR2D &aCenterPoint, double aHoleRadius, double aWallWidth) override
Draw a hole wall ring.
 
bool m_isFramebufferInitialized
Are the framebuffers initialized?
 
void ComputeWorldScreenMatrix() override
Compute the world <-> screen transformation matrix.
 
bool Show(bool aShow) override
Shows/hides the GAL canvas.
 
void SetMinLineWidth(float aLineWidth) override
Set the minimum line width in pixels.
 
static GLuint g_fontTexture
Bitmap font texture handle (shared)
 
virtual bool HasTarget(RENDER_TARGET aTarget) override
Return true if the target exists.
 
void reserveLineQuads(const int aLineCount)
Reserve specified number of line quads.
 
void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a line.
 
OPENGL_GAL(const KIGFX::VC_SETTINGS &aVcSettings, GAL_DISPLAY_OPTIONS &aDisplayOptions, wxWindow *aParent, wxEvtHandler *aMouseListener=nullptr, wxEvtHandler *aPaintListener=nullptr, const wxString &aName=wxT("GLCanvas"))
 
void beginUpdate() override
 
double calcAngleStep(double aRadius) const
Compute the angle step when drawing arcs/circles approximated with lines.
 
virtual void DrawGlyph(const KIFONT::GLYPH &aGlyph, int aNth, int aTotal) override
Draw a polygon representing a font glyph.
 
bool m_isGrouping
Was a group started?
 
void BeginDrawing() override
Start/end drawing functions, draw calls can be only made in between the calls to BeginDrawing()/EndDr...
 
GLint ufm_screenPixelSize
 
void Rotate(double aAngle) override
Rotate the context.
 
int BeginGroup() override
Begin a group.
 
GLint ufm_pixelSizeMultiplier
 
VECTOR2D getScreenPixelSize() const
 
void DrawBitmap(const BITMAP_BASE &aBitmap, double alphaBlend=1.0) override
Draw a bitmap image.
 
void drawPolyline(const std::function< VECTOR2D(int)> &aPointGetter, int aPointCount, bool aReserve=true)
Generic way of drawing a polyline stored in different containers.
 
RENDER_TARGET GetTarget() const override
Get the currently used target for rendering.
 
void skipGestureEvent(wxGestureEvent &aEvent)
Skip the gesture event to the parent.
 
void UnlockContext(int aClientCookie) override
 
void drawSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a semicircle.
 
void drawLineQuad(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, bool aReserve=true)
Draw a quad for the line.
 
VERTEX_MANAGER * m_tempManager
Container for storing temp (diff mode) VERTEX_ITEMs.
 
virtual void DrawGlyphs(const std::vector< std::unique_ptr< KIFONT::GLYPH > > &aGlyphs) override
Draw polygons representing font glyphs.
 
void onSetNativeCursor(wxSetCursorEvent &aEvent)
Give the correct cursor image when the native widget asks for it.
 
void EnableDepthTest(bool aEnabled=false) override
 
void EndDrawing() override
End the drawing, needs to be called for every new frame.
 
SHADER * m_shader
There is only one shader used for different objects.
 
void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle) override
Draw an arc.
 
void DrawPolylines(const std::vector< std::vector< VECTOR2D > > &aPointLists) override
Draw multiple polylines.
 
RENDER_TARGET m_currentTarget
Current rendering target.
 
wxGLContext * m_glPrivContext
Canvas-specific OpenGL context.
 
void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor) override
Change the color used to draw the group.
 
static bool m_isBitmapFontLoaded
Is the bitmap font texture loaded?
 
static wxGLContext * m_glMainContext
Parent OpenGL context.
 
void setupShaderParameters()
Set up the shader parameters for OpenGL rendering.
 
unsigned int m_tempBuffer
Temporary rendering target (for diffing etc.)
 
void init()
Basic OpenGL initialization and feature checks.
 
static int m_instanceCounter
GL GAL instance counter.
 
Provide the access to the OpenGL shaders.
 
Class to control vertex container and GPU with possibility of emulating old-style OpenGL 1....
 
bool Vertex(const VERTEX &aVertex)
Add a vertex with the given coordinates to the currently set item.
 
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
 
GL_CONTEXT_MANAGER * GetGLContextManager()
 
A small class to help profiling.
 
void Stop()
Save the time when this function was called, and set the counter stane to stop.
 
void Start()
Start or restart the counter.
 
double msecs(bool aSinceLast=false)
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
bool IsClosed() const override
 
int PointCount() const
Return the number of points (vertices) in this line chain.
 
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
 
int SegmentCount() const
Return the number of segments in this line chain.
 
size_t GetTriangleCount() const
 
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
 
Represent a set of closed polygons.
 
bool IsTriangulationUpToDate() const
 
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
 
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const
 
unsigned int TriangulatedPolyCount() const
Return the number of triangulated polygons.
 
int OutlineCount() const
Return the number of outlines in the set.
 
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
 
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
 
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
 
uni_iter uend() const
Return a uni_iter initialized to the end of "this" UTF8 byte sequence.
 
uni_iter ubegin() const
Returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
 
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
 
static constexpr EDA_ANGLE FULL_CIRCLE
 
a few functions useful in geometry calculations.
 
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
 
const wxChar *const traceGalProfile
Flag to enable debug output of GAL performance profiling.
 
This file contains miscellaneous commonly used macros and functions.
 
MATRIX3x3< double > MATRIX3x3D
 
FONT_IMAGE_TYPE font_image
 
const FONT_GLYPH_TYPE * LookupGlyph(unsigned int aCodepoint)
 
FONT_INFO_TYPE font_information
 
The Cairo implementation of the graphics abstraction layer.
 
@ SMALL_CROSS
Use small cross instead of dots for the grid.
 
@ DOTS
Use dots for the grid.
 
@ SHADER_TYPE_VERTEX
Vertex shader.
 
@ SHADER_TYPE_FRAGMENT
Fragment shader.
 
RENDER_TARGET
RENDER_TARGET: Possible rendering targets.
 
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
 
@ TARGET_TEMP
Temporary target for drawing in separate layer.
 
@ TARGET_CACHED
Main rendering target (cached)
 
@ TARGET_OVERLAY
Items that may change while the view stays the same (noncached)
 
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
 
static void InitTesselatorCallbacks(GLUtesselator *aTesselator)
 
void CALLBACK CombineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut, void *aData)
 
void CALLBACK VertexCallback(GLvoid *aVertexPtr, void *aData)
 
void CALLBACK EdgeCallback(GLboolean aEdgeFlag)
 
static wxGLAttributes getGLAttribs()
 
void CALLBACK ErrorCallback(GLenum aErrorCode)
 
double round_to_half_pixel(double f, double r)
 
#define SEG_PER_CIRCLE_COUNT
 
#define CALLBACK
The default number of points for circle approximation.
 
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
 
PGM_BASE & Pgm()
The global program "get" accessor.
 
std::vector< FAB_LAYER_COLOR > dummy
 
VERTEX_MANAGER * vboManager
Manager used for storing new vertices.
 
std::deque< std::shared_ptr< GLdouble > > & intersectPoints
Intersect points, that have to be freed after tessellation.
 
Structure to keep VIEW_CONTROLS settings for easy store/restore operations.
 
@ GR_TEXT_H_ALIGN_INDETERMINATE
 
@ GR_TEXT_V_ALIGN_INDETERMINATE
 
wxLogTrace helper definitions.
 
#define KI_TRACE(aWhat,...)
 
void enableGlDebug(bool aEnable)
Enable or disable OpenGL driver messages output.
 
int checkGlError(const std::string &aInfo, const char *aFile, int aLine, bool aThrow)
Check if a recent OpenGL operation has failed.
 
VECTOR2< int32_t > VECTOR2I
 
VECTOR2< double > VECTOR2D
 
VECTOR2I ToVECTOR2I(const wxSize &aSize)