void BITMAPCONV_INFO::CreateOutputFile( BMP2CMP_MOD_LAYER aModLayer )
{
    KPolyPoint currpoint;

    std::vector <potrace_dpoint_t> cornersBuffer;

    // This KPolygonSet polyset_areas is a complex polygon to draw
    // and can be complex depending on holes inside this polygon
    KPolygonSet polyset_areas;

    // This KPolygonSet polyset_holes is the set of holes inside polyset_areas
    KPolygonSet polyset_holes;

    potrace_dpoint_t( *c )[3];

    LOCALE_IO toggle;   // Temporary switch the locale to standard C to r/w floats

    // The layer name has meaning only for .kicad_mod files.
    // For these files the header creates 2 invisible texts: value and ref
    // (needed but not usefull) on silk screen layer
    OuputFileHeader( getBrdLayerName( MOD_LYR_FSILKS ) );

    bool main_outline = true;

    /* draw each as a polygon with no hole.
     * Bezier curves are approximated by a polyline
     */
    potrace_path_t* paths = m_Paths;    // the list of paths
    while( paths != NULL )
    {
        int cnt  = paths->curve.n;
        int* tag = paths->curve.tag;
        c = paths->curve.c;
        potrace_dpoint_t startpoint = c[cnt - 1][2];
        for( int i = 0; i < cnt; i++ )
        {
            switch( tag[i] )
            {
            case POTRACE_CORNER:
                cornersBuffer.push_back( c[i][1] );
                cornersBuffer.push_back( c[i][2] );
                startpoint = c[i][2];
                break;

            case POTRACE_CURVETO:
                BezierToPolyline( cornersBuffer, startpoint, c[i][0], c[i][1], c[i][2] );
                startpoint = c[i][2];
                break;
            }
        }

        // Store current path
        if( main_outline )
        {
            main_outline = false;

            // build the current main polygon
            std::vector<KPolyPoint> cornerslist; // a simple boost polygon
            for( unsigned int i = 0; i < cornersBuffer.size(); i++ )
            {
                currpoint.x( (coordinate_type) (cornersBuffer[i].x * m_ScaleX) );
                currpoint.y( (coordinate_type) (cornersBuffer[i].y * m_ScaleY) );
                cornerslist.push_back( currpoint );
            }

            KPolygon poly;
            bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
            polyset_areas.push_back( poly );
        }
        else
        {
            // Add current hole in polyset_holes
            std::vector<KPolyPoint> cornerslist; // a simple boost polygon
            for( unsigned int i = 0; i < cornersBuffer.size(); i++ )
            {
                currpoint.x( (coordinate_type) (cornersBuffer[i].x * m_ScaleX) );
                currpoint.y( (coordinate_type) (cornersBuffer[i].y * m_ScaleY) );
                cornerslist.push_back( currpoint );
            }

            KPolygon poly;
            bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
            polyset_holes.push_back( poly );
        }
        cornersBuffer.clear();

        /* at the end of a group of a positive path and its negative children, fill.
         */
        if( paths->next == NULL || paths->next->sign == '+' )
        {
            // Substract holes to main polygon:
            polyset_areas -= polyset_holes;

            // Output current resulting polygon(s)
            for( unsigned ii = 0; ii < polyset_areas.size(); ii++ )
            {
                KPolygon& poly = polyset_areas[ii];
                OuputOnePolygon(poly, getBrdLayerName( aModLayer ) );
            }

            polyset_areas.clear();
            polyset_holes.clear();
            main_outline = true;
        }
        paths = paths->next;
    }

    OuputFileEnd();
}
Beispiel #2
0
void BITMAPCONV_INFO::CreateOutputFile()
{
    KPolyPoint currpoint;

    std::vector <potrace_dpoint_t> cornersBuffer;

    // This KPolygonSet polyset_areas is a complex polygon to draw
    // and can be complex depending on holes inside this polygon
    KPolygonSet polyset_areas;

    // This KPolygonSet polyset_holes is the set of holes inside polyset_areas
    KPolygonSet polyset_holes;

    potrace_dpoint_t( *c )[3];
    OuputFileHeader();

    bool main_outline = true;

    /* draw each as a polygon with no hole.
     * Bezier curves are approximated by a polyline
     */
    potrace_path_t* paths = m_Paths;    // the list of paths
    while( paths != NULL )
    {
        int cnt  = paths->curve.n;
        int* tag = paths->curve.tag;
        c = paths->curve.c;
        potrace_dpoint_t startpoint = c[cnt - 1][2];
        for( int i = 0; i < cnt; i++ )
        {
            switch( tag[i] )
            {
            case POTRACE_CORNER:
                cornersBuffer.push_back( c[i][1] );
                cornersBuffer.push_back( c[i][2] );
                startpoint = c[i][2];
                break;

            case POTRACE_CURVETO:
                BezierToPolyline( cornersBuffer, startpoint, c[i][0], c[i][1], c[i][2] );
                startpoint = c[i][2];
                break;
            }
        }

        // Store current path
        if( main_outline )
        {
            main_outline = false;

            // build the current main polygon
            std::vector<KPolyPoint> cornerslist; // a simple boost polygon
            for( unsigned int i = 0; i < cornersBuffer.size(); i++ )
            {
                currpoint.x( (coordinate_type) (cornersBuffer[i].x * m_ScaleX) );
                currpoint.y( (coordinate_type) (cornersBuffer[i].y * m_ScaleY) );
                cornerslist.push_back( currpoint );
            }

            KPolygon poly;
            bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
            polyset_areas.push_back( poly );
        }
        else
        {
            // Add current hole in polyset_holes
            std::vector<KPolyPoint> cornerslist; // a simple boost polygon
            for( unsigned int i = 0; i < cornersBuffer.size(); i++ )
            {
                currpoint.x( (coordinate_type) (cornersBuffer[i].x * m_ScaleX) );
                currpoint.y( (coordinate_type) (cornersBuffer[i].y * m_ScaleY) );
                cornerslist.push_back( currpoint );
            }

            KPolygon poly;
            bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
            polyset_holes.push_back( poly );
        }
        cornersBuffer.clear();

        /* at the end of a group of a positive path and its negative children, fill.
         */
        if( paths->next == NULL || paths->next->sign == '+' )
        {
            // Substract holes to main polygon:
            polyset_areas -= polyset_holes;

            // Output current resulting polygon(s)
            for( unsigned ii = 0; ii < polyset_areas.size(); ii++ )
            {
                KPolygon& poly = polyset_areas[ii];
                OuputOnePolygon(poly );
            }

            polyset_areas.clear();
            polyset_holes.clear();
            main_outline = true;
        }
        paths = paths->next;
    }

    OuputFileEnd();
}
/**
 * Function OuputOnePolygon
 * write one polygon to output file.
 * Polygon coordinates are expected scaled by the polygon extraction function
 */
