1
0
forked from 0ad/0ad
0ad/source/dcdt/se/sr_sa_eps_export.cpp
janwas 5bf9bca9ef fix/disable warnings.
there are too many W4 and "potentially uninitialized", so those are
disabled by 0ad_warning_disable.h.

the silly "int x = strlen" and very dangerous "int x = (void*)p" (and
vice versa) problems are fixed.

This was SVN commit r5526.
2007-12-23 12:18:57 +00:00

381 lines
11 KiB
C++

#include "precompiled.h"
#include "0ad_warning_disable.h"
# include "sr_sa_eps_export.h"
# include "sr_sa_bbox.h"
# include "sr_sn_shape.h"
# include "sr_lines.h"
# include "sr_points.h"
# include "sr_polygons.h"
//# define SR_USE_TRACE1 // constructor / destructor
//# define SR_USE_TRACE2 // render
# include "sr_trace.h"
//============================= export functions ====================================
// detect if lines are in 3d or 2d!!?
// make use of current matrix (and camera) transformation
static void export_lines ( SrSnShapeBase* shape, SrOutput& o, const SrSaEpsExport* epsexp )
{
SrLines& l = ((SrSnLines*)shape)->shape();
SrArray<SrPnt>& V = l.V;
SrArray<SrColor>& C = l.C;
SrArray<int>& I = l.I;
float c[4];
if ( V.size()<2 ) return;
shape->material().diffuse.get ( c );
o << c[0] << srspc << c[1] << srspc << c[2] << " setrgbcolor\n";
float res = shape->resolution(); // 0.5 1.0 1.5
res *= 0.02f; // makes resolution 1 be .02 cms
res *= 28.346f; // put in unit pts
res /= epsexp->scale_factor();
o << res << " setlinewidth\n";
int v=0; // current V index
int i; // current I index
int imax = I.size()-1; // max value for i
int i1=-1, i2; // pair I[i],I[i+1]
if ( I.size()>1 ) { i=0; i1=I[i]; i2=I[i+1]; }
while ( v<V.size() )
{
if ( v==i1 )
{ if ( i2<0 ) // new color
{ C[-i2-1].get ( c );
o << c[0] << srspc << c[1] << srspc << c[2] << " setrgbcolor\n";
}
else if ( v<V.size() ) // new polyline
{ o << "newpath\n";
o << V[v].x << srspc << V[v].y << " moveto\n";
v++;
while ( v<V.size() && v<=i2 )
{ o << V[v].x << srspc << V[v].y << " lineto\n";
v++;
}
//o << "closepath\n";
o << "stroke\n\n";
}
i+=2; // update next I information
if ( i<imax ) { i1=I[i]; i2=I[i+1]; } else i1=-1;
}
else
{ o << "newpath\n";
bool move=true;
while ( v<V.size() && v!=i1 )
{ o << V[v].x << srspc << V[v].y;
v++;
if ( move )
{ o<<" moveto\n"; move=false; }
else
{ o<<" lineto\n"; move=true; }
}
//o << "closepath\n";
o << "stroke\n\n";
}
}
}
static void export_points ( SrSnShapeBase* shape, SrOutput& o, const SrSaEpsExport* epsexp )
{
/*
SrPoints& p = ((SrSnPoints*)shape)->get();
if ( p.P.size()==0 ) return;
glDisable ( GL_LIGHTING );
glColor ( shape->material().diffuse );
if ( shape->render_mode()==srRenderModeSmooth )
{ // render shperes, with resolution as radius?
}
glPointSize ( shape->resolution() ); // default is 1.0
int i;
glBegin ( GL_POINTS );
for ( i=0; i<p.P.size(); i++ )
glVertex ( p.P[i] );
glEnd ();
*/
}
static void export_polygon ( SrPolygon& p, srRenderMode rm, float res,
SrOutput& o, const SrSaEpsExport* epsexp )
{
int i;
{ o << "newpath\n";
o << p[0] << " moveto\n";
for ( i=1; i<p.size(); i++ ) o << p[i] << " lineto\n";
if ( !p.open() ) o << p[0] << " lineto\n";
o << "closepath\n";
o << "stroke\n\n";
}
/*
if ( p.open() )
{ glBegin ( GL_LINE_STRIP );
for ( i=0; i<p.size(); i++ ) glVertex ( p[i] );
glEnd ();
}
else
{ if ( rm==srRenderModeSmooth || rm==srRenderModeFlat || rm==srRenderModeDefault )
{ SrArray<SrPnt2> tris;
p.ear_triangulation ( tris );
glBegin ( GL_TRIANGLES );
for ( i=0; i<tris.size(); i++ ) glVertex ( tris[i] );
glEnd ();
}
else
{ o << "newpath\n";
o << p[0] << " moveto\n";
for ( i=1; i<p.size(); i++ ) o << p[i] << " lineto\n";
if ( !p.open() ) o << p[0] << " moveto\n";
o << "closepath\n";
o << "stroke\n\n";
}
}
if ( rm==srRenderModePoints || rm==srRenderModeFlat )
{ glPointSize ( res*4 );
glBegin ( GL_POINTS );
for ( i=0; i<p.size(); i++ ) glVertex ( p[i] );
glEnd ();
}
*/
}
static void export_polygon ( SrSnShapeBase* shape, SrOutput& o,
const SrSaEpsExport* epsexp )
{
SrPolygon& p = ((SrSnPolygon*)shape)->shape();
if ( p.size()==0 ) return;
float resolution = shape->resolution();
// glDisable ( GL_LIGHTING );
// glColor ( shape->material().diffuse );
// glLineWidth ( resolution ); // default is 1.0
export_polygon ( p, shape->render_mode(), resolution, o, epsexp );
}
static void export_polygons ( SrSnShapeBase* shape, SrOutput& o, const SrSaEpsExport* epsexp )
{
SrPolygons& p = ((SrSnPolygons*)shape)->shape();
if ( p.size()==0 ) return;
float resolution = shape->resolution();
/* glDisable ( GL_LIGHTING );
glColor ( shape->material().diffuse );
glLineWidth ( resolution ); // default is 1.0
*/
int i;
for ( i=0; i<p.size(); i++ ) ::export_polygon ( p[i], shape->render_mode(), resolution, o, epsexp );
}
//=============================== SrSaEpsExport ====================================
SrArray<SrSaEpsExport::RegData> SrSaEpsExport::_efuncs;
SrSaEpsExport::SrSaEpsExport ( SrOutput& o )
: _output ( o )
{
SR_TRACE1 ( "Constructor" );
_page_width = 21.59f; // == 612 pts
_page_height = 27.94f; // == 792 pts
_page_margin = 4.0f;
_bbox_margin = 0.1f;
if ( _efuncs.size()==0 ) // no functions registered
{ //register_export_function ( "model", export_model );
register_export_function ( "lines", export_lines );
register_export_function ( "points", export_points );
//register_export_function ( "box", export_box );
//register_export_function ( "sphere", export_sphere );
register_export_function ( "polygon", export_polygon );
register_export_function ( "polygons", export_polygons );
}
}
SrSaEpsExport::~SrSaEpsExport ()
{
SR_TRACE1 ( "Destructor" );
}
void register_export_function ( const char* class_name, SrSaEpsExport::export_function efunc ) // friend function
{
SrArray<SrSaEpsExport::RegData> &ef = SrSaEpsExport::_efuncs;
int i;
for ( i=0; i<ef.size(); i++ )
{ if ( sr_compare(ef[i].class_name,class_name)==0 ) break;
}
if ( i==ef.size() ) ef.push(); // if not found, push a new position
ef[i].class_name = class_name;
ef[i].efunc = efunc;
}
bool SrSaEpsExport::apply ( SrSn* n )
{
// get bounding box
SrSaBBox ab;
ab.apply(n);
SrBox bbox = ab.get();
SrVec bboxsize = bbox.size();
SrVec bboxcenter = bbox.center();
// PostScript uses pts as default unit: 1inch==72pts, 1cm==28.346pts
// so we put this transformation constant here:
const float topts = 28.346f;
// The required scaling so that the bounding box is inside the page
// and respecting the desired margin:
_scale_factor = _page_width / (bboxsize.x+2*_page_margin);
_scale_factor *= topts;
// The required translation to make the center of the bounding box
// be in the middle of the page:
_translation.set ( _page_width*topts/2 - bboxcenter.x*_scale_factor,
_page_height*topts/2 - bboxcenter.y*_scale_factor );
// Output eps header
_output << "%!PS-Adobe-3.0 EPSF-3.0\n";
// Output the ebounding box:
// The four arguments of the bounding box comment correspond to the lowerleft
// and upper-right corners of the bounding box, expressed in the default
// PostScript coordinate system (pts) (28.346 passes from cms to pts).
float a = ( bbox.a.x - _bbox_margin ) * _scale_factor + _translation.x;
float b = ( bbox.a.y + _bbox_margin ) * _scale_factor + _translation.y;
float c = ( bbox.b.x - _bbox_margin ) * _scale_factor + _translation.x;
float d = ( bbox.b.y + _bbox_margin ) * _scale_factor + _translation.y;
_output << "%%BoundingBox: " << int(a) << srspc << int(b) << srspc
<< int(c) << srspc << int(d) << srnl;
// %!SrBoundingBox: -28.000000 -28.000000 28.000000 28.000000
// %%BoundingBox: 124 123 734 623
// Output other information:
_output << "%%Creator: Sr EPS Exporter, Marcelo Kallmann 2002-2003\n";
_output << "%!SrBoundingBox: " << bbox.a.x << srspc << bbox.a.y << srspc
<< bbox.b.x << srspc << bbox.b.y << srnl;
_output << "%!\n\n";
// Save the graphics state:
_output << "gsave\n";
// Output transformations so to work in cms and to fit the bbox in the page:
_output << _translation << " translate\n";
_output << _scale_factor << srspc << _scale_factor << " scale\n";
// Other settings:
// _output << "1 setlinewidth\n";
_output << srnl;
// Call the scene graph:
bool result = SrSa::apply ( n );
// Finalize:
_output << "\n";
_output << "grestore\n";
// _output << "showpage\n";
return result;
}
//==================================== virtuals ====================================
void SrSaEpsExport::mult_matrix ( const SrMat& mat )
{
//glMultMatrix ( mat );
}
void SrSaEpsExport::push_matrix ()
{
//glPushMatrix ();
}
void SrSaEpsExport::pop_matrix ()
{
//glPopMatrix ();
}
bool SrSaEpsExport::shape_apply ( SrSnShapeBase* s )
{
// 1. Search for export function
int i;
const char* class_name = s->inst_class_name ();
SrArray<SrSaEpsExport::RegData>& ef = SrSaEpsExport::_efuncs;
for ( i=0; i<ef.size(); i++ )
if ( sr_compare(ef[i].class_name,class_name)==0 ) break;
if ( i==ef.size() ) return true; // not found: nothing is done
// 2. Export only if needed
if ( !s->visible() ) return true;
// 3. Export
ef[i].efunc ( s, _output, this );
return true;
}
//======================================= PS GUIDE ====================================
/*
http://adela.karlin.mff.cuni.cz/netkarl/prirucky/Flat/paths.html
72 72 scale points to inches, 1 pt = 1/72 inches
2.8346 2.8346 scale points to mms
1.0 setlinewidth 0 is valid
2 setlinecap 0, 1, 2: butt ends, round ends, square ends
2 setlinejoin 0, 1, 2: miter corners, round corners, bevel corners
0.5 setgray 0 to 1
gsave
grestore
EXAMPLE:
%!
0.025 setlinewidth
72 72 scale
0.8 setgray
newpath
1 1 moveto
7 1 lineto
1 5 lineto
closepath
fill
0 setgray
newpath
1 1 moveto
7 1 lineto
1 5 lineto
closepath
stroke
showpage
*/
//======================================= EOF ====================================