20#include <tqapplication.h>
22#include <tqdatetime.h>
26#include <tqvaluelist.h>
29#include <kgenericfactory.h>
30#include <KoDocumentInfo.h>
32#include <KoFilterChain.h>
36#include "epsexportdlg.h"
38#include "vcomposite.h"
39#include "vdashpattern.h"
46#include "vselection.h"
49#include "vcomputeboundingbox.h"
52static char l1_newpath =
'N';
53static char l1_closepath =
'C';
54static char l1_moveto =
'm';
55static char l1_curveto =
'c';
56static char l1_lineto =
'l';
57static char l1_stroke =
's';
58static char l1_fill =
'f';
60static char l1_setlinewidth =
'w';
61static char l1_setdash =
'd';
62static char l1_setrgbcolor =
'r';
63static char l1_gsave =
'S';
64static char l1_grestore =
'R';
67class EpsExportFactory : KGenericFactory<EpsExport, KoFilter>
70 EpsExportFactory(
void )
71 : KGenericFactory<EpsExport, KoFilter>(
"karbonepsexport" )
75 virtual void setupTranslations(
void )
77 TDEGlobal::locale()->insertCatalogue(
"kofficefilters" );
82K_EXPORT_COMPONENT_FACTORY( libkarbonepsexport, EpsExportFactory() )
85EpsExport::EpsExport( KoFilter*, const
char*, const TQStringList& )
86 : KoFilter(), m_exportHidden( true )
90KoFilter::ConversionStatus
91EpsExport::convert(
const TQCString& from,
const TQCString& to )
93 if ( to !=
"image/x-eps" || from !=
"application/x-karbon" )
95 return KoFilter::NotImplemented;
99 KoStoreDevice* storeIn = m_chain->storageFile(
"root", KoStore::Read );
102 return KoFilter::StupidError;
105 KoFilter::ConversionStatus status = KoFilter::OK;
108 EpsExportDlg* dialog =
new EpsExportDlg();
110 TQApplication::setOverrideCursor( TQt::arrowCursor );
115 m_psLevel = dialog->psLevel() + 1;
116 m_exportHidden = dialog->exportHidden();
118 TQFile fileOut( m_chain->outputFile() );
119 if( !fileOut.open( IO_WriteOnly ) )
121 TQApplication::restoreOverrideCursor();
124 return KoFilter::StupidError;
128 domIn.setContent( storeIn );
129 TQDomElement docNode = domIn.documentElement();
131 m_stream =
new TQTextStream( &fileOut );
146 status = KoFilter::UserCancelled;
149 TQApplication::restoreOverrideCursor();
156EpsExport::visitVDocument( VDocument& document )
159 VComputeBoundingBox bbox( ! m_exportHidden );
160 document.accept( bbox );
161 const KoRect &rect = bbox.boundingRect();
165 "%!PS-Adobe-3.0 EPSF-3.0\n"
168 tqRound( rect.left() - 0.5 ) <<
" " <<
169 tqRound( rect.top() - 0.5 ) <<
" " <<
171 tqRound( rect.right() + 0.5 ) <<
" " <<
172 tqRound( rect.bottom() + 0.5 ) <<
"\n" <<
173 "%%HiResBoundingBox: " <<
174 rect.left() <<
" " <<
176 rect.right() <<
" " <<
177 rect.bottom() <<
"\n"
178 "%%Creator: Karbon14 EPS Exportfilter 0.5"
182 KoStoreDevice* storeIn;
183 storeIn = m_chain->storageFile(
"documentinfo.xml", KoStore::Read );
188 domIn.setContent( storeIn );
190 KoDocumentInfo docInfo;
191 docInfo.load( domIn );
193 KoDocumentInfoAuthor* authorPage =
194 static_cast<KoDocumentInfoAuthor*
>( docInfo.page(
"author" ) );
197 TQDateTime now( TQDateTime::currentDateTime() );
200 "%%CreationDate: (" << now.toString( TQt::LocalDate ) <<
")\n"
201 "%%For: (" << authorPage->fullName() <<
") (" << authorPage->company() <<
")\n"
202 "%%Title: (" << docInfo.title() <<
")"
210 "/" << l1_newpath <<
" {newpath} def\n"
211 "/" << l1_closepath <<
" {closepath} def\n"
212 "/" << l1_moveto <<
" {moveto} def\n"
213 "/" << l1_curveto <<
" {curveto} def\n"
214 "/" << l1_lineto <<
" {lineto} def\n"
215 "/" << l1_stroke <<
" {stroke} def\n"
216 "/" << l1_fill <<
" {fill} def\n"
217 "/" << l1_setlinewidth <<
" {setlinewidth} def\n"
218 "/" << l1_setdash <<
" {setdash} def\n"
219 "/" << l1_setrgbcolor <<
" {setrgbcolor} def\n"
220 "/" << l1_gsave <<
" {gsave} def\n"
221 "/" << l1_grestore <<
" {grestore} def\n"
225 VVisitor::visitVDocument( document );
234EpsExport::visitVGroup( VGroup& group )
236 VObjectListIterator itr( group.objects() );
238 for( ; itr.current(); ++itr )
241 if( ! m_exportHidden && ! isVisible( itr.current() ) )
243 itr.current()->accept( *
this );
248EpsExport::visitVLayer( VLayer& layer )
251 if( ! m_exportHidden && ! isVisible( &layer ) )
254 VObjectListIterator itr( layer.objects() );
256 for( ; itr.current(); ++itr )
259 if( ! m_exportHidden && ! isVisible( itr.current() ) )
261 itr.current()->accept( *
this );
266EpsExport::visitVPath( VPath& composite )
268 *m_stream << l1_newpath <<
"\n";
270 VVisitor::visitVPath( composite );
272 getFill( *composite.fill() );
273 getStroke( *composite.stroke() );
279EpsExport::visitVSubpath( VSubpath& path )
282 VSubpathIterator itr( path );
284 for( ; itr.current(); ++itr )
286 VSegment *segment = itr.current();
287 if ( segment->isCurve() ) {
289 itr.current()->point( 0 ).x() <<
" " <<
290 itr.current()->point( 0 ).y() <<
" " <<
291 itr.current()->point( 1 ).x() <<
" " <<
292 itr.current()->point( 1 ).y() <<
" " <<
293 itr.current()->knot().x() <<
" " <<
294 itr.current()->knot().y() <<
" " <<
296 }
else if ( segment->isLine() ) {
298 itr.current()->knot().x() <<
" " <<
299 itr.current()->knot().y() <<
" " <<
301 }
else if ( segment->isBegin() ) {
303 itr.current()->knot().x() <<
" " <<
304 itr.current()->knot().y() <<
" " <<
309 if( path.isClosed() )
310 *m_stream << l1_closepath <<
"\n";
314EpsExport::visitVText( VText& text )
319 VPathListIterator itr( text.glyphs() );
321 for( ; itr.current(); ++itr )
323 visit( *itr.current() );
328EpsExport::getStroke(
const VStroke& stroke )
331 if( stroke.type() == VStroke::solid )
336 const TQValueList<float>&
337 array( stroke.dashPattern().array() );
339 TQValueListConstIterator<float> itr = array.begin();
340 for( ; itr != array.end(); ++itr )
341 *m_stream << *itr <<
" ";
344 "] " << stroke.dashPattern().offset() <<
345 " " << l1_setdash <<
" ";
347 getColor( stroke.color() );
351 " " << stroke.lineWidth() <<
352 " " << l1_setlinewidth <<
353 " " << l1_stroke <<
"\n";
355 else if( stroke.type() == VStroke::grad )
365EpsExport::getFill(
const VFill& fill )
368 if( fill.type() == VFill::solid )
371 *m_stream << l1_gsave <<
" ";
374 getColor( fill.color() );
377 *m_stream <<
" " << l1_fill <<
" " << l1_grestore <<
"\n";
380 else if( fill.type() == VFill::grad )
385 *m_stream << l1_gsave <<
" ";
387 VGradient grad = fill.gradient();
388 TQPtrVector<VColorStop> ramp = grad.colorStops();
389 if( ramp.size() < 2 )
391 if( ramp.size() == 1 )
392 getColor( ramp[0]->color );
394 if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 )
397 for( uint i = 1;i < ramp.size();i++ )
400 sprintf( name,
"Function%d", 2 * i - 1 );
402 VColorStop stop1 = *ramp[i - 1];
403 VColorStop stop2 = *ramp[i];
405 mid.set( 0.5 * ( stop1.color[0] + stop2.color[0] ), 0.5 * ( stop1.color[1] + stop2.color[1] ), 0.5 * ( stop1.color[2] + stop2.color[2] ) );
406 *m_stream <<
"/" << name <<
" 7 dict def " << name <<
" begin\n" <<
"\t/FunctionType 2 def\n"
407 <<
"\t/Domain [ 0 1 ] def\n" <<
"\t/C0 [ " << stop1.color[0] <<
" " << stop1.color[1] <<
" "
408 << stop1.color[2] <<
" ] def\n" <<
"\t/C1 [ " << mid[0] <<
" " << mid[1] <<
" "
409 << mid[2] <<
" ] def\n" <<
"\t/N 1 def\n" <<
"end\n";
411 sprintf( name,
"Function%d", 2 * i );
413 *m_stream <<
"/" << name <<
" 7 dict def " << name <<
" begin\n" <<
"\t/FunctionType 2 def\n" <<
"\t/Domain [ 0 1 ] def\n"
414 <<
"\t/C0 [ " << mid[0] <<
" " << mid[1] <<
" " << mid[2] <<
" ] def\n" <<
"\t/C1 [ " << stop2.color[0] <<
" "
415 << stop2.color[1] <<
" " << stop2.color[2] <<
" ] def\n" <<
"\t/N 1 def\n" <<
"end\n";
418 if( grad.type() == VGradient::linear )
419 *m_stream <<
"clip newpath\n" <<
"/DeviceRGB setcolorspace\n" <<
"<<\n" <<
"\t/ShadingType 2\n" <<
"\t/ColorSpace /DeviceRGB\n" <<
"\t/Coords [ "
420 << grad.origin().x() <<
" " << grad.origin().y() <<
" " << grad.vector().x() <<
" " << grad.vector().y() <<
" ]\n\t/Extend[ true true ]\n" <<
"\t/Function <<\n";
421 else if( grad.type() == VGradient::radial )
423 double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) );
424 *m_stream <<
"clip newpath\n" <<
"/DeviceRGB setcolorspace\n" <<
"<<\n" <<
"\t/ShadingType 3\n" <<
"\t/ColorSpace /DeviceRGB\n" <<
"\t/Coords [ "
425 << grad.origin().x() <<
" " << grad.origin().y() <<
" 0.0 " << grad.origin().x() <<
" " << grad.origin().y()
426 <<
" " << r <<
"]\n\t\t/Extend [ false true ]\n" <<
"\t/Function <<\n";
428 if( ramp.size() == 2 && ramp[0]->midPoint == 0.5 )
431 VColorStop stop1 = *ramp[0];
432 VColorStop stop2 = *ramp[1];
433 *m_stream <<
"\t\t/FunctionType 2\n" <<
"\t\t/C0 [ " << stop1.color[0] <<
" " << stop1.color[1] <<
" " << stop1.color[2]
434 <<
" ]\n" <<
"\t\t/C1 [ " << stop2.color[0] <<
" " << stop2.color[1] <<
" " << stop2.color[2] <<
" ]\n" <<
"\t\t/N 1\n";
436 else if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 )
439 *m_stream <<
"\t\t/FunctionType 3\n" <<
"\t\t/Functions [ ";
440 for( uint i = 1; i < ( 2 * ramp.size() - 1 );i++ )
441 *m_stream <<
"Function" << i <<
" ";
442 *m_stream <<
"]\n" <<
"\t\t/Bounds [";
443 for( uint i = 0;i < ramp.size() - 1;i++ )
445 VColorStop stop = *ramp[i];
447 *m_stream <<
" " << stop.rampPoint;
448 *m_stream <<
" " << ( stop.rampPoint + ( ramp[i + 1]->rampPoint - stop.rampPoint ) * stop.midPoint );
450 *m_stream <<
" ]\n" <<
"\t\t/Encode [ ";
451 for( uint i = 0;i < 2 * ramp.size() - 2;i++ )
455 *m_stream <<
"\t\t/Domain [ " << ramp[0]->rampPoint <<
" "
456 << ramp[ramp.size() - 1]->rampPoint <<
" ]\n" <<
"\t>>\n" <<
">>\n";
458 *m_stream <<
" shfill " << l1_grestore <<
"\n";
464EpsExport::getColor(
const VColor& color )
466 VColor copy( color );
467 copy.setColorSpace( VColor::rgb );
472 copy[2] <<
" " << l1_setrgbcolor;
476EpsExport::isVisible(
const VObject*
object )
const
478 return object->state() != VObject::hidden &&
object->state() != VObject::hidden_locked;
481#include "epsexport.moc"