27#include <tqvaluelist.h>
29#include <kgenericfactory.h>
31#include <KoFilterChain.h>
34#include "xamlexport.h"
36#include "vcomposite.h"
37#include "vdashpattern.h"
45#include "vselection.h"
53typedef KGenericFactory<XAMLExport, KoFilter> XAMLExportFactory;
54K_EXPORT_COMPONENT_FACTORY( libkarbonxamlexport, XAMLExportFactory(
"kofficefilters" ) )
57XAMLExport::XAMLExport( KoFilter*, const
char*, const TQStringList& )
60 m_gc.setAutoDelete(
true );
63KoFilter::ConversionStatus
64XAMLExport::convert(
const TQCString& from,
const TQCString& to )
67 if ( to !=
"image/wvg+xml" || from !=
"application/x-karbon" )
69 return KoFilter::NotImplemented;
72 KoStoreDevice* storeIn = m_chain->storageFile(
"root", KoStore::Read );
74 return KoFilter::StupidError;
76 TQFile fileOut( m_chain->outputFile() );
77 if( !fileOut.open( IO_WriteOnly ) )
80 return KoFilter::StupidError;
84 domIn.setContent( storeIn );
85 TQDomElement docNode = domIn.documentElement();
87 m_stream =
new TQTextStream( &fileOut );
89 m_body =
new TQTextStream( &body, IO_ReadWrite );
91 m_defs =
new TQTextStream( &defs, IO_ReadWrite );
112XAMLExport::visitVDocument( VDocument& document )
115 document.selection()->append();
118 KoRect rect( 0, 0, document.width(), document.height() );
122 "<?xml version=\"1.0\" ?>\n" <<
134 "<!-- Generator: Karbon14 WVG XAML Graphics export filter $VERSION/$DATE. -->" << endl;
136 "<Canvas xmlns=\"http://schemas.microsoft.com/winfx/avalon/2005\" Width=\"" << rect.width() <<
137 "Height=\"" << rect.height() <<
"\">" << endl;
138 *m_defs <<
"<Canvas.Resources>" << endl;
142 *m_body <<
"<Transform=\"scale(1, -1) Translate(0, -" << rect.height() <<
")\">" << endl;
145 document.selection()->clear();
148 XAMLGraphicsContext *gc =
new XAMLGraphicsContext;
152 VVisitor::visitVDocument( document );
155 *m_body <<
"</Canvas>" << endl;
156 *m_defs <<
"</Canvas.Resources>" << endl;
157 *m_body <<
"</Canvas>" << endl;
161XAMLExport::getID( VObject *obj )
163 if( obj && !obj->name().isEmpty() )
164 return TQString(
" Name=\"%1\"" ).arg( obj->name() );
171XAMLExport::visitVGroup( VGroup& group )
173 *m_body <<
"<Canvas" << getID( &group ) <<
">" << endl;
174 VVisitor::visitVGroup( group );
175 *m_body <<
"</Canvas>" << endl;
179XAMLExport::visitVPath( VPath& composite )
181 *m_body <<
"<Path" << getID( &composite );
183 VVisitor::visitVPath( composite );
185 getFill( *( composite.fill() ) );
186 getStroke( *( composite.stroke() ) );
189 composite.saveSvgPath( d );
190 *m_body <<
" Data=\"" << d <<
"\" ";
192 if( composite.fillRule() != m_gc.current()->fillRule )
194 if( composite.fillRule() == evenOdd )
195 *m_body <<
" FillRule=\"EvenOdd\"";
197 *m_body <<
" FillRule=\"NonZero\"";
200 *m_body <<
" />" << endl;
204XAMLExport::visitVSubpath( VSubpath& )
210 static unsigned int nr = 0;
212 return "defitem" + TQString().setNum( nr++ );
216XAMLExport::getColorStops(
const TQPtrVector<VColorStop> &colorStops )
218 for(
unsigned int i = 0; i < colorStops.count() ; i++ )
220 *m_defs <<
"<GradientStop Color=\"";
221 getHexColor( m_defs, colorStops.at( i )->color );
222 *m_defs <<
"\" Offset=\"" << TQString().setNum( colorStops.at( i )->rampPoint );
230XAMLExport::getGradient(
const VGradient& grad )
232 TQString uid = createUID();
233 if( grad.type() == VGradient::linear )
236 *m_defs <<
"<LinearGradientBrush id=\"" << uid <<
"\" ";
237 *m_defs <<
"GradientUnits=\"UserSpaceOnUse\" ";
238 *m_defs <<
"StartPoint=\"" << grad.origin().x() <<
",";
239 *m_defs << grad.origin().y() <<
"\" ";
240 *m_defs <<
"EndPoint=\"" << grad.vector().x() <<
",";
241 *m_defs << grad.vector().y() <<
"\" ";
242 if( grad.repeatMethod() == VGradient::reflect )
243 *m_defs <<
"SpreadMethod=\"Reflect\" ";
244 else if( grad.repeatMethod() == VGradient::repeat )
245 *m_defs <<
"SpreadMethod=\"Repeat\" ";
246 *m_defs <<
">" << endl;
249 getColorStops( grad.colorStops() );
251 *m_defs <<
"</LinearGradientBrush>" << endl;
252 *m_body <<
"url(#" << uid <<
")";
254 else if( grad.type() == VGradient::radial )
257 *m_defs <<
"<RadialGradientBrush Name=\"" << uid <<
"\" ";
259 *m_defs <<
"Center=\"" << grad.origin().x() <<
",";
260 *m_defs << grad.origin().y() <<
"\" ";
262 *m_defs <<
"GradientOrigin=\"" << grad.focalPoint().x() <<
",";
263 *m_defs << grad.focalPoint().y() <<
"\" ";
264 double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) );
265 *m_defs <<
"Radius=\"" << TQString().setNum( r ) <<
"\" ";
266 if( grad.repeatMethod() == VGradient::reflect )
267 *m_defs <<
"SpreadMethod=\"Reflect\" ";
268 else if( grad.repeatMethod() == VGradient::repeat )
269 *m_defs <<
"SpreadMethod=\"Repeat\" ";
270 *m_defs <<
">" << endl;
273 getColorStops( grad.colorStops() );
275 *m_defs <<
"</RadialGradientBrush>" << endl;
276 *m_body <<
"url(#" << uid <<
")";
281XAMLExport::getFill(
const VFill& fill )
283 *m_body <<
" Fill=\"";
284 if( fill.type() == VFill::none )
286 else if( fill.type() == VFill::grad )
287 getGradient( fill.gradient() );
289 getHexColor( m_body, fill.color() );
292 if( fill.color().opacity() != m_gc.current()->fill.color().opacity() )
293 *m_body <<
" FillOpacity=\"" << fill.color().opacity() <<
"\"";
297XAMLExport::getStroke(
const VStroke& stroke )
299 if( stroke.type() != m_gc.current()->stroke.type() )
301 *m_body <<
" Stroke=\"";
302 if( stroke.type() == VStroke::none )
304 else if( stroke.type() == VStroke::grad )
305 getGradient( stroke.gradient() );
307 getHexColor( m_body, stroke.color() );
311 if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() )
312 *m_body <<
" StrokeOpacity=\"" << stroke.color().opacity() <<
"\"";
314 if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() )
315 *m_body <<
" StrokeThickness=\"" << stroke.lineWidth() <<
"\"";
317 if( stroke.lineCap() != m_gc.current()->stroke.lineCap() )
319 if( stroke.lineCap() == VStroke::capButt )
320 *m_body <<
" StrokeLineCap=\"Butt\"";
321 else if( stroke.lineCap() == VStroke::capRound )
322 *m_body <<
" StrokeLineCap=\"round\"";
323 else if( stroke.lineCap() == VStroke::capSquare )
324 *m_body <<
" StrokeLineCap=\"square\"";
327 if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() )
329 if( stroke.lineJoin() == VStroke::joinMiter )
331 *m_body <<
" StrokeLineJoin=\"Miter\"";
332 *m_body <<
" StrokeMiterLimit=\"" << stroke.miterLimit() <<
"\"";
334 else if( stroke.lineJoin() == VStroke::joinRound )
335 *m_body <<
" StrokeLineJoin=\"Round\"";
336 else if( stroke.lineJoin() == VStroke::joinBevel )
337 *m_body <<
" StrokeLineJoin=\"Bevel\"";
341 if( stroke.dashPattern().array().count() > 0 )
343 *m_body <<
" StrokeDashOffset=\"" << stroke.dashPattern().offset() <<
"\"";
344 *m_body <<
" StrokeDashArray=\" ";
346 TQValueListConstIterator<float> itr;
347 for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr )
349 *m_body << *itr <<
" ";
356XAMLExport::getHexColor( TQTextStream *stream,
const VColor& color )
362 VColor copy( color );
363 copy.setColorSpace( VColor::rgb );
365 Output.sprintf(
"#%02x%02x%02x",
int( copy[0] * 255.0 ),
int( copy[1] * 255.0 ),
int( copy[2] * 255.0 ) );
370#include "xamlexport.moc"