void BITMAPCONV_INFO::OuputOnePolygon( KPolygon & aPolygon, const char * aBrdLayerName )
{
    unsigned ii, jj;
    KPolyPoint currpoint;

    int   offsetX = (int)( m_PixmapWidth / 2 * m_ScaleX );
    int   offsetY = (int)( m_PixmapHeight / 2 * m_ScaleY );

    KPolyPoint startpoint = *aPolygon.begin();

    switch( m_Format )
    {
    case POSTSCRIPT_FMT:
        offsetY = (int)( m_PixmapHeight * m_ScaleY );
        fprintf( m_Outfile, "newpath\n%d %d moveto\n",
                 startpoint.x(), offsetY - startpoint.y() );
        jj = 0;
        for( ii = 1; ii < aPolygon.size(); ii++ )
        {
            currpoint = *(aPolygon.begin() + ii);
            fprintf( m_Outfile, " %d %d lineto",
                     currpoint.x(), offsetY - currpoint.y() );

            if( jj++ > 6 )
            {
                jj = 0;
                fprintf( m_Outfile, ("\n") );
            }
        }

        fprintf( m_Outfile, "\nclosepath fill\n" );
        break;

    case PCBNEW_KICAD_MOD:
    {
        double width = 0.1;
        fprintf( m_Outfile, "  (fp_poly (pts" );

        jj = 0;
        for( ii = 0; ii < aPolygon.size(); ii++ )
        {
            currpoint = *( aPolygon.begin() + ii );
            fprintf( m_Outfile, " (xy %f %f)",
                    (currpoint.x() - offsetX) / 1e6,
                    (currpoint.y() - offsetY) / 1e6 );

            if( jj++ > 6 )
            {
                jj = 0;
                fprintf( m_Outfile, ("\n    ") );
            }
        }
        // Close polygon
        fprintf( m_Outfile, " (xy %f %f) )",
                (startpoint.x() - offsetX) / 1e6, (startpoint.y() - offsetY) / 1e6 );

        fprintf( m_Outfile, "(layer %s) (width  %f)\n  )\n", aBrdLayerName, width );

    }
    break;

    case KICAD_LOGO:
        fprintf( m_Outfile, "  (pts" );
        // Internal units = micron, file unit = mm
        jj = 0;
        for( ii = 0; ii < aPolygon.size(); ii++ )
        {
            currpoint = *( aPolygon.begin() + ii );
            fprintf( m_Outfile, " (xy %.3f %.3f)",
                    (currpoint.x() - offsetX) / 1e3,
                    (currpoint.y() - offsetY) / 1e3 );

            if( jj++ > 4 )
            {
                jj = 0;
                fprintf( m_Outfile, ("\n    ") );
            }
        }
        // Close polygon
        fprintf( m_Outfile, " (xy %.3f %.3f) )\n",
                (startpoint.x() - offsetX) / 1e3, (startpoint.y() - offsetY) / 1e3 );
        break;

    case EESCHEMA_FMT:
        fprintf( m_Outfile, "P %d 0 0 1", (int) aPolygon.size() + 1 );
        for( ii = 0; ii < aPolygon.size(); ii++ )
        {
            currpoint = *(aPolygon.begin() + ii);
            fprintf( m_Outfile, " %d %d",
                     currpoint.x() - offsetX, currpoint.y() - offsetY );
        }

        // Close polygon
        fprintf( m_Outfile, " %d %d",
                 startpoint.x() - offsetX, startpoint.y() - offsetY );

        fprintf( m_Outfile, " F\n" );
        break;
    }
}
Beispiel #4
0
/**
 * Function OuputOnePolygon
 * write one polygon to output file.
 * Polygon coordinates are expected scaled by the polugon extraction function
 */
