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
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()
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
00117 QFile fileOut( m_chain->outputFile() );
00118 if( !fileOut.open( IO_WriteOnly ) )
00119 {
00120 QApplication::restoreOverrideCursor();
00121 delete( dialog );
00122
00123 return KoFilter::StupidError;
00124 }
00125
00126 QDomDocument domIn;
00127 domIn.setContent( storeIn );
00128 QDomElement docNode = domIn.documentElement();
00129
00130 m_stream = new QTextStream( &fileOut );
00131
00132
00133 VDocument doc;
00134 doc.load( docNode );
00135
00136
00137 doc.accept( *this );
00138
00139 delete m_stream;
00140 fileOut.close();
00141 }
00142 else
00143 {
00144
00145 status = KoFilter::UserCancelled;
00146 }
00147
00148 QApplication::restoreOverrideCursor();
00149 delete( dialog );
00150
00151 return status;
00152 }
00153
00154 void
00155 EpsExport::visitVDocument( VDocument& document )
00156 {
00157
00158 document.selection()->append();
00159
00160
00161 const KoRect& rect = document.selection()->boundingBox();
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 document.selection()->clear();
00183
00184
00185
00186 KoStoreDevice* storeIn;
00187 storeIn = m_chain->storageFile( "documentinfo.xml", KoStore::Read );
00188
00189 if( storeIn )
00190 {
00191 QDomDocument domIn;
00192 domIn.setContent( storeIn );
00193
00194 KoDocumentInfo docInfo;
00195 docInfo.load( domIn );
00196
00197 KoDocumentInfoAuthor* authorPage =
00198 static_cast<KoDocumentInfoAuthor*>( docInfo.page( "author" ) );
00199
00200
00201 QDateTime now( QDateTime::currentDateTime() );
00202
00203 *m_stream <<
00204 "%%CreationDate: (" << now.toString( Qt::LocalDate ) << ")\n"
00205 "%%For: (" << authorPage->fullName() << ") (" << authorPage->company() << ")\n"
00206 "%%Title: (" << docInfo.title() << ")"
00207 << endl;
00208 }
00209
00210
00211
00212 *m_stream <<
00213 "\n"
00214 "/" << l1_newpath << " {newpath} def\n"
00215 "/" << l1_closepath << " {closepath} def\n"
00216 "/" << l1_moveto << " {moveto} def\n"
00217 "/" << l1_curveto << " {curveto} def\n"
00218 "/" << l1_lineto << " {lineto} def\n"
00219 "/" << l1_stroke << " {stroke} def\n"
00220 "/" << l1_fill << " {fill} def\n"
00221 "/" << l1_setlinewidth << " {setlinewidth} def\n"
00222 "/" << l1_setdash << " {setdash} def\n"
00223 "/" << l1_setrgbcolor << " {setrgbcolor} def\n"
00224 "/" << l1_gsave << " {gsave} def\n"
00225 "/" << l1_grestore << " {grestore} def\n"
00226 << endl;
00227
00228
00229 VVisitor::visitVDocument( document );
00230
00231
00232 *m_stream <<
00233 "%%EOF"
00234 << endl;
00235 }
00236
00237 void
00238 EpsExport::visitVPath( VPath& composite )
00239 {
00240 *m_stream << l1_newpath << "\n";
00241
00242 VVisitor::visitVPath( composite );
00243
00244 getFill( *composite.fill() );
00245 getStroke( *composite.stroke() );
00246
00247 *m_stream << endl;
00248 }
00249
00250 void
00251 EpsExport::visitVSubpath( VSubpath& path )
00252 {
00253
00254 VSubpathIterator itr( path );
00255
00256 for( ; itr.current(); ++itr )
00257 {
00258 VSegment *segment = itr.current();
00259 if ( segment->isCurve() ) {
00260 *m_stream <<
00261 itr.current()->point( 0 ).x() << " " <<
00262 itr.current()->point( 0 ).y() << " " <<
00263 itr.current()->point( 1 ).x() << " " <<
00264 itr.current()->point( 1 ).y() << " " <<
00265 itr.current()->knot().x() << " " <<
00266 itr.current()->knot().y() << " " <<
00267 l1_curveto << "\n";
00268 } else if ( segment->isLine() ) {
00269 *m_stream <<
00270 itr.current()->knot().x() << " " <<
00271 itr.current()->knot().y() << " " <<
00272 l1_lineto << "\n";
00273 } else if ( segment->isBegin() ) {
00274 *m_stream <<
00275 itr.current()->knot().x() << " " <<
00276 itr.current()->knot().y() << " " <<
00277 l1_moveto << "\n";
00278 }
00279 }
00280
00281 if( path.isClosed() )
00282 *m_stream << l1_closepath << "\n";
00283 }
00284
00285 void
00286 EpsExport::visitVText( VText& text )
00287 {
00288
00289
00290
00291 VPathListIterator itr( text.glyphs() );
00292
00293 for( ; itr.current(); ++itr )
00294 {
00295 visit( *itr.current() );
00296 }
00297 }
00298
00299 void
00300 EpsExport::getStroke( const VStroke& stroke )
00301 {
00302
00303 if( stroke.type() == VStroke::solid )
00304 {
00305
00306 *m_stream << "[";
00307
00308 const QValueList<float>&
00309 array( stroke.dashPattern().array() );
00310
00311 QValueListConstIterator<float> itr = array.begin();
00312 for( ; itr != array.end(); ++itr )
00313 *m_stream << *itr << " ";
00314
00315 *m_stream <<
00316 "] " << stroke.dashPattern().offset() <<
00317 " " << l1_setdash << " ";
00318
00319 getColor( stroke.color() );
00320
00321
00322 *m_stream <<
00323 " " << stroke.lineWidth() <<
00324 " " << l1_setlinewidth <<
00325 " " << l1_stroke << "\n";
00326 }
00327 else if( stroke.type() == VStroke::grad )
00328 {
00329 if( m_psLevel == 3 )
00330 {
00331
00332 }
00333 }
00334 }
00335
00336 void
00337 EpsExport::getFill( const VFill& fill )
00338 {
00339
00340 if( fill.type() == VFill::solid )
00341 {
00342
00343 *m_stream << l1_gsave << " ";
00344
00345
00346 getColor( fill.color() );
00347
00348
00349 *m_stream << " " << l1_fill << " " << l1_grestore << "\n";
00350 }
00351
00352 else if( fill.type() == VFill::grad )
00353 {
00354 if( m_psLevel == 3 )
00355 {
00356
00357 *m_stream << l1_gsave << " ";
00358
00359 VGradient grad = fill.gradient();
00360 QPtrVector<VColorStop> ramp = grad.colorStops();
00361 if( ramp.size() < 2 )
00362 {
00363 if( ramp.size() == 1 )
00364 getColor( ramp[0]->color );
00365 }
00366 if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 )
00367 {
00368
00369 for( uint i = 1;i < ramp.size();i++ )
00370 {
00371 char name[15];
00372 sprintf( name, "Function%d", 2 * i - 1 );
00373
00374 VColorStop stop1 = *ramp[i - 1];
00375 VColorStop stop2 = *ramp[i];
00376 VColor mid;
00377 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] ) );
00378 *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n"
00379 << "\t/Domain [ 0 1 ] def\n" << "\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " "
00380 << stop1.color[2] << " ] def\n" << "\t/C1 [ " << mid[0] << " " << mid[1] << " "
00381 << mid[2] << " ] def\n" << "\t/N 1 def\n" << "end\n";
00382
00383 sprintf( name, "Function%d", 2 * i );
00384
00385 *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n" << "\t/Domain [ 0 1 ] def\n"
00386 << "\t/C0 [ " << mid[0] << " " << mid[1] << " " << mid[2] << " ] def\n" << "\t/C1 [ " << stop2.color[0] << " "
00387 << stop2.color[1] << " " << stop2.color[2] << " ] def\n" << "\t/N 1 def\n" << "end\n";
00388 }
00389 }
00390 if( grad.type() == VGradient::linear )
00391 *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 2\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ "
00392 << grad.origin().x() << " " << grad.origin().y() << " " << grad.vector().x() << " " << grad.vector().y() << " ]\n\t/Extend[ true true ]\n" << "\t/Function <<\n";
00393 else if( grad.type() == VGradient::radial )
00394 {
00395 double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) );
00396 *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 3\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ "
00397 << grad.origin().x() << " " << grad.origin().y() << " 0.0 " << grad.origin().x() << " " << grad.origin().y()
00398 << " " << r << "]\n\t\t/Extend [ false true ]\n" << "\t/Function <<\n";
00399 }
00400 if( ramp.size() == 2 && ramp[0]->midPoint == 0.5 )
00401 {
00402
00403 VColorStop stop1 = *ramp[0];
00404 VColorStop stop2 = *ramp[1];
00405 *m_stream << "\t\t/FunctionType 2\n" << "\t\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " " << stop1.color[2]
00406 << " ]\n" << "\t\t/C1 [ " << stop2.color[0] << " " << stop2.color[1] << " " << stop2.color[2] << " ]\n" << "\t\t/N 1\n";
00407 }
00408 else if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 )
00409 {
00410
00411 *m_stream << "\t\t/FunctionType 3\n" << "\t\t/Functions [ ";
00412 for( uint i = 1; i < ( 2 * ramp.size() - 1 );i++ )
00413 *m_stream << "Function" << i << " ";
00414 *m_stream << "]\n" << "\t\t/Bounds [";
00415 for( uint i = 0;i < ramp.size() - 1;i++ )
00416 {
00417 VColorStop stop = *ramp[i];
00418 if( i > 0 )
00419 *m_stream << " " << stop.rampPoint;
00420 *m_stream << " " << ( stop.rampPoint + ( ramp[i + 1]->rampPoint - stop.rampPoint ) * stop.midPoint );
00421 }
00422 *m_stream << " ]\n" << "\t\t/Encode [ ";
00423 for( uint i = 0;i < 2 * ramp.size() - 2;i++ )
00424 *m_stream << "0 1 ";
00425 *m_stream << "]\n";
00426 }
00427 *m_stream << "\t\t/Domain [ " << ramp[0]->rampPoint << " "
00428 << ramp[ramp.size() - 1]->rampPoint << " ]\n" << "\t>>\n" << ">>\n";
00429
00430 *m_stream << " shfill " << l1_grestore << "\n";
00431 }
00432 }
00433 }
00434
00435 void
00436 EpsExport::getColor( const VColor& color )
00437 {
00438 VColor copy( color );
00439 copy.setColorSpace( VColor::rgb );
00440
00441 *m_stream <<
00442 copy[0] << " " <<
00443 copy[1] << " " <<
00444 copy[2] << " " << l1_setrgbcolor;
00445 }
00446
00447
00448 #include "epsexport.moc"
|