diff options
Diffstat (limited to 'filters/karbon/wmf/wmfexport.cpp')
-rw-r--r-- | filters/karbon/wmf/wmfexport.cpp | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/filters/karbon/wmf/wmfexport.cpp b/filters/karbon/wmf/wmfexport.cpp new file mode 100644 index 000000000..de929ca88 --- /dev/null +++ b/filters/karbon/wmf/wmfexport.cpp @@ -0,0 +1,263 @@ +/* This file is part of the KDE project + * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include <config.h> +#include <tqdom.h> +#include <tqcstring.h> +#include <kdebug.h> +#include <kgenericfactory.h> +#include <KoFilterChain.h> +#include <KoStore.h> +#include <KoStoreDevice.h> +#include "vdocument.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vlayer.h" +#include "vpath.h" +#include "vsegment.h" +#include "vfill.h" +#include "vstroke.h" +#include "vtext.h" +#include "vflattencmd.h" + +#include "wmfexport.h" +#include "kowmfwrite.h" + +/* +TODO: bs.wmf stroke in red with MSword and in brown with Kword ?? +*/ + +typedef KGenericFactory<WmfExport, KoFilter> WmfExportFactory; +K_EXPORT_COMPONENT_FACTORY( libwmfexport, WmfExportFactory( "kofficefilters" ) ) + + +WmfExport::WmfExport( KoFilter *, const char *, const TQStringList&) : + KoFilter() +{ +} + +WmfExport::~WmfExport() +{ +} + +KoFilter::ConversionStatus WmfExport::convert( const TQCString& from, const TQCString& to ) +{ + if( to != "image/x-wmf" || from != "application/x-karbon" ) { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + + if( !storeIn ) { + return KoFilter::StupidError; + } + + // open Placeable Wmf file + mWmf = new KoWmfWrite( m_chain->outputFile() ); + if( !mWmf->begin() ) { + delete mWmf; + return KoFilter::WrongFormat; + } + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement docNode = domIn.documentElement(); + + // Load the document. + mDoc = new VDocument; + mDoc->load( docNode ); + + // Process the document. + mDoc->accept( *this ); + + mWmf->end(); + + delete mWmf; + delete mDoc; + + return KoFilter::OK; +} + + +void WmfExport::visitVDocument( VDocument& document ) { + int width; + int height; + + mDoc = &document; + mListPa.setAutoDelete( true ); + + // resolution + mDpi = 1000; + width = (int)(POINT_TO_INCH( document.width() ) * mDpi); + height = (int)(POINT_TO_INCH( document.height() ) * mDpi); + + mWmf->setDefaultDpi( mDpi ); + mWmf->setWindow( 0, 0, width, height ); + + if ( (document.width() != 0) && (document.height() != 0) ) { + mScaleX = (double)width / document.width(); + mScaleY = (double)height / document.height(); + } + + // Export layers. + VVisitor::visitVDocument( document ); + +} + + +void WmfExport::visitVPath( VPath& composite ) { + TQPen pen; + TQBrush brush; + + getPen( pen, composite.stroke() ); + getBrush( brush, composite.fill() ); + + VVisitor::visitVPath( composite ); + + if ( mListPa.count() > 0 ) { + mWmf->setPen( pen ); + if( (brush.style() == TQt::NoBrush) + && (mListPa.count() == 1) ) { + mWmf->drawPolyline( *mListPa.first() ); + } + else { + mWmf->setBrush( brush ); + + if ( mListPa.count() == 1 ) { + mWmf->drawPolygon( *mListPa.first() ); + } + else { + // combined path + mWmf->drawPolyPolygon( mListPa ); + } + } + } + mListPa.clear(); +} + + +// Export segment. +void WmfExport::visitVSubpath( VSubpath& path ) { + VSubpath *newPath; + VSubpathIterator itr( path ); + VFlattenCmd cmd( 0L, INCH_TO_POINT(0.3 / (double)mDpi) ); + TQPointArray *pa = new TQPointArray( path.count() ); + int nbrPoint=0; // number of points in the path + + for( ; itr.current(); ++itr ) { + VSegment *segment= itr.current(); + if (segment->isCurve()) { + newPath = new VSubpath( mDoc ); + + // newPath duplicate the list of curve + newPath->moveTo( itr.current()->prev()->knot() ); + newPath->append( itr.current()->clone() ); + while( itr.current()->next() ) { + if ( itr.current()->next()->isCurve() ) { + newPath->append( itr.current()->next()->clone() ); + } + else { + break; + } + ++itr; + } + + // flatten the curve + cmd.visit( *newPath ); + + // adjust the number of points + pa->resize( pa->size() + newPath->count() - 2 ); + + // Ommit the first segment and insert points + newPath->first(); + while( newPath->next() ) { + pa->setPoint( nbrPoint++, coordX( newPath->current()->knot().x() ), + coordY( newPath->current()->knot().y() ) ); + } + delete newPath; + } else if (segment->isLine()) { + pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ), + coordY( itr.current()->knot().y() ) ); + } else if (segment->isBegin()) { + // start a new polygon + pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ), + coordY( itr.current()->knot().y() ) ); + } + } + + // adjust the number of points + if ( nbrPoint > 1 ) { + pa->resize( nbrPoint ); + mListPa.append( pa ); + } + else { + delete pa; + // TODO: check why we have empty path + kdDebug() << "WmfExport::visitVSubpath : Empty path ?" << endl; + } +} + + +void WmfExport::visitVText( VText& text ) { + // TODO: export text + visitVSubpath( text.basePath() ); +} + + +void WmfExport::getBrush( TQBrush& brush, const VFill *fill ) { + if( (fill->type() == VFill::solid) || (fill->type() == VFill::grad) + || (fill->type() == VFill::patt) ) { + if ( fill->color().opacity() < 0.1 ) { + brush.setStyle( Qt::NoBrush ); + } + else { + brush.setStyle( Qt::SolidPattern ); + brush.setColor( fill->color() ); + } + } + else { + brush.setStyle( Qt::NoBrush ); + } +} + + +void WmfExport::getPen( TQPen& pen, const VStroke *stroke ) { + if( (stroke->type() == VStroke::solid) || (stroke->type() == VStroke::grad) + || (stroke->type() == VStroke::patt) ) { + // TODO : Dash pattern. + + if ( stroke->lineCap() == VStroke::capRound ) { + pen.setCapStyle( Qt::RoundCap ); + } + else { + pen.setCapStyle( Qt::SquareCap ); + } + pen.setStyle( Qt::SolidLine ); + pen.setColor( stroke->color() ); + pen.setWidth( coordX( stroke->lineWidth() ) ); + } + else { + pen.setStyle( Qt::NoPen ); + } +} + + +#include <wmfexport.moc> + |