filters

wmfexport.cc

00001 /* This file is part of the KDE project
00002  * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr)
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License version 2 as published by the Free Software Foundation.
00007  *
00008  * This library is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * Library General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Library General Public License
00014  * along with this library; see the file COPYING.LIB.  If not, write to
00015  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include <config.h>
00020 #include <qdom.h>
00021 #include <qcstring.h>
00022 #include <kdebug.h>
00023 #include <kgenericfactory.h>
00024 #include <KoFilterChain.h>
00025 #include <KoStore.h>
00026 #include <KoStoreDevice.h>
00027 #include "vdocument.h"
00028 #include "vcolor.h"
00029 #include "vcomposite.h"
00030 #include "vdashpattern.h"
00031 #include "vdocument.h"
00032 #include "vlayer.h"
00033 #include "vpath.h"
00034 #include "vsegment.h"
00035 #include "vfill.h"
00036 #include "vstroke.h"
00037 #include "vtext.h"
00038 #include "vflattencmd.h"
00039 
00040 #include "wmfexport.h"
00041 #include "kowmfwrite.h"
00042 
00043 /*
00044 TODO: bs.wmf stroke in red with MSword and in brown with Kword ??
00045 */
00046 
00047 typedef KGenericFactory<WmfExport, KoFilter> WmfExportFactory;
00048 K_EXPORT_COMPONENT_FACTORY( libwmfexport, WmfExportFactory( "kofficefilters" ) )
00049 
00050 
00051 WmfExport::WmfExport( KoFilter *, const char *, const QStringList&) :
00052         KoFilter()
00053 {
00054 }
00055 
00056 WmfExport::~WmfExport()
00057 {
00058 }
00059 
00060 KoFilter::ConversionStatus WmfExport::convert( const QCString& from, const QCString& to )
00061 {
00062     if( to != "image/x-wmf" || from != "application/x-karbon" ) {
00063         return KoFilter::NotImplemented;
00064     }
00065 
00066     KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read );
00067 
00068     if( !storeIn ) {
00069         return KoFilter::StupidError;
00070     }
00071 
00072     // open Placeable Wmf file
00073     mWmf = new KoWmfWrite( m_chain->outputFile() );
00074     if( !mWmf->begin() ) {
00075         delete mWmf;
00076         return KoFilter::WrongFormat;
00077     }
00078 
00079     QDomDocument domIn;
00080     domIn.setContent( storeIn );
00081     QDomElement docNode = domIn.documentElement();
00082 
00083     // Load the document.
00084     mDoc = new VDocument;
00085     mDoc->load( docNode );
00086 
00087     // Process the document.
00088     mDoc->accept( *this );
00089 
00090     mWmf->end();
00091 
00092     delete mWmf;
00093     delete mDoc;
00094 
00095     return KoFilter::OK;
00096 }
00097 
00098 
00099 void WmfExport::visitVDocument( VDocument& document ) {
00100     int width;
00101     int height;
00102 
00103     mDoc = &document;
00104     mListPa.setAutoDelete( true );
00105 
00106     // resolution
00107     mDpi = 1000;
00108     width = (int)(POINT_TO_INCH( document.width() ) * mDpi);
00109     height = (int)(POINT_TO_INCH( document.height() ) * mDpi);
00110 
00111     mWmf->setDefaultDpi( mDpi );
00112     mWmf->setWindow( 0, 0, width, height );
00113 
00114     if ( (document.width() != 0) && (document.height() != 0) ) {
00115         mScaleX = (double)width / document.width();
00116         mScaleY = (double)height / document.height();
00117     }
00118 
00119     // Export layers.
00120     VVisitor::visitVDocument( document );
00121 
00122 }
00123 
00124 
00125 void WmfExport::visitVPath( VPath& composite ) {
00126     QPen      pen;
00127     QBrush    brush;
00128 
00129     getPen( pen, composite.stroke() );
00130     getBrush( brush, composite.fill() );
00131 
00132     VVisitor::visitVPath( composite );
00133 
00134     if ( mListPa.count() > 0 ) {
00135         mWmf->setPen( pen );
00136         if( (brush.style() == Qt::NoBrush)
00137             && (mListPa.count() == 1) ) {
00138             mWmf->drawPolyline( *mListPa.first() );
00139         }
00140         else {
00141             mWmf->setBrush( brush );
00142 
00143             if ( mListPa.count() == 1 ) {
00144                 mWmf->drawPolygon( *mListPa.first() );
00145             }
00146             else {
00147                 // combined path
00148                 mWmf->drawPolyPolygon( mListPa );
00149             }
00150         }
00151     }
00152     mListPa.clear();
00153 }
00154 
00155 
00156 // Export segment.
00157 void WmfExport::visitVSubpath( VSubpath& path ) {
00158     VSubpath *newPath;
00159     VSubpathIterator itr( path );
00160     VFlattenCmd cmd( 0L, INCH_TO_POINT(0.3 / (double)mDpi) );
00161     QPointArray *pa = new QPointArray( path.count() );
00162     int  nbrPoint=0;      // number of points in the path
00163 
00164     for( ; itr.current(); ++itr ) {
00165     VSegment *segment= itr.current();
00166     if (segment->isCurve()) {
00167         newPath = new VSubpath( mDoc );
00168 
00169         // newPath duplicate the list of curve
00170         newPath->moveTo( itr.current()->prev()->knot() );
00171         newPath->append( itr.current()->clone() );
00172         while( itr.current()->next() ) {
00173         if ( itr.current()->next()->isCurve() ) {
00174             newPath->append( itr.current()->next()->clone() );
00175         }
00176         else {
00177             break;
00178         }
00179         ++itr;
00180         }
00181 
00182         // flatten the curve
00183         cmd.visit( *newPath );
00184 
00185         // adjust the number of points
00186         pa->resize( pa->size() + newPath->count() - 2 );
00187 
00188         // Ommit the first segment and insert points
00189         newPath->first();
00190         while( newPath->next() ) {
00191         pa->setPoint( nbrPoint++, coordX( newPath->current()->knot().x() ),
00192             coordY( newPath->current()->knot().y() ) );
00193         }
00194         delete newPath;
00195     } else if (segment->isLine()) {
00196         pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ),
00197             coordY( itr.current()->knot().y() ) );
00198     } else if (segment->isBegin()) {
00199         // start a new polygon
00200         pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ),
00201             coordY( itr.current()->knot().y() ) );
00202         }
00203     }
00204 
00205     // adjust the number of points
00206     if ( nbrPoint > 1 ) {
00207         pa->resize( nbrPoint );
00208         mListPa.append( pa );
00209     }
00210     else {
00211         delete pa;
00212         // TODO: check why we have empty path
00213         kdDebug() << "WmfExport::visitVSubpath : Empty path ?" << endl;
00214     }
00215 }
00216 
00217 
00218 void WmfExport::visitVText( VText& text ) {
00219     // TODO: export text
00220     visitVSubpath( text.basePath() );
00221 }
00222 
00223 
00224 void WmfExport::getBrush( QBrush& brush, const VFill *fill ) {
00225     if( (fill->type() == VFill::solid) || (fill->type() == VFill::grad)
00226         || (fill->type() == VFill::patt) ) {
00227         if ( fill->color().opacity() < 0.1 ) {
00228             brush.setStyle( Qt::NoBrush );
00229         }
00230         else {
00231             brush.setStyle( Qt::SolidPattern );
00232             brush.setColor( fill->color() );
00233         }
00234     }
00235     else {
00236         brush.setStyle( Qt::NoBrush );
00237     }
00238 }
00239 
00240 
00241 void WmfExport::getPen( QPen& pen, const VStroke *stroke ) {
00242     if( (stroke->type() == VStroke::solid) || (stroke->type() == VStroke::grad)
00243         || (stroke->type() == VStroke::patt) ) {
00244         // TODO : Dash pattern.
00245 
00246         if ( stroke->lineCap() == VStroke::capRound ) {
00247             pen.setCapStyle( Qt::RoundCap );
00248         }
00249         else {
00250             pen.setCapStyle( Qt::SquareCap );
00251         }
00252         pen.setStyle( Qt::SolidLine );
00253         pen.setColor( stroke->color() );
00254         pen.setWidth( coordX( stroke->lineWidth() ) );
00255     }
00256     else {
00257         pen.setStyle( Qt::NoPen );
00258     }
00259 }
00260 
00261 
00262 #include <wmfexport.moc>
00263 
KDE Home | KDE Accessibility Home | Description of Access Keys