KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
9.4KB

  1. /* This file is part of the KDE project
  2. Copyright (C) 2002, Sven Lüppken <sven@kde.org>
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public License
  12. along with this library; see the file COPYING.LIB. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  14. * Boston, MA 02110-1301, USA.
  15. */
  16. #include <kontourimport.h>
  17. #include <KoFilterChain.h>
  18. #include <kgenericfactory.h>
  19. #include <kdebug.h>
  20. #include <KoUnit.h>
  21. #include <KoGlobal.h>
  22. #include <shapes/vellipse.h>
  23. #include <shapes/vrectangle.h>
  24. #include <shapes/vpolygon.h>
  25. #include <commands/vtransformcmd.h>
  26. #include <core/vpath.h>
  27. #include <core/vfill.h>
  28. #include <core/vstroke.h>
  29. #include <tqcolor.h>
  30. #include <tqfile.h>
  31. #define DPI 90
  32. typedef KGenericFactory<KontourImport, KoFilter> KontourImportFactory;
  33. K_EXPORT_COMPONENT_FACTORY( libkarbonkontourimport, KontourImportFactory( "kofficefilters" ) )
  34. KontourImport::KontourImport(KoFilter *, const char *, const TQStringList&) :
  35. KoFilter(),
  36. outdoc( "DOC" )
  37. {
  38. }
  39. KontourImport::~KontourImport()
  40. {
  41. }
  42. KoFilter::ConversionStatus KontourImport::convert(const TQCString& from, const TQCString& to)
  43. {
  44. // check for proper conversion
  45. if ( to != "application/x-karbon" || ( from != "application/x-kontour" && from != "application/x-killustrator") )
  46. return KoFilter::NotImplemented;
  47. KoStoreDevice* inpdev = m_chain->storageFile( "root", KoStore::Read );
  48. if ( !inpdev )
  49. {
  50. kdError(30502) << "Unable to open input stream" << endl;
  51. return KoFilter::StorageCreationError;
  52. }
  53. inpdoc.setContent( inpdev );
  54. // Do the conversion!
  55. convert();
  56. KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write );
  57. if(!out)
  58. {
  59. kdError(30502) << "Unable to open output file!" << endl;
  60. return KoFilter::StorageCreationError;
  61. }
  62. TQCString cstring = outdoc.toCString(); // utf-8 already
  63. out->writeBlock( cstring.data(), cstring.length() );
  64. return KoFilter::OK; // was successful
  65. }
  66. void
  67. KontourImport::parseGObject( VObject *object, const TQDomElement &e )
  68. {
  69. if( !e.attribute( "fillstyle" ).isEmpty() )
  70. {
  71. VFill fill;
  72. int fillstyle = e.attribute( "fillstyle" ).toInt();
  73. switch( fillstyle )
  74. {
  75. case 1:
  76. {
  77. fill.setType( VFill::solid );
  78. TQColor c;
  79. c.setNamedColor( e.attribute( "fillcolor" ) );
  80. VColor color( c );
  81. fill.setColor( color );
  82. }
  83. break;
  84. case 4:
  85. {
  86. VGradient grad;
  87. // set color stops
  88. grad.clearStops();
  89. TQColor c;
  90. c.setNamedColor( e.attribute( "gradcolor1" ) );
  91. VColor color( c );
  92. grad.addStop( color, 0.0, 0.5 );
  93. c.setNamedColor( e.attribute( "gradcolor2" ) );
  94. VColor color2( c );
  95. grad.addStop( color2, 1.0, 0.5 );
  96. // set coords
  97. KoRect bbox = object->boundingBox();
  98. grad.setOrigin( KoPoint( bbox.left(), bbox.y() ) );
  99. grad.setVector( KoPoint( bbox.right(), bbox.y() ) );
  100. grad.setType( (VGradient::VGradientType)e.attribute( "gradstyle" ).toInt() );
  101. fill.setType( VFill::grad );
  102. fill.gradient() = grad;
  103. }
  104. break;
  105. }
  106. object->setFill( fill );
  107. }
  108. if( !e.attribute( "strokecolor" ).isEmpty() )
  109. {
  110. VStroke stroke;
  111. int strokestyle = e.attribute( "strokestyle" ).toInt();
  112. switch( strokestyle )
  113. {
  114. case 0: stroke.setType( VStroke::none );
  115. break;
  116. case 1:
  117. {
  118. TQColor c;
  119. c.setNamedColor( e.attribute( "strokecolor" ) );
  120. VColor color( c );
  121. stroke.setColor( color );
  122. }
  123. break;
  124. case 2: case 3: case 4: case 5:
  125. {
  126. TQColor c;
  127. c.setNamedColor( e.attribute( "strokecolor" ) );
  128. VColor color( c );
  129. stroke.setColor( color );
  130. VDashPattern dash;
  131. TQValueList<float> list;
  132. switch ( strokestyle )
  133. {
  134. case 2: // dashed line
  135. list << 10 << 5;
  136. break;
  137. case 3: // dotted line
  138. list << 1 << 5;
  139. break;
  140. case 4: // dash-dot
  141. list << 10 << 5 << 1 << 5;
  142. break;
  143. case 5: // dash-dot-dot
  144. list << 10 << 5 << 1 << 5 << 1 << 5;
  145. break;
  146. }
  147. dash.setArray( list );
  148. stroke.dashPattern() = dash;
  149. }
  150. break;
  151. }
  152. float lineWidth = e.attribute( "linewidth" ).toFloat();
  153. stroke.setLineWidth( lineWidth );
  154. object->setStroke( stroke );
  155. }
  156. // handle matrix
  157. TQDomElement matrix = e.namedItem( "matrix" ).toElement();
  158. TQWMatrix mat( matrix.attribute( "m11" ).toDouble(),
  159. matrix.attribute( "m12" ).toDouble(),
  160. matrix.attribute( "m21" ).toDouble(),
  161. matrix.attribute( "m22" ).toDouble(),
  162. matrix.attribute( "dx" ).toDouble(),
  163. matrix.attribute( "dy" ).toDouble() );
  164. // undo y-mirroring
  165. mat.scale( 1, -1 );
  166. mat.translate( 0, -m_document.height() );
  167. VTransformCmd trafo( 0L, mat );
  168. trafo.visit( *object );
  169. }
  170. void
  171. KontourImport::convert()
  172. {
  173. TQDomElement docElem = inpdoc.documentElement();
  174. TQDomElement lay;
  175. double height;
  176. double width;
  177. if( docElem.attribute( "version" ).toInt() == 2 )
  178. {
  179. lay = docElem;
  180. height = lay.firstChild().namedItem( "layout" ).toElement().attribute( "height" ).toDouble();
  181. width = lay.firstChild().namedItem( "layout" ).toElement().attribute( "width" ).toDouble();
  182. }
  183. else
  184. {
  185. lay = docElem.namedItem( "page" ).toElement();
  186. height = lay.firstChild().toElement().attribute( "height" ).toDouble();
  187. width = lay.firstChild().toElement().attribute( "width" ).toDouble();
  188. }
  189. m_document.setHeight( ( ( height / 72.0 ) * DPI ) );
  190. m_document.setWidth( ( ( width / 72.0 ) * DPI ) );
  191. parseGroup( lay.firstChild().toElement() );
  192. outdoc = m_document.saveXML();
  193. }
  194. void
  195. KontourImport::parseGroup( const TQDomElement &e )
  196. {
  197. TQDomElement b = e;
  198. for( ; !b.isNull(); b = b.nextSibling().toElement() )
  199. {
  200. if ( b.tagName() == "rectangle" )
  201. {
  202. int x = b.attribute( "x" ).toInt();
  203. int y = b.attribute( "y" ).toInt();
  204. int width = b.attribute( "width" ).toInt();
  205. int height = b.attribute( "height" ).toInt();
  206. VObject *rect = new VRectangle( 0L, KoPoint( x, height + y ) , width, height );
  207. TQDomElement object = b.namedItem( "polyline" ).namedItem( "gobject" ).toElement();
  208. parseGObject( rect, object );
  209. m_document.append( rect );
  210. }
  211. else
  212. if ( b.tagName() == "ellipse" )
  213. {
  214. TQDomElement object = b.namedItem( "gobject" ).toElement();
  215. TQDomElement matrix = object.namedItem( "matrix" ).toElement();
  216. /**
  217. * Kontour uses a quite different way to display ellipses, so we
  218. * need to calculate the values for the Karbon ellipse here
  219. */
  220. double left = ( b.attribute( "x" ).toDouble() + matrix.attribute( "dx" ).toInt() ) - ( b.attribute( "rx" ).toDouble() / 2 );
  221. double right = left + b.attribute( "rx" ).toDouble();
  222. double top = ( b.attribute( "y" ).toDouble() + matrix.attribute( "dy" ).toInt() ) - ( b.attribute( "ry" ).toDouble() / 2 );
  223. double bottom = top + b.attribute( "ry" ).toDouble();
  224. double height = top - bottom;
  225. double width = right - left;
  226. // Append the ellipse to the document
  227. VObject *ellipse = new VEllipse( 0L, KoPoint( left, top ), width, height );
  228. parseGObject( ellipse, object );
  229. m_document.append( ellipse );
  230. }
  231. else if( b.tagName() == "polyline" )
  232. {
  233. /**
  234. * Kontour is much simpler because it doesn't support curves, so
  235. * we're done with connecting points with lines.
  236. */
  237. TQDomElement point = b.firstChild().toElement();
  238. VPath *path = new VPath( &m_document );
  239. double x, y;
  240. x = point.attribute( "x" ).toDouble();
  241. y = point.attribute( "y" ).toDouble();
  242. path->moveTo( KoPoint( x, y ) );
  243. point = point.nextSibling().toElement();
  244. for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() )
  245. {
  246. x = point.attribute( "x" ).toDouble();
  247. y = point.attribute( "y" ).toDouble();
  248. path->lineTo( KoPoint( x, y ) );
  249. }
  250. parseGObject( path, point );
  251. m_document.append( path );
  252. }
  253. else if( b.tagName() == "polygon" )
  254. {
  255. TQDomElement point = b.namedItem( "polyline" ).firstChild().toElement();
  256. VPath *path = new VPath( &m_document );
  257. double x, y;
  258. x = point.attribute( "x" ).toDouble();
  259. y = point.attribute( "y" ).toDouble();
  260. path->moveTo( KoPoint( x, y ) );
  261. point = point.nextSibling().toElement();
  262. for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() )
  263. {
  264. x = point.attribute( "x" ).toDouble();
  265. y = point.attribute( "y" ).toDouble();
  266. path->lineTo( KoPoint( x, y ) );
  267. }
  268. path->close();
  269. // back to first point
  270. parseGObject( path, point );
  271. m_document.append( path );
  272. }
  273. else if( b.tagName() == "bezier" )
  274. {
  275. TQDomElement point = b.namedItem( "polyline" ).firstChild().toElement();
  276. VPath *path = new VPath( &m_document );
  277. double x, y;
  278. x = point.attribute( "x" ).toDouble();
  279. y = point.attribute( "y" ).toDouble();
  280. path->moveTo( KoPoint( x, y ) );
  281. point = point.nextSibling().toElement();
  282. for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() )
  283. {
  284. x = point.attribute( "x" ).toDouble();
  285. y = point.attribute( "y" ).toDouble();
  286. path->lineTo( KoPoint( x, y ) );
  287. }
  288. parseGObject( path, point );
  289. m_document.append( path );
  290. }
  291. else if( b.tagName() == "group" || b.tagName() == "layer" )
  292. {
  293. parseGroup( b.toElement().firstChild().toElement() );
  294. }
  295. }
  296. }
  297. #include <kontourimport.moc>