filters

kontourimport.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002, Sven Lüppken <sven@kde.org>
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 as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <kontourimport.h>
00021 #include <KoFilterChain.h>
00022 #include <kgenericfactory.h>
00023 #include <kdebug.h>
00024 #include <KoUnit.h>
00025 #include <KoGlobal.h>
00026 #include <shapes/vellipse.h>
00027 #include <shapes/vrectangle.h>
00028 #include <shapes/vpolygon.h>
00029 #include <commands/vtransformcmd.h>
00030 #include <core/vpath.h>
00031 #include <core/vfill.h>
00032 #include <core/vstroke.h>
00033 #include <qcolor.h>
00034 #include <qfile.h>
00035 
00036 #define DPI 90
00037 
00038 typedef KGenericFactory<KontourImport, KoFilter> KontourImportFactory;
00039 K_EXPORT_COMPONENT_FACTORY( libkarbonkontourimport, KontourImportFactory( "kofficefilters" ) )
00040 
00041 KontourImport::KontourImport(KoFilter *, const char *, const QStringList&) :
00042     KoFilter(),
00043     outdoc( "DOC" )
00044 {
00045 }
00046 
00047 KontourImport::~KontourImport()
00048 {
00049 
00050 }
00051 
00052 KoFilter::ConversionStatus KontourImport::convert(const QCString& from, const QCString& to)
00053 {
00054     // check for proper conversion
00055     if ( to != "application/x-karbon" || ( from != "application/x-kontour" && from != "application/x-killustrator") )
00056         return KoFilter::NotImplemented;
00057 
00058 
00059     KoStoreDevice* inpdev = m_chain->storageFile( "root", KoStore::Read );
00060     if ( !inpdev )
00061     {
00062         kdError(30502) << "Unable to open input stream" << endl;
00063         return KoFilter::StorageCreationError;
00064     }
00065 
00066     inpdoc.setContent( inpdev );
00067 
00068     // Do the conversion!
00069     convert();
00070 
00071     KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write );
00072     if(!out)
00073     {
00074         kdError(30502) << "Unable to open output file!" << endl;
00075         return KoFilter::StorageCreationError;
00076     }
00077     QCString cstring = outdoc.toCString(); // utf-8 already
00078     out->writeBlock( cstring.data(), cstring.length() );
00079 
00080     return KoFilter::OK; // was successful
00081 }
00082 
00083 void
00084 KontourImport::parseGObject( VObject *object, const QDomElement &e )
00085 {
00086     if( !e.attribute( "fillstyle" ).isEmpty() )
00087     {
00088         VFill fill;
00089         int fillstyle = e.attribute( "fillstyle" ).toInt();
00090         switch( fillstyle )
00091         {
00092             case 1:
00093             {
00094                 fill.setType( VFill::solid );
00095                 QColor c;
00096                 c.setNamedColor( e.attribute( "fillcolor" ) );
00097                 VColor color( c );
00098                 fill.setColor( color );
00099             }
00100             break;
00101             case 4:
00102             {
00103                 VGradient grad;
00104                 // set color stops
00105                 grad.clearStops();
00106                 QColor c;
00107                 c.setNamedColor( e.attribute( "gradcolor1" ) );
00108                 VColor color( c );
00109                 grad.addStop( color, 0.0, 0.5 );
00110                 c.setNamedColor( e.attribute( "gradcolor2" ) );
00111                 VColor color2( c );
00112                 grad.addStop( color2, 1.0, 0.5 );
00113                 // set coords
00114                 KoRect bbox = object->boundingBox();
00115                 grad.setOrigin( KoPoint( bbox.left(), bbox.y() ) );
00116                 grad.setVector( KoPoint( bbox.right(), bbox.y() ) );
00117                 grad.setType( (VGradient::VGradientType)e.attribute( "gradstyle" ).toInt() );
00118                 fill.setType( VFill::grad );
00119                 fill.gradient() = grad;
00120             }
00121             break;
00122         }
00123         object->setFill( fill );
00124     }
00125     if( !e.attribute( "strokecolor" ).isEmpty() )
00126     {
00127         VStroke stroke;
00128         int strokestyle = e.attribute( "strokestyle" ).toInt();
00129         switch( strokestyle )
00130         {
00131             case 0: stroke.setType( VStroke::none );
00132                     break;
00133             case 1:
00134             {
00135                 QColor c;
00136                 c.setNamedColor( e.attribute( "strokecolor" ) );
00137                 VColor color( c );
00138                 stroke.setColor( color );
00139             }
00140             break;
00141             case 2: case 3: case 4: case 5:
00142             {
00143                 QColor c;
00144                 c.setNamedColor( e.attribute( "strokecolor" ) );
00145                 VColor color( c );
00146                 stroke.setColor( color );
00147                 VDashPattern dash;
00148                 QValueList<float> list;
00149                 switch ( strokestyle )
00150                 {
00151                     case 2: // dashed line
00152                         list << 10 << 5;
00153                         break;
00154                     case 3: // dotted line
00155                         list << 1 << 5;
00156                         break;
00157                     case 4: // dash-dot
00158                         list << 10 << 5 << 1 << 5;
00159                         break;
00160                     case 5: // dash-dot-dot
00161                         list << 10 << 5 << 1 << 5 << 1 << 5;
00162                         break;
00163                 }
00164 
00165                 dash.setArray( list );
00166                 stroke.dashPattern() = dash;
00167             }
00168             break;
00169         }
00170         float lineWidth = e.attribute( "linewidth" ).toFloat();
00171         stroke.setLineWidth( lineWidth );
00172         object->setStroke( stroke );
00173     }
00174     // handle matrix
00175     QDomElement matrix = e.namedItem( "matrix" ).toElement();
00176     QWMatrix mat( matrix.attribute( "m11" ).toDouble(),
00177                   matrix.attribute( "m12" ).toDouble(),
00178                   matrix.attribute( "m21" ).toDouble(),
00179                   matrix.attribute( "m22" ).toDouble(),
00180                   matrix.attribute( "dx" ).toDouble(),
00181                   matrix.attribute( "dy" ).toDouble() );
00182 
00183     // undo y-mirroring
00184     mat.scale( 1, -1 );
00185     mat.translate( 0, -m_document.height() );
00186     VTransformCmd trafo( 0L, mat );
00187     trafo.visit( *object );
00188 
00189 }
00190 
00191 void
00192 KontourImport::convert()
00193 {
00194     QDomElement docElem = inpdoc.documentElement();
00195     QDomElement lay;
00196     double height;
00197     double width;
00198     if( docElem.attribute( "version" ).toInt() == 2 )
00199     {
00200         lay = docElem;
00201         height = lay.firstChild().namedItem( "layout" ).toElement().attribute( "height" ).toDouble();
00202         width = lay.firstChild().namedItem( "layout" ).toElement().attribute( "width" ).toDouble();
00203     }
00204     else
00205     {
00206         lay = docElem.namedItem( "page" ).toElement();
00207         height = lay.firstChild().toElement().attribute( "height" ).toDouble();
00208         width = lay.firstChild().toElement().attribute( "width" ).toDouble();
00209     }
00210 
00211     m_document.setHeight( ( ( height / 72.0 ) * DPI ) );
00212     m_document.setWidth( ( ( width / 72.0 ) * DPI )  );
00213 
00214     parseGroup( lay.firstChild().toElement() );
00215 
00216     outdoc = m_document.saveXML();
00217 }
00218 
00219 void
00220 KontourImport::parseGroup( const QDomElement &e )
00221 {
00222     QDomElement b = e;
00223     for( ; !b.isNull(); b = b.nextSibling().toElement() )
00224     {
00225         if ( b.tagName() == "rectangle" )
00226         {
00227             int x = b.attribute( "x" ).toInt();
00228             int y = b.attribute( "y" ).toInt();
00229             int width = b.attribute( "width" ).toInt();
00230             int height = b.attribute( "height" ).toInt();
00231             VObject *rect = new VRectangle( 0L, KoPoint( x, height + y ) , width, height );
00232             QDomElement object = b.namedItem( "polyline" ).namedItem( "gobject" ).toElement();
00233             parseGObject( rect, object );
00234             m_document.append( rect );
00235         }
00236         else
00237         if ( b.tagName() == "ellipse" )
00238         {
00239             QDomElement object = b.namedItem( "gobject" ).toElement();
00240             QDomElement matrix = object.namedItem( "matrix" ).toElement();
00245             double left = ( b.attribute( "x" ).toDouble() + matrix.attribute( "dx" ).toInt() ) - ( b.attribute( "rx" ).toDouble() / 2 );
00246             double right = left + b.attribute( "rx" ).toDouble();
00247             double top = ( b.attribute( "y" ).toDouble() + matrix.attribute( "dy" ).toInt() ) - ( b.attribute( "ry" ).toDouble() / 2 );
00248             double bottom = top + b.attribute( "ry" ).toDouble();
00249             double height =  top - bottom;
00250             double width = right - left;
00251             // Append the ellipse to the document
00252             VObject *ellipse = new VEllipse( 0L, KoPoint( left, top ),  width, height );
00253             parseGObject( ellipse, object );
00254             m_document.append( ellipse );
00255         }
00256         else if( b.tagName() == "polyline" )
00257         {
00262             QDomElement point = b.firstChild().toElement();
00263             VPath *path = new VPath( &m_document );
00264             double x, y;
00265             x = point.attribute( "x" ).toDouble();
00266             y = point.attribute( "y" ).toDouble();
00267             path->moveTo( KoPoint( x, y ) );
00268             point = point.nextSibling().toElement();
00269             for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() )
00270             {
00271                 x = point.attribute( "x" ).toDouble();
00272                 y = point.attribute( "y" ).toDouble();
00273                 path->lineTo( KoPoint( x, y ) );
00274             }
00275             parseGObject( path, point );
00276             m_document.append( path );
00277         }
00278         else if( b.tagName() == "polygon" )
00279         {
00280             QDomElement point = b.namedItem( "polyline" ).firstChild().toElement();
00281             VPath *path = new VPath( &m_document );
00282             double x, y;
00283             x = point.attribute( "x" ).toDouble();
00284             y = point.attribute( "y" ).toDouble();
00285             path->moveTo( KoPoint( x, y ) );
00286             point = point.nextSibling().toElement();
00287             for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() )
00288             {
00289                 x = point.attribute( "x" ).toDouble();
00290                 y = point.attribute( "y" ).toDouble();
00291                 path->lineTo( KoPoint( x, y ) );
00292             }
00293             path->close();
00294             // back to first point
00295             parseGObject( path, point );
00296             m_document.append( path );
00297         }
00298         else if( b.tagName() == "bezier" )
00299         {
00300             QDomElement point = b.namedItem( "polyline" ).firstChild().toElement();
00301             VPath *path = new VPath( &m_document );
00302             double x, y;
00303             x = point.attribute( "x" ).toDouble();
00304             y = point.attribute( "y" ).toDouble();
00305             path->moveTo( KoPoint( x, y ) );
00306             point = point.nextSibling().toElement();
00307             for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() )
00308             {
00309                 x = point.attribute( "x" ).toDouble();
00310                 y = point.attribute( "y" ).toDouble();
00311                 path->lineTo( KoPoint( x, y ) );
00312             }
00313             parseGObject( path, point );
00314             m_document.append( path );
00315         }
00316         else if( b.tagName() == "group" || b.tagName() == "layer" )
00317         {
00318             parseGroup( b.toElement().firstChild().toElement() );
00319         }
00320     }
00321 }
00322 
00323 #include <kontourimport.moc>
KDE Home | KDE Accessibility Home | Description of Access Keys