Source

liblayout / dxf.cpp

Full commit
/*
** This code is distributed under a modified BSD license.
** Please refer to http://www.sourceforge.net/projects/adsm/
**
*************************************************************************
**
** Copyright (c) 2004-2006 Robert W. Johnstone
** All rights reserved.
**
*************************************************************************
**
** Description not written.
**
*/

#include "layout.h"
#include "layout_shapes.h"
#include <assert.h>
#include <iostream>

using namespace liblayout;

static void write_HEADER( std::ostream& out )
{
	out << "  0\n";
	out << "SECTION\n";
	out << "  2\n";
	out << "HEADER\n";
	out << "  0\n";
	out << "ENDSEC\n";
}

static void write_start_ENTITIES( std::ostream& out )
{
	out << "  0\n";
	out << "SECTION\n";
	out << "  2\n";
	out << "ENTITIES\n";
}

static void write_end_ENTITIES( std::ostream& out )
{
	out << "  0\n";
	out << "ENDSEC\n";
}

static void write_EOF( std::ostream& out )
{
	out << "  0\n";
	out << "EOF\n";
}

static void write_point( std::ostream& out, dimension_t x, dimension_t y, bool final_point )
{
	out << "  10\n";
	out << x << '\n';
	out << "  20\n";
	out << y << '\n';
	out << "  30\n0\n";
	if ( final_point )
		out << "  0\nSEQEND\n";
	else
		out << "  0\nVERTEX\n";
}

static void write_shape( std::ostream& out, shape const& view, char const* layer )
{
	assert( layer );
	
	rect_shape const* box = 0;
	polygon_shape const* poly = 0;

	out << "  0\nPOLYLINE\n"; // start of a polyline
	out << "  70\n1\n"; // flag indicating closed polyline (polygon)
	out << "  8\n" << layer << '\n';

	if ( box = dynamic_cast<rect_shape const*>( view.get() ) ) {
		write_point( out, box->x1, box->y1, false );
		write_point( out, box->x2, box->y1, false );
		write_point( out, box->x2, box->y2, false );
		write_point( out, box->x1, box->y2, false );
		write_point( out, box->x1, box->y1, true );
	}
	else if ( poly = dynamic_cast<polygon_shape const*>( view.get() ) ) {
		// write out the polygon points
		for ( polygon::const_iterator lp=poly->begin(); lp!=poly->end(); ++lp )
			write_point( out, lp->x, lp->y, false );
		if ( poly->begin()!=poly->end() ) 
			write_point( out, poly->begin()->x, poly->begin()->y, true );
	}
	else {
		// convert to a polygon
		polygon p;
		view.get_polygon( p );

		// write out the polygon points
		for( polygon::const_iterator lp=p.begin(); lp!=p.end(); ++lp ) 
			write_point( out, lp->x, lp->y, false );
		if ( poly->begin()!=poly->end() ) 
			write_point( out, p.begin()->x, p.begin()->y, true );
	}
}

static char const* look_up_layer_name( dxf::map_id_name const& id_to_name, layer_id layer )
{
	dxf::map_id_name::const_iterator lp = id_to_name.find( layer );
	if ( lp != id_to_name.end() ) {
		return lp->second.c_str();
	}
	else {
		return "UNKNOWN";
	}
}

void dxf::write( layout const * view, map_id_name const& id_to_name, std::ostream& out )
{
	// get the shapes
	std::vector<shape>	shapes;
	view->get_shapes( shapes );

	// write the file header
	write_HEADER( out );

	// draw the shapes
	write_start_ENTITIES( out );
	std::vector<shape>::const_iterator lp;
	for ( lp = shapes.begin(); lp != shapes.end(); ++lp )
	{
		char const* layer_name = look_up_layer_name( id_to_name, lp->layer() );
		write_shape( out, *lp, layer_name );
	}
	write_end_ENTITIES( out );

	// complete the file
	write_EOF( out );
}

void dxf::write( layout const * view, layer_id layer, map_id_name const& id_to_name, std::ostream& out )
{
	// get the shapes
	std::vector<shape>	shapes;
	view->get_shapes( shapes, layer );
	// look-up the layer name
	char const* layer_name = look_up_layer_name( id_to_name, layer );

	// write the file header
	write_HEADER( out );

	// draw the shapes
	write_start_ENTITIES( out );
	std::vector<shape>::const_iterator lp;
	for ( lp = shapes.begin(); lp != shapes.end(); ++lp )
	{
		write_shape( out, *lp, layer_name );
	}
	write_end_ENTITIES( out );

	// complete the file
	write_EOF( out );
}