filters
epsexport.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qapplication.h>
00021 #include <qcstring.h>
00022 #include <qdatetime.h>
00023 #include <qdom.h>
00024 #include <qfile.h>
00025 #include <qstring.h>
00026 #include <qvaluelist.h>
00027
00028 #include <kdebug.h>
00029 #include <kgenericfactory.h>
00030 #include <KoDocumentInfo.h>
00031 #include <KoFilter.h>
00032 #include <KoFilterChain.h>
00033 #include <KoStore.h>
00034
00035 #include "epsexport.h"
00036 #include "epsexportdlg.h"
00037 #include "vcolor.h"
00038 #include "vcomposite.h"
00039 #include "vdashpattern.h"
00040 #include "vdocument.h"
00041 #include "vfill.h"
00042 #include "vgroup.h"
00043 #include "vlayer.h"
00044 #include "vpath.h"
00045 #include "vsegment.h"
00046 #include "vselection.h"
00047 #include "vstroke.h"
00048 #include "vtext.h"
00049 #include "vcomputeboundingbox.h"
00050
00051
00052 static char l1_newpath = 'N';
00053 static char l1_closepath = 'C';
00054 static char l1_moveto = 'm';
00055 static char l1_curveto = 'c';
00056 static char l1_lineto = 'l';
00057 static char l1_stroke = 's';
00058 static char l1_fill = 'f';
00059
00060 static char l1_setlinewidth = 'w';
00061 static char l1_setdash = 'd';
00062 static char l1_setrgbcolor = 'r';
00063 static char l1_gsave = 'S';
00064 static char l1_grestore = 'R';
00065
00066
00067 class EpsExportFactory : KGenericFactory<EpsExport, KoFilter>
00068 {
00069 public:
00070 EpsExportFactory( void )
00071 : KGenericFactory<EpsExport, KoFilter>( "karbonepsexport" )
00072 {}
00073
00074 protected:
00075 virtual void setupTranslations( void )
00076 {
00077 KGlobal::locale()->insertCatalogue( "kofficefilters" );
00078 }
00079 };
00080
00081
00082 K_EXPORT_COMPONENT_FACTORY( libkarbonepsexport, EpsExportFactory() )
00083
00084
00085 EpsExport::EpsExport( KoFilter*, const char*, const QStringList& )
00086 : KoFilter(), m_exportHidden( true )
00087 {
00088 }
00089
00090 KoFilter::ConversionStatus
00091 EpsExport::convert( const QCString& from, const QCString& to )
00092 {
00093 if ( to != "image/x-eps" || from != "application/x-karbon" )
00094 {
00095 return KoFilter::NotImplemented;
00096 }
00097
00098
00099 KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read );
00100
00101 if( !storeIn )
00102 return KoFilter::StupidError;
00103
00104
00105 KoFilter::ConversionStatus status = KoFilter::OK;
00106
00107
00108 EpsExportDlg* dialog = new EpsExportDlg();
00109
00110 QApplication::setOverrideCursor( Qt::arrowCursor );
00111
00112 if( dialog->exec() )
00113 {
00114
00115 m_psLevel = dialog->psLevel() + 1;
00116 m_exportHidden = dialog->exportHidden();
00117
00118 QFile fileOut( m_chain->outputFile() );
00119 if( !fileOut.open( IO_WriteOnly ) )
00120 {
00121 QApplication::restoreOverrideCursor();
00122 delete( dialog );
00123
00124 return KoFilter::StupidError;
00125 }
00126
00127 QDomDocument domIn;
00128 domIn.setContent( storeIn );
00129 QDomElement docNode = domIn.documentElement();
00130
00131 m_stream = new QTextStream( &fileOut );
00132
00133
00134 VDocument doc;
00135 doc.load( docNode );
00136
00137
00138 doc.accept( *this );
00139
00140 delete m_stream;
00141 fileOut.close();
00142 }
00143 else
00144 {
00145
00146 status = KoFilter::UserCancelled;
00147 }
00148
00149 QApplication::restoreOverrideCursor();
00150 delete( dialog );
00151
00152 return status;
00153 }
00154
00155 void
00156 EpsExport::visitVDocument( VDocument& document )
00157 {
00158
00159 VComputeBoundingBox bbox( ! m_exportHidden );
00160 document.accept( bbox );
00161 const KoRect &rect = bbox.boundingRect();
00162
00163
00164 *m_stream <<
00165 "%!PS-Adobe-3.0 EPSF-3.0\n"
00166 "%%BoundingBox: " <<
00167
00168 qRound( rect.left() - 0.5 ) << " " <<
00169 qRound( rect.top() - 0.5 ) << " " <<
00170
00171 qRound( rect.right() + 0.5 ) << " " <<
00172 qRound( rect.bottom() + 0.5 ) << "\n" <<
00173 "%%HiResBoundingBox: " <<
00174 rect.left() << " " <<
00175 rect.top() << " " <<
00176 rect.right() << " " <<
00177 rect.bottom() << "\n"
00178 "%%Creator: Karbon14 EPS Exportfilter 0.5"
00179 << endl;
00180
00181
00182 KoStoreDevice* storeIn;
00183 storeIn = m_chain->storageFile( "documentinfo.xml", KoStore::Read );
00184
00185 if( storeIn )
00186 {
00187 QDomDocument domIn;
00188 domIn.setContent( storeIn );
00189
00190 KoDocumentInfo docInfo;
00191 docInfo.load( domIn );
00192
00193 KoDocumentInfoAuthor* authorPage =
00194 static_cast<KoDocumentInfoAuthor*>( docInfo.page( "author" ) );
00195
00196
00197 QDateTime now( QDateTime::currentDateTime() );
00198
00199 *m_stream <<
00200 "%%CreationDate: (" << now.toString( Qt::LocalDate ) << ")\n"
00201 "%%For: (" << authorPage->fullName() << ") (" << authorPage->company() << ")\n"
00202 "%%Title: (" << docInfo.title() << ")"
00203 << endl;
00204 }
00205
00206
00207
00208 *m_stream <<
00209 "\n"
00210 "/" << l1_newpath << " {newpath} def\n"
00211 "/" << l1_closepath << " {closepath} def\n"
00212 "/" << l1_moveto << " {moveto} def\n"
00213 "/" << l1_curveto << " {curveto} def\n"
00214 "/" << l1_lineto << " {lineto} def\n"
00215 "/" << l1_stroke << " {stroke} def\n"
00216 "/" << l1_fill << " {fill} def\n"
00217 "/" << l1_setlinewidth << " {setlinewidth} def\n"
00218 "/" << l1_setdash << " {setdash} def\n"
00219 "/" << l1_setrgbcolor << " {setrgbcolor} def\n"
00220 "/" << l1_gsave << " {gsave} def\n"
00221 "/" << l1_grestore << " {grestore} def\n"
00222 << endl;
00223
00224
00225 VVisitor::visitVDocument( document );
00226
00227
00228 *m_stream <<
00229 "%%EOF"
00230 << endl;
00231 }
00232
00233 void
00234 EpsExport::visitVGroup( VGroup& group )
00235 {
00236 VObjectListIterator itr( group.objects() );
00237
00238 for( ; itr.current(); ++itr )
00239 {
00240
00241 if( ! m_exportHidden && ! isVisible( itr.current() ) )
00242 continue;
00243 itr.current()->accept( *this );
00244 }
00245 }
00246
00247 void
00248 EpsExport::visitVLayer( VLayer& layer )
00249 {
00250
00251 if( ! m_exportHidden && ! isVisible( &layer ) )
00252 return;
00253
00254 VObjectListIterator itr( layer.objects() );
00255
00256 for( ; itr.current(); ++itr )
00257 {
00258
00259 if( ! m_exportHidden && ! isVisible( itr.current() ) )
00260 continue;
00261 itr.current()->accept( *this );
00262 }
00263 }
00264
00265 void
00266 EpsExport::visitVPath( VPath& composite )
00267 {
00268 *m_stream << l1_newpath << "\n";
00269
00270 VVisitor::visitVPath( composite );
00271
00272 getFill( *composite.fill() );
00273 getStroke( *composite.stroke() );
00274
00275 *m_stream << endl;
00276 }
00277
00278 void
00279 EpsExport::visitVSubpath( VSubpath& path )
00280 {
00281
00282 VSubpathIterator itr( path );
00283
00284 for( ; itr.current(); ++itr )
00285 {
00286 VSegment *segment = itr.current();
00287 if ( segment->isCurve() ) {
00288 *m_stream <<
00289 itr.current()->point( 0 ).x() << " " <<
00290 itr.current()->point( 0 ).y() << " " <<
00291 itr.current()->point( 1 ).x() << " " <<
00292 itr.current()->point( 1 ).y() << " " <<
00293 itr.current()->knot().x() << " " <<
00294 itr.current()->knot().y() << " " <<
00295 l1_curveto << "\n";
00296 } else if ( segment->isLine() ) {
00297 *m_stream <<
00298 itr.current()->knot().x() << " " <<
00299 itr.current()->knot().y() << " " <<
00300 l1_lineto << "\n";
00301 } else if ( segment->isBegin() ) {
00302 *m_stream <<
00303 itr.current()->knot().x() << " " <<
00304 itr.current()->knot().y() << " " <<
00305 l1_moveto << "\n";
00306 }
00307 }
00308
00309 if( path.isClosed() )
00310 *m_stream << l1_closepath << "\n";
00311 }
00312
00313 void
00314 EpsExport::visitVText( VText& text )
00315 {
00316
00317
00318
00319 VPathListIterator itr( text.glyphs() );
00320
00321 for( ; itr.current(); ++itr )
00322 {
00323 visit( *itr.current() );
00324 }
00325 }
00326
00327 void
00328 EpsExport::getStroke( const VStroke& stroke )
00329 {
00330
00331 if( stroke.type() == VStroke::solid )
00332 {
00333
00334 *m_stream << "[";
00335
00336 const QValueList<float>&
00337 array( stroke.dashPattern().array() );
00338
00339 QValueListConstIterator<float> itr = array.begin();
00340 for( ; itr != array.end(); ++itr )
00341 *m_stream << *itr << " ";
00342
00343 *m_stream <<
00344 "] " << stroke.dashPattern().offset() <<
00345 " " << l1_setdash << " ";
00346
00347 getColor( stroke.color() );
00348
00349
00350 *m_stream <<
00351 " " << stroke.lineWidth() <<
00352 " " << l1_setlinewidth <<
00353 " " << l1_stroke << "\n";
00354 }
00355 else if( stroke.type() == VStroke::grad )
00356 {
00357 if( m_psLevel == 3 )
00358 {
00359
00360 }
00361 }
00362 }
00363
00364 void
00365 EpsExport::getFill( const VFill& fill )
00366 {
00367
00368 if( fill.type() == VFill::solid )
00369 {
00370
00371 *m_stream << l1_gsave << " ";
00372
00373
00374 getColor( fill.color() );
00375
00376
00377 *m_stream << " " << l1_fill << " " << l1_grestore << "\n";
00378 }
00379
00380 else if( fill.type() == VFill::grad )
00381 {
00382 if( m_psLevel == 3 )
00383 {
00384
00385 *m_stream << l1_gsave << " ";
00386
00387 VGradient grad = fill.gradient();
00388 QPtrVector<VColorStop> ramp = grad.colorStops();
00389 if( ramp.size() < 2 )
00390 {
00391 if( ramp.size() == 1 )
00392 getColor( ramp[0]->color );
00393 }
00394 if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 )
00395 {
00396
00397 for( uint i = 1;i < ramp.size();i++ )
00398 {
00399 char name[15];
00400 sprintf( name, "Function%d", 2 * i - 1 );
00401
00402 VColorStop stop1 = *ramp[i - 1];
00403 VColorStop stop2 = *ramp[i];
00404 VColor mid;
00405 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] ) );
00406 *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n"
00407 << "\t/Domain [ 0 1 ] def\n" << "\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " "
00408 << stop1.color[2] << " ] def\n" << "\t/C1 [ " << mid[0] << " " << mid[1] << " "
00409 << mid[2] << " ] def\n" << "\t/N 1 def\n" << "end\n";
00410
00411 sprintf( name, "Function%d", 2 * i );
00412
00413 *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n" << "\t/Domain [ 0 1 ] def\n"
00414 << "\t/C0 [ " << mid[0] << " " << mid[1] << " " << mid[2] << " ] def\n" << "\t/C1 [ " << stop2.color[0] << " "
00415 << stop2.color[1] << " " << stop2.color[2] << " ] def\n" << "\t/N 1 def\n" << "end\n";
00416 }
00417 }
00418 if( grad.type() == VGradient::linear )
00419 *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 2\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ "
00420 << grad.origin().x() << " " << grad.origin().y() << " " << grad.vector().x() << " " << grad.vector().y() << " ]\n\t/Extend[ true true ]\n" << "\t/Function <<\n";
00421 else if( grad.type() == VGradient::radial )
00422 {
00423 double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) );
00424 *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 3\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ "
00425 << grad.origin().x() << " " << grad.origin().y() << " 0.0 " << grad.origin().x() << " " << grad.origin().y()
00426 << " " << r << "]\n\t\t/Extend [ false true ]\n" << "\t/Function <<\n";
00427 }
00428 if( ramp.size() == 2 && ramp[0]->midPoint == 0.5 )
00429 {
00430
00431 VColorStop stop1 = *ramp[0];
00432 VColorStop stop2 = *ramp[1];
00433 *m_stream << "\t\t/FunctionType 2\n" << "\t\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " " << stop1.color[2]
00434 << " ]\n" << "\t\t/C1 [ " << stop2.color[0] << " " << stop2.color[1] << " " << stop2.color[2] << " ]\n" << "\t\t/N 1\n";
00435 }
00436 else if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 )
00437 {
00438
00439 *m_stream << "\t\t/FunctionType 3\n" << "\t\t/Functions [ ";
00440 for( uint i = 1; i < ( 2 * ramp.size() - 1 );i++ )
00441 *m_stream << "Function" << i << " ";
00442 *m_stream << "]\n" << "\t\t/Bounds [";
00443 for( uint i = 0;i < ramp.size() - 1;i++ )
00444 {
00445 VColorStop stop = *ramp[i];
00446 if( i > 0 )
00447 *m_stream << " " << stop.rampPoint;
00448 *m_stream << " " << ( stop.rampPoint + ( ramp[i + 1]->rampPoint - stop.rampPoint ) * stop.midPoint );
00449 }
00450 *m_stream << " ]\n" << "\t\t/Encode [ ";
00451 for( uint i = 0;i < 2 * ramp.size() - 2;i++ )
00452 *m_stream << "0 1 ";
00453 *m_stream << "]\n";
00454 }
00455 *m_stream << "\t\t/Domain [ " << ramp[0]->rampPoint << " "
00456 << ramp[ramp.size() - 1]->rampPoint << " ]\n" << "\t>>\n" << ">>\n";
00457
00458 *m_stream << " shfill " << l1_grestore << "\n";
00459 }
00460 }
00461 }
00462
00463 void
00464 EpsExport::getColor( const VColor& color )
00465 {
00466 VColor copy( color );
00467 copy.setColorSpace( VColor::rgb );
00468
00469 *m_stream <<
00470 copy[0] << " " <<
00471 copy[1] << " " <<
00472 copy[2] << " " << l1_setrgbcolor;
00473 }
00474
00475 bool
00476 EpsExport::isVisible( const VObject* object ) const
00477 {
00478 return object->state() != VObject::hidden && object->state() != VObject::hidden_locked;
00479 }
00480
00481 #include "epsexport.moc"
|