00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
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();
00078 out->writeBlock( cstring.data(), cstring.length() );
00079
00080 return KoFilter::OK;
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
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
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:
00152 list << 10 << 5;
00153 break;
00154 case 3:
00155 list << 1 << 5;
00156 break;
00157 case 4:
00158 list << 10 << 5 << 1 << 5;
00159 break;
00160 case 5:
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
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
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
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
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>