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(); }
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; } }
/** * 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; } }