void BITMAPCONV_INFO::OuputOnePolygon( KPolygon & aPolygon )
{
    unsigned ii;
    KPolyPoint currpoint;

    int   offsetX = (int)( m_PixmapWidth / 2 * m_ScaleX );
    int   offsetY = (int)( m_PixmapHeight / 2 * m_ScaleY );

    KPolyPoint startpoint = *aPolygon.begin();

    switch( m_Format )
    {
    case POSTSCRIPT_FMT:
        fprintf( m_Outfile, "%d %d moveto\n",
                 startpoint.x(), startpoint.y() );
        for( ii = 1; ii < aPolygon.size(); ii++ )
        {
            currpoint = *(aPolygon.begin() + ii);
            fprintf( m_Outfile, "%d %d lineto\n",
                     currpoint.x(), currpoint.y() );
        }

        fprintf( m_Outfile, "0 setgray fill\n" );
        break;

    case PCBNEW_FMT:
    {
        #define SILKSCREEN_N_FRONT 21
        int layer = SILKSCREEN_N_FRONT;
        int width = 1;
        fprintf( m_Outfile, "DP %d %d %d %d %d %d %d\n",
                 0, 0, 0, 0,
                 (int) aPolygon.size() + 1, width, layer );

        for( ii = 0; ii < aPolygon.size(); ii++ )
        {
            currpoint = *( aPolygon.begin() + ii );
            fprintf( m_Outfile, "Dl %d %d\n",
                    currpoint.x() - offsetX, currpoint.y() - offsetY );
        }

        // Close polygon
        fprintf( m_Outfile, "Dl %d %d\n",
                 startpoint.x() - offsetX, startpoint.y() - offsetY );
    }
    break;

    case EESCHEMA_FMT:
        fprintf( m_Outfile, "P %d 0 0 1", (int) aPolygon.size() + 1 );
        for( ii = 0; ii < aPolygon.size(); ii++ )
        {
            currpoint = *(aPolygon.begin() + ii);
            fprintf( m_Outfile, " %d %d",
                     currpoint.x() - offsetX, currpoint.y() - offsetY );
        }

        // Close polygon
        fprintf( m_Outfile, " %d %d",
                 startpoint.x() - offsetX, startpoint.y() - offsetY );

        fprintf( m_Outfile, " F\n" );
        break;
    }
}