filters
xamlexport.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qcstring.h>
00024 #include <qdom.h>
00025 #include <qfile.h>
00026 #include <qstring.h>
00027 #include <qvaluelist.h>
00028
00029 #include <kgenericfactory.h>
00030 #include <KoFilter.h>
00031 #include <KoFilterChain.h>
00032 #include <KoStore.h>
00033
00034 #include "xamlexport.h"
00035 #include "vcolor.h"
00036 #include "vcomposite.h"
00037 #include "vdashpattern.h"
00038 #include "vdocument.h"
00039 #include "vfill.h"
00040 #include "vgradient.h"
00041 #include "vgroup.h"
00042 #include "vlayer.h"
00043 #include "vpath.h"
00044 #include "vsegment.h"
00045 #include "vselection.h"
00046 #include "vstroke.h"
00047
00048
00049
00050 #include <kdebug.h>
00051
00052
00053 typedef KGenericFactory<XAMLExport, KoFilter> XAMLExportFactory;
00054 K_EXPORT_COMPONENT_FACTORY( libkarbonxamlexport, XAMLExportFactory( "kofficefilters" ) )
00055
00056
00057 XAMLExport::XAMLExport( KoFilter*, const char*, const QStringList& )
00058 : KoFilter()
00059 {
00060 m_gc.setAutoDelete( true );
00061 }
00062
00063 KoFilter::ConversionStatus
00064 XAMLExport::convert( const QCString& from, const QCString& to )
00065 {
00066
00067 if ( to != "image/wvg+xml" || from != "application/x-karbon" )
00068 {
00069 return KoFilter::NotImplemented;
00070 }
00071
00072 KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read );
00073 if( !storeIn )
00074 return KoFilter::StupidError;
00075
00076 QFile fileOut( m_chain->outputFile() );
00077 if( !fileOut.open( IO_WriteOnly ) )
00078 {
00079 delete storeIn;
00080 return KoFilter::StupidError;
00081 }
00082
00083 QDomDocument domIn;
00084 domIn.setContent( storeIn );
00085 QDomElement docNode = domIn.documentElement();
00086
00087 m_stream = new QTextStream( &fileOut );
00088 QString body;
00089 m_body = new QTextStream( &body, IO_ReadWrite );
00090 QString defs;
00091 m_defs = new QTextStream( &defs, IO_ReadWrite );
00092
00093
00094
00095 VDocument doc;
00096 doc.load( docNode );
00097 doc.accept( *this );
00098
00099 *m_stream << defs;
00100 *m_stream << body;
00101
00102 fileOut.close();
00103
00104 delete m_stream;
00105 delete m_defs;
00106 delete m_body;
00107
00108 return KoFilter::OK;
00109 }
00110
00111 void
00112 XAMLExport::visitVDocument( VDocument& document )
00113 {
00114
00115 document.selection()->append();
00116
00117
00118 KoRect rect( 0, 0, document.width(), document.height() );
00119
00120
00121 *m_defs <<
00122 "<?xml version=\"1.0\" ?>\n" <<
00123
00124
00125 endl;
00126
00127
00128
00129
00130
00131
00132
00133 *m_defs <<
00134 "<!-- Generator: Karbon14 WVG XAML Graphics export filter $VERSION/$DATE. -->" << endl;
00135 *m_defs <<
00136 "<Canvas xmlns=\"http://schemas.microsoft.com/winfx/avalon/2005\" Width=\"" << rect.width() <<
00137 "Height=\"" << rect.height() << "\">" << endl;
00138 *m_defs << "<Canvas.Resources>" << endl;
00139
00140
00141
00142 *m_body << "<Transform=\"scale(1, -1) Translate(0, -" << rect.height() << ")\">" << endl;
00143
00144
00145 document.selection()->clear();
00146
00147
00148 XAMLGraphicsContext *gc = new XAMLGraphicsContext;
00149 m_gc.push( gc );
00150
00151
00152 VVisitor::visitVDocument( document );
00153
00154
00155 *m_body << "</Canvas>" << endl;
00156 *m_defs << "</Canvas.Resources>" << endl;
00157 *m_body << "</Canvas>" << endl;
00158 }
00159
00160 QString
00161 XAMLExport::getID( VObject *obj )
00162 {
00163 if( obj && !obj->name().isEmpty() )
00164 return QString( " Name=\"%1\"" ).arg( obj->name() );
00165 return QString();
00166 }
00167
00168
00169
00170 void
00171 XAMLExport::visitVGroup( VGroup& group )
00172 {
00173 *m_body << "<Canvas" << getID( &group ) << ">" << endl;
00174 VVisitor::visitVGroup( group );
00175 *m_body << "</Canvas>" << endl;
00176 }
00177
00178 void
00179 XAMLExport::visitVPath( VPath& composite )
00180 {
00181 *m_body << "<Path" << getID( &composite );
00182
00183 VVisitor::visitVPath( composite );
00184
00185 getFill( *( composite.fill() ) );
00186 getStroke( *( composite.stroke() ) );
00187
00188 QString d;
00189 composite.saveSvgPath( d );
00190 *m_body << " Data=\"" << d << "\" ";
00191
00192 if( composite.fillRule() != m_gc.current()->fillRule )
00193 {
00194 if( composite.fillRule() == evenOdd )
00195 *m_body << " FillRule=\"EvenOdd\"";
00196 else
00197 *m_body << " FillRule=\"NonZero\"";
00198 }
00199
00200 *m_body << " />" << endl;
00201 }
00202
00203 void
00204 XAMLExport::visitVSubpath( VSubpath& )
00205 {
00206 }
00207
00208 QString createUID()
00209 {
00210 static unsigned int nr = 0;
00211
00212 return "defitem" + QString().setNum( nr++ );
00213 }
00214
00215 void
00216 XAMLExport::getColorStops( const QPtrVector<VColorStop> &colorStops )
00217 {
00218 for( unsigned int i = 0; i < colorStops.count() ; i++ )
00219 {
00220 *m_defs << "<GradientStop Color=\"";
00221 getHexColor( m_defs, colorStops.at( i )->color );
00222 *m_defs << "\" Offset=\"" << QString().setNum( colorStops.at( i )->rampPoint );
00223
00224
00225
00226 }
00227 }
00228
00229 void
00230 XAMLExport::getGradient( const VGradient& grad )
00231 {
00232 QString uid = createUID();
00233 if( grad.type() == VGradient::linear )
00234 {
00235
00236 *m_defs << "<LinearGradientBrush id=\"" << uid << "\" ";
00237 *m_defs << "GradientUnits=\"UserSpaceOnUse\" ";
00238 *m_defs << "StartPoint=\"" << grad.origin().x() << ",";
00239 *m_defs << grad.origin().y() << "\" ";
00240 *m_defs << "EndPoint=\"" << grad.vector().x() << ",";
00241 *m_defs << grad.vector().y() << "\" ";
00242 if( grad.repeatMethod() == VGradient::reflect )
00243 *m_defs << "SpreadMethod=\"Reflect\" ";
00244 else if( grad.repeatMethod() == VGradient::repeat )
00245 *m_defs << "SpreadMethod=\"Repeat\" ";
00246 *m_defs << ">" << endl;
00247
00248
00249 getColorStops( grad.colorStops() );
00250
00251 *m_defs << "</LinearGradientBrush>" << endl;
00252 *m_body << "url(#" << uid << ")";
00253 }
00254 else if( grad.type() == VGradient::radial )
00255 {
00256
00257 *m_defs << "<RadialGradientBrush Name=\"" << uid << "\" ";
00258
00259 *m_defs << "Center=\"" << grad.origin().x() << ",";
00260 *m_defs << grad.origin().y() << "\" ";
00261
00262 *m_defs << "GradientOrigin=\"" << grad.focalPoint().x() << ",";
00263 *m_defs << grad.focalPoint().y() << "\" ";
00264 double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) );
00265 *m_defs << "Radius=\"" << QString().setNum( r ) << "\" ";
00266 if( grad.repeatMethod() == VGradient::reflect )
00267 *m_defs << "SpreadMethod=\"Reflect\" ";
00268 else if( grad.repeatMethod() == VGradient::repeat )
00269 *m_defs << "SpreadMethod=\"Repeat\" ";
00270 *m_defs << ">" << endl;
00271
00272
00273 getColorStops( grad.colorStops() );
00274
00275 *m_defs << "</RadialGradientBrush>" << endl;
00276 *m_body << "url(#" << uid << ")";
00277 }
00278 }
00279
00280 void
00281 XAMLExport::getFill( const VFill& fill )
00282 {
00283 *m_body << " Fill=\"";
00284 if( fill.type() == VFill::none )
00285 *m_body << "none";
00286 else if( fill.type() == VFill::grad )
00287 getGradient( fill.gradient() );
00288 else
00289 getHexColor( m_body, fill.color() );
00290 *m_body << "\"";
00291
00292 if( fill.color().opacity() != m_gc.current()->fill.color().opacity() )
00293 *m_body << " FillOpacity=\"" << fill.color().opacity() << "\"";
00294 }
00295
00296 void
00297 XAMLExport::getStroke( const VStroke& stroke )
00298 {
00299 if( stroke.type() != m_gc.current()->stroke.type() )
00300 {
00301 *m_body << " Stroke=\"";
00302 if( stroke.type() == VStroke::none )
00303 *m_body << "None";
00304 else if( stroke.type() == VStroke::grad )
00305 getGradient( stroke.gradient() );
00306 else
00307 getHexColor( m_body, stroke.color() );
00308 *m_body << "\"";
00309 }
00310
00311 if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() )
00312 *m_body << " StrokeOpacity=\"" << stroke.color().opacity() << "\"";
00313
00314 if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() )
00315 *m_body << " StrokeThickness=\"" << stroke.lineWidth() << "\"";
00316
00317 if( stroke.lineCap() != m_gc.current()->stroke.lineCap() )
00318 {
00319 if( stroke.lineCap() == VStroke::capButt )
00320 *m_body << " StrokeLineCap=\"Butt\"";
00321 else if( stroke.lineCap() == VStroke::capRound )
00322 *m_body << " StrokeLineCap=\"round\"";
00323 else if( stroke.lineCap() == VStroke::capSquare )
00324 *m_body << " StrokeLineCap=\"square\"";
00325 }
00326
00327 if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() )
00328 {
00329 if( stroke.lineJoin() == VStroke::joinMiter )
00330 {
00331 *m_body << " StrokeLineJoin=\"Miter\"";
00332 *m_body << " StrokeMiterLimit=\"" << stroke.miterLimit() << "\"";
00333 }
00334 else if( stroke.lineJoin() == VStroke::joinRound )
00335 *m_body << " StrokeLineJoin=\"Round\"";
00336 else if( stroke.lineJoin() == VStroke::joinBevel )
00337 *m_body << " StrokeLineJoin=\"Bevel\"";
00338 }
00339
00340
00341 if( stroke.dashPattern().array().count() > 0 )
00342 {
00343 *m_body << " StrokeDashOffset=\"" << stroke.dashPattern().offset() << "\"";
00344 *m_body << " StrokeDashArray=\" ";
00345
00346 QValueListConstIterator<float> itr;
00347 for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr )
00348 {
00349 *m_body << *itr << " ";
00350 }
00351 *m_body << "\"";
00352 }
00353 }
00354
00355 void
00356 XAMLExport::getHexColor( QTextStream *stream, const VColor& color )
00357 {
00358
00359
00360 QString Output;
00361
00362 VColor copy( color );
00363 copy.setColorSpace( VColor::rgb );
00364
00365 Output.sprintf( "#%02x%02x%02x", int( copy[0] * 255.0 ), int( copy[1] * 255.0 ), int( copy[2] * 255.0 ) );
00366
00367 *stream << Output;
00368 }
00369
00370 #include "xamlexport.moc"
00371
|