From 8362bf63dea22bbf6736609b0f49c152f975eb63 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 20 Jan 2010 01:29:50 +0000 Subject: Added old abandoned KDE3 version of koffice git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- filters/karbon/Makefile.am | 2 + filters/karbon/ai/Makefile.am | 44 + filters/karbon/ai/ai3handler.cc | 74 ++ filters/karbon/ai/ai3handler.h | 39 + filters/karbon/ai/ai88handler.cc | 564 ++++++++ filters/karbon/ai/ai88handler.h | 56 + filters/karbon/ai/aicolor.cc | 100 ++ filters/karbon/ai/aicolor.h | 57 + filters/karbon/ai/aielement.cc | 804 +++++++++++ filters/karbon/ai/aielement.h | 151 +++ filters/karbon/ai/aiimport.cc | 101 ++ filters/karbon/ai/aiimport.h | 47 + filters/karbon/ai/ailexer.cc | 514 ++++++++ filters/karbon/ai/ailexer.h | 123 ++ filters/karbon/ai/aiparserbase.cc | 1337 +++++++++++++++++++ filters/karbon/ai/aiparserbase.h | 440 +++++++ filters/karbon/ai/karbon_ai_import.desktop | 67 + filters/karbon/ai/karbonaiparserbase.cc | 637 +++++++++ filters/karbon/ai/karbonaiparserbase.h | 202 +++ filters/karbon/applixgraphics/Makefile.am | 20 + .../karbon/applixgraphics/applixgraphicimport.cc | 832 ++++++++++++ .../karbon/applixgraphics/applixgraphicimport.h | 71 + .../kontour_applixgraphic_import.desktop | 69 + filters/karbon/applixgraphics/status.html | 175 +++ filters/karbon/eps/Makefile.am | 37 + filters/karbon/eps/epsexport.cc | 481 +++++++ filters/karbon/eps/epsexport.h | 71 + filters/karbon/eps/epsexportdlg.cc | 65 + filters/karbon/eps/epsexportdlg.h | 44 + filters/karbon/eps/epsimport.cc | 117 ++ filters/karbon/eps/epsimport.h | 42 + filters/karbon/eps/karbon_eps_export.desktop | 66 + filters/karbon/eps/karbon_eps_import.desktop | 66 + filters/karbon/eps/karbon_ps_import.desktop | 66 + filters/karbon/eps/pscommentlexer.cc | 324 +++++ filters/karbon/eps/pscommentlexer.h | 112 ++ filters/karbon/kontour/Makefile.am | 27 + .../karbon/kontour/karbon_kontour_import.desktop | 66 + filters/karbon/kontour/kontourimport.cpp | 323 +++++ filters/karbon/kontour/kontourimport.h | 48 + filters/karbon/msod/Makefile.am | 18 + filters/karbon/msod/karbon_msod_import.desktop | 61 + filters/karbon/msod/msod.cc | 1340 +++++++++++++++++++ filters/karbon/msod/msod.h | 307 +++++ filters/karbon/msod/msodimport.cc | 313 +++++ filters/karbon/msod/msodimport.h | 87 ++ filters/karbon/msod/status.html | 153 +++ filters/karbon/oodraw/Makefile.am | 24 + filters/karbon/oodraw/karbon_oodraw_import.desktop | 63 + filters/karbon/oodraw/oodrawimport.cc | 757 +++++++++++ filters/karbon/oodraw/oodrawimport.h | 78 ++ filters/karbon/png/Makefile.am | 27 + filters/karbon/png/karbon_png_export.desktop | 67 + filters/karbon/png/pngexport.cc | 96 ++ filters/karbon/png/pngexport.h | 39 + filters/karbon/svg/Makefile.am | 34 + filters/karbon/svg/TODO | 8 + filters/karbon/svg/color.h | 306 +++++ filters/karbon/svg/karbon_svg_export.desktop | 67 + filters/karbon/svg/karbon_svg_import.desktop | 64 + filters/karbon/svg/svgexport.cc | 512 ++++++++ filters/karbon/svg/svgexport.h | 88 ++ filters/karbon/svg/svggraphiccontext.h | 48 + filters/karbon/svg/svgimport.cc | 1389 ++++++++++++++++++++ filters/karbon/svg/svgimport.h | 102 ++ filters/karbon/wmf/Makefile.am | 27 + filters/karbon/wmf/karbon_wmf_export.desktop | 63 + filters/karbon/wmf/karbon_wmf_import.desktop | 66 + filters/karbon/wmf/wmfexport.cc | 263 ++++ filters/karbon/wmf/wmfexport.h | 71 + filters/karbon/wmf/wmfimport.cc | 78 ++ filters/karbon/wmf/wmfimport.h | 42 + filters/karbon/wmf/wmfimportparser.cc | 371 ++++++ filters/karbon/wmf/wmfimportparser.h | 141 ++ filters/karbon/xaml/Makefile.am | 35 + filters/karbon/xaml/color.h | 306 +++++ filters/karbon/xaml/karbon_xaml_export.desktop | 54 + filters/karbon/xaml/karbon_xaml_import.desktop | 53 + filters/karbon/xaml/xamlexport.cc | 371 ++++++ filters/karbon/xaml/xamlexport.h | 76 ++ filters/karbon/xaml/xamlgraphiccontext.h | 46 + filters/karbon/xaml/xamlimport.cc | 1042 +++++++++++++++ filters/karbon/xaml/xamlimport.h | 91 ++ filters/karbon/xcf/Makefile.am | 27 + filters/karbon/xcf/karbon_xcf_export.desktop | 65 + filters/karbon/xcf/xcfexport.cc | 458 +++++++ filters/karbon/xcf/xcfexport.h | 97 ++ filters/karbon/xfig/karbon_xfig_import.desktop | 61 + filters/karbon/xfig/status.html | 157 +++ filters/karbon/xfig/xfigimport.cc | 760 +++++++++++ filters/karbon/xfig/xfigimport.h | 94 ++ filters/karbon/xfig/xfigimport_factory.cc | 67 + filters/karbon/xfig/xfigimport_factory.h | 46 + 93 files changed, 19557 insertions(+) create mode 100644 filters/karbon/Makefile.am create mode 100644 filters/karbon/ai/Makefile.am create mode 100644 filters/karbon/ai/ai3handler.cc create mode 100644 filters/karbon/ai/ai3handler.h create mode 100644 filters/karbon/ai/ai88handler.cc create mode 100644 filters/karbon/ai/ai88handler.h create mode 100644 filters/karbon/ai/aicolor.cc create mode 100644 filters/karbon/ai/aicolor.h create mode 100644 filters/karbon/ai/aielement.cc create mode 100644 filters/karbon/ai/aielement.h create mode 100644 filters/karbon/ai/aiimport.cc create mode 100644 filters/karbon/ai/aiimport.h create mode 100644 filters/karbon/ai/ailexer.cc create mode 100644 filters/karbon/ai/ailexer.h create mode 100644 filters/karbon/ai/aiparserbase.cc create mode 100644 filters/karbon/ai/aiparserbase.h create mode 100644 filters/karbon/ai/karbon_ai_import.desktop create mode 100644 filters/karbon/ai/karbonaiparserbase.cc create mode 100644 filters/karbon/ai/karbonaiparserbase.h create mode 100644 filters/karbon/applixgraphics/Makefile.am create mode 100644 filters/karbon/applixgraphics/applixgraphicimport.cc create mode 100644 filters/karbon/applixgraphics/applixgraphicimport.h create mode 100644 filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop create mode 100644 filters/karbon/applixgraphics/status.html create mode 100644 filters/karbon/eps/Makefile.am create mode 100644 filters/karbon/eps/epsexport.cc create mode 100644 filters/karbon/eps/epsexport.h create mode 100644 filters/karbon/eps/epsexportdlg.cc create mode 100644 filters/karbon/eps/epsexportdlg.h create mode 100644 filters/karbon/eps/epsimport.cc create mode 100644 filters/karbon/eps/epsimport.h create mode 100644 filters/karbon/eps/karbon_eps_export.desktop create mode 100644 filters/karbon/eps/karbon_eps_import.desktop create mode 100644 filters/karbon/eps/karbon_ps_import.desktop create mode 100644 filters/karbon/eps/pscommentlexer.cc create mode 100644 filters/karbon/eps/pscommentlexer.h create mode 100644 filters/karbon/kontour/Makefile.am create mode 100644 filters/karbon/kontour/karbon_kontour_import.desktop create mode 100644 filters/karbon/kontour/kontourimport.cpp create mode 100644 filters/karbon/kontour/kontourimport.h create mode 100644 filters/karbon/msod/Makefile.am create mode 100644 filters/karbon/msod/karbon_msod_import.desktop create mode 100644 filters/karbon/msod/msod.cc create mode 100644 filters/karbon/msod/msod.h create mode 100644 filters/karbon/msod/msodimport.cc create mode 100644 filters/karbon/msod/msodimport.h create mode 100644 filters/karbon/msod/status.html create mode 100644 filters/karbon/oodraw/Makefile.am create mode 100644 filters/karbon/oodraw/karbon_oodraw_import.desktop create mode 100644 filters/karbon/oodraw/oodrawimport.cc create mode 100644 filters/karbon/oodraw/oodrawimport.h create mode 100644 filters/karbon/png/Makefile.am create mode 100644 filters/karbon/png/karbon_png_export.desktop create mode 100644 filters/karbon/png/pngexport.cc create mode 100644 filters/karbon/png/pngexport.h create mode 100644 filters/karbon/svg/Makefile.am create mode 100644 filters/karbon/svg/TODO create mode 100644 filters/karbon/svg/color.h create mode 100644 filters/karbon/svg/karbon_svg_export.desktop create mode 100644 filters/karbon/svg/karbon_svg_import.desktop create mode 100644 filters/karbon/svg/svgexport.cc create mode 100644 filters/karbon/svg/svgexport.h create mode 100644 filters/karbon/svg/svggraphiccontext.h create mode 100644 filters/karbon/svg/svgimport.cc create mode 100644 filters/karbon/svg/svgimport.h create mode 100644 filters/karbon/wmf/Makefile.am create mode 100644 filters/karbon/wmf/karbon_wmf_export.desktop create mode 100644 filters/karbon/wmf/karbon_wmf_import.desktop create mode 100644 filters/karbon/wmf/wmfexport.cc create mode 100644 filters/karbon/wmf/wmfexport.h create mode 100644 filters/karbon/wmf/wmfimport.cc create mode 100644 filters/karbon/wmf/wmfimport.h create mode 100644 filters/karbon/wmf/wmfimportparser.cc create mode 100644 filters/karbon/wmf/wmfimportparser.h create mode 100644 filters/karbon/xaml/Makefile.am create mode 100644 filters/karbon/xaml/color.h create mode 100644 filters/karbon/xaml/karbon_xaml_export.desktop create mode 100644 filters/karbon/xaml/karbon_xaml_import.desktop create mode 100644 filters/karbon/xaml/xamlexport.cc create mode 100644 filters/karbon/xaml/xamlexport.h create mode 100644 filters/karbon/xaml/xamlgraphiccontext.h create mode 100644 filters/karbon/xaml/xamlimport.cc create mode 100644 filters/karbon/xaml/xamlimport.h create mode 100644 filters/karbon/xcf/Makefile.am create mode 100644 filters/karbon/xcf/karbon_xcf_export.desktop create mode 100644 filters/karbon/xcf/xcfexport.cc create mode 100644 filters/karbon/xcf/xcfexport.h create mode 100644 filters/karbon/xfig/karbon_xfig_import.desktop create mode 100644 filters/karbon/xfig/status.html create mode 100644 filters/karbon/xfig/xfigimport.cc create mode 100644 filters/karbon/xfig/xfigimport.h create mode 100644 filters/karbon/xfig/xfigimport_factory.cc create mode 100644 filters/karbon/xfig/xfigimport_factory.h (limited to 'filters/karbon') diff --git a/filters/karbon/Makefile.am b/filters/karbon/Makefile.am new file mode 100644 index 00000000..f6202386 --- /dev/null +++ b/filters/karbon/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = eps ai svg png wmf kontour xcf msod oodraw + diff --git a/filters/karbon/ai/Makefile.am b/filters/karbon/ai/Makefile.am new file mode 100644 index 00000000..761feaff --- /dev/null +++ b/filters/karbon/ai/Makefile.am @@ -0,0 +1,44 @@ +kde_module_LTLIBRARIES = libkarbonaiimport.la + +libkarbonaiimport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +libkarbonaiimport_la_LDFLAGS = \ + $(all_libraries) \ + $(KDE_RPATH) \ + -module -avoid-version -no-undefined + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + $(all_includes) + +service_DATA = karbon_ai_import.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + aicolor.h \ + aielement.h \ + aiimport.h \ + ailexer.h \ + aiparserbase.h \ + ai88handler.h \ + ai3handler.h \ + karbonaiparserbase.h + +libkarbonaiimport_la_SOURCES = \ + aicolor.cc \ + aielement.cc \ + aiimport.cc \ + ailexer.cc \ + aiparserbase.cc \ + ai88handler.cc \ + ai3handler.cc \ + karbonaiparserbase.cc + +libkarbonaiimport_la_METASOURCES = \ + AUTO + diff --git a/filters/karbon/ai/ai3handler.cc b/filters/karbon/ai/ai3handler.cc new file mode 100644 index 00000000..ae0252a3 --- /dev/null +++ b/filters/karbon/ai/ai3handler.cc @@ -0,0 +1,74 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "ai3handler.h" + +AI3Handler::AI3Handler(AIParserBase *delegate){ + m_delegate = delegate; +} +AI3Handler::~AI3Handler(){ +} + +bool AI3Handler::handleAIOperation (AIOperation op) { +// PathElement pathElement; +// double fval; + int ival; + + switch (op) { + case AIO_SetWindingOrder : + ival = m_delegate->getIntValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotWindingOrder (ival); + return true; + break; + case AIO_BeginGroupNoClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginGroup (false); + return true; + break; + case AIO_EndGroupNoClip : + if (m_delegate->m_debug) qDebug ("got end group noclip"); + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (false); + if (m_delegate->m_debug) qDebug ("/got end group noclip"); + return true; + break; + case AIO_BeginCombination : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginCombination (); + return true; + break; + case AIO_EndCombination : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndCombination (); + return true; + break; + case AIO_BeginGroupClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginGroup (true); + return true; + break; + case AIO_EndGroupClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (true); + return true; + break; + case AIO_SetFillMode : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillMode((FillMode) m_delegate->getIntValue()); + return true; + break; + default : + return false; + } + return false; +} + diff --git a/filters/karbon/ai/ai3handler.h b/filters/karbon/ai/ai3handler.h new file mode 100644 index 00000000..27f23cec --- /dev/null +++ b/filters/karbon/ai/ai3handler.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef AI3HANDLER_H +#define AI3HANDLER_H + +#include "aiparserbase.h" + +/** + *@author Dirk Schoenberger + */ + +class AI3Handler { +private: + AIParserBase *m_delegate; +public: + AI3Handler(AIParserBase *delegate); + ~AI3Handler(); + + bool handleAIOperation (AIOperation op); +}; + +#endif diff --git a/filters/karbon/ai/ai88handler.cc b/filters/karbon/ai/ai88handler.cc new file mode 100644 index 00000000..f3cf53a7 --- /dev/null +++ b/filters/karbon/ai/ai88handler.cc @@ -0,0 +1,564 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include "ai88handler.h" + +AI88Handler::AI88Handler(AIParserBase *delegate){ + m_delegate = delegate; +} +AI88Handler::~AI88Handler(){ +} + +bool AI88Handler::handleAIOperation (AIOperation op) { + PathElement pathElement; + double fval; + int ival; + + switch (op) { + case AIO_SetFillColorCMYK : + _handleSetFillColorCMYK(); + return true; + break; + case AIO_SetStrokeColorCMYK : + _handleSetStrokeColorCMYK(); + return true; + break; + case AIO_SetFillColorGray : + _handleSetFillColorGray(); + return true; + break; + case AIO_SetStrokeColorGray : + _handleSetStrokeColorGray(); + return true; + break; + case AIO_SetFillColorCustom : + _handleSetFillColorCustom(); + return true; + break; + case AIO_SetStrokeColorCustom : + _handleSetStrokeColorCustom(); + return true; + break; + case AIO_SetFillPattern : + _handleSetFillPattern(); + return true; + break; + case AIO_SetStrokePattern : + _handleSetStrokePattern(); + return true; + break; + case AIO_SetFillOverprinting : + if (m_delegate->m_miscGStateHandler) m_delegate->m_miscGStateHandler->gotFillOverprinting (m_delegate->getBoolValue()); + return true; + break; + case AIO_SetStrokeOverprinting : + if (m_delegate->m_miscGStateHandler) m_delegate->m_miscGStateHandler->gotStrokeOverprinting (m_delegate->getBoolValue()); + return true; + break; + case AIO_LockElement : + if (m_delegate->m_miscGStateHandler) m_delegate->m_miscGStateHandler->gotLockNextObject (m_delegate->getBoolValue()); + return true; + break; + case AIO_SetFlatness : + fval = m_delegate->getDoubleValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFlatness (fval); + return true; + break; + case AIO_SetLineCap : + ival = m_delegate->getIntValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotLineCaps (ival); + return true; + break; + case AIO_SetLineJoin : + ival = m_delegate->getIntValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotLineJoin (ival); + return true; + break; + case AIO_SetLineWidth : + fval = kMax(0.2, m_delegate->getDoubleValue()); // Use thinnest pen stroke possible for 0 (Rob) + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotLineWidth (fval); + return true; + break; + case AIO_SetMiterLimit : + fval = m_delegate->getDoubleValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotMiterLimit (fval); + return true; + break; + case AIO_SetDash : + _handleSetDash(); + return true; + break; + case AIO_BeginGroupClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginGroup (true); + return true; + break; + case AIO_EndGroupClip : + if (m_delegate->m_debug) qDebug ("got end group clip"); + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (true); + if (m_delegate->m_debug) qDebug ("/got end group clip"); + return true; + + break; + case AIO_MoveTo : + pathElement.petype = PET_MoveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.pointdata.y = m_delegate->getDoubleValue(); + pathElement.pevalue.pointdata.x = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_LineToCorner : + pathElement.petype = PET_LineTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.pointdata.y = m_delegate->getDoubleValue(); + pathElement.pevalue.pointdata.x = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_LineToSmooth : + pathElement.petype = PET_LineTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.pointdata.y = m_delegate->getDoubleValue(); + pathElement.pevalue.pointdata.x = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToCorner : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToSmooth : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC1Corner : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC1Smooth : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC2Corner : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC2Smooth : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + + case AIO_PathIgnoreReset : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(false, true); + return true; + break; + case AIO_PathIgnoreResetClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(true, true); + return true; + break; + case AIO_PathIgnoreNoReset : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(false, false); + return true; + break; + case AIO_PathIgnoreNoResetClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(true, false); + return true; + break; + case AIO_PathClipPath : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotClipPath(false); + return true; + break; + case AIO_PathFillNonZero : + if (m_delegate->m_pathHandler) + { + m_delegate->m_pathHandler->gotFillMode (FM_NonZero); + m_delegate->m_pathHandler->gotFillPath(false, true); + } + return true; + break; + case AIO_PathFillNonZeroClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillPath(true, true); + return true; + break; + case AIO_PathFillNoReset : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillPath(false, false); + return true; + break; + case AIO_PathFillNoResetClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillPath(true, false); + return true; + break; + case AIO_PathStroke : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotStrokePath(false); + return true; + break; + case AIO_PathStrokeClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotStrokePath(true); + return true; + break; + case AIO_PatternDefinition : + _handlePatternDefinition(); + return true; + break; + case AIO_GsaveIncludeDocument : + _handleGsaveIncludeDocument(); + return true; + break; + case AIO_Grestore : + if (m_delegate->m_embeddedHandler) m_delegate->m_embeddedHandler->gotGrestore(); + return true; + break; + case AIO_FontEncoding : + _handleFontEncoding(); + return true; + break; + case AIO_SetCurrentText : + _handleSetCurrentText(); + return true; + break; + case AIO_TextBlockFillStroke : + _handleTextBlock (TO_FillStroke); + return true; + break; + case AIO_TextBlockFill : + _handleTextBlock (TO_Fill); + return true; + break; + case AIO_TextBlockAppend : + _handleTextBlock (TO_Append); + return true; + break; + case AIO_TextBlockIgnore : + _handleTextBlock (TO_Ignore); + return true; + break; + case AIO_TextBlockStroke : + _handleTextBlock (TO_Stroke); + return true; + break; + case AIO_TextOutput : + _handleTextOutput (); + return true; + break; + case AIO_TextBlockEnd : + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotTextBlockEnd(); + return true; + break; + default : + return false; + } + return false; +} + + +void AI88Handler::_handleSetFillColorCMYK() +{ + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + + if (m_delegate->m_debug) qDebug ("values 1 are %f %f %f %f",c,m,y,k); + AIColor color (c,m,y,k); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillColor (color); +} + +void AI88Handler::_handleSetFillPattern() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = m_delegate->getDoubleValue(); + double k = m_delegate->getDoubleValue(); + double r = m_delegate->getDoubleValue(); + double rf = m_delegate->getDoubleValue(); + double angle = m_delegate->getDoubleValue(); + double sy = m_delegate->getDoubleValue(); + double sx = m_delegate->getDoubleValue(); + double py = m_delegate->getDoubleValue(); + double px = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillPattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} + +void AI88Handler::_handleSetStrokePattern() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = m_delegate->getDoubleValue(); + double k = m_delegate->getDoubleValue(); + double r = m_delegate->getDoubleValue(); + double rf = m_delegate->getDoubleValue(); + double angle = m_delegate->getDoubleValue(); + double sy = m_delegate->getDoubleValue(); + double sx = m_delegate->getDoubleValue(); + double py = m_delegate->getDoubleValue(); + double px = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokePattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} + + +void AI88Handler::_handleSetStrokeColorCMYK() +{ + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 2 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokeColor (color); +} + +void AI88Handler::_handleSetFillColorGray() +{ + double g = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 3 are %f",g); + + AIColor color (g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillColor (color); +} + +void AI88Handler::_handleSetStrokeColorGray() +{ + double g = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 4 are %f",g); + + AIColor color (g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokeColor (color); +} + +void AI88Handler::_handleSetFillColorCustom() +{ + double g = m_delegate->getDoubleValue(); + const QString name = m_delegate->getStringValue(); + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 5 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillColor (color); +} + +void AI88Handler::_handleSetDash() +{ +// qDebug ("found dash operation"); + double fval = m_delegate->getDoubleValue(); + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotDash (aval, fval); +// qDebug ("dash operation finished"); +} + +void AI88Handler::_handlePatternDefinition() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ury = m_delegate->getDoubleValue(); + double urx = m_delegate->getDoubleValue(); + double lly = m_delegate->getDoubleValue(); + double llx = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + + if (m_delegate->m_documentHandler) m_delegate->m_documentHandler->gotPatternDefinition (name.latin1(), aval, llx, lly, urx, ury); +} + +void AI88Handler::_handleGsaveIncludeDocument() { + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + + int ury = m_delegate->getIntValue(); + int urx = m_delegate->getIntValue(); + int lly = m_delegate->getIntValue(); + int llx = m_delegate->getIntValue(); + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_delegate->m_embeddedHandler) m_delegate->m_embeddedHandler->gotGsaveIncludeDocument (aval, llx,lly,urx,ury,name.latin1()); +} + +void AI88Handler::_handleSetCurrentText() { + int iAlign = m_delegate->getIntValue(); + TextAlign ta = TA_HLeft; + + switch (iAlign) + { + case 0 : ta = TA_HLeft; break; + case 1 : ta = TA_HCenter; break; + case 2 : ta = TA_HRight; break; + case 3: ta = TA_VTop; break; + case 4 : ta = TA_VCenter; break; + case 5 : ta = TA_VBottom; break; + } + + double kerning = m_delegate->getDoubleValue(); + double leading = m_delegate->getDoubleValue(); + double size = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &fontname = elem2.toReference(); + + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotFontDefinition (fontname.latin1(), size, leading, kerning, ta); + +} + +void AI88Handler::_handleTextBlock (TextOperation to) { + AIElement elem (m_delegate->m_stack.top()); + qDebug ("to element is (%s)",elem.typeName()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotTextBlockBegin (aval, to); +} + +void AI88Handler::_handleTextOutput () { + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &text = elem.toString(); + + int length = -1; + + if (m_delegate->m_stack.empty()) + { + AIElement elem2 (m_delegate->m_stack.top()); + if (elem2.type() == AIElement::Int) + { + length = elem2.asInt(); + m_delegate->m_stack.pop(); + } + } + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotTextOutput (text.latin1(), length); +} + +void AI88Handler::_handleFontEncoding() +{ + while (m_delegate->m_stack.top().type() != AIElement::Reference) { + m_delegate->m_stack.pop(); + } + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const QString &oldFont = elem.toReference(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const QString &newFont = elem2.toReference(); + + AIElement elem3 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const QValueVector encodingData = elem3.toElementArray(); + + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotFontEncoding (encodingData, oldFont.latin1(), newFont.latin1()); +} + +void AI88Handler::_handleSetStrokeColorCustom() +{ + double g = m_delegate->getDoubleValue(); + const QString name = m_delegate->getStringValue(); + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 6 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokeColor (color); +} diff --git a/filters/karbon/ai/ai88handler.h b/filters/karbon/ai/ai88handler.h new file mode 100644 index 00000000..be031113 --- /dev/null +++ b/filters/karbon/ai/ai88handler.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef AI88HANDLER_H +#define AI88HANDLER_H + +#include "aiparserbase.h" + +/** + *@author Dirk Schoenberger + */ + +class AI88Handler { +private: + AIParserBase *m_delegate; + + void _handleSetDash(); + void _handleSetStrokeColorCMYK(); + void _handleSetFillColorCMYK(); + void _handleSetStrokeColorGray(); + void _handleSetFillColorGray(); + void _handleSetStrokeColorCustom(); + void _handleSetFillColorCustom(); + void _handleSetFillPattern(); + void _handleSetStrokePattern(); + void _handlePatternDefinition(); + void _handleGsaveIncludeDocument(); + void _handleSetCurrentText(); + void _handleTextBlock (TextOperation to); + void _handleTextOutput (); + void _handleFontEncoding(); + +public: + AI88Handler(AIParserBase *delegate); + ~AI88Handler(); + + bool handleAIOperation (AIOperation op); +}; + +#endif diff --git a/filters/karbon/ai/aicolor.cc b/filters/karbon/ai/aicolor.cc new file mode 100644 index 00000000..67384167 --- /dev/null +++ b/filters/karbon/ai/aicolor.cc @@ -0,0 +1,100 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "aicolor.h" +#include + +AIColor::AIColor(){ + ctype = AIColor::CT_CMYK; + cdata.cmykdata.cvalue = 0; + cdata.cmykdata.mvalue = 0; + cdata.cmykdata.yvalue = 0; + cdata.cmykdata.kvalue = 0; +} + +AIColor::AIColor( const AIColor& value ){ + ctype = value.ctype; + memcpy (&cdata, &value.cdata, sizeof (cdata)); +} +AIColor::AIColor( double c, double m, double y, double k ){ + ctype = AIColor::CT_CMYK; + cdata.cmykdata.cvalue = c; + cdata.cmykdata.mvalue = m; + cdata.cmykdata.yvalue = y; + cdata.cmykdata.kvalue = k; +} +AIColor::AIColor( double c, double m, double y, double k, const char* colorname, double gray ){ + ctype = AIColor::CT_CMYK_Key; + cdata.cmykdata.cvalue = c; + cdata.cmykdata.mvalue = m; + cdata.cmykdata.yvalue = y; + cdata.cmykdata.kvalue = k; + cdata.cmykdata.colorname = strdup (colorname); +} +AIColor::AIColor( double gray ){ + ctype = AIColor::CT_Gray; + cdata.graydata = gray; +} + +AIColor::~AIColor(){ +} + +void AIColor::toRGB (double &r, double &g, double &b) +{ + switch (ctype) + { + case CT_CMYK : + case CT_CMYK_Key : + r = 1 - cdata.cmykdata.cvalue - cdata.cmykdata.kvalue; + g = 1 - cdata.cmykdata.mvalue - cdata.cmykdata.kvalue; + b = 1 - cdata.cmykdata.yvalue - cdata.cmykdata.kvalue; + break; + case CT_Gray : + r = cdata.graydata; + g = cdata.graydata; + b = cdata.graydata; + break; + default : + qDebug ("unknown colortype %d", ctype); + } +} + +void AIColor::toCMYK (double &c, double &m, double &y, double &k) +{ + switch (ctype) + { + case CT_CMYK : + case CT_CMYK_Key : + c = cdata.cmykdata.cvalue; + m = cdata.cmykdata.mvalue; + y = cdata.cmykdata.yvalue; + k = cdata.cmykdata.kvalue; + break; + case CT_Gray : + c = 0; + m = 0; + y = 0; + k = cdata.graydata; + break; + default : + qDebug ("unknown colortype %d", ctype); + } +} + + diff --git a/filters/karbon/ai/aicolor.h b/filters/karbon/ai/aicolor.h new file mode 100644 index 00000000..b8cc1414 --- /dev/null +++ b/filters/karbon/ai/aicolor.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef AICOLOR_H +#define AICOLOR_H + +#include + +/** + *@author + */ + +class AIColor { + public: + typedef enum { CT_CMYK, CT_CMYK_Key, CT_Gray } ColorType; + + private: + ColorType ctype; + + union { + struct { + double cvalue, mvalue, yvalue, kvalue; + char *colorname; + double graydata; + } cmykdata; + double graydata; + } cdata; +public: + AIColor(); + ~AIColor(); + AIColor( const AIColor& ); + AIColor( double c, double m, double y, double k ); + AIColor( double c, double m, double y, double k, const char *colorname, double gray ); + AIColor( double gray ); + + void toRGB (double &r, double &g, double &b); + void toCMYK (double &c, double &m, double &y, double &k); + +}; + +#endif diff --git a/filters/karbon/ai/aielement.cc b/filters/karbon/ai/aielement.cc new file mode 100644 index 00000000..13887b50 --- /dev/null +++ b/filters/karbon/ai/aielement.cc @@ -0,0 +1,804 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "aielement.h" +#include + +AIElement::Private::Private() +{ + typ = AIElement::Invalid; +} + +AIElement::Private::Private( Private* d ) +{ + switch( d->typ ) + { + case AIElement::Invalid: + break; + case AIElement::String: + case AIElement::Reference: + case AIElement::Operator: + value.ptr = new QString( *((QString*)d->value.ptr) ); + break; + case AIElement::CString: + // QCString is explicit shared + value.ptr = new QCString( *((QCString*)d->value.ptr) ); + break; +/* case AIElement::List: + value.ptr = new QValueList( *((QValueList*)d->value.ptr) ); + break; */ + case AIElement::ElementArray: + value.ptr = new QValueVector( *((QValueVector*)d->value.ptr) ); + break; + case AIElement::Block: + value.ptr = new QValueVector( *((QValueVector*)d->value.ptr) ); + break; + case AIElement::ByteArray: + value.ptr = new QByteArray( *((QByteArray*)d->value.ptr) ); + break; + case AIElement::Int: + value.i = d->value.i; + break; + case AIElement::UInt: + value.u = d->value.u; + break; + case AIElement::Double: + value.d = d->value.d; + break; + case AIElement::Byte: + value.b = d->value.b; + break; + default: + Q_ASSERT( 0 ); + } + + typ = d->typ; +} + +AIElement::Private::~Private() +{ + clear(); +} + +void AIElement::Private::clear() +{ + switch( typ ) + { + case AIElement::String: + case AIElement::Operator: + case AIElement::Reference: + delete (QString*)value.ptr; + break; + case AIElement::CString: + delete (QCString*)value.ptr; + break; +/* case AIElement::List: + delete (QValueList*)value.ptr; + break; */ + case AIElement::ElementArray: + delete (QValueVector*)value.ptr; + break; + case AIElement::Block: + delete (QValueVector*)value.ptr; + break; + case AIElement::ByteArray: + delete (QByteArray*)value.ptr; + break; + case AIElement::Invalid: + case AIElement::Int: + case AIElement::UInt: + case AIElement::Double: + case AIElement::Byte: + break; + } + + typ = AIElement::Invalid; +} + +/*! + Constructs an invalid aielement. +*/ +AIElement::AIElement() +{ + d = new Private; +} + +/*! + Destroys the AIElement and the contained object. + + Note that subclasses that reimplement clear() should reimplement + the destructor to call clear(). This destructor calls clear(), but + because it is the destructor, AIElement::clear() is called rather than + a subclass's clear(). +*/ +AIElement::~AIElement() +{ + if ( d->deref() ) + delete d; +} + +/*! + Constructs a copy of the aielement, \a p, passed as the argument to this + constructor. Usually this is a deep copy, but a shallow copy is made + if the stored data type is explicitly shared, as e.g. QImage is. +*/ +AIElement::AIElement( const AIElement& p ) +{ + d = new Private; + *this = p; +} + +/*! + Constructs a new aielement with a string value, \a val. +*/ +AIElement::AIElement( const QString& val, Type type ) +{ + d = new Private; + d->typ = type; + d->value.ptr = new QString( val ); +} + +/*! + Constructs a new aielement with a C-string value, \a val. + + If you want to modify the QCString after you've passed it to this + constructor, we recommend passing a deep copy (see + QCString::copy()). +*/ +AIElement::AIElement( const QCString& val ) +{ + d = new Private; + d->typ = CString; + d->value.ptr = new QCString( val ); +} + +/*! + Constructs a new aielement with a C-string value of \a val if \a val + is non-null. The aielement creates a deep copy of \a val. + + If \a val is null, the resulting aielement has type Invalid. +*/ +AIElement::AIElement( const char* val ) +{ + d = new Private; + if ( val == 0 ) + return; + d->typ = CString; + d->value.ptr = new QCString( val ); +} + +/*! + Constructs a new aielement with an integer value, \a val. +*/ +AIElement::AIElement( int val ) +{ + d = new Private; + d->typ = Int; + d->value.i = val; +} + +/*! + Constructs a new aielement with an unsigned integer value, \a val. +*/ +AIElement::AIElement( uint val ) +{ + d = new Private; + d->typ = UInt; + d->value.u = val; +} + +/*! + Constructs a new aielement with an byte value, \a val. +*/ +AIElement::AIElement( uchar val ) +{ + d = new Private; + d->typ = Byte; + d->value.b = val; +} + + +/*! + Constructs a new aielement with a floating point value, \a val. +*/ +AIElement::AIElement( double val ) +{ + d = new Private; + d->typ = Double; + d->value.d = val; +} + +/*! + Constructs a new aielement with a list value, \a val. +*/ +/* AIElement::AIElement( const QValueList& val ) +{ + d = new Private; + d->typ = List; + d->value.ptr = new QValueList( val ); +} */ + +AIElement::AIElement( const QValueVector& val, Type type ) +{ + d = new Private; + d->typ = type; + d->value.ptr = new QValueVector( val ); +} + +AIElement::AIElement( const QByteArray& val ) +{ + d = new Private; + d->typ = ByteArray; + d->value.ptr = new QByteArray( val ); +} + +/*! + Assigns the value of the aielement \a aielement to this aielement. + + This is a deep copy of the aielement, but note that if the aielement + holds an explicitly shared type such as QImage, a shallow copy + is performed. +*/ +AIElement& AIElement::operator= ( const AIElement& aielement ) +{ + AIElement& other = (AIElement&)aielement; + + other.d->ref(); + if ( d->deref() ) + delete d; + + d = other.d; + + return *this; +} + +/*! + \internal +*/ +void AIElement::detach() +{ + if ( d->count == 1 ) + return; + + d->deref(); + d = new Private( d ); +} + +/*! + Returns the name of the type stored in the aielement. + The returned strings describe the C++ datatype used to store the + data: for example, "QFont", "QString", or "QValueList". + An Invalid aielement returns 0. +*/ +const char* AIElement::typeName() const +{ + return typeToName( d->typ ); +} + +/*! Convert this aielement to type Invalid and free up any resources + used. +*/ +void AIElement::clear() +{ + if ( d->count > 1 ) + { + d->deref(); + d = new Private; + return; + } + + d->clear(); +} + +static const int ntypes = 11; +static const char* const type_map[ntypes] = +{ + 0, +// "QValueList", + "QString", + "int", + "uint", + "double", + "QCString", + "Operator", + "Reference", + "QValueVector", + "QByteArray", + "uchar", +}; + +/*! + Converts the enum representation of the storage type, \a typ, to its + string representation. +*/ +const char* AIElement::typeToName( Type typ ) +{ + if ( typ >= ntypes ) + return 0; + return type_map[typ]; +} + +/*! + Converts the string representation of the storage type gven in \a + name, to its enum representation. + + If the string representation cannot be converted to any enum + representation, the aielement is set to \c Invalid. +*/ +AIElement::Type AIElement::nameToType( const char* name ) +{ + for ( int i = 0; i < ntypes; i++ ) { + if ( !qstrcmp( type_map[i], name ) ) + return (Type) i; + } + return Invalid; +} + +/*! + Returns the aielement as a QString if the aielement has type() + String, CString, ByteArray, Int, Uint, Double, + or QString::null otherwise. + + \sa asString() +*/ +const QString AIElement::toString() const +{ + if ( d->typ == CString ) + return QString::fromLatin1( toCString() ); + if ( d->typ == Int ) + return QString::number( toInt() ); + if ( d->typ == UInt ) + return QString::number( toUInt() ); + if ( d->typ == Double ) + return QString::number( toDouble() ); + if ( d->typ == Byte ) + return QString::number( toByte() ); + if ( d->typ != String ) + return QString::null; + return *((QString*)d->value.ptr); +} + +const QString AIElement::toReference() const +{ + if ( d->typ != Reference ) + return QString::null; + return *((QString*)d->value.ptr); +} + +const QString AIElement::toOperator() const +{ + if ( d->typ != Operator ) + return QString::null; + return *((QString*)d->value.ptr); +} + +/*! + Returns the aielement as a QCString if the aielement has type() + CString or String, or a 0 otherwise. + + \sa asCString() +*/ +const QCString AIElement::toCString() const +{ + if ( d->typ == CString ) + return *((QCString*)d->value.ptr); + if ( d->typ == String ) + return ((QString*)d->value.ptr)->latin1(); + if ( d->typ == Operator ) + return ((QString*)d->value.ptr)->latin1(); + if ( d->typ == Reference ) + return ((QString*)d->value.ptr)->latin1(); + + return 0; +} + + +/*! + Returns the aielement as an int if the aielement has type() + String, CString, Int, UInt, Double, Byte, or 0 otherwise. + + If \a ok is non-null, \a *ok is set to TRUE if the value could be + converted to an int and FALSE otherwise. + + \sa asInt() canCast() +*/ +int AIElement::toInt( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toInt( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toInt( ok ); + if ( ok ) + *ok = canCast( UInt ); + if( d->typ == Int ) + return d->value.i; + if( d->typ == UInt ) + return (int)d->value.u; + if( d->typ == Byte ) + return (int)d->value.b; + if ( d->typ == Double ) + return (int)d->value.d; + return 0; +} + +uchar AIElement::toByte( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toShort( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toShort( ok ); + if ( ok ) + *ok = canCast( UInt ); + if( d->typ == Byte ) + return d->value.b; + if( d->typ == Int ) + return (uchar)d->value.i; + if( d->typ == UInt ) + return (uchar)d->value.u; + if ( d->typ == Double ) + return (uchar)d->value.d; + return 0; +} + + +/*! + Returns the aielement as an unsigned int if the aielement has type() + String, CString, UInt, Int, Double, Byte, or 0 otherwise. + + If \a ok is non-null, \a *ok is set to TRUE if the value could be + converted to a uint and FALSE otherwise. + + \sa asUInt() +*/ +uint AIElement::toUInt( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toUInt( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toUInt( ok ); + if ( ok ) + *ok = canCast( UInt ); + if( d->typ == Int ) + return d->value.i; + if( d->typ == UInt ) + return (int)d->value.u; + if( d->typ == Byte ) + return (int)d->value.b; + if ( d->typ == Double ) + return (int)d->value.d; + + return 0; +} + +/*! + Returns the aielement as a double if the aielement has type() + String, CString, Double, Int, UInt, Byte, or 0.0 otherwise. + + If \a ok is non-null, \a *ok is set to TRUE if the value could be + converted to a double and FALSE otherwise. + + \sa asDouble() +*/ +double AIElement::toDouble( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toDouble( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toDouble( ok ); + if ( ok ) + *ok = canCast( Double ); + if ( d->typ == Double ) + return d->value.d; + if ( d->typ == Int ) + return (double)d->value.i; + if ( d->typ == UInt ) + return (double)d->value.u; + if ( d->typ == Byte ) + return (double)d->value.b; + return 0.0; +} + +/*! + Returns the aielement as a QValueList if the aielement has type() + List or StringList, or an empty list otherwise. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QValueList list = myAIElement.toList(); + QValueList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa asList() +*/ +/* const QValueList AIElement::toList() const +{ + if ( d->typ == List ) + return *((QValueList*)d->value.ptr); + return QValueList(); +} */ + +const QValueVector AIElement::toElementArray() const +{ + if ( d->typ == ElementArray ) + return *((QValueVector*)d->value.ptr); + return QValueVector(); +} + +const QValueVector AIElement::toBlock() const +{ + if ( d->typ == Block ) + return *((QValueVector*)d->value.ptr); + return QValueVector(); +} + + +const QByteArray AIElement::toByteArray() const +{ + if ( d->typ == ByteArray ) + return *((QByteArray*)d->value.ptr); + return QByteArray(); +} + +#define Q_VARIANT_AS( f ) Q##f& AIElement::as##f() { \ + if ( d->typ != f ) *this = AIElement( to##f() ); else detach(); return *((Q##f*)d->value.ptr);} + +Q_VARIANT_AS(String) +Q_VARIANT_AS(CString) + +/*! + Returns the aielement's value as int reference. +*/ +int& AIElement::asInt() +{ + detach(); + if ( d->typ != Int ) { + int i = toInt(); + d->clear(); + d->value.i = i; + d->typ = Int; + } + return d->value.i; +} + +/*! + Returns the aielement's value as unsigned int reference. +*/ +uint& AIElement::asUInt() +{ + detach(); + if ( d->typ != UInt ) { + uint u = toUInt(); + d->clear(); + d->value.u = u; + d->typ = UInt; + } + return d->value.u; +} + +/*! + Returns the aielement's value as double reference. +*/ +double& AIElement::asDouble() +{ + if ( d->typ != Double ) { + double dbl = toDouble(); + d->clear(); + d->value.d = dbl; + d->typ = Double; + } + return d->value.d; +} + +/*! + Returns the aielement's value as byte reference. +*/ +uchar& AIElement::asByte() +{ + detach(); + if ( d->typ != Byte ) { + uchar b = toByte(); + d->clear(); + d->value.b = b; + d->typ = Byte; + } + return d->value.b; +} + + +/*! + Returns the aielement's value as aielement list reference. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QValueList list = myAIElement.asList(); + QValueList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode +*/ +/* QValueList& AIElement::asList() +{ + if ( d->typ != List ) + *this = AIElement( toList() ); + return *((QValueList*)d->value.ptr); +} */ + +QValueVector& AIElement::asElementArray() +{ + if ( d->typ != ElementArray ) + *this = AIElement( toElementArray() ); + return *((QValueVector*)d->value.ptr); +} + +QValueVector& AIElement::asBlock() +{ + if ( d->typ != Block ) + *this = AIElement( toBlock() ); + return *((QValueVector*)d->value.ptr); +} + + +QByteArray& AIElement::asByteArray() +{ + if ( d->typ != ByteArray ) + *this = AIElement( toByteArray() ); + return *((QByteArray*)d->value.ptr); +} + +/*! + Returns TRUE if the aielement's type can be cast to the requested + type, \p t. Such casting is done automatically when calling the + toInt(), ... or asInt(), ... methods. + + The following casts are done automatically: +
    +
  • CString => String +
  • Double => String, Int, UInt +
  • Int => String, Double, UInt +
  • String => CString, Int, Uint, Double +
  • UInt => String, Double, Int +
+*/ +bool AIElement::canCast( Type t ) const +{ + if ( d->typ == t ) + return TRUE; + if ( t == Int && ( d->typ == String || d->typ == Double || d->typ == UInt || d->typ == Byte) ) + return TRUE; + if ( t == UInt && ( d->typ == String || d->typ == Double || d->typ == Int || d->typ == Byte) ) + return TRUE; + if ( t == Double && ( d->typ == String || d->typ == Int || d->typ == UInt || d->typ == Byte) ) + return TRUE; + if ( t == CString && d->typ == String ) + return TRUE; + if ( t == String && ( d->typ == CString || d->typ == Int || d->typ == UInt || d->typ == Double || d->typ == Byte) ) + return TRUE; + + return FALSE; +} + +/*! + \brief Casts the aielement to the requested type. + + If the cast cannot be + done, the aielement is set to the default value of the requested type + (e.g. an empty string if the requested type \p t is + AIElement::String, an empty point array if the requested type \p t is + AIElement::PointArray, etc). + + \returns TRUE if the current type of the + aielement was successfully casted; otherwise returns FALSE. + + \see canCast() +*/ + +bool AIElement::cast( Type t ) +{ + switch ( t ) { +/* case AIElement::List: + asList(); + break; */ + case AIElement::ElementArray: + asElementArray(); + break; + case AIElement::Block: + asBlock(); + break; + case AIElement::String: + asString(); + break; + case AIElement::Int: + asInt(); + break; + case AIElement::UInt: + asUInt(); + break; + case AIElement::Double: + asDouble(); + break; + case AIElement::CString: + asCString(); + break; + case AIElement::Byte: + asByte(); + break; + case AIElement::ByteArray: + asByteArray(); + break; + default: + case AIElement::Invalid: + (*this) = AIElement(); + } + return canCast( t ); +} + +/*! Compares this AIElement with \a v and returns TRUE if they are + equal; otherwise returns FALSE. +*/ + +bool AIElement::operator==( const AIElement &v ) const +{ + if ( !v.canCast( type() ) ) + return FALSE; + switch( d->typ ) { +/* case List: + return v.toList() == toList(); */ + case ElementArray: + return v.toElementArray() == toElementArray(); + case Block: + return v.toBlock() == toBlock(); + case ByteArray: + return v.toByteArray() == toByteArray(); + + case String: + return v.toString() == toString(); + case Operator: + return v.toOperator() == toOperator(); + case Reference: + return v.toReference() == toReference(); + case CString: + return v.toCString() == toCString(); + case Int: + return v.toInt() == toInt(); + case UInt: + return v.toUInt() == toUInt(); + case Byte: + return v.toByte() == toByte(); + case Invalid: + break; + } + return FALSE; +} + +/*! Compares this AIElement with \a v and returns TRUE if they are + not equal; otherwise returns FALSE. +*/ + +bool AIElement::operator!=( const AIElement &v ) const +{ + return !( v == *this ); +} diff --git a/filters/karbon/ai/aielement.h b/filters/karbon/ai/aielement.h new file mode 100644 index 00000000..5c6ab045 --- /dev/null +++ b/filters/karbon/ai/aielement.h @@ -0,0 +1,151 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef AIELEMENT_H +#define AIELEMENT_H + +// #include +#include + +class QString; +class QCString; + +/** + *@author + */ + +class AIElement { +public: + enum Type { + Invalid, +// List, + String, + Int, + UInt, + Double, + CString, + // Custom Types + Operator, + Reference, + ElementArray, + Block, + ByteArray, + Byte + }; + + AIElement(); + ~AIElement(); + AIElement( const AIElement& ); + AIElement( const QString&, Type type = String ); + AIElement( const QCString& ); + AIElement( const char* ); +// AIElement( const QValueList& ); + AIElement( const QValueVector&, Type type = ElementArray); + AIElement( int ); + AIElement( uint ); + AIElement( double ); + AIElement( const QByteArray& ); + AIElement( uchar ); + + AIElement& operator= ( const AIElement& ); + bool operator==( const AIElement& ) const; + bool operator!=( const AIElement& ) const; + + Type type() const; + const char* typeName() const; + + bool canCast( Type ) const; + bool cast( Type ); + + bool isValid() const; + + void clear(); + + const QString toString() const; + const QCString toCString() const; + int toInt( bool * ok=0 ) const; + uint toUInt( bool * ok=0 ) const; + double toDouble( bool * ok=0 ) const; +// const QValueList toList() const; + const QValueVector toElementArray() const; + const QValueVector toBlock() const; + + // Custom types + const QString toReference() const; + const QString toOperator() const; + const QByteArray toByteArray() const; + uchar toByte( bool * ok=0 ) const; + +// QValueListConstIterator listBegin() const; +// QValueListConstIterator listEnd() const; + QString& asString(); + QCString& asCString(); + int& asInt(); + uint& asUInt(); + double& asDouble(); +// QValueList& asList(); + QValueVector& asElementArray(); + QValueVector& asBlock(); + + // Custom types + QString& asReference(); + QString& asToken(); + QByteArray& asByteArray(); + uchar& asByte(); + + static const char* typeToName( Type typ ); + static Type nameToType( const char* name ); + +private: + void detach(); + + class Private : public QShared + { + public: + Private(); + Private( Private* ); + ~Private(); + + void clear(); + + Type typ; + union + { + uint u; + int i; + double d; + uchar b; + void *ptr; + } value; + }; + + Private* d; +}; + +inline AIElement::Type AIElement::type() const +{ + return d->typ; +} + +inline bool AIElement::isValid() const +{ + return (d->typ != Invalid); +} + +#endif diff --git a/filters/karbon/ai/aiimport.cc b/filters/karbon/ai/aiimport.cc new file mode 100644 index 00000000..a5e24f5b --- /dev/null +++ b/filters/karbon/ai/aiimport.cc @@ -0,0 +1,101 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include + +#include +#include +#include + +#include + +#include "aiimport.h" +#include "karbonaiparserbase.h" + +class AiImportFactory : KGenericFactory +{ +public: + AiImportFactory( void ) + : KGenericFactory( "karbonaiimport" ) + {} + +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libkarbonaiimport, AiImportFactory() ) + +AiImport::AiImport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ +} + +AiImport::~AiImport() +{ +} + +KoFilter::ConversionStatus +AiImport::convert( const QCString& from, const QCString& to ) +{ + if ( from != "application/illustrator" || to != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + QFile fileIn( m_chain->inputFile() ); + if( !fileIn.open( IO_ReadOnly ) ) + { + fileIn.close(); + return KoFilter::FileNotFound; + } + + QDomDocument doc ("DOC"); + KarbonAIParserBase parser; + + if (!parser.parse (fileIn, doc)) + { + fileIn.close(); + return KoFilter::CreationError; + } + QString result = doc.toString(); + + kdDebug() << result << endl; + KoStoreDevice* storeOut = m_chain->storageFile( "root", KoStore::Write ); + if( !storeOut ) + { + fileIn.close(); + return KoFilter::StorageCreationError; + } + + QCString cStr = result.latin1(); + storeOut->writeBlock( cStr, cStr.size() - 1 ); + + return KoFilter::OK; +} + + +#include "aiimport.moc" + + + diff --git a/filters/karbon/ai/aiimport.h b/filters/karbon/ai/aiimport.h new file mode 100644 index 00000000..2ec2d19b --- /dev/null +++ b/filters/karbon/ai/aiimport.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __AIIMPORT_H__ +#define __AIIMPORT_H__ + +#include + +#include "karbonaiparserbase.h" + +class QDomElement; +class QTextStream; + +class AiImport : public KoFilter +{ + Q_OBJECT + +public: + AiImport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~AiImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +/* private: + QString m_result; */ + + +}; + +#endif + + diff --git a/filters/karbon/ai/ailexer.cc b/filters/karbon/ai/ailexer.cc new file mode 100644 index 00000000..7b660f7f --- /dev/null +++ b/filters/karbon/ai/ailexer.cc @@ -0,0 +1,514 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include "ailexer.h" + +#define CATEGORY_WHITESPACE -1 +#define CATEGORY_ALPHA -2 +#define CATEGORY_DIGIT -3 +#define CATEGORY_SPECIAL -4 +#define CATEGORY_LETTERHEX -5 +#define CATEGORY_INTTOOLONG -6 + +#define CATEGORY_ANY -127 + +#define MAX_INTLEN 9 +#define MIN_HEXCHARS 6 + +#define STOP 0 + +int iswhitespace(char c){ + return (c==' ')||(c=='\n')||(c=='\t')||(c=='\r'); +} + +int isSpecial(char c){ + return (c=='*')||(c=='_')||(c=='?')||(c=='~')||(c=='-')||(c=='^')||(c=='`')||(c=='!')||(c=='.')||(c=='@')||(c=='&')||(c=='$')||(c=='='); +} + +int isletterhex(char c){ + return (c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F'); +} + +const char*statetoa (State state){ + switch (state) + { + case State_Comment : return "comment"; + case State_Integer : return "integer"; + case State_Float : return "float"; + case State_String : return "string"; + case State_Token : return "token"; + case State_Reference : return "reference"; + case State_Start : return "start"; + case State_BlockStart : return "block start"; + case State_BlockEnd : return "block end"; + case State_ArrayStart : return "array start"; + case State_ArrayEnd : return "array end"; + case State_Byte : return "byte"; + case State_ByteArray : return "byte array"; + case State_StringEncodedChar : return "encoded char (string)"; + case State_CommentEncodedChar : return "encoded char (comment)"; + case State_ByteArray2 : return "byte array (mode 2)"; + default : return "unknown"; + } +} + +typedef struct { + State oldState; + char c; + State newState; + Action action; +} Transition; + +static Transition transitions[] = { + { State_Comment, '\n', State_Start, Action_Output}, + { State_Comment, '\r', State_Start, Action_Output}, + { State_Comment, '\\', State_CommentEncodedChar, Action_InitTemp}, + { State_Comment, CATEGORY_ANY, State_Comment, Action_Copy}, + { State_Integer, CATEGORY_DIGIT, State_Integer, Action_Copy}, + { State_Integer, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Integer, '.', State_Float, Action_Copy}, + { State_Integer, ']', State_Start, Action_OutputUnget}, + { State_Integer, '}', State_Start, Action_OutputUnget}, + { State_Integer, '#', State_Byte, Action_Copy }, + { State_Integer, '/', State_Start, Action_OutputUnget }, + { State_Integer, '{', State_Start, Action_OutputUnget }, + { State_Integer, '%', State_Start, Action_OutputUnget }, + { State_Integer, CATEGORY_LETTERHEX, State_ByteArray2, Action_Copy }, + { State_Integer, CATEGORY_INTTOOLONG, State_ByteArray2, Action_Copy }, + { State_Integer, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Float, CATEGORY_DIGIT, State_Float, Action_Copy}, + { State_Float, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Float, ']', State_Start, Action_OutputUnget}, + { State_Float, '}', State_Start, Action_OutputUnget}, + { State_Float, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Token, CATEGORY_ALPHA, State_Token, Action_Copy}, + { State_Token, CATEGORY_DIGIT, State_Token, Action_Copy}, + { State_Token, CATEGORY_SPECIAL, State_Token, Action_Copy}, + { State_Token, '}', State_Start, Action_OutputUnget}, + { State_Token, ']', State_Start, Action_OutputUnget}, + { State_Token, '{', State_BlockStart, Action_Output}, + { State_Token, '}', State_BlockEnd, Action_Output}, + { State_Token, '/', State_Start, Action_OutputUnget}, + { State_Token, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Token, CATEGORY_ANY, State_Start, Action_Abort}, + { State_String, ')', State_Start, Action_Output}, + { State_String, '\\', State_StringEncodedChar, Action_InitTemp}, + { State_String, CATEGORY_ANY, State_String, Action_Copy}, +// { State_Array, CATEGORY_ALPHA, State_Array, Action_Copy}, +// { State_Array, CATEGORY_DIGIT, State_Array, Action_Copy}, +// { State_Array, ' ', State_Array, Action_Copy}, + { State_BlockStart, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_BlockEnd, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_ArrayStart, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_ArrayEnd, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_Reference, '#', State_Reference, Action_Copy }, + { State_Reference, CATEGORY_ALPHA, State_Reference, Action_Copy }, + { State_Reference, CATEGORY_DIGIT, State_Reference, Action_Copy }, + { State_Reference, CATEGORY_SPECIAL, State_Reference, Action_Copy }, + { State_Reference, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_Byte, '/', State_Start, Action_OutputUnget }, + { State_Byte, CATEGORY_DIGIT, State_Byte, Action_Copy}, + { State_Byte, CATEGORY_ALPHA, State_Byte, Action_Copy}, + { State_Byte, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_ByteArray, '>', State_Start, Action_Output }, + { State_ByteArray, CATEGORY_ALPHA, State_ByteArray, Action_Copy }, + { State_ByteArray, CATEGORY_DIGIT, State_ByteArray, Action_Copy }, + { State_ByteArray, CATEGORY_WHITESPACE, State_ByteArray, Action_Ignore }, + { State_ByteArray, CATEGORY_ANY, State_Start, Action_Abort }, + { State_StringEncodedChar, '\\', State_String, Action_Copy}, + { State_StringEncodedChar, CATEGORY_DIGIT, State_StringEncodedChar, Action_CopyTemp}, + { State_StringEncodedChar, CATEGORY_ANY, State_String, Action_DecodeUnget}, + { State_CommentEncodedChar, '\\', State_Comment, Action_Copy}, + { State_CommentEncodedChar, CATEGORY_DIGIT, State_CommentEncodedChar, Action_CopyTemp}, + { State_CommentEncodedChar, CATEGORY_ANY, State_Comment, Action_DecodeUnget}, + { State_ByteArray2, '\n', State_Start, Action_Output}, + { State_ByteArray2, '\r', State_Start, Action_Output}, + { State_ByteArray2, '}', State_Start, Action_ByteArraySpecial}, + { State_ByteArray2, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_ByteArray2, CATEGORY_DIGIT, State_ByteArray2, Action_Copy}, + { State_ByteArray2, CATEGORY_LETTERHEX, State_ByteArray2, Action_Copy}, + { State_ByteArray2, CATEGORY_ALPHA, State_Token, Action_Copy}, + { State_ByteArray2, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Start, '%', State_Comment, Action_Ignore}, + { State_Start, CATEGORY_DIGIT, State_Integer, Action_Copy}, + { State_Start, '-', State_Integer, Action_Copy}, + { State_Start, '+', State_Integer, Action_Copy}, + { State_Start, '.', State_Float, Action_Copy}, + { State_Start, '/', State_Reference, Action_Ignore }, + { State_Start, '(', State_String, Action_Ignore}, + { State_Start, '{', State_BlockStart, Action_Copy}, + { State_Start, '}', State_BlockEnd, Action_Copy}, + { State_Start, '[', State_ArrayStart, Action_Copy}, + { State_Start, ']', State_ArrayEnd, Action_Copy}, + { State_Start, '<', State_ByteArray, Action_Ignore}, + { State_Start, CATEGORY_ALPHA, State_Token, Action_Copy}, + { State_Start, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Start, CATEGORY_SPECIAL, State_Token, Action_Copy}, + { State_Start, CATEGORY_LETTERHEX, State_ByteArray2, Action_Copy}, + { State_Start, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Start, STOP, State_Start, Action_Abort} +}; + +AILexer::AILexer(){ +} +AILexer::~AILexer(){ +} + +bool AILexer::parse (QIODevice& fin){ + char c; + + m_buffer.clear(); + m_curState = State_Start; + + parsingStarted(); + + while (!fin.atEnd()) + { + c = fin.getch (); + +// qDebug ("got %c", c); + + State newState; + Action action; + + nextStep (c, &newState, &action); + + switch (action) + { + case Action_Copy : + m_buffer.append (c); + break; + case Action_CopyOutput : + m_buffer.append (c); + doOutput(); + break; + case Action_Output : + doOutput(); + break; + case Action_OutputUnget : + doOutput(); + fin.ungetch(c); + break; + case Action_Ignore : + /* ignore */ + break; + case Action_Abort : + qWarning ( "state %s / %s char %c (%d)" , statetoa(m_curState), statetoa(newState), c, c ); + parsingAborted(); + return false; + break; + case Action_InitTemp : + m_temp.clear(); + break; + case Action_CopyTemp : + m_temp.append (c); + break; + case Action_DecodeUnget : + m_buffer.append (decode()); + fin.ungetch(c); + break; + // in Postscript Quelltext: Kombination F} + case Action_ByteArraySpecial : + m_curState = State_Token; + doOutput(); + fin.ungetch(c); + break; + default : + qWarning ( "unknown action: %d ", action); + } + + m_curState = newState; + } + + parsingFinished(); + return true; +} + +void AILexer::doOutput () +{ + if (m_buffer.length() == 0) return; + switch (m_curState) + { + case State_Comment : + gotComment (m_buffer.latin1()); + break; + case State_Integer : + gotIntValue (m_buffer.toInt()); + break; + case State_Float : + gotDoubleValue (m_buffer.toFloat()); + break; + case State_String : + gotStringValue (m_buffer.latin1()); + break; + case State_Token : + gotToken (m_buffer.latin1()); + break; + case State_Reference : + gotReference (m_buffer.latin1()); + break; + case State_BlockStart : + gotBlockStart (); + break; + case State_BlockEnd : + gotBlockEnd (); + break; + case State_Start : + break; + case State_ArrayStart : + gotArrayStart (); + break; + case State_ArrayEnd : + gotArrayEnd (); + break; + case State_Byte : + gotByte (getByte()); + break; + case State_ByteArray : + case State_ByteArray2 : + doHandleByteArray (); + break; + default: + qWarning ( "unknown state: %d", m_curState ); + } + + m_buffer.clear(); +} + +void AILexer::gotComment (const char *value) { + qDebug ( "gotComment: %s ", value ); +} + +void AILexer::gotIntValue (int value) { + qDebug ( "gotInt: %d ", value ); +} + +void AILexer::gotDoubleValue (double value) { + qDebug ( "gotDouble: %f ", value ); +} + +void AILexer::gotStringValue (const char *value) { + qDebug ( "gotString: %s ", value ); +} + +void AILexer::gotToken (const char *value) { + qDebug ( "gotToken: %s ", value ); +} + +void AILexer::gotReference (const char *value) { + qDebug ( "gotReference: %s ", value ); +} + +void AILexer::gotBlockStart (){ + qDebug ( "gotBlockStart" ); +} + +void AILexer::gotBlockEnd (){ + qDebug ( "gotBlockEnd" ); +} + +void AILexer::gotArrayStart (){ + qDebug ( "gotArrayStart" ); +} + +void AILexer::gotArrayEnd (){ + qDebug ( "gotArrayEnd" ); +} + +void AILexer::parsingStarted() { + qDebug ( "parsing started" ); +} + +void AILexer::parsingFinished() { + qDebug ( "parsing finished" ); +} + +void AILexer::parsingAborted() { + qDebug ( "parsing aborted" ); +} + +void AILexer::gotByte (uchar value) { + qDebug ( "got byte %d" , value ); +} + +void AILexer::gotByteArray (const QByteArray &data) { + qDebug ( "got byte array" ); +/* for ( uint i = 0; i < data.size(); i++ ) + { + uchar value = data[i]; + qDebug( "%d: %x", i, value ); + } + qDebug ( "/byte array" ); */ + +} + + +void AILexer::nextStep (char c, State *newState, Action *newAction) { + int i=0; + + while (true) { + Transition trans = transitions[i]; + + if (trans.c == STOP) { + *newState = trans.newState; + *newAction = trans.action; + return; + } + + bool found = false; + + if (trans.oldState == m_curState) { + switch (trans.c) { + case CATEGORY_WHITESPACE : found = isspace(c); break; + case CATEGORY_ALPHA : found = isalpha(c); break; + case CATEGORY_DIGIT : found = isdigit(c); break; + case CATEGORY_SPECIAL : found = isSpecial(c); break; + case CATEGORY_LETTERHEX : found = isletterhex(c); break; + case CATEGORY_INTTOOLONG : found = m_buffer.length() > MAX_INTLEN; break; + case CATEGORY_ANY : found = true; break; + default : found = (trans.c == c); + } + + if (found) { + *newState = trans.newState; + *newAction = trans.action; + + return; + } + } + + + i++; + } +} + +void AILexer::doHandleByteArray () +{ + // Special case - too short + if (m_buffer.length () < MIN_HEXCHARS) + { + gotToken (m_buffer.latin1()); + return; + } + + uint strIdx = 0; + uint arrayIdx = 0; + + QByteArray data (m_buffer.length() >> 1); + + while (strIdx < m_buffer.length()) + { + const QString &item = m_buffer.mid (strIdx, 2); + uchar val = item.toShort(NULL, 16); + data[arrayIdx] = val; + strIdx += 2; + arrayIdx++; + } + + gotByteArray (data); +} + +uchar AILexer::getByte() +{ +// qDebug ("convert string to byte (%s)", m_buffer.latin1()); + + QStringList list = QStringList::split ("#", m_buffer.toString()); + int radix = list[0].toShort(); + uchar value = list[1].toShort (NULL, radix); + + return value; +} + +uchar AILexer::decode() +{ + uchar value = m_temp.toString().toShort(NULL, 8); +// qDebug ("got encoded char %c",value); + return value; +} + +/* StringBuffer implementation */ + +int initialSize = 20; +int addSize = 10; + +StringBuffer::StringBuffer () { + m_buffer = (char*)calloc (initialSize, sizeof(char)); + m_length = 0; + m_capacity = initialSize; +} + +StringBuffer::~StringBuffer (){ + free(m_buffer); +} + +void StringBuffer::append (char c){ + ensureCapacity(m_length + 1); + m_buffer[m_length] = c; + m_length++; +} + +void StringBuffer::clear(){ + for (uint i=0; i= p_capacity) return; + + int newSize = m_capacity + addSize; + if (p_capacity > newSize) newSize = p_capacity; + + char* oldBuffer = m_buffer; + char *newBuffer = (char*)calloc (newSize, sizeof(char)); + strcpy (newBuffer, m_buffer); + free(oldBuffer); + m_buffer = newBuffer; + m_capacity = newSize; +} + +uint StringBuffer::length() { + return m_length; +} + +double StringBuffer::toFloat() { + QString data = toString(); + return data.toFloat(); +} + +int StringBuffer::toInt() { + QString data = toString(); + return data.toInt(); +} + +const char *StringBuffer::latin1() { + return m_buffer; +} + +QString StringBuffer::mid( uint index, uint len) const { + QString data = toString(); + return data.mid(index,len); +} diff --git a/filters/karbon/ai/ailexer.h b/filters/karbon/ai/ailexer.h new file mode 100644 index 00000000..c53aab66 --- /dev/null +++ b/filters/karbon/ai/ailexer.h @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef AILEXER_H +#define AILEXER_H + +#include +#include + +/** + *@author Dirk Sch鰊berger + */ +typedef enum { + State_Comment=0, + State_Integer, + State_Float, + State_String, + State_Token, + State_Reference, + State_Start, + State_BlockStart, + State_BlockEnd, + State_ArrayStart, + State_ArrayEnd, + State_Byte, + State_ByteArray, + State_StringEncodedChar, + State_CommentEncodedChar, + State_ByteArray2 +} State; + +typedef enum { + Action_Copy=1, + Action_CopyOutput, + Action_Output, + Action_Ignore, + Action_Abort, + Action_OutputUnget, + Action_InitTemp, + Action_CopyTemp, + Action_DecodeUnget, + Action_ByteArraySpecial +} Action; + +class StringBuffer { +public: + StringBuffer (); + virtual ~StringBuffer (); + + void append (char c); + void clear(); + QString toString() const; + uint length(); + double toFloat(); + int toInt(); + const char *latin1(); + QString mid( uint index, uint len=0xffffffff) const; +private: + char *m_buffer; + uint m_length; + int m_capacity; + + void ensureCapacity (int p_capacity); +}; + +class AILexer { +public: + AILexer(); + virtual ~AILexer(); + + virtual bool parse (QIODevice& fin); +private: + State m_curState; + StringBuffer m_buffer; + StringBuffer m_temp; + +/* State nextState (char c); + Action nextAction (char c); */ + + void nextStep (char c, State* newState, Action* newAction); + + void doOutput (); + void doHandleByteArray (); + uchar getByte(); + uchar decode(); + +protected: + virtual void parsingStarted(); + virtual void parsingFinished(); + virtual void parsingAborted(); + + virtual void gotComment (const char *value); + virtual void gotIntValue (int value); + virtual void gotDoubleValue (double value); + virtual void gotStringValue (const char *value); + virtual void gotToken (const char *value); + virtual void gotReference (const char *value); + virtual void gotBlockStart (); + virtual void gotBlockEnd (); + virtual void gotArrayStart (); + virtual void gotArrayEnd (); + virtual void gotByte (uchar value); + virtual void gotByteArray (const QByteArray &data); +}; + +#endif + diff --git a/filters/karbon/ai/aiparserbase.cc b/filters/karbon/ai/aiparserbase.cc new file mode 100644 index 00000000..63ace734 --- /dev/null +++ b/filters/karbon/ai/aiparserbase.cc @@ -0,0 +1,1337 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch枚nberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "aiparserbase.h" +#include "ai88handler.h" +#include "ai3handler.h" +#include +#include + +typedef struct { + char* op; + AIOperation action; +} AIOperationMapping; + +typedef struct { + char* op; + PSOperation action; +} PSOperationMapping; + +typedef struct { + char* op; + CommentOperation action; +} CommentOperationMapping; + +static AIOperationMapping aiMappings[] = { + { "k", AIO_SetFillColorCMYK }, + { "K", AIO_SetStrokeColorCMYK }, + { "g", AIO_SetFillColorGray }, + { "G", AIO_SetStrokeColorGray }, + { "x", AIO_SetFillColorCustom }, + { "X", AIO_SetStrokeColorCustom }, + { "p", AIO_SetFillPattern }, + { "P", AIO_SetStrokePattern }, + { "O", AIO_SetFillOverprinting }, + { "R", AIO_SetStrokeOverprinting }, + { "i", AIO_SetFlatness }, + { "J", AIO_SetLineCap }, + { "j", AIO_SetLineJoin }, + { "M", AIO_SetMiterLimit }, + { "w", AIO_SetLineWidth }, + { "d", AIO_SetDash }, + { "q", AIO_BeginGroupClip }, + { "Q", AIO_EndGroupClip }, + { "m", AIO_MoveTo }, + { "l", AIO_LineToSmooth }, + { "L", AIO_LineToCorner }, + { "c", AIO_CurveToSmooth }, + { "C", AIO_CurveToCorner }, + + { "v", AIO_CurveToOmitC1Smooth }, + { "V", AIO_CurveToOmitC1Corner }, + { "y", AIO_CurveToOmitC2Smooth }, + { "Y", AIO_CurveToOmitC2Corner }, + + { "H", AIO_PathIgnoreNoReset }, + { "h", AIO_PathIgnoreNoResetClose }, + { "W", AIO_PathClipPath }, + { "N", AIO_PathIgnoreReset }, + { "n", AIO_PathIgnoreResetClose }, + { "F", AIO_PathFillNonZero }, + { "f", AIO_PathFillNonZeroClose }, + { "B", AIO_PathFillNoReset }, + { "b", AIO_PathFillNoResetClose }, + { "S", AIO_PathStroke }, + { "s", AIO_PathStrokeClose }, + { "D", AIO_SetWindingOrder }, + { "Z", AIO_FontEncoding }, + { "E", AIO_PatternDefinition }, + { "A", AIO_LockElement }, + + { "z", AIO_SetCurrentText }, + { "a", AIO_TextBlockFillStroke }, + { "e", AIO_TextBlockFill }, + { "I", AIO_TextBlockAppend }, + { "o", AIO_TextBlockIgnore }, + { "r", AIO_TextBlockStroke }, + { "t", AIO_TextOutput }, + { "T", AIO_TextBlockEnd }, + { "`", AIO_GsaveIncludeDocument }, + { "~", AIO_Grestore }, + + { "u", AIO_BeginGroupNoClip }, + { "U", AIO_EndGroupNoClip }, + { "*u", AIO_BeginCombination }, + { "*U", AIO_EndCombination }, + + { "XR", AIO_SetFillMode }, + + { NULL, AIO_Other } +}; + +static PSOperationMapping psMappings[] = { + { "get", PSO_Get }, + { "exec", PSO_Exec }, + { "string", PSO_String }, + { "bind", PSO_Bind }, + { "def", PSO_Def }, + { "userdict", PSO_Userdict }, + { "dict", PSO_Dict }, + { "dup", PSO_Dup }, + { "begin", PSO_Begin }, + { "put", PSO_Put }, + { NULL, PSO_Other }, +}; + +static CommentOperationMapping commentMappings[] = { + { "BeginProlog", CO_BeginProlog }, + { "BeginSetup", CO_BeginSetup }, + { "BeginProcSet", CO_BeginProcSet }, + { "BeginResource", CO_BeginResource }, + { "BeginEncoding", CO_BeginEncoding }, + { "BeginPattern", CO_BeginPattern }, + { "BeginDocument", CO_BeginPattern }, + { "Trailer", CO_Trailer }, + { "EndProlog", CO_EndProlog }, + { "EndSetup", CO_EndSetup }, + { "EndProcSet", CO_EndProcSet }, + { "EndResource", CO_EndResource }, + { "EndEncoding", CO_EndEncoding }, + { "EndPattern", CO_EndPattern }, + { "EndDocument", CO_EndDocument }, + + { "Title", CO_Title }, + { "Creator", CO_Creator }, + + { "EOF", CO_Ignore }, + { "Note", CO_Ignore }, + { "EndComments", CO_Ignore }, + { "PS-Adobe", CO_Ignore }, + + { "BoundingBox", CO_BoundingBox }, + { "TemplateBox", CO_TemplateBox }, + { "AI3_Margin", CO_Margin }, + + { "For", CO_For }, + { "CreationDate", CO_CreationDate }, + { "DocumentFonts", CO_DocumentFonts }, + { "DocumentFiles", CO_DocumentFiles }, + { "ColorUsage", CO_ColorUsage }, + { "DocumentProcSets", CO_DocumentProcSets }, + { "DocumentSuppliedProcSets", CO_DocumentSuppliedProcSets }, + + { "DocumentProcessColors", CO_DocumentProcessColors }, + { "DocumentCustomColors", CO_DocumentCustomColors }, + { "CMYKCustomColor", CO_CMYKCustomColor }, + { "TileBox", CO_TileBox }, + { "%+", CO_Continuation }, + + { "Template", CO_Template }, + { "PageOrigin", CO_PageOrigin }, + { "PrinterName", CO_PrinterName }, + { "PrinterRect", CO_PrinterRect }, + { "Note", CO_Note }, + + { "DocumentNeededResources", CO_DocumentNeededResources }, + + + { "IncludeFont", CO_IncludeFont }, + { "BeginBrushPattern", CO_BeginBrushPattern }, + { "EndBrushPattern", CO_EndBrushPattern }, + { "BeginGradient", CO_BeginGradient }, + { "EndGradient", CO_EndGradient }, + { "BeginPalette", CO_BeginPalette }, + { "EndPalette", CO_EndPalette }, + + { "IncludeFile", CO_IncludeFile }, + { "IncludeResource", CO_IncludeResource }, + + { NULL, CO_Other } +}; + +AIParserBase::AIParserBase() : m_debug(false), m_ignoring(false), m_sink (DS_Other), m_continuationMode(CM_None) + { + m_gstateHandler = NULL; + m_structureHandler = NULL; + m_pathHandler = NULL; + m_miscGStateHandler = NULL; + m_documentHandler = NULL; + m_moduleHandler = NULL; + m_embeddedHandler = NULL; + m_ai88Handler = new AI88Handler(this); + m_ai3Handler = new AI3Handler(this); +} + +AIParserBase::~AIParserBase(){ + delete m_ai88Handler; + delete m_ai3Handler; + +} + +bool AIParserBase::parse (QIODevice& fin){ + return AILexer::parse (fin); +} + +void AIParserBase::gotComment (const char *value) { + int llx, lly, urx, ury; + + CommentOperation cop = getCommentOperation (value); + switch (cop) { + case CO_BeginDocument : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Document, value); + break; + case CO_EndDocument : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Document, value); + break; + case CO_BeginPattern : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Pattern, value); + break; + case CO_EndPattern : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Pattern, value); + break; + case CO_BeginProlog : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Prolog, value); + break; + case CO_BeginProcSet : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_ProcSet, value); + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginResource : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Resource, value); + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginEncoding : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Encoding, value); + m_ignoring = false; + break; + case CO_IncludeFont : + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginBrushPattern : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_BrushPattern, value); + break; + case CO_BeginGradient : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Gradient, value); + break; + case CO_Trailer : + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginPalette : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Palette, value); + break; + case CO_BeginSetup : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Setup, value); + break; + case CO_EndSetup : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Setup, value); + break; + case CO_EndProlog : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Prolog, value); + break; + case CO_EndProcSet : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_ProcSet, value); + if (m_debug) qDebug ("stop ignoring"); + m_ignoring = false; + break; + case CO_EndResource : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Resource, value); + if (m_debug) qDebug ("stop ignoring"); + m_ignoring = false; + break; + case CO_EndEncoding : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Encoding, value); + break; + case CO_EndBrushPattern : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_BrushPattern, value); + break; + case CO_EndGradient : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Gradient, value); + break; + case CO_EndPalette : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Palette, value); + break; + case CO_Ignore : + break; + case CO_BoundingBox : + if (getRectangle (value, llx, lly, urx, ury)) + { + if (m_documentHandler) m_documentHandler->gotBoundingBox (llx, lly, urx, ury); + } + break; + case CO_TemplateBox : + if (getRectangle (value, llx, lly, urx, ury)) + { + if (m_documentHandler) m_documentHandler->gotTemplateBox (llx, lly, urx, ury); + } + break; + case CO_Margin : + if (getRectangle (value, llx, lly, urx, ury)) + { + if (m_documentHandler) m_documentHandler->gotMargin (llx, lly, urx, ury); + } + break; + case CO_Title : + if (m_documentHandler) m_documentHandler->gotTitle (getValue (value)); + break; + case CO_Creator : + if (m_documentHandler) m_documentHandler->gotCreator (getValue (value)); + break; + case CO_DocumentFonts : + _handleDocumentFonts (value); + m_continuationMode = CM_DocumentFonts; + break; + case CO_DocumentFiles : + _handleDocumentFiles (value); + m_continuationMode = CM_DocumentFiles; + break; + case CO_DocumentCustomColors : + _handleDocumentCustomColors (value); + m_continuationMode = CM_DocumentFiles; + break; + case CO_CMYKCustomColor : + _handleCMYKCustomColor (value); + m_continuationMode = CM_CMYKCustomColor; + break; + case CO_DocumentNeededResources : + _handleDocumentNeededResources (value); + m_continuationMode = CM_DocumentNeededResources; + break; + case CO_DocumentProcessColors : + _handleDocumentProcessColors (value); + break; + case CO_CreationDate : + _handleCreationDate (value); + break; + case CO_IncludeFile : + break; + case CO_IncludeResource : + _handleIncludeResource (value); + break; + case CO_Continuation : + switch (m_continuationMode) { + case CM_DocumentFonts : _handleDocumentFonts (value); break; + case CM_DocumentFiles : _handleDocumentFiles (value); break; + case CM_DocumentCustomColors : _handleDocumentCustomColors (value); break; + case CM_CMYKCustomColor : _handleCMYKCustomColor (value); break; + case CM_DocumentNeededResources : _handleDocumentNeededResources (value); break; + + default : qWarning ("unknown continuation mode %d",m_continuationMode); + } + break; + + default : + qWarning( "unhandled comment: %s", value ); + } +} + +void AIParserBase::handleElement (AIElement &element) +{ + if (m_ignoring) return; + + if (m_sink == DS_Array) + { + if (m_debug) qDebug ("in mode array"); + QValueVector &elementArray = m_arrayStack.top(); + elementArray.push_back(element); + } + if (m_sink == DS_Block) + { + if (m_debug) qDebug ("in mode block"); + QValueVector &elementArray = m_blockStack.top(); + elementArray.push_back(element); + } + else + { + if (m_debug) qDebug ("in mode stack"); + m_stack.push (element); + } +} + +void AIParserBase::gotIntValue (int value) { + if (m_debug) qDebug ("got int value"); + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got int value"); +} + +void AIParserBase::gotDoubleValue (double value) { + if (m_debug) qDebug ("got double value"); + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got double value"); +} + +void AIParserBase::gotStringValue (const char *value) { + if (m_debug) qDebug ("got string value"); + if (m_ignoring) return; + if (value == NULL) value = ""; + if (m_debug) qDebug ("string: %s", value); + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got string value"); + +} + +void AIParserBase::gotReference (const char *value) { + if (m_debug) qDebug ("got reference value"); + + if (m_ignoring) return; + if (value == NULL) value = ""; + if (m_debug) qDebug ("reference: %s", value); + QString string(value); + AIElement element (string, AIElement::Reference); + handleElement (element); + if (m_debug) qDebug ("/got reference value"); + +} + +void AIParserBase::gotByte (uchar value) { + if (m_debug) qDebug ("got byte value"); + + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got byte value"); +} + +void AIParserBase::gotByteArray (const QByteArray &data) { + if (m_ignoring) return; + AIElement element (data); + handleElement (element); +} + + +void AIParserBase::gotArrayStart () { + if (m_ignoring) return; + if (m_debug) qDebug ("got array start"); + + QValueVector array; + m_arrayStack.push (array); + + m_sink = DS_Array; +} + +void AIParserBase::gotBlockStart () { + if (m_ignoring) return; + if (m_debug) qDebug ("got block start"); + + QValueVector array; + m_blockStack.push (array); + + m_sink = DS_Block; +} + +void AIParserBase::gotArrayEnd () { + if (m_ignoring) return; + if (m_debug) qDebug ("got array end"); + + QValueVector stackArray = m_arrayStack.pop(); + + if (m_arrayStack.empty()) + { + if (m_debug) qDebug ("put elements to stack"); + AIElement realElement (stackArray); + + if (m_debug) { + qDebug ("going to stack"); + elementtoa (realElement); + qDebug ("done"); + } + m_stack.push (realElement); + + m_sink = DS_Other; + } + else + { + if (m_debug) qDebug ("put elements to nest stack level"); + QValueVector currentTOS = m_arrayStack.top(); + currentTOS.push_back (stackArray); + } +} + +void AIParserBase::gotBlockEnd () { + if (m_ignoring) return; + if (m_debug) qDebug ("got block end"); + + QValueVector stackArray = m_blockStack.pop(); + + if (m_blockStack.empty()) + { + if (m_debug) qDebug ("put elements to stack"); + AIElement realElement (stackArray, AIElement::Block); + + if (m_debug) { + qDebug ("going to stack"); + elementtoa (realElement); + qDebug ("done"); + } + m_stack.push (realElement); + + m_sink = DS_Other; + } + else + { + if (m_debug) qDebug ("put elements to nest stack level"); + QValueVector currentTOS = m_blockStack.top(); + currentTOS.push_back (stackArray); + } +} + +/*Ai88*/ /* void AIParserBase::_handleSetDash() +{ + double fval = getDoubleValue(); + + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + if (m_gstateHandler) m_gstateHandler->gotDash (aval, fval); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorCMYK() +{ + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + + if (m_debug) qDebug ("values 1 are %f %f %f %f",c,m,y,k); + AIColor color (c,m,y,k); + + if (m_gstateHandler) m_gstateHandler->gotFillColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillPattern() +{ + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = getDoubleValue(); + double k = getDoubleValue(); + double r = getDoubleValue(); + double rf = getDoubleValue(); + double angle = getDoubleValue(); + double sy = getDoubleValue(); + double sx = getDoubleValue(); + double py = getDoubleValue(); + double px = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_gstateHandler) m_gstateHandler->gotFillPattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetStrokePattern() +{ + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = getDoubleValue(); + double k = getDoubleValue(); + double r = getDoubleValue(); + double rf = getDoubleValue(); + double angle = getDoubleValue(); + double sy = getDoubleValue(); + double sx = getDoubleValue(); + double py = getDoubleValue(); + double px = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_gstateHandler) m_gstateHandler->gotStrokePattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetStrokeColorCMYK() +{ + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) qDebug ("values 2 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorGray() +{ + double g = getDoubleValue(); + if (m_debug) qDebug ("values 3 are %f",g); + + AIColor color (g); + + if (m_gstateHandler) m_gstateHandler->gotFillColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetStrokeColorGray() +{ + double g = getDoubleValue(); + if (m_debug) qDebug ("values 4 are %f",g); + + AIColor color (g); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorCustom() +{ + double g = getDoubleValue(); + const QString &name = getStringValue(); + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) qDebug ("values 5 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_gstateHandler) m_gstateHandler->gotFillColor (color); +} */ + +void AIParserBase::_handlePSGet() { + m_stack.pop(); + m_stack.pop(); + + QString name ("xxx"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSExec() { + m_stack.pop(); +} + +void AIParserBase::_handlePSString() { + m_stack.pop(); + + QString name ("stringval"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSBind() { + m_stack.pop(); + + QString name ("bindentry"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSUserdict() { + QString name ("userdict"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSDict() { + m_stack.pop(); + m_stack.pop(); + m_stack.pop(); + + QString name ("dict"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSDup() { + AIElement &tos = m_stack.top(); + + AIElement copy (tos); + m_stack.push (copy); +} + +void AIParserBase::_handlePSBegin() { + m_stack.pop(); + + QString name ("dictionary begin"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSPut() { + m_stack.pop(); + m_stack.pop(); +} + +/*Ai88*/ /* void AIParserBase::_handlePatternDefinition() +{ + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ury = getDoubleValue(); + double urx = getDoubleValue(); + double lly = getDoubleValue(); + double llx = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + + if (m_documentHandler) m_documentHandler->gotPatternDefinition (name.latin1(), aval, llx, lly, urx, ury); +} */ + +void AIParserBase::_handlePSDef() { + // name ref + m_stack.pop(); + + // impl + m_stack.pop(); +} + +/*Ai88*/ /* void AIParserBase::_handleSetStrokeColorCustom() +{ + double g = getDoubleValue(); + const QString &name = getStringValue(); + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) qDebug ("values 6 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +void AIParserBase::_handleDocumentFonts(const char *) { +} + +void AIParserBase::_handleDocumentFiles(const char *) { +} + +void AIParserBase::_handleDocumentCustomColors(const char *) { +} + +void AIParserBase::_handleDocumentNeededResources(const char *data) { + if (!data) return; + QStringList items = QStringList::split (' ', data); + + QString itemType = items[1]; + QString name = items[2]; + QString version = items[3]; + QString release = items[4]; +} + +void AIParserBase::_handleIncludeResource(const char *data) { + if (!data) return; + QStringList items = QStringList::split (' ', data); + + QString itemType = items[1]; + QString name = items[2]; + QString version = items[3]; + QString release = items[4]; + + m_modules.push_back (name); +} + +void AIParserBase::_handleDocumentProcessColors(const char *data) { + if (!data) return; + + int colorSet = 0; + QString tmp (data); + + signed int index; + + index = tmp.find ("Cyan"); + if (index > 0) colorSet |= PC_Cyan; + + index = tmp.find ("Magenta"); + if (index > 0) colorSet |= PC_Magenta; + + index = tmp.find ("Yellow"); + if (index > 0) colorSet |= PC_Yellow; + + index = tmp.find ("Black"); + if (index > 0) colorSet |= PC_Black; + + if (m_documentHandler) m_documentHandler->gotProcessColors (colorSet); +} + +void AIParserBase::_handleCMYKCustomColor(const char *) { +} + +/*Ai88*/ /* void AIParserBase::_handleGsaveIncludeDocument() { + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + + int ury = getIntValue(); + int urx = getIntValue(); + int lly = getIntValue(); + int llx = getIntValue(); + + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_embeddedHandler) m_embeddedHandler->gotGsaveIncludeDocument (aval, llx,lly,urx,ury,name.latin1()); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetCurrentText() { + int iAlign = getIntValue(); + TextAlign ta = TA_HLeft; + + switch (iAlign) + { + case 0 : ta = TA_HLeft; break; + case 1 : ta = TA_HCenter; break; + case 2 : ta = TA_HRight; break; + case 3: ta = TA_VTop; break; + case 4 : ta = TA_VCenter; break; + case 5 : ta = TA_VBottom; break; + } + + double kerning = getDoubleValue(); + double leading = getDoubleValue(); + double size = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &fontname = elem2.toReference(); + + if (m_textHandler) m_textHandler->gotFontDefinition (fontname.latin1(), size, leading, kerning, ta); +} */ + +/*Ai88*/ /* void AIParserBase::_handleTextBlock (TextOperation to) { + AIElement elem (m_stack.top()); + qDebug ("to element is (%s)",elem.typeName()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_textHandler) m_textHandler->gotTextBlockBegin (aval, to); +} */ + +/*Ai88*/ /* void AIParserBase::_handleTextOutput () { + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QString &text = elem.toString(); + + int length = -1; + + if (m_stack.empty()) + { + AIElement elem2 (m_stack.top()); + if (elem2.type() == AIElement::Int) + { + length = elem2.asInt(); + m_stack.pop(); + } + } + if (m_textHandler) m_textHandler->gotTextOutput (text.latin1(), length); +} */ + +void AIParserBase::_handleCreationDate (const char *data) +{ + if (!data) return; + + QRegExp test ("\\((.+)\\) \\((.+)\\)"); + if (test.search (data)) + { + QString val1 = test.cap(1); + QString val2 = test.cap(2); + + if (m_documentHandler) m_documentHandler->gotCreationDate (val1.latin1(),val2.latin1()); + } +} + +void AIParserBase::gotToken (const char *value) { + if (m_debug) qDebug ("got token"); + + if (m_ignoring) return; + if (m_debug) qDebug ("token: %s", value); + + if (m_sink == DS_Array) + { + if (m_debug) qDebug ("token in array"); + QString op (value); + AIElement realElement (op, AIElement::Operator); + handleElement (realElement); + + return; + } + if (m_sink == DS_Block) + { + if (m_debug) qDebug ("token in block"); + QString op (value); + AIElement realElement (op, AIElement::Operator); + handleElement (realElement); + + return; + } + + if (m_debug) qDebug ("get ai operation"); + + AIOperation op = getAIOperation (value); +// PathElement pathElement; +// double fval; +// int ival; + + bool handled = false; + + handled = m_ai88Handler->handleAIOperation (op); + if (!handled) handled = m_ai3Handler->handleAIOperation (op); + + if (!handled) + { + if (m_sink == DS_Other) + { + if (handlePS (value)) return; + } + qWarning ( "unknown operator: %s", value ); + + QString string(value); + + if (m_modules.findIndex(string) != -1) + { + AIElement element (string, AIElement::Reference); + handleElement (element); + return; + } + + if (m_debug) stacktoa (m_stack); + qWarning ( "pushing %s to stack", value ); + AIElement element (string, AIElement::Operator); + handleElement (element); + } + + if (m_debug) qDebug ("/got token value"); +} + +bool AIParserBase::handlePS (const char *operand){ + if (m_ignoring) return false; + + PSOperation psop = getPSOperation (operand); + + switch (psop) + { + case PSO_Get : + _handlePSGet (); + return true; + case PSO_Exec : + _handlePSExec (); + return true; + case PSO_Def : + _handlePSDef (); + return true; + case PSO_String : + _handlePSString (); + return true; + case PSO_Bind : + _handlePSBind (); + return true; + case PSO_Userdict : + _handlePSUserdict (); + return true; + case PSO_Dict : + _handlePSDict (); + return true; + case PSO_Dup : + _handlePSDup (); + return true; + case PSO_Begin : + _handlePSBegin (); + return true; + case PSO_Put : + _handlePSPut (); + return true; + default: break; + } + return false; +} + +const double AIParserBase::getDoubleValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toDouble(); +} + +const int AIParserBase::getIntValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toInt(); +} + +const bool AIParserBase::getBoolValue(void) { + return getIntValue() == 1; +} + +const QString AIParserBase::getStringValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toString(); +} + +const QString AIParserBase::getOperatorValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toOperator(); +} + +AIOperation AIParserBase::getAIOperation (const char *operand) +{ + int i=0; + QString cmpValue (operand); + + for(;;) { AIOperationMapping map = aiMappings[i]; + if (map.op == NULL) return AIO_Other; + if (cmpValue.compare (map.op) == 0) return map.action; + + i++; + } +} + +PSOperation AIParserBase::getPSOperation (const char *operand) +{ + int i=0; + QString cmpValue (operand); + + for(;;) { PSOperationMapping map = psMappings[i]; + if (map.op == NULL) return PSO_Other; + if (cmpValue.compare (map.op) == 0) return map.action; + + i++; + } +} + +CommentOperation AIParserBase::getCommentOperation (const char *command) { + QString data (command); + + signed int index; + + int i=0; + + for(;;) { + CommentOperationMapping map = commentMappings[i]; + if (map.op == NULL) return CO_Other; + index = data.find (map.op); + if (index >= 0) return map.action; + i++; + } +} + +void GStateHandlerBase::gotFillPattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData) { + qDebug ( "got fill pattern %s %f %f %f %f %f %f %f %f %f", pname, px, py, sx, sy, angle, rf, r, k, ka); + arraytoa (transformData); + qDebug ("/got fill pattern"); +} + +void GStateHandlerBase::gotStrokePattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData) { + qDebug ( "got stroke pattern %s %f %f %f %f %f %f %f %f %f", pname, px, py, sx, sy, angle, rf, r, k, ka); + arraytoa (transformData); + qDebug ("/got stroke pattern"); +} + +const char *AIParserBase::getValue (const char *input) { + QString data(input); + + signed int index = data.find (':'); + if (index < 0) return ""; + index++; + while (data.at(index) == ' ') index++; + return data.mid(index).latin1(); +} + +bool AIParserBase::getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury) { + if (input == NULL) return false; + + QString s(input); + if (s.contains ("(atend)")) return false; + QStringList values = QStringList::split (" ", input); + if (values.size() < 5) return false; + llx = values[1].toInt(); + lly = values[2].toInt(); + urx = values[3].toInt(); + ury = values[4].toInt(); + + return true; +} + +bool AIParserBase::getPoint (const char* input, int &x, int &y) { + if (input == NULL) return false; + + QString s(input); + QStringList values = QStringList::split (" ", input); + + if (values.size() < 3) return false; + + x = values[1].toInt(); + y = values[2].toInt(); + + return true; +} + +void AIParserBase::cleanupArrays() +{ + if (m_sink == DS_Array) qDebug ("unclosed array(s)."); + while (m_sink == DS_Array) gotArrayEnd (); + stacktoa (m_stack); +} + +/*Ai88*/ /* void AIParserBase::_handleFontEncoding() +{ + while (m_stack.top().type() != AIElement::Reference) { + m_stack.pop(); + } + + AIElement elem (m_stack.top()); + m_stack.pop(); + const QString &oldFont = elem.toReference(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + const QString &newFont = elem2.toReference(); + + AIElement elem3 (m_stack.top()); + m_stack.pop(); + const QValueVector encodingData = elem3.toElementArray(); + + if (m_textHandler) m_textHandler->gotFontEncoding (encodingData, oldFont.latin1(), newFont.latin1()); +} */ + +void TextHandlerBase::gotFontEncoding (const QValueVector& encodingData, const char*oldFontName, const char*newFontName) +{ + qDebug ("font encoding %s to %s",oldFontName, newFontName); + arraytoa (encodingData); + qDebug ("/font encoding"); +} + +void TextHandlerBase::gotFontDefinition (const char*fontName, double size, double leading, double kerning, TextAlign align) +{ + qDebug ("font definition: name %s size %f leading %f kerning %f align %d", fontName, size, leading, kerning, align); +} + +void TextHandlerBase::gotTextBlockBegin (const QValueVector& transData, TextOperation mode) +{ + qDebug ("text block begin %d",mode); + arraytoa (transData); + qDebug ("/text block begin"); +} + +void TextHandlerBase::gotTextOutput (const char*text, int length) +{ + qDebug ("text output (%s) %d",text,length); +} + +void TextHandlerBase::gotTextBlockEnd () +{ + qDebug ("text block end"); +} + +const void elementtoa (const AIElement &/*data*/) +{ +/* AIElement::Type type = data.type(); + qDebug ("type: %s", AIElement::typeToName (type)); + + switch (type) + { + case AIElement::String : + case AIElement::CString : + case AIElement::Int : + case AIElement::UInt : + case AIElement::Double : + qDebug ("string value : %s",data.toString().latin1()); + break; + case AIElement::Reference : + qDebug ("string value : %s",data.toReference().latin1()); + break; + case AIElement::Operator : + qDebug ("string value : %s",data.toOperator().latin1()); + break; + case AIElement::ElementArray : + arraytoa (data.toElementArray()); + break; + case AIElement::Block : + arraytoa (data.toBlock()); + break; + + default : + qDebug ("could not fetch data"); + } */ +} + +const void arraytoa (const QValueVector &/*data*/) +{ +/* qDebug ("array size is %d ",data.size()); + if (data.size() > 0) + { + qDebug ("[[[[[[[[[[[[[[[[[[[["); + for (uint i=0; i< data.size(); i++) + { + elementtoa (data[i]); + } + qDebug ("]]]]]]]]]]]]]]]]]]]]"); + } */ +} + +const void stacktoa (const QValueStack &/*data*/) +{ +/* qDebug ("stack size is %d",data.size()); + if (data.size() > 0) + { + qDebug ("<<<<<<<<<<<<<<<<<<"); + for (uint i=0; i< data.size(); i++) + { + elementtoa (data[i]); + } + } + qDebug (">>>>>>>>>>>>>>>>>>"); */ +} + +const void stacktoa2 (const QValueStack >&/*data*/) +{ +/* qDebug ("stack size is %d",data.size()); + + if (data.size() > 0) + { + qDebug ("((((((((((((((((((((((("); + for (uint i=0; i< data.size(); i++) + { + arraytoa (data[i]); + } + qDebug (")))))))))))))))))))))))"); + } */ +} + +const void aiotoa (AIOperation &data) +{ + switch (data) + { + case AIO_SetFillColorCMYK : qDebug ("AIO_SetFillColorCMYK"); break; + case AIO_SetStrokeColorCMYK : qDebug ("AIO_SetStrokeColorCMYK"); break; + case AIO_SetFillColorGray : qDebug ("AIO_SetFillColorGray"); break; + case AIO_SetStrokeColorGray : qDebug ("AIO_SetStrokeColorGray"); break; + case AIO_SetFillColorCustom : qDebug ("AIO_SetFillColorCustom"); break; + case AIO_SetStrokeColorCustom : qDebug ("AIO_SetStrokeColorCustom"); break; + case AIO_SetFillPattern : qDebug ("AIO_SetFillPattern"); break; + case AIO_SetStrokePattern : qDebug ("AIO_SetStrokePattern"); break; + case AIO_SetFillOverprinting : qDebug ("AIO_SetFillOverprinting"); break; + case AIO_SetStrokeOverprinting : qDebug ("AIO_SetStrokeOverprinting"); break; + case AIO_SetFlatness : qDebug ("AIO_SetFlatness"); break; + case AIO_SetLineCap : qDebug ("AIO_SetLineCap"); break; + case AIO_SetLineJoin : qDebug ("AIO_SetLineJoin"); break; + case AIO_SetLineWidth : qDebug ("AIO_SetLineWidth"); break; + case AIO_SetMiterLimit : qDebug ("AIO_SetMiterLimit"); break; + case AIO_SetDash : qDebug ("AIO_SetDash"); break; + case AIO_BeginGroupClip : qDebug ("AIO_BeginGroupClip"); break; + case AIO_EndGroupClip : qDebug ("AIO_EndGroupClip"); break; + case AIO_MoveTo : qDebug ("AIO_MoveTo"); break; + case AIO_LineToCorner : qDebug ("AIO_LineToCorner"); break; + case AIO_LineToSmooth : qDebug ("AIO_LineToSmooth"); break; + case AIO_CurveToSmooth : qDebug ("AIO_CurveToSmooth"); break; + case AIO_CurveToCorner : qDebug ("AIO_CurveToCorner"); break; + case AIO_CurveToOmitC1Smooth : qDebug ("AIO_CurveToOmitC1Smooth"); break; + case AIO_CurveToOmitC1Corner : qDebug ("AIO_CurveToOmitC1Corner"); break; + case AIO_CurveToOmitC2Smooth : qDebug ("AIO_CurveToOmitC2Smooth"); break; + case AIO_CurveToOmitC2Corner : qDebug ("AIO_CurveToOmitC2Corner"); break; + case AIO_PathIgnoreNoReset : qDebug ("AIO_PathIgnoreNoReset"); break; + case AIO_PathIgnoreNoResetClose : qDebug ("AIO_PathIgnoreNoResetClose"); break; + case AIO_PathClipPath : qDebug ("AIO_PathClipPath"); break; + case AIO_PathIgnoreReset : qDebug ("AIO_PathIgnoreReset"); break; + case AIO_PathIgnoreResetClose : qDebug ("AIO_PathIgnoreResetClose"); break; + case AIO_PathFillNonZero : qDebug ("AIO_PathFillNonZero"); break; + case AIO_PathFillNonZeroClose : qDebug ("AIO_PathFillNonZeroClose"); break; + case AIO_PathStroke : qDebug ("AIO_PathStroke"); break; + case AIO_PathStrokeClose : qDebug ("AIO_PathStrokeClose"); break; + case AIO_PathFillNoReset : qDebug ("AIO_PathFillNoReset"); break; + case AIO_PathFillNoResetClose : qDebug ("AIO_PathFillNoResetClose"); break; + case AIO_FontEncoding : qDebug ("AIO_FontEncoding"); break; + case AIO_PatternDefinition : qDebug ("AIO_PatternDefinition"); break; + case AIO_SetCurrentText : qDebug ("AIO_SetCurrentText"); break; + case AIO_TextBlockFillStroke : qDebug ("AIO_TextBlockFillStroke"); break; + case AIO_TextBlockFill : qDebug ("AIO_TextBlockFill"); break; + case AIO_TextBlockAppend : qDebug ("AIO_TextBlockAppend"); break; + case AIO_TextBlockIgnore : qDebug ("AIO_TextBlockIgnore"); break; + case AIO_TextBlockStroke : qDebug ("AIO_TextBlockStroke"); break; + case AIO_TextOutput : qDebug ("AIO_TextOutput"); break; + case AIO_TextBlockEnd : qDebug ("AIO_TextBlockEnd"); break; + case AIO_GsaveIncludeDocument : qDebug ("AIO_GsaveIncludeDocument"); break; + case AIO_Grestore : qDebug ("AIO_Grestore"); break; + case AIO_LockElement : qDebug ("AIO_LockElement"); break; + case AIO_SetWindingOrder : qDebug ("AIO_SetWindingOrder"); break; + default : qDebug ("unknown"); + } +} + +const void sttoa (SectionType &data, bool begin) +{ + switch (data) + { + case ST_Setup : begin ? qDebug ("start setup") : qDebug ("end setup"); break; + case ST_Prolog : begin ? qDebug ("start prolog") : qDebug ("end prolog"); break; + case ST_ProcSet : begin ? qDebug ("start procset") : qDebug ("end procset"); break; + case ST_Encoding : begin ? qDebug ("start encoding") : qDebug ("end encoding"); break; + case ST_Pattern : begin ? qDebug ("start pattern") : qDebug ("end pattern"); break; + case ST_Document : begin ? qDebug ("start document") : qDebug ("end document"); break; + case ST_BrushPattern : begin ? qDebug ("start brush pattern") : qDebug ("end brush pattern"); break; + case ST_Gradient : begin ? qDebug ("start gradient") : qDebug ("end gradient"); break; + case ST_Palette : begin ? qDebug ("start palette") : qDebug ("end palette"); break; + case ST_Resource : begin ? qDebug ("start resource") : qDebug ("end resouce"); break; + + default : begin ? qDebug ("unknown") : qDebug ("end unknown"); + } +} + diff --git a/filters/karbon/ai/aiparserbase.h b/filters/karbon/ai/aiparserbase.h new file mode 100644 index 00000000..8d2633f3 --- /dev/null +++ b/filters/karbon/ai/aiparserbase.h @@ -0,0 +1,440 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch枚nberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef AIPARSERBASE_H +#define AIPARSERBASE_H + +#include "ailexer.h" + +#include +#include +#include +#include + +#include "aielement.h" +#include "aicolor.h" + + +const void arraytoa (const QValueVector &data); +const void elementtoa (const AIElement &data); +const void stacktoa (const QValueStack &data); +const void stacktoa2 (const QValueStack >&data); + +class GStateHandlerBase; +class StructureHandlerBase; +class PathHandlerBase; +class MiscGStateHandlerBase; +class DocumentHandlerBase; +class ModuleHandlerBase; +class EmbeddedHandlerBase; +class TextHandlerBase; +class AI88Handler; +class AI3Handler; + +/** + *@author Dirk Sch枚nberger + */ + +typedef enum { PET_MoveTo, PET_LineTo, PET_CurveTo, PET_CurveToOmitC1, PET_CurveToOmitC2 } PathElementType; +typedef enum { PT_Smooth, PT_Corner } PointType; +typedef enum { TO_FillStroke, TO_Fill, TO_Append, TO_Ignore, TO_Stroke } TextOperation; +typedef enum { FM_NonZero=0, FM_EvenOdd=1 } FillMode; +typedef enum { FS_Roman, FS_Kanji } FontScript; + +typedef enum { DS_Array, DS_Block, DS_Other } DataSink; +typedef enum { ST_Setup, ST_Prolog, ST_ProcSet, ST_Encoding, ST_Pattern, ST_Document, ST_BrushPattern, ST_Gradient, ST_Palette, ST_Resource } SectionType; + +typedef enum { TA_HLeft, TA_HCenter, TA_HRight, TA_VTop, TA_VCenter, TA_VBottom } TextAlign; + +#define PC_Cyan 0x0001 +#define PC_Magenta 0x0002 +#define PC_Yellow 0x0004 +#define PC_Black 0x0008 + +typedef enum { + /* AI 88 */ + AIO_SetFillColorCMYK, AIO_SetStrokeColorCMYK, + AIO_SetFillColorGray, AIO_SetStrokeColorGray, + AIO_SetFillColorCustom, AIO_SetStrokeColorCustom, + AIO_SetFillPattern, AIO_SetStrokePattern, + AIO_SetFillOverprinting, AIO_SetStrokeOverprinting, + AIO_SetFlatness, AIO_SetLineCap, AIO_SetLineJoin, + AIO_SetLineWidth, AIO_SetMiterLimit, AIO_SetDash, + AIO_BeginGroupClip, AIO_EndGroupClip, + AIO_MoveTo, + AIO_LineToCorner, + AIO_LineToSmooth, + AIO_CurveToSmooth, + AIO_CurveToCorner, + AIO_CurveToOmitC1Smooth, + AIO_CurveToOmitC1Corner, + AIO_CurveToOmitC2Smooth, + AIO_CurveToOmitC2Corner, + + AIO_PathIgnoreNoReset, AIO_PathIgnoreNoResetClose, + AIO_PathClipPath, + AIO_PathIgnoreReset, AIO_PathIgnoreResetClose, + AIO_PathFillNonZero, AIO_PathFillNonZeroClose, + AIO_PathStroke, AIO_PathStrokeClose, + AIO_PathFillNoReset, AIO_PathFillNoResetClose, + + AIO_FontEncoding, + AIO_PatternDefinition, + + AIO_SetCurrentText, + AIO_TextBlockFillStroke, + AIO_TextBlockFill, + AIO_TextBlockAppend, + AIO_TextBlockIgnore, + AIO_TextBlockStroke, + AIO_TextOutput, + AIO_TextBlockEnd, + + AIO_GsaveIncludeDocument, + AIO_Grestore, + + AIO_LockElement, + + /* AI 3 */ + AIO_SetWindingOrder, + AIO_SetFillMode, + + AIO_BeginGroupNoClip, AIO_EndGroupNoClip, + AIO_BeginCombination, AIO_EndCombination, + + AIO_Other +} AIOperation; + +typedef enum { + PSO_Get, + PSO_Exec, + PSO_Def, + PSO_String, + PSO_Bind, + PSO_Userdict, + PSO_Dict, + PSO_Dup, + PSO_Begin, + PSO_Put, + PSO_Other +} PSOperation; + +typedef enum { + CU_BlackWhite, + CU_Color, + CU_Unknown +} ColorUsage; + +typedef enum { + CO_BeginSetup, CO_EndSetup, + CO_BeginProlog, CO_EndProlog, + CO_BeginProcSet, CO_EndProcSet, + CO_BeginEncoding, CO_EndEncoding, + CO_BeginPattern, CO_EndPattern, + CO_IncludeFile, + CO_BeginDocument, CO_EndDocument, + + CO_Trailer, + CO_BoundingBox, + CO_TemplateBox, + CO_Margin, + CO_Title, + CO_Creator, + CO_Other, +/**/ CO_For, + CO_CreationDate, +/**/ CO_DocumentFonts, +/**/ CO_DocumentFiles, +/**/ CO_ColorUsage, +/**/ CO_DocumentProcSets, +/**/ CO_DocumentSuppliedProcSets, + CO_DocumentProcessColors, +/**/ CO_DocumentCustomColors, +/**/ CO_CMYKCustomColor, +/**/ CO_TileBox, + CO_Continuation, +/**/ CO_Note, + + // AI88 Win +/**/ CO_Template, +/**/ CO_PageOrigin, +/**/ CO_PrinterName, +/**/ CO_PrinterRect, + + // AI8 + CO_BeginBrushPattern, CO_EndBrushPattern, + CO_BeginGradient, CO_EndGradient, + CO_BeginPalette, CO_EndPalette, + + // other + CO_BeginResource, CO_EndResource, + CO_IncludeFont, + CO_IncludeResource, + CO_DocumentNeededResources, + + CO_Ignore +} CommentOperation; + +typedef enum { + CM_DocumentFonts = 1, + CM_DocumentFiles = 2, + CM_DocumentCustomColors = 3, + CM_CMYKCustomColor = 4, + CM_DocumentNeededResources = 5, + CM_None = -1 +} ContinuationMode; + +typedef enum { +/**/ PDO_ColorDefinition, +/**/ PDO_TileDefinition +} PatternDefinitionOperation; + +/**/ +#define PatternTileFilledDefiniton "_" +#define TextSizeUnknown -1 + +/* typedef QValueVector ElementArray; +typedef QValueStack ElementStack; +typedef QValueStack ElementArrayStack; */ + +typedef struct { + PathElementType petype; + union { + struct { + float x, y; + } pointdata; + struct { + float x1, y1, x2, y2, x3, y3; + } bezierdata; + } pevalue; + PointType pttype; +} PathElement; + +class AIParserBase : protected AILexer { + friend class AI88Handler; + friend class AI3Handler; + +protected: + bool m_debug; +private: + bool m_ignoring; + QValueStack m_stack; + QValueStack > m_arrayStack; + QValueStack > m_blockStack; + DataSink m_sink; + QValueList m_modules; + ContinuationMode m_continuationMode; + + const double getDoubleValue(void); + const int getIntValue(void); + const bool getBoolValue(void); + const QString getStringValue(void); + const QString& getReferenceValue(void); + const QString getOperatorValue(void); + +/*Ai88*/ // void _handleSetDash(); +/*Ai88*/ // void _handleGsaveIncludeDocument(); +/*Ai88*/ // void _handleSetStrokeColorCMYK(); +/*Ai88*/ // void _handleSetFillColorCMYK(); +/*Ai88*/ // void _handleSetStrokeColorGray(); +/*Ai88*/ // void _handleSetFillColorGray(); +/*Ai88*/ // void _handleSetStrokeColorCustom(); +/*Ai88*/ // void _handleSetFillColorCustom(); +/*Ai88*/ // void _handleSetFillPattern(); +/*Ai88*/ // void _handleSetStrokePattern(); + +/*Ai88*/ // void _handlePatternDefinition(); +/*Ai88*/ // void _handleFontEncoding(); + + void _handlePSGet(); + void _handlePSExec(); + void _handlePSDef(); + void _handlePSString(); + void _handlePSBind(); + void _handlePSUserdict(); + void _handlePSDict(); + void _handlePSDup(); + void _handlePSBegin(); + void _handlePSPut(); + + void _handleDocumentFonts(const char *data); + void _handleDocumentFiles(const char *data); + void _handleDocumentCustomColors(const char *data); + void _handleCMYKCustomColor(const char *data); + void _handleDocumentProcessColors(const char *data); + void _handleDocumentNeededResources(const char *data); + void _handleIncludeResource(const char *data); + +/*Ai88*/ // void _handleSetCurrentText(); +/*Ai88*/ // void _handleTextBlock (TextOperation to); +/*Ai88*/ // void _handleTextOutput (); + + void _handleCreationDate (const char *data); + + AIOperation getAIOperation (const char *operand); + PSOperation getPSOperation (const char *operand); + CommentOperation getCommentOperation (const char *command); + + bool handlePS (const char *operand); + + const char *getValue (const char *input); + bool getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury); + bool getPoint (const char* input, int &x, int &y); +protected: + void gotComment (const char *value); + void gotIntValue (int value); + void gotDoubleValue (double value); + void gotStringValue (const char *value); + void gotToken (const char *value); + void gotReference (const char *value); + void gotBlockStart (); + void gotBlockEnd (); + void gotArrayStart (); + void gotArrayEnd (); + void gotByte (uchar value); + void gotByteArray (const QByteArray &data); + + GStateHandlerBase *m_gstateHandler; + StructureHandlerBase *m_structureHandler; + PathHandlerBase *m_pathHandler; + MiscGStateHandlerBase *m_miscGStateHandler; + DocumentHandlerBase *m_documentHandler; + ModuleHandlerBase *m_moduleHandler; + EmbeddedHandlerBase *m_embeddedHandler; + TextHandlerBase *m_textHandler; + AI88Handler *m_ai88Handler; + AI3Handler *m_ai3Handler; + +private: + void handleElement (AIElement &element); + void cleanupArrays(); +public: + AIParserBase(); + ~AIParserBase(); + + bool parse (QIODevice& fin); +}; + +const void aiotoa (AIOperation &data); +const void sttoa (SectionType &data, bool begin); + +class GStateHandlerBase +{ + public: + GStateHandlerBase() {} + virtual ~GStateHandlerBase() {} + + virtual void gotFillColor (AIColor &) {} + virtual void gotStrokeColor (AIColor &) {} + virtual void gotFillPattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData); + virtual void gotStrokePattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData); + virtual void gotFlatness (double) {} + virtual void gotLineWidth (double) {} + virtual void gotLineCaps (int) {} + virtual void gotLineJoin (int) {} + virtual void gotMiterLimit (double) {} + virtual void gotWindingOrder (int) {} + virtual void gotDash (const QValueVector& /*dashData*/, double /*phase*/) {} +}; + +class StructureHandlerBase { + public: + StructureHandlerBase() {} + virtual ~StructureHandlerBase() {} + + virtual void gotBeginGroup (bool /*clipping*/) {} + virtual void gotEndGroup (bool /*clipping*/) {} + virtual void gotBeginCombination () {} + virtual void gotEndCombination () {} +}; + +class PathHandlerBase { + public: + PathHandlerBase() {} + virtual ~PathHandlerBase() {} + + virtual void gotPathElement (PathElement &) {} + virtual void gotFillPath (bool /*closed*/, bool /*reset*/) {} + virtual void gotStrokePath (bool /*closed*/) {} + virtual void gotIgnorePath (bool /*closed*/, bool /*reset*/) {} + virtual void gotClipPath (bool /*closed*/) {} + virtual void gotFillMode (FillMode) {} +}; + +class MiscGStateHandlerBase { + public: + MiscGStateHandlerBase() {} + virtual ~MiscGStateHandlerBase() {} + + virtual void gotLockNextObject (bool /*value*/) {} + virtual void gotFillOverprinting (bool /*value*/) {} + virtual void gotStrokeOverprinting (bool /*value*/) {} +}; + +class DocumentHandlerBase { + public: + DocumentHandlerBase() {} + virtual ~DocumentHandlerBase() {} + + virtual void gotBoundingBox (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotTemplateBox (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotMargin (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotPrinterRect (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotPrinterName (const char *) {} + virtual void gotPageOrigin (int /*x*/, int /*y*/) {} + virtual void gotTemplate (const char *) {} + virtual void gotTitle (const char *) {} + virtual void gotCreator (const char *) {} + virtual void gotPatternDefinition (const char */*name*/, const QValueVector& /*layerData*/, double /*llx*/, double /*lly*/, double /*urx*/, double /*ury*/) {} + virtual void gotCreationDate (const char */*val1*/,const char */*val2*/) {} + virtual void gotProcessColors (int /*colors*/) {} +}; + +class ModuleHandlerBase { + public: + ModuleHandlerBase() {} + virtual ~ModuleHandlerBase() {} + + virtual void gotBeginSection (SectionType, const char *) {} + virtual void gotEndSection (SectionType, const char *) {} +}; + +class EmbeddedHandlerBase { + public: + EmbeddedHandlerBase() {} + virtual ~EmbeddedHandlerBase() {} + + virtual void gotGsaveIncludeDocument (const QValueVector& /*transData*/, int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/, const char*/*fileName*/) {} + virtual void gotGrestore () {} +}; + +class TextHandlerBase { + public: + TextHandlerBase() {} + virtual ~TextHandlerBase() {} + + virtual void gotFontEncoding (const QValueVector& encodingData, const char*oldFontName, const char*newFontName); + virtual void gotFontDefinition (const char*fontName, double size, double leading, double kerning, TextAlign align); + virtual void gotTextBlockBegin (const QValueVector& transData, TextOperation mode); + virtual void gotTextOutput (const char*text, int length=-1); + virtual void gotTextBlockEnd (); +}; + +#endif + diff --git a/filters/karbon/ai/karbon_ai_import.desktop b/filters/karbon/ai/karbon_ai_import.desktop new file mode 100644 index 00000000..bec797b2 --- /dev/null +++ b/filters/karbon/ai/karbon_ai_import.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 Illustrator Import Filter +Name[af]=Karbon14 Illustreerder In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 Illustrator 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 Illustrator 胁 Karbon14 +Name[br]=Sil enporzh Illustrator evit Karbon14 +Name[ca]=Filtre d'importaci贸 Illustrator per a Karbon14 +Name[cs]=Importn铆 filtr soubor暖 aplikace Illustrator pro Karbon14 +Name[cy]=Hidlen Fewnforio Illustrator Karbon14 +Name[da]=Karbon14 Illustrator-importfilter +Name[de]=Karbon14 Illustrator-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 Illustrator 蟿慰蠀 Karbon14 +Name[eo]=Importfiltrilo por Karbon-Ilustrilo +Name[es]=Filtro de importaci贸n Karbon14 Illustrator +Name[et]=Karbon14 Illustrator'i impordifilter +Name[eu]=Karbon14 ilustratzailearen inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 鬲氐賵蹖乇诏乇 Karbon14 +Name[fi]=Karbon14 Illustrator -tuontisuodin +Name[fr]=Filtre d'importation Illustrator vers Karbon 14 +Name[fy]=Illustrator-Ymportfilter foar Karbon14 +Name[ga]=Scagaire Iomp贸rt谩la Karbon14 Illustrator +Name[gl]=Filtro de Importaci贸n de Illustrator para Karbon14 +Name[he]=诪住谞谉 讬讬讘讜讗 诪志Illustrator 诇志Karbon14 +Name[hi]=啶曕ぞ啶班啶え 14 啶囙げ啶膏啶熰啶班啶熰ぐ 啶嗋く啶距い 啶涏え啶ㄠ +Name[hr]=Karbon14 Illustrator filtar uvoza +Name[hu]=Karbon14 Illustrator importsz疟r艖 +Name[is]=Karbon14 Illustrator innflutningss铆a +Name[it]=Filtro di importazione Illustrator per Karbon14 +Name[ja]=Karbon14 Illustrator 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣涒嬦灉釣丰瀰釣丰瀼釤掅灇釣熱灦釣涒嬦灍釣樶煉釣氠灦釣斸煁 Karbon 釤♂煠 +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰 Illustrator +Name[lt]=Karbon14 Illustrator importavimo filtras +Name[lv]=Karbon14 Ilustratora importa filtrs +Name[ms]=Penapis Import Karbon14 Illustrator +Name[mt]=Filtru g魔all-importazzjoni Illustrator g魔al Karbon14 +Name[nb]=Illustrator-importfilter for Karbon14 +Name[nds]=Illustrator-Importfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶啶ぞ啶栢啶ぞ啶曕ぐ啷嵿い啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]=Illustrator-importfilter voor Karbon14 +Name[nn]=Illustrator-importfilter for Karbon14 +Name[pl]=Filtr importu formatu Illustrator do Karbon14 +Name[pt]=Filtro de Importa莽茫o de Illustrator para o Karbon14 +Name[pt_BR]=Filtro de Importa莽茫o Illustrator do Karbon14 +Name[ro]=Filtru importare Karbon14 pentru Illustrator +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褎邪泄谢芯胁 Illustrator 胁 Karbon14 +Name[se]=Karbon14:a Illustrator-sisafievrridansilli +Name[sk]=Illustrator filter pre import do Karbon14 +Name[sl]=Uvozni filter Illustrator za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 Illustrator-邪 +Name[sr@Latn]=Karbon14-ov filter za uvoz iz Illustrator-a +Name[sv]=Karbon14 Illustrator-importfilter +Name[ta]=Karbon 14 Illustrator 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 EPS 肖懈谢褌褉懈 袙芯褉懈写芯褌懈 袠谢谢褞褋褌褉邪褌芯褉 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔權赋喙喔傕箟喔 Illustrator 喔傕腑喔囙竸喔侧福喙屶笟喔笝14 +Name[tr]=Karbon14 Illustrator Alma Filtresi +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 Illustrator 写谢褟 Karbon14 +Name[uz]=Karbon14 Illustrator import filteri +Name[uz@cyrillic]=Karbon14 Illustrator 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba Somzobi we Karbon 14 +Name[zh_CN]=Karbon14 Illustrator 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon14 Illustrator 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=application/illustrator +X-KDE-Weight=1 +X-KDE-Library=libkarbonaiimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/ai/karbonaiparserbase.cc b/filters/karbon/ai/karbonaiparserbase.cc new file mode 100644 index 00000000..8c2b5a5f --- /dev/null +++ b/filters/karbon/ai/karbonaiparserbase.cc @@ -0,0 +1,637 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch枚nberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "karbonaiparserbase.h" + +#include +#include +#include +#include +#include +#include "aicolor.h" +#include +#include + +#include + +const void pottoa (PathOutputType &data); + +// generic +KarbonAIParserBase::KarbonAIParserBase() : m_pot(POT_Other), m_ptt (PTT_Output), m_bbox(0,0,612,792), m_emptyFill(), m_emptyStroke() +/* , m_strokeColor(), m_fillColor() */ { + + // A4, 70 dpi +/* m_bbox.llx = 0; + m_bbox.lly = 0; + m_bbox.urx = 612; + m_bbox.ury = 792; */ + +/* m_lineWidth = 0; + m_flatness = 0; + m_lineCaps = 0; + m_lineJoin = 0; + m_miterLimit = 10; */ + m_windingOrder = 0; + + m_fm = FM_NonZero; + + m_curKarbonPath = new VPath( 0L ); + + m_document = new VDocument(); + m_layer = NULL; + m_combination = NULL; + + m_emptyFill.setType (VFill::none); + m_emptyStroke.setType (VStroke::none); + + setupHandlers(); +} + +// generic +KarbonAIParserBase::~KarbonAIParserBase(){ + teardownHandlers(); + delete m_curKarbonPath; + + delete m_document; +} + +// generic +void KarbonAIParserBase::parsingStarted(){ +// qDebug ( getHeader().latin1() ); +} + +// generic +void KarbonAIParserBase::parsingFinished(){ +// qDebug ( getFooter().latin1() ); + + // handle bounding box + if (m_document) + { + kdDebug() << "bbox 1 is " << m_bbox << endl; + + if (m_bbox.width() > 0. ) + m_document->setWidth (m_bbox.width()); + if (m_bbox.height() > 0. ) + m_document->setHeight (m_bbox.height()); + +/* QWMatrix matrix; + matrix.translate (-m_bbox.x(),-m_bbox.y()); + + VTransformNodes translator (matrix); + m_document->accept (translator); */ + VTranslateCmd cmd (0L, -m_bbox.x(), -m_bbox.y()); + m_document->accept (cmd); + } +} + +// generic +QString KarbonAIParserBase::getParamList(Parameters& params){ + QString data(""); + + Parameter *param; + + if (params.count() > 0) + { + + for ( param=params.first(); param != 0; param=params.next() ) { + data += " " + param->first + "=\"" + param->second + "\""; + } + } + + return data; +} + +// generic +void KarbonAIParserBase::gotStartTag (const char *tagName, Parameters& params){ + qDebug ("<%s%s>", tagName, getParamList (params).latin1() ); +} + +// generic +void KarbonAIParserBase::gotEndTag (const char *tagName){ + qDebug ("", tagName ); +} + +// generic +void KarbonAIParserBase::gotSimpleTag (const char *tagName, Parameters& params){ + qDebug ("<%s%s/>", tagName, getParamList (params).latin1() ); +} + +// generic +void KarbonAIParserBase::gotPathElement (PathElement &element){ + switch (element.petype) + { + case PET_MoveTo : + m_curKarbonPath->moveTo (KoPoint (element.pevalue.pointdata.x,element.pevalue.pointdata.y)); + break; + case PET_LineTo : + m_curKarbonPath->lineTo (KoPoint (element.pevalue.pointdata.x,element.pevalue.pointdata.y)); + break; + case PET_CurveTo : + m_curKarbonPath->curveTo (KoPoint (element.pevalue.bezierdata.x1,element.pevalue.bezierdata.y1), + KoPoint (element.pevalue.bezierdata.x2,element.pevalue.bezierdata.y2), + KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3)); + break; + case PET_CurveToOmitC1 : + m_curKarbonPath->curve1To (KoPoint (element.pevalue.bezierdata.x2,element.pevalue.bezierdata.y2), + KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3)); + break; + case PET_CurveToOmitC2 : + m_curKarbonPath->curve2To (KoPoint (element.pevalue.bezierdata.x1,element.pevalue.bezierdata.y1), + KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3)); + break; + } +} + +// generic +void KarbonAIParserBase::gotFillPath (bool closed, bool reset, FillMode /*fm*/){ +// qDebug ("found fill path"); +// if (!reset) qDebug ("retain filled path"); + + if (closed) m_curKarbonPath->close(); + + if (!reset) + m_pot = POT_Filled; + else + { + doOutputCurrentPath2 (POT_Filled); + m_pot = POT_Other; + } +} + +// generic +void KarbonAIParserBase::gotIgnorePath (bool closed, bool reset){ +// qDebug ("found ignore path"); + + if (closed) m_curKarbonPath->close(); + + if (! reset) + m_pot = POT_Other; + else + { + doOutputCurrentPath2 (POT_Ignore); + m_pot = POT_Other; + } +} + +// generic +void KarbonAIParserBase::gotStrokePath (bool closed) { +// qDebug ("found stroke path"); + + if (closed) m_curKarbonPath->close(); + + PathOutputType pot = POT_Stroked; + if (m_pot != POT_Other) + { + pot = POT_FilledStroked; + } + + doOutputCurrentPath2 (pot); + + m_pot = POT_Other; +} + +// generic +void KarbonAIParserBase::gotClipPath (bool /*closed*/){ + + doOutputCurrentPath2 (POT_Clip); +} + +// generic +void KarbonAIParserBase::gotFillColor (AIColor &color){ +// double r, g, b; +// color.toRGB (r,g,b); +// qDebug ("set fillcolor to %f %f %f",r,g,b); +// m_fillColor = color; + + VColor karbonColor = toKarbonColor (color); + m_fill.setColor (karbonColor); +} + +// generic +void KarbonAIParserBase::gotStrokeColor (AIColor &color){ +// double r, g, b; +// color.toRGB (r,g,b); +// qDebug ("set strokecolor to %f %f %f",r,g,b); +// m_strokeColor = color; + + VColor karbonColor = toKarbonColor (color); + m_stroke.setColor (karbonColor); +} + +// generic +void KarbonAIParserBase::gotBoundingBox (int llx, int lly, int urx, int ury){ +/* m_bbox.llx = llx; + m_bbox.lly = lly; + m_bbox.urx = urx; + m_bbox.ury = ury; */ + m_bbox.setCoords(llx,lly,urx,ury); +} + +void KarbonAIParserBase::gotLineWidth (double val){ +// m_lineWidth = val; + m_stroke.setLineWidth (val); +} + +void KarbonAIParserBase::gotFlatness (double /*val*/) +{ +// m_flatness = val; +// m_stroke.setFlatness (val); +} + +void KarbonAIParserBase::gotLineCaps (int val) +{ +// m_lineCaps = val; + VStroke::VLineCap lineCap = VStroke::capButt; + + switch (val) + { + case 0 : lineCap = VStroke::capButt; break; + case 1 : lineCap = VStroke::capRound; break; + case 2 : lineCap = VStroke::capSquare; break; + } + + m_stroke.setLineCap (lineCap); +} + +void KarbonAIParserBase::gotLineJoin (int val) +{ +// m_lineJoin = val; + + VStroke::VLineJoin lineJoin = VStroke::joinMiter; + + switch (val) + { + case 0 : lineJoin = VStroke::joinMiter; break; + case 1 : lineJoin = VStroke::joinRound; break; + case 2 : lineJoin = VStroke::joinBevel; break; + } + + m_stroke.setLineJoin (lineJoin); + +} + +void KarbonAIParserBase::gotMiterLimit (double val) +{ +// m_miterLimit = val; + m_stroke.setMiterLimit (val); +} + +void KarbonAIParserBase::gotWindingOrder (int val) +{ + m_windingOrder = val; +} + +void KarbonAIParserBase::gotBeginGroup (bool clipping) +{ +// qDebug ("start begin group"); + if (clipping) + { + VClipGroup *group = new VClipGroup( 0L ); + m_groupStack.push (group); + } + else + { + VGroup *group = new VGroup( 0L ); + m_groupStack.push (group); + } + +// qDebug ("end begin group"); + +} + +void KarbonAIParserBase::gotEndGroup (bool /*clipping*/) +{ +// qDebug ("start end group"); + + if (m_debug) qDebug ("got end group"); + + if (m_groupStack.isEmpty()) return; + + if (m_debug) qDebug ("got end group 2"); + + VGroup *group = m_groupStack.pop(); + + if (m_debug) qDebug ("got end group 3"); + + if (m_debug) + { + if (!group) qDebug ("group is NULL"); + } + + if (m_groupStack.isEmpty()) + { + if (m_debug) qDebug ("insert object"); + ensureLayer(); + m_layer->append (group); + if (m_debug) qDebug ("/insert object"); + } + else + { + if (m_debug) qDebug ("insert object to group"); + + m_groupStack.top()->append (group); + if (m_debug) qDebug ("/insert object to group"); + } + + if (m_debug) qDebug ("/got end group"); + +// qDebug ("end end group"); +} + +void KarbonAIParserBase::gotBeginCombination () { + m_ptt = PTT_Combine; +} + +void KarbonAIParserBase::gotEndCombination () { +// qDebug ( "got end combination" ); + + m_ptt = PTT_Output; + + if (m_combination != NULL) + { + m_curKarbonPath = m_combination; + doOutputCurrentPath2 (POT_Leave); + } + + m_combination = NULL; +} + + +const VColor KarbonAIParserBase::toKarbonColor (const AIColor &color) +{ + AIColor temp (color); + VColor value; + + double v1, v2, v3, v4; + temp.toCMYK (v1, v2, v3, v4); + + float cv1 = v1; + float cv2 = v2; + float cv3 = v3; + float cv4 = v4; + + value.setColorSpace (VColor::cmyk); + value.set (cv1, cv2, cv3, cv4); + + return value; +} + +void KarbonAIParserBase::doOutputCurrentPath2(PathOutputType type) +{ + ensureLayer(); + + if (type != POT_Leave) + { +// pottoa(type); + + m_curKarbonPath->setStroke(m_emptyStroke); + m_curKarbonPath->setFill(m_emptyFill); + + if ((type != POT_Filled) && (type != POT_Stroked) && (type != POT_FilledStroked)) return; + if ((type == POT_Filled) || (type == POT_FilledStroked)) + { +/* VFill fill; + fill.setColor (toKarbonColor (m_fillColor)); + m_curKarbonPath->setFill(fill); */ +// qDebug ("set filled"); + m_curKarbonPath->setFill(m_fill); + } + + if ((type == POT_Stroked) || (type == POT_FilledStroked)) + { +/* VStroke stroke; + stroke.setColor (toKarbonColor (m_strokeColor)); + m_curKarbonPath->setStroke (stroke); */ +// qDebug ("set stroked"); + m_curKarbonPath->setStroke (m_stroke); + } + } + + if (m_ptt == PTT_Combine) + { +// m_pot |= type; + if (m_combination == NULL) + m_combination = m_curKarbonPath; + else + m_combination->combine (*m_curKarbonPath); + + m_curKarbonPath = new VPath( 0L ); + + return; + } + + ensureLayer(); + + if (m_groupStack.isEmpty()) + { + m_layer->append( m_curKarbonPath ); + } + else + { + m_groupStack.top()->append( m_curKarbonPath ); + } + + m_curKarbonPath = new VPath( 0L ); +} + +bool KarbonAIParserBase::parse (QIODevice& fin, QDomDocument &doc) +{ + + bool res = AIParserBase::parse (fin); + +// qDebug ("document is %s",doc.toString().latin1()); + if (res) + { + qDebug ("before save document"); + doc = m_document->saveXML(); + // add paper info, we always need custom for svg (Rob) + QDomElement paper = doc.createElement( "PAPER" ); + doc.documentElement().appendChild( paper ); + paper.setAttribute( "format", PG_CUSTOM ); + paper.setAttribute( "width", m_document->width() ); + paper.setAttribute( "height", m_document->height() ); + + qDebug ("after save document"); + } + else + { + QDomDocument tempDoc; + doc = tempDoc; + } + + return res; +} + +void KarbonAIParserBase::ensureLayer () +{ + if (!m_layer) + { + m_layer = new VLayer( 0 ); + m_document->insertLayer (m_layer); + } +} + + +void KarbonAIParserBase::setupHandlers() +{ +// qDebug("setupHandler called"); + m_gstateHandler = new KarbonGStateHandler(this); + m_structureHandler = new KarbonStructureHandler(this); + m_pathHandler = new KarbonPathHandler(this); + m_documentHandler = new KarbonDocumentHandler(this); + + m_textHandler = new TextHandlerBase(); + +} + +void KarbonAIParserBase::teardownHandlers() +{ +// qDebug("teardownHandler called"); + delete m_textHandler; + + delete m_gstateHandler; + delete m_structureHandler; + delete m_pathHandler; + delete m_documentHandler; +} + + +void KarbonDocumentHandler::gotBoundingBox (int llx, int lly, int urx, int ury) +{ + delegate->gotBoundingBox(llx,lly,urx,ury); +} + +void KarbonDocumentHandler::gotCreationDate (const char */*val1*/,const char */*val2*/) +{ +// qDebug ("got creation date [%s], [%s]",val1,val2); +} + +void KarbonDocumentHandler::gotProcessColors (int /*colors*/) +{ +/* if (colors && PC_Cyan) qDebug ("contains cyan"); + if (colors && PC_Magenta) qDebug ("contains magenta"); + if (colors && PC_Yellow) qDebug ("contains yellow"); + if (colors && PC_Black) qDebug ("contains black"); */ +} + + +void KarbonGStateHandler::gotFillColor (AIColor &color) +{ + delegate->gotFillColor (color); +} + +void KarbonGStateHandler::gotStrokeColor (AIColor &color) +{ + delegate->gotStrokeColor(color); +} + +void KarbonGStateHandler::gotFlatness (double val) +{ + delegate->gotFlatness(val); +} + +void KarbonGStateHandler::gotLineWidth (double val) +{ + delegate->gotLineWidth(val); +} + +void KarbonGStateHandler::gotLineCaps (int val) +{ + delegate->gotLineCaps(val); +} + +void KarbonGStateHandler::gotLineJoin (int val) +{ + delegate->gotLineJoin(val); +} + +void KarbonGStateHandler::gotMiterLimit (double val) +{ + delegate->gotMiterLimit(val); +} + +void KarbonGStateHandler::gotWindingOrder (int val) +{ + delegate->gotWindingOrder(val); +} + +void KarbonStructureHandler::gotBeginGroup (bool clipping) +{ + delegate->gotBeginGroup(clipping); +} + +void KarbonStructureHandler::gotEndGroup (bool clipping) +{ + delegate->gotEndGroup(clipping); +} + +void KarbonStructureHandler::gotBeginCombination () +{ + delegate->gotBeginCombination(); +} + +void KarbonStructureHandler::gotEndCombination () +{ + delegate->gotEndCombination(); +} + +void KarbonPathHandler::gotPathElement (PathElement &element) +{ + delegate->gotPathElement (element); +} + +void KarbonPathHandler::gotFillPath (bool closed, bool reset) +{ + delegate->gotFillPath(closed, reset, m_fm); +} + +void KarbonPathHandler::gotFillMode (FillMode fm) +{ + m_fm = fm; +} + +void KarbonPathHandler::gotStrokePath (bool closed) +{ + delegate->gotStrokePath(closed); +} + +void KarbonPathHandler::gotIgnorePath (bool closed, bool reset) +{ + delegate->gotIgnorePath(closed, reset); +} + +void KarbonPathHandler::gotClipPath (bool closed) +{ + delegate->gotClipPath(closed); +} + +const void pottoa (PathOutputType &data) +{ + switch (data) + { + case POT_Filled : qDebug ("filled"); break; + case POT_Stroked : qDebug ("stroked"); break; + case POT_FilledStroked : qDebug ("filled/stroked"); break; + case POT_Clip : qDebug ("clip"); break; + case POT_Ignore : qDebug ("ignore"); break; + case POT_Leave : qDebug ("leave"); break; + default : qDebug ("unknown"); + } +} + diff --git a/filters/karbon/ai/karbonaiparserbase.h b/filters/karbon/ai/karbonaiparserbase.h new file mode 100644 index 00000000..4b6f05a9 --- /dev/null +++ b/filters/karbon/ai/karbonaiparserbase.h @@ -0,0 +1,202 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef KARBONAIPARSERBASE_H +#define KARBONAIPARSERBASE_H + +#include +#include +#include +#include + +#include "aicolor.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + *@author + */ +typedef QPair Parameter; +typedef QPtrList Parameters; +typedef QPtrList PathElements; + +typedef enum { POT_Filled = 1, POT_Stroked = 2, POT_FilledStroked = 3, POT_Clip = 4, POT_Ignore = 8, POT_Leave = -1, POT_Other = 0 } PathOutputType; +typedef enum { PTT_Output = 1, PTT_Combine = 2 } PathTransferType; + +// typedef struct { int llx, lly, urx, ury; } BoundingBox; + +class KarbonAIParserBase; +class KarbonGStateHandler; +class KarbonStructureHandler; +class KarbonPathHandler; +class KarbonDocumentHandler; + +class KarbonDocumentHandler : public DocumentHandlerBase +{ + private: + KarbonAIParserBase *delegate; + public: + KarbonDocumentHandler (KarbonAIParserBase *delegate) : DocumentHandlerBase () { this->delegate = delegate; } + + void gotBoundingBox (int llx, int lly, int urx, int ury); + void gotCreationDate (const char *val1,const char *val2); + void gotProcessColors (int colors); +}; + +class KarbonGStateHandler : public GStateHandlerBase +{ + private: + KarbonAIParserBase *delegate; + public: + KarbonGStateHandler (KarbonAIParserBase *delegate) : GStateHandlerBase() { this->delegate = delegate; } + + void gotFillColor (AIColor &color); + void gotStrokeColor (AIColor &color); + + void gotFlatness (double val); + void gotLineWidth (double val); + void gotLineCaps (int val); + void gotLineJoin (int val); + void gotMiterLimit (double val); + void gotWindingOrder (int val); + +}; + +class KarbonStructureHandler : public StructureHandlerBase +{ + private: + KarbonAIParserBase *delegate; + public: + KarbonStructureHandler (KarbonAIParserBase *delegate) : StructureHandlerBase() { this->delegate = delegate; } + + void gotBeginGroup (bool clipping); + void gotEndGroup (bool clipping); + void gotBeginCombination (); + void gotEndCombination (); + +}; + +class KarbonPathHandler : public PathHandlerBase +{ + private: + KarbonAIParserBase *delegate; + FillMode m_fm; + public: + KarbonPathHandler (KarbonAIParserBase *delegate) : PathHandlerBase () + { + m_fm = FM_EvenOdd; + this->delegate = delegate; + } + + void gotPathElement (PathElement &element); + void gotFillPath (bool closed, bool reset); + void gotStrokePath (bool closed); + void gotIgnorePath (bool closed, bool reset); + void gotClipPath (bool closed); + void gotFillMode (FillMode fm); + +}; + +class KarbonAIParserBase : public AIParserBase { + friend class KarbonDocumentHandler; + friend class KarbonGStateHandler; + friend class KarbonStructureHandler; + friend class KarbonPathHandler; + +public: + KarbonAIParserBase(); + ~KarbonAIParserBase(); + + bool parse (QIODevice& fin, QDomDocument &doc); +private: + VPath *m_curKarbonPath; + VDocument *m_document; + VLayer *m_layer; + VPath *m_combination; + QPtrStack m_groupStack; + + FillMode m_fm; + PathOutputType m_pot; + PathTransferType m_ptt; + +// BoundingBox m_bbox; + KoRect m_bbox; + VFill m_fill; + VStroke m_stroke; +/** AIColor m_strokeColor; + AIColor m_fillColor; + double m_lineWidth; + double m_flatness; + int m_lineCaps; + int m_lineJoin; + double m_miterLimit; */ + int m_windingOrder; + + void doOutputCurrentPath2(PathOutputType type); + const VColor toKarbonColor (const AIColor &color); + void ensureLayer (); + + VFill m_emptyFill; + VStroke m_emptyStroke; + +protected: + void setupHandlers(); + void teardownHandlers(); + + void parsingStarted(); + void parsingFinished(); + + QString getParamList(Parameters& params); + + void gotPathElement (PathElement &element); + void gotFillPath (bool closed, bool reset, FillMode fm = FM_NonZero); + void gotStrokePath (bool closed); + void gotIgnorePath (bool closed, bool reset); + void gotClipPath (bool closed); + + void gotFillColor (AIColor &color); + void gotStrokeColor (AIColor &color); + void gotBoundingBox (int llx, int lly, int urx, int ury); + + void gotFlatness (double val); + void gotLineWidth (double val); + void gotLineCaps (int val); + void gotLineJoin (int val); + void gotMiterLimit (double val); + void gotWindingOrder (int val); + void gotBeginGroup (bool clipping); + void gotEndGroup (bool clipping); + void gotBeginCombination (); + void gotEndCombination (); + + virtual void gotStartTag (const char *tagName, Parameters& params); + virtual void gotEndTag (const char *tagName); + virtual void gotSimpleTag (const char *tagName, Parameters& params); +}; + +#endif diff --git a/filters/karbon/applixgraphics/Makefile.am b/filters/karbon/applixgraphics/Makefile.am new file mode 100644 index 00000000..b3c03f38 --- /dev/null +++ b/filters/karbon/applixgraphics/Makefile.am @@ -0,0 +1,20 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes) +libapplixgraphicimport_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) + +####### Files + +kde_module_LTLIBRARIES = libapplixgraphicimport.la + +libapplixgraphicimport_la_SOURCES = applixgraphicimport.cc +libapplixgraphicimport_la_LIBADD = $(KOFFICE_LIBS) +noinst_HEADERS = applixgraphicimport.h + +METASOURCES = AUTO + +service_DATA = kontour_applixgraphic_import.desktop +servicedir = $(kde_servicesdir) + +messages: rc.cpp + $(XGETTEXT) *.cc *.cpp -o $(podir)/kontourapplixgraphicsfilter.pot diff --git a/filters/karbon/applixgraphics/applixgraphicimport.cc b/filters/karbon/applixgraphics/applixgraphicimport.cc new file mode 100644 index 00000000..2ee52685 --- /dev/null +++ b/filters/karbon/applixgraphics/applixgraphicimport.cc @@ -0,0 +1,832 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Enno Bartels + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ +#define FAKTOR 39.4 // 1000 dots/inch / 2.54 cm/inch = 394 dots/cm = 39.4 dots/mm + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef KGenericFactory APPLIXGRAPHICImportFactory; +K_EXPORT_COMPONENT_FACTORY( libapplixgraphicimport, APPLIXGRAPHICImportFactory( "kofficefilters" ) ) + +int s_area = 30517; + +/****************************************************************************** + * class: applixGraphicsLine function: constructor * + ****************************************************************************** + * * + * Short description : - Initialize all variables * + * * + * * + ******************************************************************************/ +applixGraphicsLine::applixGraphicsLine() +{ + offX = 0; + offY = 0; + reColor = 0; + thickNess = 1; // ?? + + for (int i=0; i<5; i++) + { + ptX[0] = 0; + ptY[0] = 0; + } +} + + + + + +/****************************************************************************** + * class: applixGraphicsRect function: constructor * + ****************************************************************************** + * * + * Short description : - Initialize all variables * + * * + * * + ******************************************************************************/ +applixGraphicsRect::applixGraphicsRect() : applixGraphicsLine() +{ + for (int i=0; i<7;i++) + { + bf[i] = 0; + lf[i] = 0; + } + + for (int i=0; i<5;i++) + { + sh[i] = 0; + } + + for (int i=0; i<8;i++) + { + pa[i] = 0; + } + + for (int i=0; i<3;i++) + { + vs[i] = 0; + } + + for (int i=0; i<2;i++) + { + xr[i] = 0; + } + +} + + + + + +/****************************************************************************** + * class: APPLIXGRAPHICImport function: constructor * + ****************************************************************************** + * * + * Short description : constructor * + * * + * * + ******************************************************************************/ +APPLIXGRAPHICImport::APPLIXGRAPHICImport (KoFilter *, const char *, const QStringList&) : + KoFilter () +{ + +} + + + +/****************************************************************************** + * class: APPLIXGRAPHICImport function: filter * + ****************************************************************************** + * * + * Short description : - Read inputfile, * + * - convert it to kontour fileformat and * + * - save it * + * * + * * + ******************************************************************************/ +KoFilter::ConversionStatus APPLIXGRAPHICImport::convert( const QCString& from, const QCString& to ) +{ + + // Check MIME Types + if (to!="application/x-karbon" || from!="application/x-applixgraphic") + return KoFilter::NotImplemented; + + // Open Inputfile + QFile in (m_chain->inputFile()); + if (!in.open (IO_ReadOnly) ) + { + kdError(30502) << "Unable to open input file!" << endl; + in.close (); + return KoFilter::FileNotFound; + } + + QString str; + + // Create karbon header + str += "\n"; + str += "\n"; + str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; + str += " \n"; + + QTextStream stream(&in); + int step = in.size()/50; + int value = 0; + int i = 0; + int picture_rememberer = 0; + int pos = 0; + int vers[3] = { 0, 0, 0 }; + int rueck; // Check scanf inputs + QString mystr; + + // Read Headline + mystr = stream.readLine (); + rueck = sscanf ((const char *) mystr.latin1() , + "*BEGIN GRAPHICS VERSION=%d/%d ENCODING=%dBIT", + &vers[0], &vers[1], &vers[2]); + kdDebug (s_area) << "Versions info: " << vers[0] << vers[1] << vers[2] << endl; + + // Check the headline + if (rueck <= 0) + { + kdDebug (s_area) << "Header not correkt - May be it is not an applixgraphics file" << endl; + kdDebug (s_area) << "Headerline: " << mystr << endl; + + QMessageBox::critical (0L, "Applixgraphics header problem", + QString ("The Applixgraphics header is not correct. " + "May be it is not an applixgraphics file!
" + "This is the header line I did read:
%1").arg(mystr.latin1()), + "Comma"); + + // i18n( "What is the separator used in this file ? First line is \n%1" ).arg(firstLine), + return KoFilter::StupidError; + } + + while (!stream.atEnd ()) + { + ++i; + + // Read one line + mystr = stream.readLine (); + kdDebug (s_area) << "<<" << mystr << ">>" << endl; + + if (mystr == "PICTURE") picture_rememberer = 1; + else if (mystr == "END PICTURE") picture_rememberer = 0; + + + // Detect a point at the first place of the ascii_linie + else if ((mystr[0] == '.') && (picture_rememberer == 1)) + { + // Delete point at the first place of the ascii_linie + mystr.remove (0, 1); + kdDebug (s_area) << "StartPoint recognized <" << mystr << ">" << endl; + + + /******************************************************************** + * Element "LINE" * + ********************************************************************/ + if (mystr.startsWith ("LINE AT") ) + { + // Define + applixGraphicsLine agLine; + + //str += agLine.read (int, mystr); + + kdDebug (s_area) << " Linie recognized: " << endl; + mystr.remove (0, 8); + //mystr.remove (0, 7); + + + //remove_pos = mystr.find ('('); + //mystr.remove (0, remove_pos); + //agLine.offX= mystr.toInt(); + + //remove_pos = mystr.find (','); + //mystr.remove (0, remove_pos); + //agLine.offY= mystr.toInt(); + rueck = sscanf ((const char *) mystr.latin1(), "(%d,%d)", + &agLine.offX, &agLine.offY); + kdDebug (s_area) << " Offset -> x:" << agLine.offX << " y:" << agLine.offY << endl; + if (rueck <= 0) + { + kdDebug (s_area) << "LINE tag not correkt" << endl; + kdDebug (s_area) << "LINE: <" << mystr << ">" << endl; + return KoFilter::StupidError; + } + + do + { + // Get acutal position + pos = in.at (); + // Read one line + mystr = stream.readLine (); + + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor "; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agLine.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agLine.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Unknown RECOLOR item <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" THICKNESS ") ) + { + kdDebug (s_area) << " Thickness: "; + mystr.remove (0, 11); + sscanf ((const char *) mystr.latin1(), "%d", &agLine.thickNess); + // + kdDebug (s_area) << agLine.thickNess << endl; + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *) mystr.latin1(), "(%d,%d)(%d,%d)", + &agLine.ptX[0], &agLine.ptY[0], &agLine.ptX[1], &agLine.ptY[1]); + kdDebug (s_area) << agLine.ptX[0] << " " << agLine.ptY[0] << " " << agLine.ptX[1] << " " << agLine.ptY[1] << endl; + } + + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + str += " \n"; +// str += " "; + str += " \n"; + +// str += " "; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + + + + str += " \n"; + + + } + /******************************************************************** + * Element RPOL Vieleck * + ********************************************************************/ + if (mystr.startsWith ("RPOL AT") ) + { + // Define + applixGraphicsLine agLine; + int nsides; + + //str += agLine.read (int, mystr); + + kdDebug (s_area) << " RPOL recognized: " << endl; + mystr.remove (0, 8); + + rueck = sscanf ((const char *) mystr.latin1(), "(%d,%d)", + &agLine.offX, &agLine.offY); + kdDebug (s_area) << " Offset -> x:" << agLine.offX << " y:" << agLine.offY << endl; + if (rueck <= 0) + { + kdDebug (s_area) << "RPOL tag not correkt " << endl; + kdDebug (s_area) << "RPOL: <" << mystr << ">" << endl; + return KoFilter::StupidError; + } + + do + { + // Akutelle Position bestimmen + pos = in.at (); + // Zeile einlesen + mystr = stream.readLine (); +//checkSubElement (mystr, subelements) + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor " ; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agLine.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agLine.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" NSIDES") ) + { + kdDebug (s_area) << " NSIDES: " ; + mystr.remove (0, 8); + pos = sscanf ((const char *) mystr.latin1(), "%d", &nsides); + kdDebug (s_area) << nsides << "(" << pos << ")" << endl; + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *) mystr.latin1(), "(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)", + &agLine.ptX[0], &agLine.ptY[0], &agLine.ptX[1], &agLine.ptY[1], + &agLine.ptX[2], &agLine.ptY[2], &agLine.ptX[3], &agLine.ptY[3], + &agLine.ptX[4], &agLine.ptY[4]); + kdDebug (s_area) << agLine.ptX[0] << " " << agLine.ptY[0] << " " << + agLine.ptX[1] << " " << agLine.ptY[1] << " " << + agLine.ptX[2] << " " << agLine.ptY[2] << " " << + agLine.ptX[3] << " " << agLine.ptY[3] << " " << + agLine.ptX[4] << " " << agLine.ptY[4] << endl; + } +//checkSubElement() ende + + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + + + // An die Position zurueckspringen + in.at (pos); + + int a, b; + float wink=0.0; + int *x = new int[nsides]; + int *y = new int[nsides]; + a = agLine.ptX[2] / 2; + b = agLine.ptY[2] / 2; + for (int i=0; i\n"; + for (int i=0; i\n"; + } + + str += " \n"; + str += " \n"; + str += " \n"; + + + + str += " \n"; + + + } + /******************************************************************** + * Element TXT - Text * + ********************************************************************/ + else if (mystr.startsWith ("TXT AT") ) + { + // Define + //applixGraphicsText agText; + applixGraphicsLine agText; + + kdDebug (s_area) << " Habe Text erkannt (keine Werte uebernommen)" << endl; + mystr.remove (0, 7); + sscanf ((const char *) mystr.latin1(), "(%d,%d)", + &agText.offX, &agText.offY); + kdDebug (s_area) << " Offset -> x:" << agText.offX << " y:" << agText.offY << endl; + + + do + { + // Aktuelle Position bestimmen + pos = in.at (); + // Zeile einlesen + mystr = stream.readLine (); +//checkSubElement() + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor : "; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agText.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agText.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" .STR") ) + { + kdDebug (s_area) << " Textstring: "; + + // Zeile einlesen + agText.str = stream.readLine (); + agText.str.remove (0, 3); // delete ront part + kdDebug (s_area) << agText.str; + } + else if (mystr.startsWith (" THICKNESS ") ) + { + kdDebug (s_area) << " Thickness: "; + mystr.remove (0, 11); + sscanf ((const char *) mystr.latin1(), "%d", &agText.thickNess); + kdDebug (s_area) << agText.thickNess << endl; + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *) mystr.latin1(), "(%d,%d)(%d,%d)", + &agText.ptX[0], &agText.ptY[0], &agText.ptX[1], &agText.ptY[1]); + kdDebug (s_area) << agText.ptX[0] << " " << agText.ptY[0] << " " << agText.ptX[1] << " " << agText.ptY[1]; + } +//checkSubElement() ende + + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + + } + + /******************************************************************** + * Element rectangle * + ********************************************************************/ + else if (mystr.startsWith ("RECT AT")) + { + applixGraphicsRect agRect; + + kdDebug (s_area) << " Habe Rectangle erkannt " << endl; + mystr.remove (0, 8); + rueck = sscanf ((const char *)mystr.latin1(), "(%d,%d)", &agRect.offX, &agRect.offY); + if (rueck < 1) kdDebug (s_area) <<"Fehler im String <" << mystr.latin1() << ">" << endl; + kdDebug (s_area) << " Offset -> x:" << agRect.offX << " y:" << agRect.offY << endl; + + + do + { + // Akutelle Position bestimmen + pos = in.at (); + // read one line + mystr = stream.readLine (); + +//checkSubElement() + // option RECOLOR + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) <<(" Recolor : "); + mystr.remove (0, 9); + if (mystr == "ON") + { kdDebug (s_area) << "On" << endl; agRect.reColor = true;} + else if (mystr == "OFF") + { kdDebug (s_area) << "Off" << endl; agRect.reColor = false;} + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + // option BACKFILL + else if (mystr.startsWith (" BACKFILL ") ) + { + kdDebug (s_area) <<(" Backfill: "); + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d %d %d>", + &agRect.bf[0], &agRect.bf[1], &agRect.bf[2], + &agRect.bf[3], &agRect.bf[4], &agRect.bf[5], + &agRect.bf[6]); + kdDebug (s_area) << agRect.bf[0] << " " << agRect.bf[1] << " " << + agRect.bf[2] << " " << agRect.bf[3] << " " << + agRect.bf[4] << " " << agRect.bf[5] << " " << + agRect.bf[6]; + + } + // option LINEFILL + else if (mystr.startsWith (" LINEFILL ") ) + { + kdDebug (s_area) << " Linefill: "; + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d %d %d>", + &agRect.lf[0], &agRect.lf[1], &agRect.lf[2], + &agRect.lf[3], &agRect.lf[4], &agRect.lf[5], + &agRect.lf[6]); + kdDebug (s_area) << agRect.lf[0] << " " << agRect.lf[1] << " " << + agRect.lf[2] << " " << agRect.lf[3] << " " << + agRect.lf[4] << " " << agRect.lf[5] << " " << + agRect.lf[6]; + + } + // option SHADOW + else if (mystr.startsWith (" SHADOW ") ) + { + kdDebug (s_area) << " Shadow : "; + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d>", + &agRect.sh[0], &agRect.sh[1], &agRect.sh[2], + &agRect.sh[3], &agRect.sh[4]); + kdDebug (s_area) << agRect.sh[0] << " " << agRect.sh[1] << " " << + agRect.sh[2] << " " << agRect.sh[3] << " " << + agRect.sh[4]; + } + // option PARA + else if (mystr.startsWith (" PARA ") ) + { + kdDebug (s_area) << " Para : "; + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d %d %d %d>", + &agRect.pa[0], &agRect.pa[1], &agRect.pa[2], + &agRect.pa[3], &agRect.pa[4], &agRect.pa[5], + &agRect.pa[6], &agRect.pa[7]); + kdDebug (s_area) << agRect.pa[0] << " " << agRect.pa[1] << " " << + agRect.pa[2] << " " << agRect.pa[3] << " " << + agRect.pa[4] << " " << agRect.pa[5] << " " << + agRect.pa[6] << " " << agRect.pa[7] ; + + } + // option THICKNESS + else if (mystr.startsWith (" THICKNESS ") ) + { + kdDebug (s_area) << " Thickness: "; + mystr.remove (0, 11); + sscanf ((const char *) mystr.latin1(), "%d", &agRect.thickNess); + kdDebug (s_area) << agRect.thickNess << endl; + } + // option V_SPACE + else if (mystr.startsWith (" V_SPACE ") ) + { + kdDebug (s_area) << " V_Space : "; + mystr.remove (0, 9); + sscanf ((const char *)mystr.latin1(), "(%d %d %d)", + &agRect.vs[0], &agRect.vs[1], &agRect.vs[2]); + kdDebug (s_area) << agRect.vs[0] << " " << agRect.vs[1] << " " << agRect.vs[2]; + } + // option XYRAD + else if (mystr.startsWith (" XYRAD ") ) + { + kdDebug (s_area) << " XYRad : "; + mystr.remove (0, 7); + sscanf ((const char *)mystr.latin1(), "<%d %d>", + &agRect.xr[0], &agRect.xr[1]); + kdDebug (s_area) << agRect.xr[0] << " " << agRect.xr[1]; + } + // option PNTS + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *)mystr.latin1(), "(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)", + &agRect.ptX[0], &agRect.ptY[0], &agRect.ptX[1], &agRect.ptY[1], + &agRect.ptX[2], &agRect.ptY[2], &agRect.ptX[3], &agRect.ptY[3], + &agRect.ptX[4], &agRect.ptY[4]); + kdDebug (s_area) << agRect.ptX[0] << " " << agRect.ptY[0] << " " << + agRect.ptX[1] << " " << agRect.ptY[1] << " " << + agRect.ptX[2] << " " << agRect.ptY[2] << " " << + agRect.ptX[3] << " " << agRect.ptY[3] << " " << + agRect.ptX[4] << " " << agRect.ptY[4] << endl; + } + +//checkSubElement() ende + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + str += " \n"; + str += " \n"; + + str += " \n"; + + str += " \n"; + + str += " \n"; + + str += " \n"; + + + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + + + + + + + } + /******************************************************************** + * Element ELL - Ellipse * + ********************************************************************/ + else if (mystr.startsWith ("ELL AT")) + { + applixGraphicsRect agEll; + + kdDebug (s_area) << " Habe ELL erkannt (keine Werte uebernommen " << endl; + mystr.remove (0, 7); + sscanf ((const char *)mystr.latin1(), "(%d,%d)", + &agEll.offX, &agEll.offY); + kdDebug (s_area) << " Offset -> x:" << agEll.offX << " y:" << agEll.offY << endl; + + do + { + // Aktuelle Position bestimmen + pos = in.at (); + // read one line + mystr = stream.readLine (); + +//checkSubElement() + // option RECOLOR + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor: "; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agEll.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agEll.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) <<(" Pnts : "); + mystr.remove (0, 6); + // + sscanf ((const char *)mystr.latin1(), "(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)", + &agEll.ptX[0], &agEll.ptY[0], &agEll.ptX[1], &agEll.ptY[1], + &agEll.ptX[2], &agEll.ptY[2], &agEll.ptX[3], &agEll.ptY[3], + &agEll.ptX[4], &agEll.ptY[4]); + kdDebug (s_area) << agEll.ptX[0] << " " << agEll.ptY[0] << " " << + agEll.ptX[1] << " " << agEll.ptY[1] << " " << + agEll.ptX[2] << " " << agEll.ptY[2] << " " << + agEll.ptX[3] << " " << agEll.ptY[3] << " " << + agEll.ptX[4] << " " << agEll.ptY[4] << endl; + + } +//checkSubElement() ende + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + // ??? + + } + else + { + kdDebug (s_area) << "Unbekannt : " << mystr << endl; + } + + } + + + if (i>step) + { + i=0; + value+=2; + emit sigProgress (value); + } + } + emit sigProgress(100); + + str += "
\n"; + str += "
\n"; +// str += "\n"; + + kdDebug (s_area) << "Text " << str.utf8() << endl; + + KoStoreDevice* out= m_chain->storageFile( "root", KoStore::Write ); + if (!out) + { + kdError(s_area) << "Unable to open output file!" << endl; + in.close (); + return KoFilter::StorageCreationError; + } + + QCString cstring = str.utf8(); + out->writeBlock ( (const char*)cstring, cstring.size() - 1 ); + + in.close (); + return KoFilter::OK; +} + +#include + + + + diff --git a/filters/karbon/applixgraphics/applixgraphicimport.h b/filters/karbon/applixgraphics/applixgraphicimport.h new file mode 100644 index 00000000..a65e26db --- /dev/null +++ b/filters/karbon/applixgraphics/applixgraphicimport.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Enno Bartels + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef APPLIXGRAPHICIMPORT_H +#define APPLIXGRAPHICIMPORT_H + +#include + + +class APPLIXGRAPHICImport : public KoFilter { + + Q_OBJECT + +public: + APPLIXGRAPHICImport (KoFilter *parent, const char *name, const QStringList&); + virtual ~APPLIXGRAPHICImport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + + + + +// Kleinstes Objekt +class applixGraphicsLine +{ + public: + int offX; + int offY; + int reColor; + int thickNess; + int ptX[5]; + int ptY[5]; + QString str; + + applixGraphicsLine (); // Constructor +}; + +class applixGraphicsRect : public applixGraphicsLine +{ + public: + int bf[7]; + int lf[7]; + + int sh[6]; + + int pa[8]; + int vs[3]; + + int xr[2]; //XYRAD + + applixGraphicsRect (); // Constructor +}; + +#endif // APPLIXGRAPHICIMPORT_H diff --git a/filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop b/filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop new file mode 100644 index 00000000..e7d51294 --- /dev/null +++ b/filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +Type=Service +Name=Kontour Applixgraphics Import Filter +Name[af]=Kontoer Applixgrafika In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 Applixgraphics 賱丿賶 Kontour +Name[az]=Kontour Applixgraphics Alma S眉zg蓹ci +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 Applixgraphics 胁 Kontour +Name[br]=Sil enporzh Applixgraphics evit Kontour +Name[ca]=Filtre d'importaci贸 Applixgraphics per a Kontour +Name[cs]=Importn铆 filtr Applixgraphics pro Kontour +Name[cy]=Hidlen Fewnforio Applixgraphics Kontour +Name[da]=Kontour Applixgraphics-importfilter +Name[de]=Kontour Applixgraphics-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 Applixgraphics 蟿慰蠀 Kontour +Name[eo]=Apliks-grafiko-importfiltrilo por Kontour +Name[es]=Filtro de importaci贸n Applixgraphics de Kontour +Name[et]=Kontouri Applixgraphics'i impordifilter +Name[eu]=Kontour Applixgraphics-en inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Kontour Applixgraphics +Name[fi]=Kontour Applixgraphics -tuontisuodin +Name[fr]=Filtre d'importation Applix Graphics vers Kontour +Name[fy]=Kontour Applixgrafysk-Ymportfilter +Name[ga]=Scagaire Iomp贸rt谩la Kontour +Name[gl]=Filtro de Importaci贸n de Applixgraphics para Kontour +Name[he]=诪住谞谉 讬讬讘讜讗 诪志Applixgraphics 诇志Kontour +Name[hi]=啶曕え啷嵿啷傕ぐ 啶忇お啷嵿げ啶苦啷嵿じ啶椸啶班ぞ啶ぜ啶苦啷嵿じ 啶嗋く啶距い 啶ぜ啶苦げ啷嵿啶 +Name[hr]=Kontour Aplixgraphics filtar uvoza +Name[hu]=Kontour Applix Graphics importsz疟r艖 +Name[is]=Kontour Applixgraphics innflutningss铆a +Name[it]=Filtro di importazione Applixgraphics per Kontour +Name[ja]=Kontour Applixgraphics 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 Applixgraphics 釣熱灅釤掅灇釣夺灁釤 Kontour +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰 Applixgraphics 嗪傕涵嗪囙簛嗪侧簷嗷佮簳嗷夃骸嗪汗嗪 K +Name[lt]=Kontour Applixgraphics importo filtras +Name[lv]=Kontour Applixgraphics importa filtrs +Name[ms]=Penapis Import Kontour Applixgraphics +Name[mt]=Filtru g魔all-importazzjoni ta' Applixgraphics 摹o Kontour +Name[nb]=Applixgraphics-importfilter for Kontour +Name[nds]=Applixgraphics-Importfilter f枚r Kontour +Name[ne]=啶班啶ぐ啷囙啶 啶忇お啷嵿げ啶苦啷嵿じ啶椸啶班ぞ啶た啶曕啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]=Kontour Applixgraphics-importfilter +Name[nn]=Applixgraphics-importfilter for Kontour +Name[pl]=Filtr importu formatu Applixgraphics do Kontour +Name[pt]=Filtro de Importa莽茫o de Applixgraphics para o Kontour +Name[pt_BR]=Filtro de importa莽茫o de aplicativos gr谩ficos para o Kontour +Name[ro]=Filtru importare Kontour pentru Applixgraphics +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褎邪泄谢芯胁 Applixgraphics 胁 Kontour +Name[se]=Kontour:a Applixgraphics-sisafievrridansilli +Name[sk]=Applixgraphics filter pre import pre Kontour +Name[sl]=Uvozni filter Applixgraphics za Kontour +Name[sr]=Kontour-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 Applixgraphics-邪 +Name[sr@Latn]=Kontour-ov filter za uvoz iz Applixgraphics-a +Name[sv]=Kontour Applixgrafik-importfilter +Name[ta]=Kontour Applixgraphics 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=肖懈谢褌褉懈 袙芯褉懈写芯褌懈 Applixgraphics +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔權赋喙喔傕箟喔 Applixgraphics 喔傕腑喔囙抚喔侧笖喔犩覆喔 K +Name[tr]=Kontour Applixgraphics Alma S眉zgeci +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 Applixgraphics 写谢褟 Kontour +Name[uz]=Kontour Applixgraphics import filteri +Name[uz@cyrillic]=Kontour Applixgraphics 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[ven]=Filithra yau dzhenisa ya Kontour Applixgraphics +Name[xh]=Isihluzi sokurhweba se Kontour Applixgraphics +Name[zh_CN]=Kontour Applixgraphics 鍥惧舰瀵煎叆杩囨护鍣 +Name[zh_TW]=Kontour Applix 鍦栧舰鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-kontour +X-KDE-Import=application/x-applixgraphics +X-KDE-Weight=1 +X-KDE-Library=libapplixgraphicimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/applixgraphics/status.html b/filters/karbon/applixgraphics/status.html new file mode 100644 index 00000000..1c4bde9c --- /dev/null +++ b/filters/karbon/applixgraphics/status.html @@ -0,0 +1,175 @@ + + + + + KOffice filters status: ApplixGraphics FILTER + + +  + +
+
+

+ KOffice filters status:   ApplixGraphics FILTER +

+
+ +
+ + + Import | + Export + + +


+
+ +Up +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ Import ApplixGraphics for karbon
+
+
+
Last update11 feb 2001
Features- Can import simple ApplixGraphics documents
Todo- Get format and style information and add this into kontour
History + + + + + + + + + + + + + + + + +
27jan2003 :  Changed the intern settings of this filter from kontour to karbon
+ Moved print function to kdDebug (area=30517) functions
+
11feb2001 :  Written a filter that only can filter simple applixgraphics files +
+ +
Authors Enno Bartels
LinksFileformat discription
Progress report -
+
+
+Up + +


+ +
+


+ + +
+ +
+ +Up +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
Export kontour to ApplixGraphics

+
+
Last update-
FeaturesNone
TodoEverything
History-
Authors-
Links-
Progress report ---
+
+
+Up + + + diff --git a/filters/karbon/eps/Makefile.am b/filters/karbon/eps/Makefile.am new file mode 100644 index 00000000..3749dfdc --- /dev/null +++ b/filters/karbon/eps/Makefile.am @@ -0,0 +1,37 @@ +kde_module_LTLIBRARIES = \ + libkarbonepsexport.la \ + libkarbonepsimport.la + +libkarbonepsexport_la_SOURCES = \ + epsexport.cc \ + epsexportdlg.cc + +libkarbonepsexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonepsexport_la_LIBADD = $(LIB_KOFFICEUI) ../../../karbon/libkarboncommon.la + +libkarbonepsimport_la_SOURCES = epsimport.cc pscommentlexer.cc +libkarbonepsimport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonepsimport_la_LIBADD = $(LIB_KOFFICEUI) + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = \ + karbon_eps_export.desktop \ + karbon_eps_import.desktop \ + karbon_ps_import.desktop + +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + epsexport.h \ + epsexportdlg.h \ + epsimport.h \ + pscommentlexer.h + +METASOURCES = AUTO diff --git a/filters/karbon/eps/epsexport.cc b/filters/karbon/eps/epsexport.cc new file mode 100644 index 00000000..8ded1772 --- /dev/null +++ b/filters/karbon/eps/epsexport.cc @@ -0,0 +1,481 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include // For creation date/time. +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "epsexport.h" +#include "epsexportdlg.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vfill.h" +#include "vgroup.h" +#include "vlayer.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vstroke.h" +#include "vtext.h" +#include "vcomputeboundingbox.h" + +// Define PostScript level1 operators. +static char l1_newpath = 'N'; +static char l1_closepath = 'C'; +static char l1_moveto = 'm'; +static char l1_curveto = 'c'; +static char l1_lineto = 'l'; +static char l1_stroke = 's'; +static char l1_fill = 'f'; +//static char l1_eofill = 'e'; +static char l1_setlinewidth = 'w'; +static char l1_setdash = 'd'; +static char l1_setrgbcolor = 'r'; +static char l1_gsave = 'S'; +static char l1_grestore = 'R'; + + +class EpsExportFactory : KGenericFactory +{ +public: + EpsExportFactory( void ) + : KGenericFactory( "karbonepsexport" ) + {} + +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + + +K_EXPORT_COMPONENT_FACTORY( libkarbonepsexport, EpsExportFactory() ) + + +EpsExport::EpsExport( KoFilter*, const char*, const QStringList& ) + : KoFilter(), m_exportHidden( true ) +{ +} + +KoFilter::ConversionStatus +EpsExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/x-eps" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + + if( !storeIn ) + return KoFilter::StupidError; + + + KoFilter::ConversionStatus status = KoFilter::OK; + + // Ask questions about PS level etc. + EpsExportDlg* dialog = new EpsExportDlg(); + + QApplication::setOverrideCursor( Qt::arrowCursor ); + + if( dialog->exec() ) + { + // Which PostScript level to support? + m_psLevel = dialog->psLevel() + 1; + m_exportHidden = dialog->exportHidden(); + + QFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + QApplication::restoreOverrideCursor(); + delete( dialog ); + + return KoFilter::StupidError; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QTextStream( &fileOut ); + + // Load the document. + VDocument doc; + doc.load( docNode ); + + // Process the document. + doc.accept( *this ); + + delete m_stream; + fileOut.close(); + } + else + { + // Dialog cancelled. + status = KoFilter::UserCancelled; + } + + QApplication::restoreOverrideCursor(); + delete( dialog ); + + return status; +} + +void +EpsExport::visitVDocument( VDocument& document ) +{ + // calculate the documents bounding box + VComputeBoundingBox bbox( ! m_exportHidden ); + document.accept( bbox ); + const KoRect &rect = bbox.boundingRect(); + + // Print a header. + *m_stream << + "%!PS-Adobe-3.0 EPSF-3.0\n" + "%%BoundingBox: " << + // Round down. + qRound( rect.left() - 0.5 ) << " " << + qRound( rect.top() - 0.5 ) << " " << + // Round up. + qRound( rect.right() + 0.5 ) << " " << + qRound( rect.bottom() + 0.5 ) << "\n" << + "%%HiResBoundingBox: " << + rect.left() << " " << + rect.top() << " " << + rect.right() << " " << + rect.bottom() << "\n" + "%%Creator: Karbon14 EPS Exportfilter 0.5" + << endl; + + // Process document info. + KoStoreDevice* storeIn; + storeIn = m_chain->storageFile( "documentinfo.xml", KoStore::Read ); + + if( storeIn ) + { + QDomDocument domIn; + domIn.setContent( storeIn ); + + KoDocumentInfo docInfo; + docInfo.load( domIn ); + + KoDocumentInfoAuthor* authorPage = + static_cast( docInfo.page( "author" ) ); + + // Get creation date/time = "now". + QDateTime now( QDateTime::currentDateTime() ); + + *m_stream << + "%%CreationDate: (" << now.toString( Qt::LocalDate ) << ")\n" + "%%For: (" << authorPage->fullName() << ") (" << authorPage->company() << ")\n" + "%%Title: (" << docInfo.title() << ")" + << endl; + } + + + // Print operator definitions. + *m_stream << + "\n" + "/" << l1_newpath << " {newpath} def\n" + "/" << l1_closepath << " {closepath} def\n" + "/" << l1_moveto << " {moveto} def\n" + "/" << l1_curveto << " {curveto} def\n" + "/" << l1_lineto << " {lineto} def\n" + "/" << l1_stroke << " {stroke} def\n" + "/" << l1_fill << " {fill} def\n" + "/" << l1_setlinewidth << " {setlinewidth} def\n" + "/" << l1_setdash << " {setdash} def\n" + "/" << l1_setrgbcolor << " {setrgbcolor} def\n" + "/" << l1_gsave << " {gsave} def\n" + "/" << l1_grestore << " {grestore} def\n" + << endl; + + // Export layers. + VVisitor::visitVDocument( document ); + + // Finished. + *m_stream << + "%%EOF" + << endl; +} + +void +EpsExport::visitVGroup( VGroup& group ) +{ + VObjectListIterator itr( group.objects() ); + + for( ; itr.current(); ++itr ) + { + // do not export hidden child objects + if( ! m_exportHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +EpsExport::visitVLayer( VLayer& layer ) +{ + // do not export hidden layers + if( ! m_exportHidden && ! isVisible( &layer ) ) + return; + + VObjectListIterator itr( layer.objects() ); + + for( ; itr.current(); ++itr ) + { + // do not export hidden objects + if( ! m_exportHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +EpsExport::visitVPath( VPath& composite ) +{ + *m_stream << l1_newpath << "\n"; + + VVisitor::visitVPath( composite ); + + getFill( *composite.fill() ); + getStroke( *composite.stroke() ); + + *m_stream << endl; +} + +void +EpsExport::visitVSubpath( VSubpath& path ) +{ + // Export segments. + VSubpathIterator itr( path ); + + for( ; itr.current(); ++itr ) + { + VSegment *segment = itr.current(); + if ( segment->isCurve() ) { + *m_stream << + itr.current()->point( 0 ).x() << " " << + itr.current()->point( 0 ).y() << " " << + itr.current()->point( 1 ).x() << " " << + itr.current()->point( 1 ).y() << " " << + itr.current()->knot().x() << " " << + itr.current()->knot().y() << " " << + l1_curveto << "\n"; + } else if ( segment->isLine() ) { + *m_stream << + itr.current()->knot().x() << " " << + itr.current()->knot().y() << " " << + l1_lineto << "\n"; + } else if ( segment->isBegin() ) { + *m_stream << + itr.current()->knot().x() << " " << + itr.current()->knot().y() << " " << + l1_moveto << "\n"; + } + } + + if( path.isClosed() ) + *m_stream << l1_closepath << "\n"; +} + +void +EpsExport::visitVText( VText& text ) +{ + // TODO: currently we only export the glyphs if available. + + // Export the glyphs (= VPaths). + VPathListIterator itr( text.glyphs() ); + + for( ; itr.current(); ++itr ) + { + visit( *itr.current() ); + } +} + +void +EpsExport::getStroke( const VStroke& stroke ) +{ + // Solid stroke. + if( stroke.type() == VStroke::solid ) + { + // Dash pattern. + *m_stream << "["; + + const QValueList& + array( stroke.dashPattern().array() ); + + QValueListConstIterator itr = array.begin(); + for( ; itr != array.end(); ++itr ) + *m_stream << *itr << " "; + + *m_stream << + "] " << stroke.dashPattern().offset() << + " " << l1_setdash << " "; + + getColor( stroke.color() ); + + // "setlinewidth", "stroke". + *m_stream << + " " << stroke.lineWidth() << + " " << l1_setlinewidth << + " " << l1_stroke << "\n"; + } + else if( stroke.type() == VStroke::grad ) + { + if( m_psLevel == 3 ) + { + + } + } +} + +void +EpsExport::getFill( const VFill& fill ) +{ + // Solid fill. + if( fill.type() == VFill::solid ) + { + // "gsave". + *m_stream << l1_gsave << " "; + + // "setrgbcolor". + getColor( fill.color() ); + + // "fill", "grestore". + *m_stream << " " << l1_fill << " " << l1_grestore << "\n"; + } + // Gradient. + else if( fill.type() == VFill::grad ) + { + if( m_psLevel == 3 ) + { + // "gsave". + *m_stream << l1_gsave << " "; + + VGradient grad = fill.gradient(); + QPtrVector ramp = grad.colorStops(); + if( ramp.size() < 2 ) + { + if( ramp.size() == 1 ) + getColor( ramp[0]->color ); + } + if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 ) + { + // Gradient with more than two colors or asymmetrical midpoint. + for( uint i = 1;i < ramp.size();i++ ) + { + char name[15]; + sprintf( name, "Function%d", 2 * i - 1 ); + + VColorStop stop1 = *ramp[i - 1]; + VColorStop stop2 = *ramp[i]; + VColor mid; + mid.set( 0.5 * ( stop1.color[0] + stop2.color[0] ), 0.5 * ( stop1.color[1] + stop2.color[1] ), 0.5 * ( stop1.color[2] + stop2.color[2] ) ); + *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n" + << "\t/Domain [ 0 1 ] def\n" << "\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " " + << stop1.color[2] << " ] def\n" << "\t/C1 [ " << mid[0] << " " << mid[1] << " " + << mid[2] << " ] def\n" << "\t/N 1 def\n" << "end\n"; + + sprintf( name, "Function%d", 2 * i ); + + *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n" << "\t/Domain [ 0 1 ] def\n" + << "\t/C0 [ " << mid[0] << " " << mid[1] << " " << mid[2] << " ] def\n" << "\t/C1 [ " << stop2.color[0] << " " + << stop2.color[1] << " " << stop2.color[2] << " ] def\n" << "\t/N 1 def\n" << "end\n"; + } + } + if( grad.type() == VGradient::linear ) + *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 2\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ " + << grad.origin().x() << " " << grad.origin().y() << " " << grad.vector().x() << " " << grad.vector().y() << " ]\n\t/Extend[ true true ]\n" << "\t/Function <<\n"; + else if( grad.type() == VGradient::radial ) + { + double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) ); + *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 3\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ " + << grad.origin().x() << " " << grad.origin().y() << " 0.0 " << grad.origin().x() << " " << grad.origin().y() + << " " << r << "]\n\t\t/Extend [ false true ]\n" << "\t/Function <<\n"; + } + if( ramp.size() == 2 && ramp[0]->midPoint == 0.5 ) + { + // Gradient with only two colors and symmetrical midpoint. + VColorStop stop1 = *ramp[0]; + VColorStop stop2 = *ramp[1]; + *m_stream << "\t\t/FunctionType 2\n" << "\t\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " " << stop1.color[2] + << " ]\n" << "\t\t/C1 [ " << stop2.color[0] << " " << stop2.color[1] << " " << stop2.color[2] << " ]\n" << "\t\t/N 1\n"; + } + else if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 ) + { + // Gradient with more than two colors or asymmetrical midpoint. + *m_stream << "\t\t/FunctionType 3\n" << "\t\t/Functions [ "; + for( uint i = 1; i < ( 2 * ramp.size() - 1 );i++ ) + *m_stream << "Function" << i << " "; + *m_stream << "]\n" << "\t\t/Bounds ["; + for( uint i = 0;i < ramp.size() - 1;i++ ) + { + VColorStop stop = *ramp[i]; + if( i > 0 ) + *m_stream << " " << stop.rampPoint; + *m_stream << " " << ( stop.rampPoint + ( ramp[i + 1]->rampPoint - stop.rampPoint ) * stop.midPoint ); + } + *m_stream << " ]\n" << "\t\t/Encode [ "; + for( uint i = 0;i < 2 * ramp.size() - 2;i++ ) + *m_stream << "0 1 "; + *m_stream << "]\n"; + } + *m_stream << "\t\t/Domain [ " << ramp[0]->rampPoint << " " + << ramp[ramp.size() - 1]->rampPoint << " ]\n" << "\t>>\n" << ">>\n"; + // "shfill", "grestore". + *m_stream << " shfill " << l1_grestore << "\n"; + } + } +} + +void +EpsExport::getColor( const VColor& color ) +{ + VColor copy( color ); + copy.setColorSpace( VColor::rgb ); + + *m_stream << + copy[0] << " " << + copy[1] << " " << + copy[2] << " " << l1_setrgbcolor; +} + +bool +EpsExport::isVisible( const VObject* object ) const +{ + return object->state() != VObject::hidden && object->state() != VObject::hidden_locked; +} + +#include "epsexport.moc" diff --git a/filters/karbon/eps/epsexport.h b/filters/karbon/eps/epsexport.h new file mode 100644 index 00000000..b2dd4919 --- /dev/null +++ b/filters/karbon/eps/epsexport.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __EPSEXPORT_H__ +#define __EPSEXPORT_H__ + + +#include + +#include "vvisitor.h" + +class QTextStream; +class VColor; +class VPath; +class VDocument; +class VFill; +class VGroup; +class VLayer; +class VSubpath; +class VStroke; +class VText; + + +class EpsExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + EpsExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~EpsExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + virtual void visitVPath( VPath& composite ); + virtual void visitVDocument( VDocument& document ); + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVText( VText& text ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVLayer( VLayer& layer ); + + void getStroke( const VStroke& stroke ); + void getFill( const VFill& fill ); + void getColor( const VColor& color ); + + bool isVisible( const VObject* object ) const; + + QTextStream* m_stream; + + uint m_psLevel; + bool m_exportHidden; +}; + +#endif + diff --git a/filters/karbon/eps/epsexportdlg.cc b/filters/karbon/eps/epsexportdlg.cc new file mode 100644 index 00000000..2fb34e14 --- /dev/null +++ b/filters/karbon/eps/epsexportdlg.cc @@ -0,0 +1,65 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include +#include + +#include +#include + +#include "epsexportdlg.h" + + +EpsExportDlg::EpsExportDlg( QWidget* parent, const char* name ) + : KDialogBase( parent, name, true, i18n( "EPS Export" ), Ok | Cancel ) +{ + QVBox* page = makeVBoxMainWidget(); + + m_psLevelButtons = new QButtonGroup( 1, QGroupBox::Horizontal, + i18n( "Options" ), page ); + + QRadioButton* radio; + radio = new QRadioButton( i18n( "PostScript level 1" ), m_psLevelButtons ); + radio = new QRadioButton( i18n( "PostScript level 2" ), m_psLevelButtons ); + radio = new QRadioButton( i18n( "PostScript level 3" ), m_psLevelButtons ); + + m_hiddenExport = new QCheckBox( i18n( "Export hidden layers" ), page ); + m_hiddenExport->setChecked( true ); + + m_psLevelButtons->setRadioButtonExclusive( true ); + m_psLevelButtons->setButton( 2 ); +} + +uint +EpsExportDlg::psLevel() const +{ + return static_cast( + m_psLevelButtons->id( m_psLevelButtons->selected() ) ); +} + +bool +EpsExportDlg::exportHidden() const +{ + return m_hiddenExport->isChecked(); +} +#include "epsexportdlg.moc" + diff --git a/filters/karbon/eps/epsexportdlg.h b/filters/karbon/eps/epsexportdlg.h new file mode 100644 index 00000000..332ca882 --- /dev/null +++ b/filters/karbon/eps/epsexportdlg.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __VEPSEXPORTDLG_H__ +#define __VEPSEXPORTDLG_H__ + +#include + + +class QButtonGroup; +class QCheckBox; + +class EpsExportDlg : public KDialogBase +{ + Q_OBJECT + +public: + EpsExportDlg( QWidget* parent = 0L, const char* name = 0L ); + + uint psLevel() const; + bool exportHidden() const; +private: + QButtonGroup* m_psLevelButtons; + QCheckBox* m_hiddenExport; +}; + +#endif + diff --git a/filters/karbon/eps/epsimport.cc b/filters/karbon/eps/epsimport.cc new file mode 100644 index 00000000..2ff34a94 --- /dev/null +++ b/filters/karbon/eps/epsimport.cc @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "epsimport.h" +#include "pscommentlexer.h" + +class EpsImportFactory : KGenericFactory +{ +public: + EpsImportFactory( void ) + : KGenericFactory( "karbonepsimport" ) + {} + +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libkarbonepsimport, EpsImportFactory() ) + +EpsImport::EpsImport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ +} + +EpsImport::~EpsImport() +{ +} + +KoFilter::ConversionStatus +EpsImport::convert( const QCString& from, const QCString& to ) +{ + if( + to != "application/illustrator" || + ( + from != "image/x-eps" && + from != "application/postscript" ) ) + { + return KoFilter::NotImplemented; + } + + // Copy input filename: + QString input = m_chain->inputFile(); + + + // EPS original bounding box + int llx = -1, lly = -1, urx = -1, ury = -1; + BoundingBoxExtractor extractor; + + QFile file (input); + + if ( file.open(IO_ReadOnly) ) + { + extractor.parse (file); + llx = extractor.llx(); + lly = extractor.lly(); + urx = extractor.urx(); + ury = extractor.ury(); + file.close(); + } + else + qDebug ("file could not be opened"); + + // sed filter + QString sedFilter = QString ("sed -e \"s/%%BoundingBox: 0 0 612 792/%%BoundingBox: %1 %2 %3 %4/g\""). + arg(llx).arg(lly).arg(urx).arg(ury); + + // Build ghostscript call to convert ps/eps -> ai: + QString command( + "gs -q -P- -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dNODISPLAY ps2ai.ps "); + command += KProcess::quote(input); + command += " | "; + command += sedFilter; + command += " > "; + command += KProcess::quote(m_chain->outputFile()); + + qDebug ("command to execute is (%s)", QFile::encodeName(command).data()); + + // Execute it: + if( !system( QFile::encodeName(command)) ) + return KoFilter::OK; + else + return KoFilter::StupidError; +} + +#include "epsimport.moc" + diff --git a/filters/karbon/eps/epsimport.h b/filters/karbon/eps/epsimport.h new file mode 100644 index 00000000..15673297 --- /dev/null +++ b/filters/karbon/eps/epsimport.h @@ -0,0 +1,42 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __EPSIMPORT_H__ +#define __EPSIMPORT_H__ + +#include + +#include + +class QDomElement; +class QTextStream; + +class EpsImport : public KoFilter +{ + Q_OBJECT + +public: + EpsImport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~EpsImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif + diff --git a/filters/karbon/eps/karbon_eps_export.desktop b/filters/karbon/eps/karbon_eps_export.desktop new file mode 100644 index 00000000..4ee7d6f3 --- /dev/null +++ b/filters/karbon/eps/karbon_eps_export.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 EPS Export Filter +Name[af]=Karbon14 Eps Voer uit Filter +Name[ar]=賲賽乇賿卮賻丨 鬲氐丿賷乇 EPS 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 械泻褋锌芯褉褌懈褉邪薪械 芯褌 Karbon14 胁 EPS +Name[br]=Sil ezporzh EPS evit Karbon14 +Name[ca]=Filtre d'exportaci贸 EPS per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu EPS pro Karbon14 +Name[cy]=Hidlen Allforio EPS Karbon14 +Name[da]=Karbon14 EPS-eksportfilter +Name[de]=Karbon14 EPS-Exportfilter +Name[el]=桅委位蟿蟻慰 蔚尉伪纬蠅纬萎蟼 EPS 蟿慰蠀 Karbon14 +Name[eo]=Karbon-EPS-eksportfiltrilo +Name[es]=Filtro de exportaci贸n EPS de Karbon14 +Name[et]=Karbon14 EPS-i ekspordifilter +Name[eu]=Karbon14-en EPS esportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 氐丕丿乇丕鬲 Karbon14 EPS +Name[fi]=Karbon14 EPS -vientisuodin +Name[fr]=Filtre d'exportation EPS de Karbon 14 +Name[fy]=EPS-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easp贸rt谩la EPS Karbon14 +Name[gl]=Filtro de Exportaci贸n de EPS para Karbon14 +Name[he]=诪住谞谉 讬讬爪讜讗 诪志Karbon14 诇志EPS +Name[hr]=Karbon14 EPS filtar izvoza +Name[hu]=Karbon14 EPS exportsz疟r艖 +Name[is]=Karbon14 EPS 煤tflutningss铆a +Name[it]=Filtro di esportazione EPS per Karbon14 +Name[ja]=Karbon14 EPS 銈ㄣ偗銈广儩銉笺儓銉曘偅銉偪 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩焷釣 EPS 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lo]= 嗪曕夯嗪о簳嗪簢嗪佮翰嗪權邯嗪秽粓嗪囙涵嗪簛 EPS 嗪傕涵嗪囙簞嗪侧寒嗷屶簹嗪簷14 +Name[lt]=Karbon14 EPS eksportavimo filtras +Name[lv]=Karbon14 EPS eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 EPS +Name[mt]=Filtru g魔all-esportazzjoni ta' EPS minn 摹o Karbon14 +Name[nb]=EPS-eksportfiler for Karbon14 +Name[nds]=EPS-Exportfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶囙お啶苦啶 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=EPS-exportfilter voor Karbon14 +Name[nn]=EPS-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu EPS z Karbon14 +Name[pt]=Filtro de Exporta莽茫o de EPS para o Karbon14 +Name[pt_BR]=Filtro de Exporta莽茫o EPS do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru EPS +Name[ru]=肖懈谢褜褌褉 褝泻褋锌芯褉褌邪 褉懈褋褍薪泻芯胁 Karbon14 胁 EPS +Name[se]=Karbon14:a EPS-olggosfievrridansilli +Name[sk]=EPS filter pre export z Karbon14 +Name[sl]=Izvozni filter EPS za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 懈蟹胁芯蟹 褍 EPS +Name[sr@Latn]=Karbon14-ov filter za izvoz u EPS +Name[sv]=Karbon14 EPS-exportfilter +Name[ta]=Karbon EPS 喈掂疅喈苦畷喈熰瘝喈熰 喈忇喁嵿喁佮喈む +Name[tg]=Karbon14 EPS 肖懈谢褌褉懈 小芯写懈褉芯褌 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔箞喔囙腑喔竵 EPS 喔傕腑喔囙竸喔侧福喙屶笟喔笝14 +Name[tr]=Karbon14 EPS Aktarma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 EPS 写谢褟 Karbon14 +Name[uz]=Karbon14 EPS eksport filteri +Name[uz@cyrillic]=Karbon14 EPS 褝泻褋锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba ngaphandle se Karbon14 EPS +Name[zh_CN]=Karbon14 EPS 瀵煎嚭杩囨护鍣 +Name[zh_TW]=Karbon14 EPS 鍖嚭閬庢烤绋嬪紡 +X-KDE-Export=image/x-eps +X-KDE-Import=application/x-karbon +X-KDE-Weight=1 +X-KDE-Library=libkarbonepsexport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/eps/karbon_eps_import.desktop b/filters/karbon/eps/karbon_eps_import.desktop new file mode 100644 index 00000000..83cae529 --- /dev/null +++ b/filters/karbon/eps/karbon_eps_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 EPS Import Filter +Name[af]=Karbon14 Eps In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 EPS 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 EPS 胁 Karbon14 +Name[br]=Sil enporzh EPS evit Karbon14 +Name[ca]=Filtre d'importaci贸 EPS per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu EPS pro Karbon14 +Name[cy]=Hidlen Fewnforio EPS Karbon14 +Name[da]=Karbon14 EPS-importfilter +Name[de]=Karbon14 EPS-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 EPS 蟿慰蠀 Karbon14 +Name[eo]=Karbon-EPS-importfiltrilo +Name[es]=Filtro de importaci贸n de Karbon14 EPS +Name[et]=Karbon14 EPS-i impordifilter +Name[eu]=Karbon14-en EPS inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon14 EPS +Name[fi]=Karbon14 EPS -tuontisuodin +Name[fr]=Filtre d'importation EPS de Karbon 14 +Name[fy]=EPS-Ymportfilter foar Karbon14 +Name[ga]=Scagaire Iomp贸rt谩la EPS Karbon14 +Name[gl]=Filtro de Importaci贸n de EPS para Karbon14 +Name[he]=诪住谞谉 讬讬讘讜讗 诪志EPS 诇志Karbon14 +Name[hr]=Karbon14 EPS filtar uvoza +Name[hu]=Karbon14 EPS importsz疟r艖 +Name[is]=Karbon14 EPS innflutningss铆a +Name[it]=Filtro di importazione EPS per Karbon14 +Name[ja]=Karbon14 EPS 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 EPS 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰 EPS 嗪傕涵嗪囙簞嗪侧寒嗷屶簹嗪簷14 +Name[lt]=Karbon14 EPS importavimo filtras +Name[lv]=Karbon14 EPS importa filtrs +Name[ms]=Penapis Import Karbon14 EPS +Name[mt]=Filtru g魔all-importazzjoni ta' EPS g魔al Karbon14 +Name[nb]=EPS-importfilter for Karbon14 +Name[nds]=EPS-Importfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶囙お啶苦啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]=EPS-importfilter voor Karbon14 +Name[nn]=EPS-eksportfilter for Karbon14 +Name[pl]=Filtr importu formatu EPS do Karbon14 +Name[pt]=Filtro de Importa莽茫o de EPS para o Karbon14 +Name[pt_BR]=Filtro de Importa莽茫o EPS do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru EPS +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 EPS 胁 Karbon14 +Name[se]=Karbon14:a EPS-sisafievrridansilli +Name[sk]=EPS filter pre export z Karbon14 +Name[sl]=Uvozni filter EPS za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 EPS-邪 +Name[sr@Latn]=Karbon14-ov filter za uvoz iz EPS-a +Name[sv]=Karbon14 EPS-exportfilter +Name[ta]=Karbon 14 EPS 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 EPS 肖懈谢褌褉懈 袙芯褉懈写芯褌 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔權赋喙喔傕箟喔 EPS 喔傕腑喔囙竸喔侧福喙屶笟喔笝14 +Name[tr]=Karbon14 EPS Alma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 EPS 写谢褟 Karbon14 +Name[uz]=Karbon14 EPS import filteri +Name[uz@cyrillic]=Karbon14 EPS 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba se Karbon14 EPS +Name[zh_CN]=Karbon14 EPS 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon14 EPS 鍖嚭閬庢烤绋嬪紡 +X-KDE-Export=application/illustrator +X-KDE-Import=image/x-eps +X-KDE-Weight=1 +X-KDE-Library=libkarbonepsimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/eps/karbon_ps_import.desktop b/filters/karbon/eps/karbon_ps_import.desktop new file mode 100644 index 00000000..1599fcca --- /dev/null +++ b/filters/karbon/eps/karbon_ps_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 EPS Import Filter +Name[af]=Karbon14 Eps In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 EPS 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 EPS 胁 Karbon14 +Name[br]=Sil enporzh EPS evit Karbon14 +Name[ca]=Filtre d'importaci贸 EPS per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu EPS pro Karbon14 +Name[cy]=Hidlen Fewnforio EPS Karbon14 +Name[da]=Karbon14 EPS-importfilter +Name[de]=Karbon14 EPS-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 EPS 蟿慰蠀 Karbon14 +Name[eo]=Karbon-EPS-importfiltrilo +Name[es]=Filtro de importaci贸n de Karbon14 EPS +Name[et]=Karbon14 EPS-i impordifilter +Name[eu]=Karbon14-en EPS inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon14 EPS +Name[fi]=Karbon14 EPS -tuontisuodin +Name[fr]=Filtre d'importation EPS de Karbon 14 +Name[fy]=EPS-Ymportfilter foar Karbon14 +Name[ga]=Scagaire Iomp贸rt谩la EPS Karbon14 +Name[gl]=Filtro de Importaci贸n de EPS para Karbon14 +Name[he]=诪住谞谉 讬讬讘讜讗 诪志EPS 诇志Karbon14 +Name[hr]=Karbon14 EPS filtar uvoza +Name[hu]=Karbon14 EPS importsz疟r艖 +Name[is]=Karbon14 EPS innflutningss铆a +Name[it]=Filtro di importazione EPS per Karbon14 +Name[ja]=Karbon14 EPS 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 EPS 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰 EPS 嗪傕涵嗪囙簞嗪侧寒嗷屶簹嗪簷14 +Name[lt]=Karbon14 EPS importavimo filtras +Name[lv]=Karbon14 EPS importa filtrs +Name[ms]=Penapis Import Karbon14 EPS +Name[mt]=Filtru g魔all-importazzjoni ta' EPS g魔al Karbon14 +Name[nb]=EPS-importfilter for Karbon14 +Name[nds]=EPS-Importfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶囙お啶苦啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]=EPS-importfilter voor Karbon14 +Name[nn]=EPS-eksportfilter for Karbon14 +Name[pl]=Filtr importu formatu EPS do Karbon14 +Name[pt]=Filtro de Importa莽茫o de EPS para o Karbon14 +Name[pt_BR]=Filtro de Importa莽茫o EPS do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru EPS +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 EPS 胁 Karbon14 +Name[se]=Karbon14:a EPS-sisafievrridansilli +Name[sk]=EPS filter pre export z Karbon14 +Name[sl]=Uvozni filter EPS za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 EPS-邪 +Name[sr@Latn]=Karbon14-ov filter za uvoz iz EPS-a +Name[sv]=Karbon14 EPS-exportfilter +Name[ta]=Karbon 14 EPS 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 EPS 肖懈谢褌褉懈 袙芯褉懈写芯褌 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔權赋喙喔傕箟喔 EPS 喔傕腑喔囙竸喔侧福喙屶笟喔笝14 +Name[tr]=Karbon14 EPS Alma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 EPS 写谢褟 Karbon14 +Name[uz]=Karbon14 EPS import filteri +Name[uz@cyrillic]=Karbon14 EPS 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba se Karbon14 EPS +Name[zh_CN]=Karbon14 EPS 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon14 EPS 鍖嚭閬庢烤绋嬪紡 +X-KDE-Export=application/illustrator +X-KDE-Import=application/postscript +X-KDE-Weight=1 +X-KDE-Library=libkarbonepsimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/eps/pscommentlexer.cc b/filters/karbon/eps/pscommentlexer.cc new file mode 100644 index 00000000..46d993dc --- /dev/null +++ b/filters/karbon/eps/pscommentlexer.cc @@ -0,0 +1,324 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include "pscommentlexer.h" + +#define CATEGORY_WHITESPACE -1 +#define CATEGORY_ALPHA -2 +#define CATEGORY_DIGIT -3 +#define CATEGORY_SPECIAL -4 +#define CATEGORY_LETTERHEX -5 +#define CATEGORY_INTTOOLONG -6 + +#define CATEGORY_ANY -127 + +#define MAX_INTLEN 9 +#define MIN_HEXCHARS 6 + +#define STOP 0 + +int iswhitespace(char c){ + return (c==' ')||(c=='\n')||(c=='\t')||(c=='\r'); +} + +int isSpecial(char c){ + return (c=='*')||(c=='_')||(c=='?')||(c=='~')||(c=='-')||(c=='^')||(c=='`')||(c=='!')||(c=='.')||(c=='@')||(c=='&')||(c=='$')||(c=='='); +} + +int isletterhex(char c){ + return (c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F'); +} + +const char*statetoa (State state){ + switch (state) + { + case State_Comment : return "comment"; + case State_CommentEncodedChar : return "encoded char (comment)"; + default : return "unknown"; + } +} + +typedef struct { + State oldState; + char c; + State newState; + Action action; +} Transition; + +static Transition transitions[] = { + { State_Comment, '\n', State_Start, Action_Output}, + { State_Comment, '\r', State_Start, Action_Output}, + { State_Comment, '\\', State_CommentEncodedChar, Action_InitTemp}, + { State_Comment, CATEGORY_ANY, State_Comment, Action_Copy}, + { State_CommentEncodedChar, '\\', State_Comment, Action_Copy}, + { State_CommentEncodedChar, CATEGORY_DIGIT, State_CommentEncodedChar, Action_CopyTemp}, + { State_CommentEncodedChar, CATEGORY_ANY, State_Comment, Action_DecodeUnget}, + { State_Start, '%', State_Comment, Action_Ignore}, + { State_Start, CATEGORY_ANY, State_Start, Action_Ignore}, + { State_Start, STOP, State_Start, Action_Abort} +}; + +PSCommentLexer::PSCommentLexer(){ +} +PSCommentLexer::~PSCommentLexer(){ +} + +bool PSCommentLexer::parse (QIODevice& fin){ + char c; + + m_buffer.clear(); + m_curState = State_Start; + + parsingStarted(); + + while (!fin.atEnd()) + { + c = fin.getch (); + +// qDebug ("got %c", c); + + State newState; + Action action; + + nextStep (c, &newState, &action); + + switch (action) + { + case Action_Copy : + m_buffer.append (c); + break; + case Action_CopyOutput : + m_buffer.append (c); + doOutput(); + break; + case Action_Output : + doOutput(); + break; + case Action_OutputUnget : + doOutput(); + fin.ungetch(c); + break; + case Action_Ignore : + /* ignore */ + break; + case Action_Abort : + qWarning ( "state %s / %s char %c (%d)" , statetoa(m_curState), statetoa(newState), c, c ); + parsingAborted(); + return false; + break; + case Action_InitTemp : + m_temp.clear(); + break; + case Action_CopyTemp : + m_temp.append (c); + break; + case Action_DecodeUnget : + m_buffer.append (decode()); + fin.ungetch(c); + break; + default : + qWarning ( "unknown action: %d ", action); + } + + m_curState = newState; + } + + parsingFinished(); + return true; +} + +void PSCommentLexer::doOutput () +{ + if (m_buffer.length() == 0) return; + switch (m_curState) + { + case State_Comment : + gotComment (m_buffer.latin1()); + break; + default: + qWarning ( "unknown state: %d", m_curState ); + } + + m_buffer.clear(); +} + +void PSCommentLexer::gotComment (const char *value) { + qDebug ( "gotComment: %s ", value ); +} + +void PSCommentLexer::parsingStarted() { + qDebug ( "parsing started" ); +} + +void PSCommentLexer::parsingFinished() { + qDebug ( "parsing finished" ); +} + +void PSCommentLexer::parsingAborted() { + qDebug ( "parsing aborted" ); +} + +void PSCommentLexer::nextStep (char c, State *newState, Action *newAction) { + int i=0; + + while (true) { + Transition trans = transitions[i]; + + if (trans.c == STOP) { + *newState = trans.newState; + *newAction = trans.action; + return; + } + + bool found = false; + + if (trans.oldState == m_curState) { + switch (trans.c) { + case CATEGORY_WHITESPACE : found = isspace(c); break; + case CATEGORY_ALPHA : found = isalpha(c); break; + case CATEGORY_DIGIT : found = isdigit(c); break; + case CATEGORY_SPECIAL : found = isSpecial(c); break; + case CATEGORY_LETTERHEX : found = isletterhex(c); break; + case CATEGORY_INTTOOLONG : found = m_buffer.length() > MAX_INTLEN; break; + case CATEGORY_ANY : found = true; break; + default : found = (trans.c == c); + } + + if (found) { + *newState = trans.newState; + *newAction = trans.action; + + return; + } + } + + + i++; + } +} + +uchar PSCommentLexer::decode() +{ + uchar value = m_temp.toString().toShort(NULL, 8); +// qDebug ("got encoded char %c",value); + return value; +} + +/* StringBuffer implementation */ + +int initialSize = 20; +int addSize = 10; + +StringBuffer::StringBuffer () { + m_buffer = (char*)calloc (initialSize, sizeof(char)); + m_length = 0; + m_capacity = initialSize; +} + +StringBuffer::~StringBuffer (){ + free(m_buffer); +} + +void StringBuffer::append (char c){ + ensureCapacity(m_length + 1); + m_buffer[m_length] = c; + m_length++; +} + +void StringBuffer::clear(){ + for (uint i=0; i= p_capacity) return; + + int newSize = m_capacity + addSize; + if (p_capacity > newSize) newSize = p_capacity; + + char* oldBuffer = m_buffer; + char *newBuffer = (char*)calloc (newSize, sizeof(char)); + strcpy (newBuffer, m_buffer); + free(oldBuffer); + m_buffer = newBuffer; + m_capacity = newSize; +} + +uint StringBuffer::length() { + return m_length; +} + +double StringBuffer::toFloat() { + QString data = toString(); + return data.toFloat(); +} + +int StringBuffer::toInt() { + QString data = toString(); + return data.toInt(); +} + +const char *StringBuffer::latin1() { + return m_buffer; +} + +QString StringBuffer::mid( uint index, uint len) const { + QString data = toString(); + return data.mid(index,len); +} + +/* BoundingBoxExtractor */ +BoundingBoxExtractor:: BoundingBoxExtractor() : m_llx(0), m_lly(0), m_urx(0), m_ury(0) {} +BoundingBoxExtractor::~BoundingBoxExtractor() {} + +void BoundingBoxExtractor::gotComment (const char *value) +{ + QString data (value); + if (data.find("%BoundingBox:")==-1) return; + + getRectangle (value, m_llx, m_lly, m_urx, m_ury); +} + +bool BoundingBoxExtractor::getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury) +{ + if (input == NULL) return false; + + QString s(input); + if (s.contains ("(atend)")) return false; + + QString s2 = s.remove("%BoundingBox:"); + QStringList values = QStringList::split (" ", s2.latin1()); + qDebug("size is %d",values.size()); +// if (values.size() < 5) return false; + llx = values[0].toInt(); + lly = values[1].toInt(); + urx = values[2].toInt(); + ury = values[3].toInt(); + + return true; +} + diff --git a/filters/karbon/eps/pscommentlexer.h b/filters/karbon/eps/pscommentlexer.h new file mode 100644 index 00000000..bf155211 --- /dev/null +++ b/filters/karbon/eps/pscommentlexer.h @@ -0,0 +1,112 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Sch鰊berger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef PSCOMMENTLEXER_H +#define PSCOMMENTLEXER_H + +#include +#include + +/** + *@author Dirk Sch鰊berger + */ +typedef enum { + State_Comment=0, + State_CommentEncodedChar, + State_Start +} State; + +typedef enum { + Action_Copy=1, + Action_CopyOutput, + Action_Output, + Action_Ignore, + Action_Abort, + Action_OutputUnget, + Action_InitTemp, + Action_CopyTemp, + Action_DecodeUnget, + Action_ByteArraySpecial +} Action; + +class StringBuffer { +public: + StringBuffer (); + virtual ~StringBuffer (); + + void append (char c); + void clear(); + QString toString() const; + uint length(); + double toFloat(); + int toInt(); + const char *latin1(); + QString mid( uint index, uint len=0xffffffff) const; +private: + char *m_buffer; + uint m_length; + int m_capacity; + + void ensureCapacity (int p_capacity); +}; + +class PSCommentLexer { +public: + PSCommentLexer(); + virtual ~PSCommentLexer(); + + virtual bool parse (QIODevice& fin); +private: + State m_curState; + StringBuffer m_buffer; + StringBuffer m_temp; + + void nextStep (char c, State* newState, Action* newAction); + + void doOutput (); + uchar decode(); + +protected: + virtual void parsingStarted(); + virtual void parsingFinished(); + virtual void parsingAborted(); + + virtual void gotComment (const char *value); +}; + +class BoundingBoxExtractor : public PSCommentLexer +{ +public: + BoundingBoxExtractor(); + virtual ~BoundingBoxExtractor(); + + int llx() { return m_llx; } + int lly() { return m_lly; } + int urx() { return m_urx; } + int ury() { return m_ury; } +private: + int m_llx, m_lly, m_urx, m_ury; + bool getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury); + +protected: + void gotComment (const char *value); +}; + +#endif + diff --git a/filters/karbon/kontour/Makefile.am b/filters/karbon/kontour/Makefile.am new file mode 100644 index 00000000..52d6220a --- /dev/null +++ b/filters/karbon/kontour/Makefile.am @@ -0,0 +1,27 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) -I$(top_srcdir)/karbon -I$(top_srcdir)/karbon/core $(all_includes) + +####### Files +# Obviously you have to change "foo" (and maybe "import") to +# reflect the name of your filter. If you have more files +# than just fooimport.cc please add them to the _SOURCES line. + +kde_module_LTLIBRARIES = libkarbonkontourimport.la + +libkarbonkontourimport_la_SOURCES = kontourimport.cpp +libkarbonkontourimport_la_LDFLAGS = -module $(KDE_PLUGIN) +libkarbonkontourimport_la_LIBADD = $(KOFFICE_LIBS) ../../../karbon/libkarboncommon.la + +METASOURCES = AUTO + +service_DATA = karbon_kontour_import.desktop +servicedir = $(kde_servicesdir) + +# Note: If your filter imports or exports some special file +# which KDE doesn't have a mimetype for, yet, you'll have to +# create a mimetype and install it using those two lines. +# In case of doubt please ask koffice@kde.org or +# koffice-devel@kde.org. Thanks. +# mydata_DATA = x-foo.desktop +# mydatadir = $(kde_mimedir)/text diff --git a/filters/karbon/kontour/karbon_kontour_import.desktop b/filters/karbon/kontour/karbon_kontour_import.desktop new file mode 100644 index 00000000..e18b68b8 --- /dev/null +++ b/filters/karbon/kontour/karbon_kontour_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon Kontour Import Filter +Name[af]=Karbon Kontoer In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 Kontour 賱丿賶 Karbon +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 Kontour 胁 Karbon +Name[br]=Sil enporzh Kontour evit Karbon +Name[ca]=Filtre d'importaci贸 Kontour per a Karbon +Name[cs]=Importn铆 filtr Kontour pro Karbon14 +Name[cy]=Hidlen Fewnforio Kontour Karbon +Name[da]=Karbon Kontour-importfilter +Name[de]=Karbon14 Kontour-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 Kontour 蟿慰蠀 Karbon +Name[eo]=Karbon-Kontour-importfiltrilo +Name[es]=Filtro de importaci贸n a Kontour de Karbon +Name[et]=Karboni Kontouri impordifilter +Name[eu]=Karbon-en Konoutr inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon Kontour +Name[fi]=Karbon Kontour -tuontisuodin +Name[fr]=Filtre d'importation Kontour de Karbon 14 +Name[fy]=Kontour-Ymportfilter foar Karbon +Name[ga]=Scagaire Iomp贸rt谩la Karbon Kontour +Name[gl]=Filtro de Importaci贸n de Kontour para Karbon +Name[he]=诪住谞谉 讬讬讘讜讗 诪志Kontour 诇志Karbon +Name[hr]=Karbon Kontour filtar uvoza +Name[hu]=Karbon Kontour importsz疟r艖 +Name[is]=Karbon Kontour innflutningss铆a +Name[it]=Filtro di importazione Kontour per Karbon +Name[ja]=Karbon Kontour 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 Kontour 釣熱灅釤掅灇釣夺灁釤 Karbon +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰嗪汗嗪氞粊嗪曕粔嗪 K 嗪傕涵嗪囙簞嗪侧寒嗷屶簹嗪簷14 +Name[lt]=Karbon Kontour importavimo filtras +Name[lv]=Karbon Kontour importa filtrs +Name[ms]=Penapis Import Karbon Kontour +Name[mt]=Filtru g魔all-importazzjoni ta' Kontour 摹o Karbon14 +Name[nb]=Kontour-importfilter for Karbon +Name[nds]=Kontour-Importfilter f枚r Karbon +Name[ne]=啶曕ぞ啶班啶え 啶班啶ぐ啷囙啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]= Kontour-importfilter voor Karbon +Name[nn]=Kontour-importfilter for Karbon +Name[pl]=Filtr importu formatu Kontour do Karbon +Name[pt]=Filtro de Importa莽茫o de Kontour para o Karbon +Name[pt_BR]=Filtro de Importa莽茫o Kontour do Karbon +Name[ro]=Filtru importare Karbon14 pentru Kontour +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褉懈褋褍薪泻芯胁 Kontour 胁 Karbon +Name[se]=Karbon:a Kontour sisafievrridansilli +Name[sk]=Karbon filter pre import pre Kontour +Name[sl]=Uvozni filter Kontour za Karbon +Name[sr]=Karbon-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 Kontour-邪 +Name[sr@Latn]=Karbon-ov filter za uvoz iz Kontour-a +Name[sv]=Karbon Kontour-importfilter +Name[ta]= karbon Kontour 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=肖懈谢褌褉懈 袙芯褉懈写芯褌懈 Karbon Kontour +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔權赋喙喔傕箟喔侧笭喔侧笧喔о覆喔 K 喔傕腑喔囙竸喔侧福喙屶笟喔笝14 +Name[tr]=Karbon Kontour Alma Filtresi +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 褎邪泄谢褨胁 Kontour 写谢褟 Karbon +Name[uz]=Karbon Kontour import filteri +Name[uz@cyrillic]=Karbon Kontour 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba se Karbon Kontour +Name[zh_CN]=Karbon Kontour 瀵煎叆杩囨护鍣 +Name[zh_TW]=Kontour Kontour 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=application/x-kontour +X-KDE-Weight=1 +X-KDE-Library=libkarbonkontourimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/kontour/kontourimport.cpp b/filters/karbon/kontour/kontourimport.cpp new file mode 100644 index 00000000..88d2fc4b --- /dev/null +++ b/filters/karbon/kontour/kontourimport.cpp @@ -0,0 +1,323 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Sven L黳pken + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPI 90 + +typedef KGenericFactory KontourImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonkontourimport, KontourImportFactory( "kofficefilters" ) ) + +KontourImport::KontourImport(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ +} + +KontourImport::~KontourImport() +{ + +} + +KoFilter::ConversionStatus KontourImport::convert(const QCString& from, const QCString& to) +{ + // check for proper conversion + if ( to != "application/x-karbon" || ( from != "application/x-kontour" && from != "application/x-killustrator") ) + return KoFilter::NotImplemented; + + + KoStoreDevice* inpdev = m_chain->storageFile( "root", KoStore::Read ); + if ( !inpdev ) + { + kdError(30502) << "Unable to open input stream" << endl; + return KoFilter::StorageCreationError; + } + + inpdoc.setContent( inpdev ); + + // Do the conversion! + convert(); + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if(!out) + { + kdError(30502) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void +KontourImport::parseGObject( VObject *object, const QDomElement &e ) +{ + if( !e.attribute( "fillstyle" ).isEmpty() ) + { + VFill fill; + int fillstyle = e.attribute( "fillstyle" ).toInt(); + switch( fillstyle ) + { + case 1: + { + fill.setType( VFill::solid ); + QColor c; + c.setNamedColor( e.attribute( "fillcolor" ) ); + VColor color( c ); + fill.setColor( color ); + } + break; + case 4: + { + VGradient grad; + // set color stops + grad.clearStops(); + QColor c; + c.setNamedColor( e.attribute( "gradcolor1" ) ); + VColor color( c ); + grad.addStop( color, 0.0, 0.5 ); + c.setNamedColor( e.attribute( "gradcolor2" ) ); + VColor color2( c ); + grad.addStop( color2, 1.0, 0.5 ); + // set coords + KoRect bbox = object->boundingBox(); + grad.setOrigin( KoPoint( bbox.left(), bbox.y() ) ); + grad.setVector( KoPoint( bbox.right(), bbox.y() ) ); + grad.setType( (VGradient::VGradientType)e.attribute( "gradstyle" ).toInt() ); + fill.setType( VFill::grad ); + fill.gradient() = grad; + } + break; + } + object->setFill( fill ); + } + if( !e.attribute( "strokecolor" ).isEmpty() ) + { + VStroke stroke; + int strokestyle = e.attribute( "strokestyle" ).toInt(); + switch( strokestyle ) + { + case 0: stroke.setType( VStroke::none ); + break; + case 1: + { + QColor c; + c.setNamedColor( e.attribute( "strokecolor" ) ); + VColor color( c ); + stroke.setColor( color ); + } + break; + case 2: case 3: case 4: case 5: + { + QColor c; + c.setNamedColor( e.attribute( "strokecolor" ) ); + VColor color( c ); + stroke.setColor( color ); + VDashPattern dash; + QValueList list; + switch ( strokestyle ) + { + case 2: // dashed line + list << 10 << 5; + break; + case 3: // dotted line + list << 1 << 5; + break; + case 4: // dash-dot + list << 10 << 5 << 1 << 5; + break; + case 5: // dash-dot-dot + list << 10 << 5 << 1 << 5 << 1 << 5; + break; + } + + dash.setArray( list ); + stroke.dashPattern() = dash; + } + break; + } + float lineWidth = e.attribute( "linewidth" ).toFloat(); + stroke.setLineWidth( lineWidth ); + object->setStroke( stroke ); + } + // handle matrix + QDomElement matrix = e.namedItem( "matrix" ).toElement(); + QWMatrix mat( matrix.attribute( "m11" ).toDouble(), + matrix.attribute( "m12" ).toDouble(), + matrix.attribute( "m21" ).toDouble(), + matrix.attribute( "m22" ).toDouble(), + matrix.attribute( "dx" ).toDouble(), + matrix.attribute( "dy" ).toDouble() ); + + // undo y-mirroring + mat.scale( 1, -1 ); + mat.translate( 0, -m_document.height() ); + VTransformCmd trafo( 0L, mat ); + trafo.visit( *object ); + +} + +void +KontourImport::convert() +{ + QDomElement docElem = inpdoc.documentElement(); + QDomElement lay; + double height; + double width; + if( docElem.attribute( "version" ).toInt() == 2 ) + { + lay = docElem; + height = lay.firstChild().namedItem( "layout" ).toElement().attribute( "height" ).toDouble(); + width = lay.firstChild().namedItem( "layout" ).toElement().attribute( "width" ).toDouble(); + } + else + { + lay = docElem.namedItem( "page" ).toElement(); + height = lay.firstChild().toElement().attribute( "height" ).toDouble(); + width = lay.firstChild().toElement().attribute( "width" ).toDouble(); + } + + m_document.setHeight( ( ( height / 72.0 ) * DPI ) ); + m_document.setWidth( ( ( width / 72.0 ) * DPI ) ); + + parseGroup( lay.firstChild().toElement() ); + + outdoc = m_document.saveXML(); +} + +void +KontourImport::parseGroup( const QDomElement &e ) +{ + QDomElement b = e; + for( ; !b.isNull(); b = b.nextSibling().toElement() ) + { + if ( b.tagName() == "rectangle" ) + { + int x = b.attribute( "x" ).toInt(); + int y = b.attribute( "y" ).toInt(); + int width = b.attribute( "width" ).toInt(); + int height = b.attribute( "height" ).toInt(); + VObject *rect = new VRectangle( 0L, KoPoint( x, height + y ) , width, height ); + QDomElement object = b.namedItem( "polyline" ).namedItem( "gobject" ).toElement(); + parseGObject( rect, object ); + m_document.append( rect ); + } + else + if ( b.tagName() == "ellipse" ) + { + QDomElement object = b.namedItem( "gobject" ).toElement(); + QDomElement matrix = object.namedItem( "matrix" ).toElement(); + /** + * Kontour uses a quite different way to display ellipses, so we + * need to calculate the values for the Karbon ellipse here + */ + double left = ( b.attribute( "x" ).toDouble() + matrix.attribute( "dx" ).toInt() ) - ( b.attribute( "rx" ).toDouble() / 2 ); + double right = left + b.attribute( "rx" ).toDouble(); + double top = ( b.attribute( "y" ).toDouble() + matrix.attribute( "dy" ).toInt() ) - ( b.attribute( "ry" ).toDouble() / 2 ); + double bottom = top + b.attribute( "ry" ).toDouble(); + double height = top - bottom; + double width = right - left; + // Append the ellipse to the document + VObject *ellipse = new VEllipse( 0L, KoPoint( left, top ), width, height ); + parseGObject( ellipse, object ); + m_document.append( ellipse ); + } + else if( b.tagName() == "polyline" ) + { + /** + * Kontour is much simpler because it doesn't support curves, so + * we're done with connecting points with lines. + */ + QDomElement point = b.firstChild().toElement(); + VPath *path = new VPath( &m_document ); + double x, y; + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->moveTo( KoPoint( x, y ) ); + point = point.nextSibling().toElement(); + for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() ) + { + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->lineTo( KoPoint( x, y ) ); + } + parseGObject( path, point ); + m_document.append( path ); + } + else if( b.tagName() == "polygon" ) + { + QDomElement point = b.namedItem( "polyline" ).firstChild().toElement(); + VPath *path = new VPath( &m_document ); + double x, y; + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->moveTo( KoPoint( x, y ) ); + point = point.nextSibling().toElement(); + for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() ) + { + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->lineTo( KoPoint( x, y ) ); + } + path->close(); + // back to first point + parseGObject( path, point ); + m_document.append( path ); + } + else if( b.tagName() == "bezier" ) + { + QDomElement point = b.namedItem( "polyline" ).firstChild().toElement(); + VPath *path = new VPath( &m_document ); + double x, y; + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->moveTo( KoPoint( x, y ) ); + point = point.nextSibling().toElement(); + for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() ) + { + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->lineTo( KoPoint( x, y ) ); + } + parseGObject( path, point ); + m_document.append( path ); + } + else if( b.tagName() == "group" || b.tagName() == "layer" ) + { + parseGroup( b.toElement().firstChild().toElement() ); + } + } +} + +#include diff --git a/filters/karbon/kontour/kontourimport.h b/filters/karbon/kontour/kontourimport.h new file mode 100644 index 00000000..f227f908 --- /dev/null +++ b/filters/karbon/kontour/kontourimport.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Sven L黳pken + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __KONTOURIMPORT_H__ +#define __KONTOURIMPORT_H__ + +#include +#include +#include + +class KontourImport : public KoFilter +{ + Q_OBJECT + +public: + KontourImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KontourImport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + +protected: + QDomDocument inpdoc; + QDomDocument outdoc; + void convert(); + +private: + void parseGObject( VObject *, const QDomElement & ); + void parseGroup( const QDomElement & ); + VDocument m_document; +}; + +#endif // __KONTOURIMPORT_H__ diff --git a/filters/karbon/msod/Makefile.am b/filters/karbon/msod/Makefile.am new file mode 100644 index 00000000..f7191cd1 --- /dev/null +++ b/filters/karbon/msod/Makefile.am @@ -0,0 +1,18 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes) +libkarbonmsodimport_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libkarbonmsodimport_la_LIBADD = $(KOFFICE_LIBS) $(LIBZ) + +####### Files + +kde_module_LTLIBRARIES = libkarbonmsodimport.la + +libkarbonmsodimport_la_SOURCES = msodimport.cc msod.cc + +noinst_HEADERS = msodimport.h msod.h + +METASOURCES = AUTO + +service_DATA = karbon_msod_import.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/karbon/msod/karbon_msod_import.desktop b/filters/karbon/msod/karbon_msod_import.desktop new file mode 100644 index 00000000..f75aac71 --- /dev/null +++ b/filters/karbon/msod/karbon_msod_import.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=Service +Name=Karbon's MS Office Drawing Import Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 乇爻賲 MS Office 丕賱禺丕氐 亘賭 Karbon +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 薪邪 MS Office Drawing 胁 Karbon +Name[br]=Sil enporzh MS Office Drawing evit Karbon's +Name[ca]=Filtre d'importaci贸 MS Office Drawing per a Karbon +Name[cs]=Importn铆 filtr Kreslen铆 MS Office pro Karbon +Name[cy]=Hidlen Fewnforio Lluniad MS Office Karbon +Name[da]=Karbons MS Office-tegning-importfilter +Name[de]=Karbon14 Importfilter f眉r Microsoft Office-Zeichnungen +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 MS Office Drawning 蟿慰蠀 Karbon +Name[eo]=Filtrilo por importado de MS-Oficeja desegno al Karbon +Name[es]=Filtro de importaci贸n dibujo de MS Office de Karbon +Name[et]=Karboni MS Office'i joonistuste impordifilter +Name[eu]=Karbon-en MSG Office-en marrazkien inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 鬲乇爻蹖賲 MS Office Karbon +Name[fi]=Karbonin MS Office -piirros tuontisuodin +Name[fr]=Filtre d'importation MS-Office Drawing de Karbon 14 +Name[fy]=MS Office Drawing-importfilter foar Karbon +Name[gl]=Filtro de Importaci贸n de Debuxos de MS Office para Karbon +Name[he]=诪住谞谉 诇讬讬讘讜讗 爪讬讜专讬诐 诪志MS Office 诇志Karbon +Name[hi]=啶曕ぞ啶班啶え 啶曕ぞ 啶忇ぎ啶忇じ 啶戉か啶监た啶 啶∴啶班ぞ啶囙啶 啶囙ぎ啷嵿お啷嬥ぐ啷嵿 啶ぜ啶苦げ啷嵿啶 +Name[hr]=Karbon filtar uvoza za MS Office crte啪e +Name[hu]=Karbon MS Office rajz importsz疟r艖 +Name[is]=Karbon MS Office teikning innflutningss铆a +Name[it]=Filtro di importazione MS Office Drawing per Karbon +Name[ja]=Karbon MS Office Drawing 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣涒嬦瀭釤嗎灀釣坚灇 MS Office 釣熱灅釤掅灇釣夺灁釤 Karbon +Name[lt]=Karbon's MS Office Drawing importavimo filtras +Name[lv]=Karbon MS Office z墨m膿jumu importa filtrs +Name[ms]=Penapis Import MS Office Drawing Karbon +Name[nb]=Importfilter fra MS Office-tegning til Karbon +Name[nds]=Tekenimportfilter f枚r Karbon +Name[ne]=啶曕ぞ啶班啶え啶曕 啶忇ぎ啶忇じ 啶曕ぞ啶班啶ぞ啶侧く 啶班啶栢ぞ啶氞た啶む啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]=MS Office Drawing-importfilter voor Karbon +Name[nn]=Importfilter fr氓 MS Office-teikning til Karbon +Name[pl]=Filtr importu z formatu MS Office Draw do Karbon +Name[pt]=Filtro de Importa莽茫o de Desenhos do MS Office para o Karbon +Name[pt_BR]=Filtro de importa莽茫o Desenho MS-Office para o Karbon +Name[ro]=Filtru importare Karbon14 pentru desene MS Office +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褉懈褋褍薪泻芯胁 MS Office 胁 Karbon +Name[se]=Karbon:a MS Office-s谩rgun sisafievrridansilli +Name[sk]=MS Office Drawing filter pre import pre Karbon +Name[sl]=Uvozni filter risbe iz MS Office za Karbon +Name[sr]=Karbon-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 MS Office Drawing-邪 +Name[sr@Latn]=Karbon-ov filter za uvoz iz MS Office Drawing-a +Name[sv]=Karbon-filter f枚r import av MS Office-teckning +Name[ta]=karbon 's MS Office 喈掂喁堗喈侧瘝 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=肖懈谢褌褉懈 袙芯褉懈写芯褌懈 Karbon-懈 MS Office 袪邪褋屑泻邪褕樱 +Name[tr]=Karbon MS Office 脟izim Alma Filtresi +Name[uk]=肖褨谢褜褌褉 写谢褟 褨屑锌芯褉褌褍 屑邪谢褞薪泻褨胁 MS Office 褍 Karbon +Name[uz]=MS Office chizmalarini Karbon'ga import qilish filteri +Name[uz@cyrillic]=MS Office 褔懈蟹屑邪谢邪褉懈薪懈 Karbon'谐邪 懈屑锌芯褉褌 覜懈谢懈褕 褎懈谢褌械褉懈 +Name[zh_CN]=Karbon 鐨 MS Office Drawing 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon 鐨 MS Office 绻湒鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/x-msod +X-KDE-Weight=1 +X-KDE-Library=libkarbonmsodimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/msod/msod.cc b/filters/karbon/msod/msod.cc new file mode 100644 index 00000000..dd848c83 --- /dev/null +++ b/filters/karbon/msod/msod.cc @@ -0,0 +1,1340 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int Msod::s_area = 30505; + +Msod::Msod( + unsigned dpi) : + KWmf(dpi) +{ + m_dpi = dpi; + m_images.setAutoDelete(true); + m_opt = new Options(*this); + m_shape.data = 0L; + m_shape.length = 0; +} + +Msod::~Msod() +{ + delete [] m_shape.data; + delete m_opt; +} + +void Msod::drawShape( + unsigned shapeType, + Q_UINT32 bytes, + QDataStream &operands) +{ + static const char *funcTab[] = + { + "UNKNOWN", // Unknown + "RECTANGLE", // Rectangle + "ROUNDRECTANGLE", // Roundrectangle + "ELLIPSE", // Ellipse + "DIAMOND", // Diamond + "ISOCELESTRIANGLE", // Isocelestriangle + "RIGHTTRIANGLE", // Righttriangle + "PARALLELOGRAM", // Parallelogram + "TRAPEZOID", // Trapezoid + "HEXAGON", // Hexagon + "OCTAGON", // Octagon + "PLUS", // Plus + "STAR", // Star + "ARROW", // Arrow + "THICKARROW", // Thickarrow + "HOMEPLATE", // Homeplate + "CUBE", // Cube + "BALLOON", // Balloon + "SEAL", // Seal + "ARC", // Arc + "LINE", // Line + "PLAQUE", // Plaque + "CAN", // Can + "DONUT", // Donut + "TEXTSIMPLE", // Textsimple + "TEXTOCTAGON", // Textoctagon + "TEXTHEXAGON", // Texthexagon + "TEXTCURVE", // Textcurve + "TEXTWAVE", // Textwave + "TEXTRING", // Textring + "TEXTONCURVE", // Textoncurve + "TEXTONRING", // Textonring + "STRAIGHTCONNECTOR1", // Straightconnector1 + "BENTCONNECTOR2", // Bentconnector2 + "BENTCONNECTOR3", // Bentconnector3 + "BENTCONNECTOR4", // Bentconnector4 + "BENTCONNECTOR5", // Bentconnector5 + "CURVEDCONNECTOR2", // Curvedconnector2 + "CURVEDCONNECTOR3", // Curvedconnector3 + "CURVEDCONNECTOR4", // Curvedconnector4 + "CURVEDCONNECTOR5", // Curvedconnector5 + "CALLOUT1", // Callout1 + "CALLOUT2", // Callout2 + "CALLOUT3", // Callout3 + "ACCENTCALLOUT1", // Accentcallout1 + "ACCENTCALLOUT2", // Accentcallout2 + "ACCENTCALLOUT3", // Accentcallout3 + "BORDERCALLOUT1", // bordercallout1 + "BORDERCALLOUT2", // Bordercallout2 + "BORDERCALLOUT3", // Bordercallout3 + "ACCENTBORDERCALLOUT1", // Accentbordercallout1 + "ACCENTBORDERCALLOUT2", // Accentbordercallout2 + "ACCENTBORDERCALLOUT3", // Accentbordercallout3 + "RIBBON", // Ribbon + "RIBBON2", // Ribbon2 + "CHEVRON", // Chevron + "PENTAGON", // Pentagon + "NOSMOKING", // Nosmoking + "SEAL8", // Seal8 + "SEAL16", // Seal16 + "SEAL32", // Seal32 + "WEDGERECTCALLOUT", // Wedgerectcallout + "WEDGERRECTCALLOUT", // Wedgerrectcallout + "WEDGEELLIPSECALLOUT", // Wedgeellipsecallout + "WAVE", // Wave + "FOLDEDCORNER", // Foldedcorner + "LEFTARROW", // Leftarrow + "DOWNARROW", // Downarrow + "UPARROW", // Uparrow + "LEFTRIGHTARROW", // Leftrightarrow + "UPDOWNARROW", // Updownarrow + "IRREGULARSEAL1", // Irregularseal1 + "IRREGULARSEAL2", // Irregularseal2 + "LIGHTNINGBOLT", // Lightningbolt + "HEART", // Heart + "PICTUREFRAME", // PictureFrame + "QUADARROW", // Quadarrow + "LEFTARROWCALLOUT", // Leftarrowcallout + "RIGHTARROWCALLOUT", // Rightarrowcallout + "UPARROWCALLOUT", // Uparrowcallout + "DOWNARROWCALLOUT", // Downarrowcallout + "LEFTRIGHTARROWCALLOUT", // Leftrightarrowcallout + "UPDOWNARROWCALLOUT", // Updownarrowcallout + "QUADARROWCALLOUT", // Quadarrowcallout + "BEVEL", // Bevel + "LEFTBRACKET", // Leftbracket + "RIGHTBRACKET", // Rightbracket + "LEFTBRACE", // Leftbrace + "RIGHTBRACE", // Rightbrace + "LEFTUPARROW", // Leftuparrow + "BENTUPARROW", // Bentuparrow + "BENTARROW", // Bentarrow + "SEAL24", // Seal24 + "STRIPEDRIGHTARROW", // Stripedrightarrow + "NOTCHEDRIGHTARROW", // Notchedrightarrow + "BLOCKARC", // Blockarc + "SMILEYFACE", // Smileyface + "VERTICALSCROLL", // Verticalscroll + "HORIZONTALSCROLL", // Horizontalscroll + "CIRCULARARROW", // Circulararrow + "NOTCHEDCIRCULARARROW", // Notchedcirculararrow + "UTURNARROW", // Uturnarrow + "CURVEDRIGHTARROW", // Curvedrightarrow + "CURVEDLEFTARROW", // Curvedleftarrow + "CURVEDUPARROW", // Curveduparrow + "CURVEDDOWNARROW", // Curveddownarrow + "CLOUDCALLOUT", // Cloudcallout + "ELLIPSERIBBON", // Ellipseribbon + "ELLIPSERIBBON2", // Ellipseribbon2 + "FLOWCHARTPROCESS", // Flowchartprocess + "FLOWCHARTDECISION", // Flowchartdecision + "FLOWCHARTINPUTOUTPUT", // Flowchartinputoutput + "FLOWCHARTPREDEFINEDPROCESS", // Flowchartpredefinedprocess + "FLOWCHARTINTERNALSTORAGE", // Flowchartinternalstorage + "FLOWCHARTDOCUMENT", // Flowchartdocument + "FLOWCHARTMULTIDOCUMENT", // Flowchartmultidocument + "FLOWCHARTTERMINATOR", // Flowchartterminator + "FLOWCHARTPREPARATION", // Flowchartpreparation + "FLOWCHARTMANUALINPUT", // Flowchartmanualinput + "FLOWCHARTMANUALOPERATION", // Flowchartmanualoperation + "FLOWCHARTCONNECTOR", // Flowchartconnector + "FLOWCHARTPUNCHEDCARD", // Flowchartpunchedcard + "FLOWCHARTPUNCHEDTAPE", // Flowchartpunchedtape + "FLOWCHARTSUMMINGJUNCTION", // Flowchartsummingjunction + "FLOWCHARTOR", // Flowchartor + "FLOWCHARTCOLLATE", // Flowchartcollate + "FLOWCHARTSORT", // Flowchartsort + "FLOWCHARTEXTRACT", // Flowchartextract + "FLOWCHARTMERGE", // Flowchartmerge + "FLOWCHARTOFFLINESTORAGE", // Flowchartofflinestorage + "FLOWCHARTONLINESTORAGE", // Flowchartonlinestorage + "FLOWCHARTMAGNETICTAPE", // Flowchartmagnetictape + "FLOWCHARTMAGNETICDISK", // Flowchartmagneticdisk + "FLOWCHARTMAGNETICDRUM", // Flowchartmagneticdrum + "FLOWCHARTDISPLAY", // Flowchartdisplay + "FLOWCHARTDELAY", // Flowchartdelay + "TEXTPLAINTEXT", // Textplaintext + "TEXTSTOP", // Textstop + "TEXTTRIANGLE", // Texttriangle + "TEXTTRIANGLEINVERTED", // Texttriangleinverted + "TEXTCHEVRON", // Textchevron + "TEXTCHEVRONINVERTED", // Textchevroninverted + "TEXTRINGINSIDE", // Textringinside + "TEXTRINGOUTSIDE", // Textringoutside + "TEXTARCHUPCURVE", // Textarchupcurve + "TEXTARCHDOWNCURVE", // Textarchdowncurve + "TEXTCIRCLECURVE", // Textcirclecurve + "TEXTBUTTONCURVE", // Textbuttoncurve + "TEXTARCHUPPOUR", // Textarchuppour + "TEXTARCHDOWNPOUR", // Textarchdownpour + "TEXTCIRCLEPOUR", // Textcirclepour + "TEXTBUTTONPOUR", // Textbuttonpour + "TEXTCURVEUP", // Textcurveup + "TEXTCURVEDOWN", // Textcurvedown + "TEXTCASCADEUP", // Textcascadeup + "TEXTCASCADEDOWN", // Textcascadedown + "TEXTWAVE1", // Textwave1 + "TEXTWAVE2", // Textwave2 + "TEXTWAVE3", // Textwave3 + "TEXTWAVE4", // Textwave4 + "TEXTINFLATE", // Textinflate + "TEXTDEFLATE", // Textdeflate + "TEXTINFLATEBOTTOM", // Textinflatebottom + "TEXTDEFLATEBOTTOM", // Textdeflatebottom + "TEXTINFLATETOP", // Textinflatetop + "TEXTDEFLATETOP", // Textdeflatetop + "TEXTDEFLATEINFLATE", // Textdeflateinflate + "TEXTDEFLATEINFLATEDEFLATE", // Textdeflateinflatedeflate + "TEXTFADERIGHT", // Textfaderight + "TEXTFADELEFT", // Textfadeleft + "TEXTFADEUP", // Textfadeup + "TEXTFADEDOWN", // Textfadedown + "TEXTSLANTUP", // Textslantup + "TEXTSLANTDOWN", // Textslantdown + "TEXTCANUP", // Textcanup + "TEXTCANDOWN", // Textcandown + "FLOWCHARTALTERNATEPROCESS", // Flowchartalternateprocess + "FLOWCHARTOFFPAGECONNECTOR", // Flowchartoffpageconnector + "CALLOUT90", // Callout90 + "ACCENTCALLOUT90", // Accentcallout90 + "BORDERCALLOUT90", // Bordercallout90 + "ACCENTBORDERCALLOUT90", // Accentbordercallout90 + "LEFTRIGHTUPARROW", // Leftrightuparrow + "SUN", // Sun + "MOON", // Moon + "BRACKETPAIR", // Bracketpair + "BRACEPAIR", // Bracepair + "SEAL4", // Seal4 + "DOUBLEWAVE", // Doublewave + "ACTIONBUTTONBLANK", // Actionbuttonblank + "ACTIONBUTTONHOME", // Actionbuttonhome + "ACTIONBUTTONHELP", // Actionbuttonhelp + "ACTIONBUTTONINFORMATION", // Actionbuttoninformation + "ACTIONBUTTONFORWARDNEXT", // Actionbuttonforwardnext + "ACTIONBUTTONBACKPREVIOUS", // Actionbuttonbackprevious + "ACTIONBUTTONEND", // Actionbuttonend + "ACTIONBUTTONBEGINNING", // Actionbuttonbeginning + "ACTIONBUTTONRETURN", // Actionbuttonreturn + "ACTIONBUTTONDOCUMENT", // Actionbuttondocument + "ACTIONBUTTONSOUND", // Actionbuttonsound + "ACTIONBUTTONMOVIE", // Actionbuttonmovie + "HOSTCONTROL", // Hostcontrol + "TEXTBOX", // Textbox + }; + struct + { + Q_UINT32 spid; // The shape id + union + { + Q_UINT32 info; + struct + { + Q_UINT32 fGroup : 1; // This shape is a group shape + Q_UINT32 fChild : 1; // Not a top-level shape + Q_UINT32 fPatriarch : 1; // This is the topmost group shape. + // Exactly one of these per drawing. + Q_UINT32 fDeleted : 1; // The shape has been deleted + Q_UINT32 fOleShape : 1; // The shape is an OLE object + Q_UINT32 fHaveMaster : 1; // Shape has a hspMaster property + Q_UINT32 fFlipH : 1; // Shape is flipped horizontally + Q_UINT32 fFlipV : 1; // Shape is flipped vertically + Q_UINT32 fConnector : 1; // Connector type of shape + Q_UINT32 fHaveAnchor : 1; // Shape has an anchor of some kind + Q_UINT32 fBackground : 1; // Background shape + Q_UINT32 fHaveSpt : 1; // Shape has a shape type property + Q_UINT32 reserved : 20; // Not yet used + } fields; + } grfPersistent; + } data; + + // Scan lookup table for operation. + + operands >> data.spid; + operands >> data.grfPersistent.info; + bytes -= 8; + kdDebug(s_area) << "shape-id: " << data.spid << " type: " << funcTab[shapeType] << " (" << shapeType << ")" << + (data.grfPersistent.fields.fGroup ? " group" : "") << + (data.grfPersistent.fields.fChild ? " child" : "") << + (data.grfPersistent.fields.fPatriarch ? " patriarch" : "") << + (data.grfPersistent.fields.fDeleted ? " deleted" : "") << + (data.grfPersistent.fields.fOleShape ? " oleshape" : "") << + (data.grfPersistent.fields.fHaveMaster ? " master" : "") << + (data.grfPersistent.fields.fFlipH ? " flipv" : "") << + (data.grfPersistent.fields.fConnector ? " connector" : "") << + (data.grfPersistent.fields.fHaveAnchor ? " anchor" : "") << + (data.grfPersistent.fields.fBackground ? " background" : "") << + (data.grfPersistent.fields.fHaveSpt ? " spt" : "") << + " operands: " << bytes << endl; + if (data.grfPersistent.fields.fDeleted) + return; + if ((!m_isRequiredDrawing) && (m_requestedShapeId != data.spid)) + return; + + // An active shape! Let's draw it... + + switch (shapeType) + { + case 0: + if (m_opt->m_pVertices) + { + gotPolyline(m_dc, *m_opt->m_pVertices); + } + break; + case 1: + if (bytes > 7) + { + QPoint topLeft; + QSize size; + + topLeft = normalisePoint(operands); + size = normaliseSize(operands); + + QRect rect(topLeft, size); + QPointArray points(4); + + points.setPoint(0, topLeft); + points.setPoint(1, rect.topRight()); + points.setPoint(2, rect.bottomRight()); + points.setPoint(3, rect.bottomLeft()); + gotRectangle(m_dc, points); + } + case 20: + if (bytes > 7) + { + QPoint lineFrom; + QPoint lineTo; + + lineTo = normalisePoint(operands); + + QPointArray points(2); + + points.setPoint(0, lineFrom); + points.setPoint(1, lineTo); + gotPolyline(m_dc, points); + } + break; + default: + break; + } +} + +void Msod::invokeHandler( + Header &op, + Q_UINT32 bytes, + QDataStream &operands) +{ + typedef void (Msod::*method)(Header &op, Q_UINT32 bytes, QDataStream &operands); + + typedef struct + { + const char *name; + Q_UINT16 opcode; + method handler; + } opcodeEntry; + + static const opcodeEntry funcTab[] = + { + { "ALIGNRULE", 0xF013, &Msod::opAlignrule }, + { "ANCHOR", 0xF00E, &Msod::opAnchor }, + { "ARCRULE", 0xF014, &Msod::opArcrule }, + { "BSE", 0xF007, &Msod::opBse }, + { "BSTORECONTAINER", 0xF001, &Msod::opBstorecontainer }, + { "CALLOUTRULE", 0xF017, &Msod::opCalloutrule }, + { "CHILDANCHOR", 0xF00F, &Msod::opChildanchor }, + { "CLIENTANCHOR", 0xF010, &Msod::opClientanchor }, + { "CLIENTDATA", 0xF011, &Msod::opClientdata }, + { "CLIENTRULE", 0xF015, &Msod::opClientrule }, + { "CLIENTTEXTBOX", 0xF00D, &Msod::opClienttextbox }, + { "CLSID", 0xF016, &Msod::opClsid }, + { "COLORMRU", 0xF11A, &Msod::opColormru }, + { "CONNECTORRULE", 0xF012, &Msod::opConnectorrule }, + { "DELETEDPSPL", 0xF11D, &Msod::opDeletedpspl }, + { "DG", 0xF008, &Msod::opDg }, + { "DGCONTAINER", 0xF002, &Msod::opDgcontainer }, + { "DGG", 0xF006, &Msod::opDgg }, + { "DGGCONTAINER", 0xF000, &Msod::opDggcontainer }, + { "OLEOBJECT", 0xF11F, &Msod::opOleobject }, + { "OPT", 0xF00B, &Msod::opOpt }, + { "REGROUPITEMS", 0xF118, &Msod::opRegroupitems }, + { "SELECTION", 0xF119, &Msod::opSelection }, + { "SOLVERCONTAINER", 0xF005, &Msod::opSolvercontainer }, + { "SP", 0xF00A, &Msod::opSp }, + { "SPCONTAINER", 0xF004, &Msod::opSpcontainer }, + { "SPGR", 0xF009, &Msod::opSpgr }, + { "SPGRCONTAINER", 0xF003, &Msod::opSpgrcontainer }, + { "SPLITMENUCOLORS", 0xF11E, &Msod::opSplitmenucolors }, + { "TEXTBOX", 0xF00C, &Msod::opTextbox }, + { NULL, 0, 0 }, + { "BLIP", 0, &Msod::opBlip } + }; + unsigned i; + method result; + + // Scan lookup table for operation. + + for (i = 0; funcTab[i].name; i++) + { + if (funcTab[i].opcode == op.opcode.fields.fbt) + { + break; + } + } + + // Invoke handler. + + result = funcTab[i].handler; + if (!result && (op.opcode.fields.fbt >= 0xF018) && (0xF117 >= op.opcode.fields.fbt)) + result = funcTab[++i].handler; + if (!result) + { + if (funcTab[i].name) + kdWarning(s_area) << "invokeHandler: unsupported opcode: " << + funcTab[i].name << + " operands: " << bytes << endl; + else + kdWarning(s_area) << "invokeHandler: unsupported opcode: 0x" << + QString::number(op.opcode.fields.fbt, 16) << + " operands: " << bytes << endl; + + // Skip data we cannot use. + + skip(bytes, operands); + } + else + { + kdDebug(s_area) << "invokeHandler: opcode: " << funcTab[i].name << + " operands: " << bytes << endl; + + // We don't invoke the handler directly on the incoming operands, but + // via a temporary datastream. This adds overhead, but eliminates the + // need for the individual handlers to read *exactly* the right amount + // of data (thus speeding development, and possibly adding some + // future-proofing). + + if (bytes) + { + QByteArray *record = new QByteArray(bytes); + QDataStream *body; + + operands.readRawBytes(record->data(), bytes); + body = new QDataStream(*record, IO_ReadOnly); + body->setByteOrder(QDataStream::LittleEndian); + (this->*result)(op, bytes, *body); + delete body; + delete record; + } + else + { + QDataStream *body = new QDataStream(); + + (this->*result)(op, bytes, *body); + delete body; + } + } +} + +QPoint Msod::normalisePoint( + QDataStream &operands) +{ + Q_UINT16 x; + Q_UINT16 y; + + operands >> x >> y; + return QPoint(x / m_dpi, y / m_dpi); +} + +QSize Msod::normaliseSize( + QDataStream &operands) +{ + Q_UINT16 width; + Q_UINT16 height; + + operands >> width >> height; + return QSize(width / m_dpi, height / m_dpi); +} + +bool Msod::parse( + unsigned shapeId, + const QString &file, + const char *delayStream) +{ + QFile in(file); + if (!in.open(IO_ReadOnly)) + { + kdError(s_area) << "Unable to open input file!" << endl; + in.close(); + return false; + } + QDataStream stream(&in); + bool result = parse(shapeId, stream, in.size(), delayStream); + in.close(); + return result; +} + +bool Msod::parse( + unsigned shapeId, + QDataStream &stream, + unsigned size, + const char *delayStream) +{ + stream.setByteOrder(QDataStream::LittleEndian); // Great, I love Qt ! + m_requestedShapeId = shapeId; + m_isRequiredDrawing = false; + m_delayStream = delayStream; + + // Read bits. + + walk(size, stream); + return true; +} + +void Msod::opAlignrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opAnchor( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opArcrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opBlip(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + typedef enum + { + msobiWMF = 0x216, // Metafile header then compressed WMF. + msobiEMF = 0x3D4, // Metafile header then compressed EMF. + msobiPICT = 0x542, // Metafile header then compressed PICT. + msobiPNG = 0x6E0, // One byte tag then PNG data. + msobiJPEG = 0x46A, // One byte tag then JFIF data. + msobiDIB = 0x7A8, // One byte tag then DIB data. + msobiClient = 0x800 // Clients should set this bit. + } MSOBI; + typedef enum + { + msocompressionDeflate, + msocompressionNone = 254, + msocompressionTest + } MSOBLIPCOMPRESSION; + + bool hasPrimaryId; + Q_UINT32 length = 0; + struct + { + Q_UINT32 cb; + struct + { + Q_UINT32 x; + Q_UINT32 y; + Q_UINT32 w; + Q_UINT32 h; + } bounds; + struct + { + Q_UINT32 w; + Q_UINT32 h; + } ptSize; + Q_UINT32 cbSave; + Q_UINT8 compression; + Q_UINT8 filter; + } data; + + // Skip any explicit primary header (m_rgbUidprimary). + + switch (m_blipType) + { + case msoblipEMF: + hasPrimaryId = (m_blipType ^ msobiEMF) != 0; + break; + case msoblipWMF: + hasPrimaryId = (m_blipType ^ msobiWMF) != 0; + break; + case msoblipPICT: + hasPrimaryId = (m_blipType ^ msobiPICT) != 0; + break; + case msoblipJPEG: + hasPrimaryId = (m_blipType ^ msobiJPEG) != 0; + break; + case msoblipPNG: + hasPrimaryId = (m_blipType ^ msobiPNG) != 0; + break; + case msoblipDIB: + hasPrimaryId = (m_blipType ^ msobiDIB) != 0; + break; + default: + hasPrimaryId = (m_blipType ^ msobiClient) != 0; + break; + } + if (hasPrimaryId) + { + length += 16; + skip(16, operands); + } + + // Process the rest of the header. + + data.compression = msocompressionNone; + switch (m_blipType) + { + case msoblipEMF: + case msoblipWMF: + case msoblipPICT: + length += 34; + operands >> data.cb; + operands >> data.bounds.x >> data.bounds.y >> data.bounds.w >> data.bounds.h; + operands >> data.ptSize.w >> data.ptSize.h; + operands >> data.cbSave; + operands >> data.compression >> data.filter; + break; + case msoblipJPEG: + case msoblipPNG: + case msoblipDIB: + // Skip the "tag". + length += 1; + skip(1, operands); + break; + default: + break; + } + + // Work out the file type. + + Image *image = new Image(); + switch (m_blipType) + { + case msoblipEMF: + image->extension = "emf"; + break; + case msoblipWMF: + image->extension = "wmf"; + break; + case msoblipPICT: + image->extension = "pic"; + break; + case msoblipJPEG: + image->extension = "jpg"; + break; + case msoblipPNG: + image->extension = "png"; + break; + case msoblipDIB: + image->extension = "dib"; + break; + default: + image->extension = "img"; + break; + } + image->length = bytes - length; + image->data = new char[image->length]; + operands.readRawBytes((char *)image->data, image->length); + if (data.compression == msocompressionDeflate) + { + const char *tmp; + uLongf destLen = data.cb; + int result; + + tmp = new char[data.cb]; + result = uncompress((Q_UINT8 *)tmp, &destLen, (Q_UINT8 *)image->data, image->length); + if (result != Z_OK) + { + kdError(s_area) << "opBlip: uncompress failed: " << result << endl; + } + if (destLen != data.cb) + { + kdError(s_area) << "opBlip: uncompressed " << destLen << " instead of " << data.cb << endl; + } + delete [] image->data; + image->data = tmp; + image->length = destLen; + } + m_images.resize(m_images.size() + 1); + m_images.insert(m_images.size() - 1, image); +} + +// FBSE - File Blip Store Entry + +void Msod::opBse(Header &op, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT8 btWin32; // Required type on Win32. + Q_UINT8 btMacOS; // Required type on Mac. + Q_UINT8 rgbUid[16]; // Identifier of blip. + Q_UINT16 tag; // currently unused. + Q_UINT32 size; // Blip size in stream. + Q_UINT32 cRef; // Reference count on the blip. + Q_UINT32 foDelay; // File offset in the delay stream. + Q_UINT8 usage; // How this blip is used (MSOBLIPUSAGE). + Q_UINT8 cbName; // length of the blip name. + Q_UINT8 unused2; // for the future. + Q_UINT8 unused3; // for the future. + } data; + unsigned i; + + // Work out the type of the BLIP. + + m_blipType = static_cast(op.opcode.fields.inst); + operands >> data.btWin32; + operands >> data.btMacOS; + for (i = 0; i < 16; i++) + operands >> data.rgbUid[i]; + operands >> data.tag >> data.size; + operands >> data.cRef >> data.foDelay; + operands >> data.usage >> data.cbName; + operands >> data.unused2 >> data.unused2; + + // If the Blip is not in this drawing file, process it "manually". + + if (m_delayStream) + { + // The m_pib refers to images by number, which includes images + // that are no longer here. Thus, we fake these out so that any + // references to non-deleted images are still valid (!!!). + + if (data.size && data.cRef) + { + QByteArray bytes; + bytes.setRawData(m_delayStream + data.foDelay, data.size); + QDataStream stream(bytes, IO_ReadOnly); + stream.setByteOrder(QDataStream::LittleEndian); + walk(data.size, stream); + bytes.resetRawData(m_delayStream + data.foDelay, data.size); + } + else + { + m_images.resize(m_images.size() + 1); + m_images.insert(m_images.size() - 1, 0L); + } + } +} + +void Msod::opBstorecontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opCalloutrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opChildanchor( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opClientanchor(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client anchor: " << data.unknown << endl; +} + +void Msod::opClientdata(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client data: " << data.unknown << endl; +} + +void Msod::opClientrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opClienttextbox( + Header &, + Q_UINT32, + QDataStream &operands) +{ + struct + { + Q_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client textbox: 0x" << QString::number(data.unknown,16) << endl; +} + +void Msod::opClsid( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opColormru( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opConnectorrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opDeletedpspl( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +// FDG - File DG + +void Msod::opDg(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 csp; // The number of shapes in this drawing. + Q_UINT32 spidCur; // The last shape ID given to an SP in this DG. + } data; + + operands >> data.csp >> data.spidCur; + kdDebug(s_area) << "drawing id: " << data.spidCur << endl; + m_isRequiredDrawing = (m_requestedShapeId == data.spidCur); + if (m_isRequiredDrawing) + { + kdDebug(s_area) << "found requested drawing" << endl; + } +} + +void Msod::opDgcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +// FDGG - File DGG + +void Msod::opDgg(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 spidMax; // The current maximum shape ID. + Q_UINT32 cidcl; // The number of ID clusters (FIDCLs). + Q_UINT32 cspSaved; // The total number of shapes saved. + // (including deleted shapes, if undo + // information was saved). + Q_UINT32 cdgSaved; // The total number of drawings saved. + } data; + + // File ID Cluster - used to save IDCLs + + struct + { + Q_UINT32 dgid; // DG owning the SPIDs in this cluster + Q_UINT32 cspidCur; // number of SPIDs used so far + } data1; + unsigned i; + + operands >> data.spidMax >> data.cidcl >> data.cspSaved >> data.cdgSaved; + kdDebug(s_area) << data.cspSaved << " shapes in " << + data.cidcl - 1 << " clusters in " << + data.cdgSaved << " drawings" << endl; + for (i = 0; i < data.cidcl - 1; i++) + { + operands >> data1.dgid >> data1.cspidCur; + } +} + +void Msod::opDggcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opOleobject( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opOpt(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + m_opt->walk(bytes, operands); +} + +void Msod::opRegroupitems( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opSelection( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opSolvercontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opSp(Header &op, Q_UINT32 bytes, QDataStream &operands) +{ + // We want to defer the act of drawing a shape until we have seen any options + // that may affect it. Thus, we merely store the data away, and let opSpContainer + // do all the ahrd work. + + m_shape.type = op.opcode.fields.inst; + m_shape.length = bytes; + m_shape.data = new char [bytes]; + operands.readRawBytes(m_shape.data, bytes); +} + +void Msod::opSpcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); + + // Having gathered all the information for this shape, we can now draw it. + + QByteArray a; + + a.setRawData(m_shape.data, m_shape.length); + QDataStream s(a, IO_ReadOnly); + s.setByteOrder(QDataStream::LittleEndian); // Great, I love Qt ! + drawShape(m_shape.type, m_shape.length, s); + a.resetRawData(m_shape.data, m_shape.length); + delete [] m_shape.data; + m_shape.data = 0L; +} + +void Msod::opSpgr(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 x; + Q_UINT32 y; + Q_UINT32 w; + Q_UINT32 h; + } data; + + operands >> data.x >> data.y >> data.w >> data.h; +} + +void Msod::opSpgrcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opSplitmenucolors(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 fill; + Q_UINT32 line; + Q_UINT32 shadow; + Q_UINT32 threeDee; + } data; + + operands >> data.fill >> data.line >> data.shadow >> data.threeDee; +} + +void Msod::opTextbox( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::skip(Q_UINT32 bytes, QDataStream &operands) +{ + if ((int)bytes < 0) + { + kdError(s_area) << "skip: " << (int)bytes << endl; + return; + } + if (bytes) + { + Q_UINT32 i; + Q_UINT8 discard; + + kdDebug(s_area) << "skip: " << bytes << endl; + for (i = 0; i < bytes; i++) + { + operands >> discard; + } + } +} + +void Msod::walk(Q_UINT32 bytes, QDataStream &operands) +{ + Header op; + Q_UINT32 length = 0; + + // Stop parsing when there are no more records. Note that we stop as soon + // as we cannot get a complete header. + while (length + 8 <= bytes) + { + operands >> op.opcode.info >> op.cbLength; + + // If we get some duff data, protect ourselves. + if (length + op.cbLength + 8 > bytes) + { + op.cbLength = bytes - length - 8; + } + length += op.cbLength + 8; + if (op.opcode.fields.fbt == 0x200) + { + // This appears to be an EOF marker. + break; + } + + // Package the arguments... + + invokeHandler(op, op.cbLength, operands); + } + + // Eat unexpected data that the caller may expect us to consume. + skip(bytes - length, operands); +} + +Msod::Options::Options( + Msod &parent) : + m_parent(parent) +{ + m_pVertices = 0L; + initialise(); +} + +Msod::Options::~Options() +{ + delete m_pVertices; +} + +double Msod::Options::from1616ToDouble(Q_UINT32 value) +{ + return (value >> 16) + 65535.0 / (double)(value & 0xffff); +} + +void Msod::Options::initialise() +{ + m_rotation = 0.0; + + m_lTxid = 0; + + m_pib = 0; + m_pibName = QString::null; + m_pibFlags = 0; + m_pictureId = 0; + m_fNoHitTestPicture = false; + m_pictureGray = false; + m_pictureBiLevel = false; + m_pictureActive = false; + + m_geoLeft = 0; + m_geoTop = 0; + m_geoRight = 21600; + m_geoBottom = 21600; + m_shapePath = 1; + delete m_pVertices; + m_pVertices = 0L; + m_fShadowOK = true; + m_f3DOK = true; + m_fLineOK = true; + m_fGTextOK = false; + m_fFillShadeShapeOK = false; + m_fFillOK = true; + + m_fFilled = true; + m_fHitTestFill = true; + m_fillShape = true; + m_fillUseRect = false; + m_fNoFillHitTest = false; + + m_lineColor = 0; + m_lineBackColor = 0xffffff; + m_lineType = 0; + m_lineWidth = 9525; + + m_fArrowheadsOK = false; + m_fLine = true; + m_fHitTestLine = true; + m_lineFillShape = true; + m_fNoLineDrawDash = false; + + m_bWMode = 1; + + m_fOleIcon = false; + m_fPreferRelativeResize = false; + m_fLockShapeType = false; + m_fDeleteAttachedObject = false; + m_fBackground = false; +} + +void Msod::Options::walk(Q_UINT32 bytes, QDataStream &operands) +{ + Header op; + Q_UINT16 length = 0; + Q_UINT16 complexLength = 0; + + // Reset all options to default values. + + initialise(); + + // First process all simple options, and add all complex options to a list. + + QPtrList
complexOpts; + complexOpts.setAutoDelete(true); + bool unsupported; + while (length + complexLength < (int)bytes) + { + operands >> op.opcode.info >> op.value; + length += 6; + + // Defer processing of complex options. + + if (op.opcode.fields.fComplex) + { + complexLength += op.value; + complexOpts.append(new Header(op)); + continue; + } + + // Now squirrel away the option value. + + unsupported = false; + switch (op.opcode.fields.pid) + { + case 4: + m_rotation = from1616ToDouble(op.value); + break; + case 128: + m_lTxid = op.value; + kdDebug(s_area) << "textbox: 0x" << QString::number(op.value,16) << endl; + break; + case 260: + if (op.opcode.fields.fBid) + { + m_pib = op.value; + if (m_parent.m_isRequiredDrawing) + { + Image *image = m_parent.m_images[m_pib - 1]; + + // If it is an embedded WMF we don't bother with the + // part; we just extract it as more vector graphics. + + if (image->extension == "wmf") + { + QByteArray a; + a.setRawData(image->data, image->length); + QDataStream s(a, IO_ReadOnly); + m_parent.KWmf::parse(s, image->length); + a.resetRawData(image->data, image->length); + } + else + { + m_parent.gotPicture( + m_pib, + image->extension, + image->length, + image->data); + } + } + } + else + { + kdError(s_area) << "Cannot handle IMsoBlip" << endl; + } + break; + case 262: + m_pibFlags = op.value; + break; + case 267: + m_pictureId = op.value; + break; + case 319: + m_fNoHitTestPicture = (op.value & 0x0008) != 0; + m_pictureGray = (op.value & 0x0004) != 0; + m_pictureBiLevel = (op.value & 0x0002) != 0; + m_pictureActive = (op.value & 0x0001) != 0; + break; + case 320: + m_geoLeft = op.value; + break; + case 321: + m_geoTop = op.value; + break; + case 322: + m_geoRight = op.value; + break; + case 323: + m_geoBottom = op.value; + break; + case 324: + m_shapePath = op.value; + break; + case 383: + m_fShadowOK = (op.value & 0x0020) != 0; + m_f3DOK = (op.value & 0x0010) != 0; + m_fLineOK = (op.value & 0x0008) != 0; + m_fGTextOK = (op.value & 0x0004) != 0; + m_fFillShadeShapeOK = (op.value & 0x0002) != 0; + m_fFillOK = (op.value & 0x0001) != 0; + break; + case 447: + m_fFilled = (op.value & 0x0010) != 0; + m_fHitTestFill = (op.value & 0x0008) != 0; + m_fillShape = (op.value & 0x0004) != 0; + m_fillUseRect = (op.value & 0x0002) != 0; + m_fNoFillHitTest = (op.value & 0x0001) != 0; + break; + case 448: + m_lineColor = op.value; + break; + case 450: + m_lineBackColor = op.value; + break; + case 452: + m_lineType = op.value; + break; + case 459: + m_lineWidth = op.value; + break; + case 511: + m_fArrowheadsOK = (op.value & 0x0010) != 0; + m_fLine = (op.value & 0x0008) != 0; + m_fHitTestLine = (op.value & 0x0004) != 0; + m_lineFillShape = (op.value & 0x0002) != 0; + m_fNoLineDrawDash = (op.value & 0x0001) != 0; + break; + case 772: + m_bWMode = op.value; + break; + case 831: + m_fOleIcon = (op.value & 0x0010) != 0; + m_fPreferRelativeResize = (op.value & 0x0008) != 0; + m_fLockShapeType = (op.value & 0x0004) != 0; + m_fDeleteAttachedObject = (op.value & 0x0002) != 0; + m_fBackground = (op.value & 0x0001) != 0; + break; + default: + unsupported = true; + kdWarning(s_area) << "unsupported simple option: " << + op.opcode.fields.pid << endl; + break; + } + if (!unsupported) + kdDebug(s_area) << "simple option: " << + op.opcode.fields.pid << endl; + } + + // Now empty the list of complex options. + + while (complexOpts.count()) + { + Q_INT16 t16; + unsigned i; + + op = *complexOpts.getFirst(); + complexOpts.removeFirst(); + unsupported = false; + switch (op.opcode.fields.pid) + { + case 261: + while (true) + { + operands >> t16; + if (!t16) + break; + m_pibName += QChar(t16); + }; + break; + case 325: + m_pVertices = new QPointArray(op.value / 4); + for (i = 0; i < m_pVertices->count(); i++) + { + m_pVertices->setPoint(i, m_parent.normalisePoint(operands)); + }; + break; + case 326: + operands >> t16; + i = t16; + operands >> t16; + operands >> t16; + m_parent.skip(i * t16, operands); + break; + default: + unsupported = true; + kdWarning(s_area) << "unsupported complex option: " << + op.opcode.fields.pid << " operands: " << op.value << endl; + m_parent.skip(op.value, operands); + break; + } + if (!unsupported) + kdDebug(s_area) << "complex option: " << + op.opcode.fields.pid << " operands: " << op.value << endl; + complexLength -= op.value; + } +} diff --git a/filters/karbon/msod/msod.h b/filters/karbon/msod/msod.h new file mode 100644 index 00000000..a3dd9efe --- /dev/null +++ b/filters/karbon/msod/msod.h @@ -0,0 +1,307 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION + + This is a generic parser for Microsoft Office Drawings (MSODs). The + specification for this is the Microsoft Office 97 Drawing File Format + published in MSDN. The output is a series of callbacks (a.k.a. virtual + functions) which the caller can override as required. +*/ + +#ifndef MSOD_H +#define MSOD_H + +class QString; +class QPointArray; +#include +#include + +class Msod : + private KWmf +{ +public: + + // Construction. + + Msod( + unsigned dpi); + virtual ~Msod(); + + // Called to parse the given file. We extract a drawing by shapeId. + // If the drawing is not found, the return value will be false. + + bool parse( + unsigned shapeId, + const QString &file, + const char *delayStream = 0L); + bool parse( + unsigned shapeId, + QDataStream &stream, + unsigned size, + const char *delayStream = 0L); + + typedef KWmf::DrawContext DrawContext; + + // Should be protected... + + void brushSet( + unsigned colour, + unsigned style); + void penSet( + unsigned colour, + unsigned style, + unsigned width); + +protected: + // Override to get results of parsing. + + virtual void gotEllipse( + const DrawContext &dc, + QString type, + QPoint topLeft, + QSize halfAxes, + unsigned startAngle, + unsigned stopAngle) = 0; + virtual void gotPicture( + unsigned id, + QString extension, + unsigned length, + const char *data) = 0; + virtual void gotPolygon( + const DrawContext &dc, + const QPointArray &points) = 0; + virtual void gotPolyline( + const DrawContext &dc, + const QPointArray &points) = 0; + virtual void gotRectangle( + const DrawContext &dc, + const QPointArray &points) = 0; + +private: + Msod(const Msod &); + const Msod &operator=(const Msod &); + + // Debug support. + + static const int s_area; + +private: + int m_dpi; + DrawContext m_dc; + unsigned m_dggError; + unsigned m_requestedShapeId; + bool m_isRequiredDrawing; + const char *m_delayStream; + struct + { + unsigned type; + char *data; + unsigned length; + } m_shape; + + QPoint normalisePoint( + QDataStream &operands); + QSize normaliseSize( + QDataStream &operands); + void drawShape( + unsigned shapeType, + Q_UINT32 bytes, + QDataStream &operands); + +public: + + // Common Header (MSOBFH) + typedef struct + { + union + { + Q_UINT32 info; + struct + { + Q_UINT32 ver: 4; + Q_UINT32 inst: 12; + Q_UINT32 fbt: 16; + } fields; + } opcode; + Q_UINT32 cbLength; + } Header; + +private: + typedef enum + { + msoblipERROR, // An error occurred during loading. + msoblipUNKNOWN, // An unknown blip type. + msoblipEMF, // Windows Enhanced Metafile. + msoblipWMF, // Windows Metafile. + msoblipPICT, // Macintosh PICT. + msoblipJPEG, // JFIF. + msoblipPNG, // PNG. + msoblipDIB, // Windows DIB. + msoblipFirstClient = 32, // First client defined blip type. + msoblipLastClient = 255 // Last client defined blip type. + } MSOBLIPTYPE; + + MSOBLIPTYPE m_blipType; + unsigned m_imageId; + class Image + { + public: + QString extension; + unsigned length; + const char *data; + Image() { data = 0L; } + ~Image() { delete [] data; } + }; + QPtrVector m_images; + + // Opcode handling and painter methods. + + void walk( + Q_UINT32 bytes, + QDataStream &operands); + void skip( + Q_UINT32 bytes, + QDataStream &operands); + void invokeHandler( + Header &op, + Q_UINT32 bytes, + QDataStream &operands); + + void opAlignrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opAnchor(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opArcrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opBlip(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opBse(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opBstorecontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opCalloutrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opChildanchor(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClientanchor(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClientdata(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClientrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClienttextbox(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClsid(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opColormru(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opConnectorrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDeletedpspl(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDg(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDgcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDgg(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDggcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opOleobject(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opOpt(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opRegroupitems(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSelection(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSolvercontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSp(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSpcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSpgr(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSpgrcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSplitmenucolors(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opTextbox(Header &op, Q_UINT32 bytes, QDataStream &operands); + + // Option handling. + + class Options + { + public: + Options(Msod &parent); + ~Options(); + void walk( + Q_UINT32 bytes, + QDataStream &operands); + + double m_rotation; + + Q_UINT32 m_lTxid; + + Q_UINT32 m_pib; + QString m_pibName; + Q_UINT32 m_pibFlags; + Q_UINT32 m_pictureId; + bool m_fNoHitTestPicture; + bool m_pictureGray; + bool m_pictureBiLevel; + bool m_pictureActive; + + Q_UINT32 m_geoLeft; + Q_UINT32 m_geoTop; + Q_UINT32 m_geoRight; + Q_UINT32 m_geoBottom; + Q_UINT32 m_shapePath; + QPointArray *m_pVertices; + bool m_fShadowOK; + bool m_f3DOK; + bool m_fLineOK; + bool m_fGTextOK; + bool m_fFillShadeShapeOK; + bool m_fFillOK; + + bool m_fFilled; + bool m_fHitTestFill; + bool m_fillShape; + bool m_fillUseRect; + bool m_fNoFillHitTest; + + Q_UINT32 m_lineColor; + Q_UINT32 m_lineBackColor; + Q_UINT32 m_lineType; + Q_UINT32 m_lineWidth; + + bool m_fArrowheadsOK; + bool m_fLine; + bool m_fHitTestLine; + bool m_lineFillShape; + bool m_fNoLineDrawDash; + + Q_UINT32 m_bWMode; + + bool m_fOleIcon; + bool m_fPreferRelativeResize; + bool m_fLockShapeType; + bool m_fDeleteAttachedObject; + bool m_fBackground; + + private: + Msod &m_parent; + + typedef struct + { + union + { + Q_UINT16 info; + struct + { + Q_UINT16 pid: 14; + Q_UINT16 fBid: 1; + Q_UINT16 fComplex: 1; + } fields; + } opcode; + Q_UINT32 value; + } Header; + + void initialise(); + double from1616ToDouble(Q_UINT32 value); + }; + friend class Msod::Options; + + Options *m_opt; +}; + +#endif diff --git a/filters/karbon/msod/msodimport.cc b/filters/karbon/msod/msodimport.cc new file mode 100644 index 00000000..9af11181 --- /dev/null +++ b/filters/karbon/msod/msodimport.cc @@ -0,0 +1,313 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory MSODImportFactory; +K_EXPORT_COMPONENT_FACTORY( libmsodimport, MSODImportFactory( "kofficefilters" ) ) + +const int MSODImport::s_area = 30505; + +MSODImport::MSODImport( + KoFilter *, + const char *, + const QStringList&) : + KoEmbeddingFilter(), Msod(100) +{ +} + +MSODImport::~MSODImport() +{ +} + +KoFilter::ConversionStatus MSODImport::convert( const QCString& from, const QCString& to ) +{ + if (to != "application/x-karbon" || from != "image/x-msod") + return KoFilter::NotImplemented; + + // Get configuration data: the shape id, and any delay stream that we were given. + unsigned shapeId; + emit commSignalShapeID( shapeId ); + const char *delayStream = 0L; + emit commSignalDelayStream( delayStream ); + kdDebug( s_area ) << "##################################################################" << endl; + kdDebug( s_area ) << "shape id: " << shapeId << endl; + kdDebug( s_area ) << "delay stream: " << delayStream << endl; + kdDebug( s_area ) << "##################################################################" << endl; +/* + QString config = ""; // ###### FIXME: We aren't able to pass config data right now + QStringList args = QStringList::split(";", config); + unsigned i; + + kdDebug(s_area) << "MSODImport::filter: config: " << config << endl; + for (i = 0; i < args.count(); i++) + { + if (args[i].startsWith("shape-id=")) + { + shapeId = args[i].mid(9).toUInt(); + } + else + if (args[i].startsWith("delay-stream=")) + { + delayStream = (const char *)args[i].mid(13).toULong(); + } + else + { + kdError(s_area) << "Invalid argument: " << args[i] << endl; + return KoFilter::StupidError; + } + } +*/ + // doc header + m_text = ""; + m_text += "\n"; + m_text += "\n"; + m_text += "\n"; + m_text += " \n"; + + if (!parse(shapeId, m_chain->inputFile(), delayStream)) + return KoFilter::WrongFormat; + + // close doc + m_text += " \n"; + m_text += "\n"; + + emit sigProgress(100); + + KoStoreDevice* dev = m_chain->storageFile( "root", KoStore::Write ); + if (!dev) + { + kdError(s_area) << "Cannot open output file" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring ( m_text.utf8() ); + dev->writeBlock(cstring.data(), cstring.size()-1); + + return KoFilter::OK; +} + +void MSODImport::gotEllipse( + const DrawContext &/*dc*/, + QString /*type*/, + QPoint /*topLeft*/, + QSize /*halfAxes*/, + unsigned /*startAngle*/, + unsigned /*stopAngle*/) +{ +// ### TODO +#if 0 + m_text += "\n"; + m_text += " \n"; + m_text += " \n"; + m_text += " \n"; + m_text += "\n"; +#endif +} + +static void toRGB(int c, double &r, double &g, double &b) +{ + r = (c >> 16) / 255.0; + g = ((c >> 8) & 0xFF) / 255.0; + b = (c & 0xFF) / 255.0; +} + +void MSODImport::gotPicture( + unsigned key, + QString extension, + unsigned length, + const char *data) +{ +// ### TODO +#if 0 + kdDebug() << "##########################################MSODImport::gotPicture" << endl; + kdDebug() << "MSODImport::gotPicture -- " << extension << endl; + if ((extension == "wmf") || + (extension == "emf") || + (extension == "pict")) + { + int partRef = internalPartReference( QString::number( key ) ); + + if (partRef == -1) + { + m_embeddeeData = data; + m_embeddeeLength = length; + + QString srcMime( KoEmbeddingFilter::mimeTypeByExtension( extension ) ); + if ( srcMime == KMimeType::defaultMimeType() ) + kdWarning( s_area ) << "Couldn't determine the mimetype from the extension" << endl; + + QCString destMime; // intentionally empty, the filter manager will do the rest + KoFilter::ConversionStatus status; + partRef = embedPart( srcMime.latin1(), destMime, status, QString::number( key ) ); + + m_embeddeeData = 0; + m_embeddeeLength = 0; + + if ( status != KoFilter::OK ) { + kdWarning(s_area) << "Couldn't convert the image!" << endl; + return; + } + } + m_text += "\n"; + } + else + { + // We could not import it as a part. Try as an image. + KTempFile tempFile( QString::null, '.' + extension ); + tempFile.file()->writeBlock( data, length ); + tempFile.close(); + + m_text += "\n" + " \n" + " \n" + " \n" + "\n"; + + // Note that we cannot delete the file... + } +#endif +} + +void MSODImport::gotPolygon( + const DrawContext &dc, + const QPointArray &points) +{ + kdDebug(s_area) << "MSODImport::gotPolygon" << endl; + kdDebug(s_area) << QString::number(dc.m_penWidth, 16) << endl; + kdDebug(s_area) << dc.m_penStyle << endl; + m_text += "\n"; + if( dc.m_penWidth > 0 ) + { + m_text += "\n";// + QString::number(dc.m_penWidth, 16) + "\">\n"; + double r, g, b; + toRGB(dc.m_penColour, r, g, b); + m_text += "\n"; + m_text += "\n"; + } + else + m_text += "\n"; + m_text += "\n"; + double r, g, b; + toRGB(dc.m_brushColour, r, g, b); + m_text += "\n"; + m_text += "\n"; + + m_text += "\n"; + pointArray(points); + m_text += "\n"; + m_text += "\n"; +} + + +void MSODImport::gotPolyline( + const DrawContext &dc, + const QPointArray &points) +{ + kdDebug(s_area) << "MSODImport::gotPolyline" << endl; + return; // ### TODO + m_text += "\n"; + m_text += "\n"; + m_text += "\n"; + m_text += "\n"; + pointArray(points); + m_text += "\n"; + m_text += "\n"; +} + +void MSODImport::gotRectangle( + const DrawContext &dc, + const QPointArray &points) +{ +// ### TODO +#if 0 + QRect bounds = points.boundingRect(); + + m_text += "\n"; + m_text += "\n"; + pointArray(points); + m_text += " \n"; + m_text += " \n"; + m_text += " \n"; + m_text += "\n"; + m_text += "\n"; +#endif +} + +void MSODImport::savePartContents( QIODevice* file ) +{ + if ( m_embeddeeData != 0 && m_embeddeeLength != 0 ) + file->writeBlock( m_embeddeeData, m_embeddeeLength ); +} + +void MSODImport::pointArray( + const QPointArray &points) +{ + + m_text += "\n"; + kdDebug(s_area) << "\n" << endl; + for (unsigned int i = 1; i < points.count(); i++) + { + m_text += "\n"; + kdDebug(s_area) << "" << endl; + } + +} + +#include diff --git a/filters/karbon/msod/msodimport.h b/filters/karbon/msod/msodimport.h new file mode 100644 index 00000000..cb6aec16 --- /dev/null +++ b/filters/karbon/msod/msodimport.h @@ -0,0 +1,87 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#ifndef MSODIMPORT_H +#define MSODIMPORT_H + +#include +#include + +class MSODImport : + public KoEmbeddingFilter, protected Msod +{ + Q_OBJECT + +public: + MSODImport( + KoFilter *parent, + const char *name, + const QStringList&); + virtual ~MSODImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +protected: + + virtual void gotEllipse( + const DrawContext &dc, + QString type, + QPoint topLeft, + QSize halfAxes, + unsigned startAngle, + unsigned stopAngle); + virtual void gotPicture( + unsigned id, + QString extension, + unsigned length, + const char *data); + virtual void gotPolygon( + const DrawContext &dc, + const QPointArray &points); + virtual void gotPolyline( + const DrawContext &dc, + const QPointArray &points); + virtual void gotRectangle( + const DrawContext &dc, + const QPointArray &points); + +signals: + // Communication signals to the parent filters + void commSignalDelayStream( const char* delay ); + void commSignalShapeID( unsigned int& shapeID ); + +private: + virtual void savePartContents( QIODevice* file ); + + // Debug support. + static const int s_area; + + void pointArray( + const QPointArray &points); + QString m_text; + + // Embedded objects. + const char* m_embeddeeData; + int m_embeddeeLength; +}; + +#endif diff --git a/filters/karbon/msod/status.html b/filters/karbon/msod/status.html new file mode 100644 index 00000000..b9b2ce5d --- /dev/null +++ b/filters/karbon/msod/status.html @@ -0,0 +1,153 @@ + + + + + Karbon filters status: MSOD FILTER + + +  + +
+
+

+ Karbon filters status:   MSOD - MS Office Drawing +

+
+ +
+ + + Import | + Export + + +


+
+ +Up +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ Import MSOD for Karbon
+
+
+
Last update24 jan 2003
Featuresvery basic
Todomany things
History24 jan 2003: port to Karbon
Authors + Shaheed Haque +
Links-
Progress report -
+
+
+Up + +


+ +
+


+ + +
+ +
+ +Up +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
Export Karbon to MSOD

+
+
Last update-
Features-
Todo-
History-
Authors-
Links-
Progress report -
+
+
+Up + + + diff --git a/filters/karbon/oodraw/Makefile.am b/filters/karbon/oodraw/Makefile.am new file mode 100644 index 00000000..4cca1e32 --- /dev/null +++ b/filters/karbon/oodraw/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir)/../../liboofilter \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + $(all_includes) + +####### Files +kde_module_LTLIBRARIES = liboodrawimport.la + + +liboodrawimport_la_SOURCES = oodrawimport.cc +liboodrawimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +liboodrawimport_la_LIBADD = ../../liboofilter/liboofilter.la \ + ../../../karbon/libkarboncommon.la \ + $(KOFFICE_LIBS) + +METASOURCES = AUTO + +service_DATA = karbon_oodraw_import.desktop + +servicedir = $(kde_servicesdir) diff --git a/filters/karbon/oodraw/karbon_oodraw_import.desktop b/filters/karbon/oodraw/karbon_oodraw_import.desktop new file mode 100644 index 00000000..b634ba6a --- /dev/null +++ b/filters/karbon/oodraw/karbon_oodraw_import.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Draw Import Filter for Karbon14 +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 乇爻賲 OpenOffice.org 賱賭 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 OpenOffice.org Draw 胁 Karbon14 +Name[br]=Sil enporzh OpenOffice.org Draw evit Karbon14 +Name[ca]=Filtre d'importaci贸 OpenOffice.org Draw per a Karbon14 +Name[cs]=OpenOffice.org Draw importn铆 filtr pro Karbon14 +Name[cy]=Hidlen Fewnforio OpenOffice.org Draw ar gyfer Karbon14 +Name[da]=OpenOffice.org Draw importfilter for Karbon14 +Name[de]=Karbon14 OpenOffice.org-Draw-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 OpenOffice.org Draw 纬喂伪 蟿慰 Karbon14 +Name[eo]=OpenOffice.org desegno-importfiltrilo por Karbon14 +Name[es]=Filtro de importaci贸n de OpenOffice.org Draw para Karbon14 +Name[et]=Karbon14 OpenOffice.org Draw' impordifilter +Name[eu]=Karbon14-en OpenOffice.org Draw-en inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 鬲乇爻蹖賲 OpenOffice.org 亘乇丕蹖 Karbon14 +Name[fi]=OpenOffice.org-piirrostuontisuodin Karbon14:lle +Name[fr]=Filtre d'importation OpenOffice.org Draw de Karbon14 +Name[fy]=OpenOffice.org Draw-Ymportfilter foar Karbon14 +Name[gl]=Filtro de Importaci贸n de OpenOffice.org Draw para Karbon14 +Name[he]=诪住谞谉 诇讬讬讘讜讗 诪志OpenOffice.org Draw 诇志Karbon14 +Name[hi]=啶曕ぞ啶班啶え 14 啶曕 啶侧た啶 啶撪お啶-啶戉か啶监た啶.啶戉ぐ啷嵿 啶嗋く啶距い 啶涏え啶ㄠ +Name[hr]=OpenOffice.org Draw filtar uvoza za Karbon14 +Name[hu]=OpenOffice.org Draw importsz疟r艖 a Karbon14-hez +Name[is]=OpenOffice.org Draw innflutningss铆a fyrir Karbon14 +Name[it]=Filtro di importazione OpenOffice.org Draw per Karbon14 +Name[ja]=Karbon14 OpenOffice.org Draw 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 OpenOffice.org Draw 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lt]=OpenOffice.org Draw importavimo filtras skirtas Karbon14 +Name[lv]=OpenOffice.org Draw importa filtrs priek拧 Karbon14 +Name[ms]=Penapis Import OpenOffice.org Draw bagi Karbon14 +Name[nb]=OpenOffice.org Draw-importfilter for Karbon14 +Name[nds]="OpenOffice.org Draw"-Importfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ啶曕ぞ 啶侧ぞ啶椸た OpenOffice.org 啶班啶栢ぞ啶氞た啶む啶 啶嗋く啶距い 啶た啶侧啶熰ぐ +Name[nl]=OpenOffice.org Draw-importfilter voor Karbon14 +Name[nn]=OpenOffice.org Draw-importfilter for Karbon14 +Name[pl]=Filtr importu z OpenOffice.org Draw do Karbon14 +Name[pt]=Filtro de Importa莽茫o de OpenOffice.org Draw para o Karbon14 +Name[pt_BR]=Filtro de Importa莽茫o OpenOffice.org Draw para o Karbon14 +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褉懈褋褍薪泻芯胁 OpenOffice.org 胁 Karbon14 +Name[se]=Karbon14:a OpenOffice.org Draw-sisafievrridansilli +Name[sk]=Filter pre import OpenOffice.org Draw pre Karbon14 +Name[sl]=Uvozni filter OpenOffice.org Draw za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 OpenOffice.org Draw-邪 +Name[sr@Latn]=Karbon14-ov filter za uvoz iz OpenOffice.org Draw-a +Name[sv]=OpenOffice.org Draw-importfilter f枚r Karbon-14 +Name[ta]=open office.org 喈掂喁堗喈侧瘝 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 karbon 14 +Name[tg]=肖懈谢褌褉懈 袙芯褉懈写芯褌懈 OpenOffice.org 袪邪褋屑泻邪褕樱 斜邪褉芯懈 Karbon14 +Name[tr]=Karbon14 i莽in OpenOffice.org Impress Alma Filtresi +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 屑邪谢褞薪泻褨胁 OpenOffice.org 褍 Karbon14 +Name[uz]=Karbon14 uchun OpenOffice.org Draw import filteri +Name[uz@cyrillic]=Karbon14 褍褔褍薪 OpenOffice.org Draw 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[zh_CN]=Karbon14 鐨 OpenOffice.org Draw 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon14 鐨 OpenOffice.org Draw 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=application/vnd.sun.xml.draw +X-KDE-Weight=1 +X-KDE-Library=liboodrawimport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/oodraw/oodrawimport.cc b/filters/karbon/oodraw/oodrawimport.cc new file mode 100644 index 00000000..f52ed5b8 --- /dev/null +++ b/filters/karbon/oodraw/oodrawimport.cc @@ -0,0 +1,757 @@ +/* This file is part of the KDE project + Copyright (c) 2003 Rob Buis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "oodrawimport.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +typedef KGenericFactory OoDrawImportFactory; +K_EXPORT_COMPONENT_FACTORY( liboodrawimport, OoDrawImportFactory( "kofficefilters" ) ) + + +OoDrawImport::OoDrawImport( KoFilter *, const char *, const QStringList & ) + : KoFilter(), + m_styles( 23, true ), + m_styleStack( ooNS::style, ooNS::fo ) +{ + m_styles.setAutoDelete( true ); +} + +OoDrawImport::~OoDrawImport() +{ +} + +KoFilter::ConversionStatus OoDrawImport::convert( QCString const & from, QCString const & to ) +{ + kdDebug() << "Entering Oodraw Import filter: " << from << " - " << to << endl; + + if( from != "application/vnd.sun.xml.draw" || to != "application/x-karbon" ) + { + kdWarning() << "Invalid mimetypes " << from << " " << to << endl; + return KoFilter::NotImplemented; + } + + m_zip = new KZip( m_chain->inputFile() ); + + if ( !m_zip->open( IO_ReadOnly ) ) + { + kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl; + delete m_zip; + return KoFilter::FileNotFound; + } + + KoFilter::ConversionStatus preStatus = openFile(); + + if( preStatus != KoFilter::OK ) + { + m_zip->close(); + delete m_zip; + return preStatus; + } +/*QDomDocument docinfo; + createDocumentInfo( docinfo ); + +// store document info +KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); +if( out ) +{ +QCString info = docinfo.toCString(); +//kdDebug() << " info :" << info << endl; +// WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end. +out->writeBlock( info , info.length() ); +}*/ + QDomDocument docinfo; + createDocumentInfo( docinfo ); + // store document info + KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); + if( out ) + { + QCString info = docinfo.toCString(); + //kdDebug(30518) << " info :" << info << endl; + // WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end. + out->writeBlock( info , info.length() ); + } + + convert(); + QDomDocument outdoc = m_document.saveXML(); + // add paper info, we always need custom for svg (Rob) + QDomElement paper = outdoc.createElement( "PAPER" ); + outdoc.documentElement().appendChild( paper ); + paper.setAttribute( "format", PG_CUSTOM ); + paper.setAttribute( "width", m_document.width() ); + paper.setAttribute( "height", m_document.height() ); + + // store document content + out = m_chain->storageFile( "maindoc.xml", KoStore::Write ); + if( out ) + { + QCString content = outdoc.toCString(); + kdDebug() << " content :" << content << endl; + out->writeBlock( content , content.length() ); + } + m_zip->close(); + delete m_zip; + + kdDebug() << "######################## OoDrawImport::convert done ####################" << endl; + + return KoFilter::OK; +} + +// Very related to OoWriterImport::createDocumentInfo +void OoDrawImport::createDocumentInfo( QDomDocument &docinfo ) +{ + docinfo = KoDocument::createDomDocument( "document-info" /*DTD name*/, "document-info" /*tag name*/, "1.1" ); + + OoUtils::createDocumentInfo(m_meta, docinfo); + //kdDebug(30518) << " meta-info :" << m_meta.toCString() << endl; +} + + +// Very related to OoWriterImport::openFile() +KoFilter::ConversionStatus OoDrawImport::openFile() +{ + KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content ); + if ( status != KoFilter::OK ) + { + kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl; + return status; + } + + // We do not stop if the following calls fail. + QDomDocument styles; + loadAndParse( "styles.xml", styles ); + loadAndParse( "meta.xml", m_meta ); + loadAndParse( "settings.xml", m_settings ); + + emit sigProgress( 10 ); + createStyleMap( styles ); + + return KoFilter::OK; +} + +void OoDrawImport::convert() +{ + m_document.saveAsPath( false ); + + QDomElement content = m_content.documentElement(); + + // content.xml contains some automatic-styles that we need to store + QDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" ); + if( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" ); + if( body.isNull() ) + return; + + // we take the settings of the first slide for the whole document. + QDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" ); + if( drawPage.isNull() ) // no pages? give up. + return; + + QDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", QString::null )]; + QDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", QString::null )]; + QDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" ).toElement(); + + if( properties.isNull() ) + { + m_document.setWidth( 550.0 ); + m_document.setHeight( 841.0 ); + } + else + { + m_document.setWidth( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-width", QString::null ) ) ); + m_document.setHeight( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", QString::null ) ) ); + } + + // parse all pages + for( QDomNode drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() ) + { + QDomElement dp = drawPage.toElement(); + m_styleStack.clear(); // remove all styles + fillStyleStack( dp ); + //m_styleStack.setPageMark(); + + // set the pagetitle + //QDomElement titleElement = doc.createElement( "Title" ); + //titleElement.setAttribute( "title", dp.attributeNS( "name" ) ); + //pageTitleElement.appendChild( titleElement ); + + parseGroup( 0L, dp ); + } +} + + +KoFilter::ConversionStatus OoDrawImport::loadAndParse(const QString& filename, QDomDocument& doc) +{ + return OoUtils::loadAndParse( filename, doc, m_zip); +} + +void +OoDrawImport::parseGroup( VGroup *parent, const QDomElement& parentobject ) +{ + // parse all objects + for( QDomNode object = parentobject.firstChild(); !object.isNull(); object = object.nextSibling() ) + { + QDomElement o = object.toElement(); + if( o.namespaceURI() != ooNS::draw ) continue; + QString name = o.localName(); + QString drawID = o.attributeNS( ooNS::draw, "id", QString::null ); + VObject *obj = 0L; + + if( name == "g" ) // polyline + { + storeObjectStyles( o ); + VGroup *group = new VGroup( parent ); + appendPen( *group ); + appendBrush( *group ); + obj = group; + parseGroup( group, o ); + } + else if( name == "rect" ) // rectangle + { + storeObjectStyles( o ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", QString::null ) ) ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", QString::null ) ); + int corner = static_cast( KoUnit::parseValue( o.attributeNS( ooNS::draw, "corner-radius", QString::null ) ) ); + VRectangle *rect = new VRectangle( parent, KoPoint( x, y ), w, h, corner ); + appendPen( *rect ); + appendBrush( *rect ); + obj = rect; + } + else if( name == "circle" || name == "ellipse" ) + { + storeObjectStyles( o ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", QString::null ) ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", QString::null ) ) ) - h; + double start = o.attributeNS( ooNS::draw, "start-angle", QString::null ).toDouble(); + double end = o.attributeNS( ooNS::draw, "end-angle", QString::null ).toDouble(); + QString kind = o.attributeNS( ooNS::draw, "kind", QString::null ); + VEllipse::VEllipseType type = VEllipse::full; + if( !kind.isEmpty() ) + { + if( kind == "section" ) + type = VEllipse::cut; + else if( kind == "cut" ) + type = VEllipse::section; + else if( kind == "arc" ) + type = VEllipse::arc; + } + VEllipse *ellipse = new VEllipse( parent, KoPoint( x, y ), w, h, type, start, end ); + appendPen( *ellipse ); + // arc has no brush + if( kind != "arc" ) + appendBrush( *ellipse ); + obj = ellipse; + } + else if( name == "line" ) // line + { + storeObjectStyles( o ); + VPath *line = new VPath( parent ); + double x1 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x1", QString::null ) ); + double y1 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y1", QString::null ) ) ); + double x2 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x2", QString::null ) ); + double y2 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y2", QString::null ) ) ); + line->moveTo( KoPoint( x1, y1 ) ); + line->lineTo( KoPoint( x2, y2 ) ); + appendPen( *line ); + appendBrush( *line ); + obj = line; + } + else if( name == "polyline" ) // polyline + { + storeObjectStyles( o ); + VPath *polyline = new VPath( parent ); + appendPoints( *polyline, o); + appendPen( *polyline ); + appendBrush( *polyline ); + obj = polyline; + } + else if( name == "polygon" ) // polygon + { + storeObjectStyles( o ); + //VPolygon *polygon = new VPolygon( parent ); + //polygon->load( o ); + VPath *polygon = new VPath( parent ); + appendPoints( *polygon, o ); + appendPen( *polygon ); + appendBrush( *polygon ); + obj = polygon; + } + else if( name == "path" ) // path + { + storeObjectStyles( o ); + VPath *path = new VPath( parent ); + path->loadSvgPath( o.attributeNS( ooNS::svg, "d", QString::null ) ); + KoRect rect = parseViewBox( o ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", QString::null ) ) ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", QString::null ) ); + QWMatrix mat; + mat.translate( x, y ); + mat.scale( w / rect.width(), -h / rect.height() ); + path->transform( mat ); + appendPen( *path ); + appendBrush( *path ); + obj = path; + } +/*else if( name == "draw:image" ) // image +{ +storeObjectStyles( o ); +e = doc.createElement( "OBJECT" ); +e.setAttribute( "type", 0 ); +appendImage( doc, e, pictureElement, o ); +}*/ + else + { + kdDebug() << "Unsupported object '" << name << "'" << endl; + continue; + } + if( parent && obj ) + parent->append( obj ); + else if( obj ) + m_document.append( obj ); + } +} + +void +OoDrawImport::appendPen( VObject &obj ) +{ + if( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" ) ) + { + VStroke stroke; + + if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" ) + stroke.setType( VStroke::none ); + else if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" ) + stroke.setType( VStroke::solid ); + else if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" ) + { + QValueList dashes; + stroke.setType( VStroke::solid ); + QString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" ); + if( style == "Ultrafine Dashed" || + style == "Fine Dashed (var)" || style == "Dashed (var)" ) + stroke.dashPattern().setArray( dashes << 2 << 2 ); + else if( style == "Fine Dashed" ) + stroke.dashPattern().setArray( dashes << 10 << 10 ); + else if( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" || + style == "Line with Fine Dots" ) + stroke.dashPattern().setArray( dashes << 2 << 10 ); + else if( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" ) + stroke.dashPattern().setArray( dashes << 3 << 3 ); + else if( style == "2 Dots 1 Dash" ) + stroke.dashPattern().setArray( dashes << 2 << 1 ); + } + if( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) ) + { + double lwidth = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) ); + if( lwidth == 0 ) + lwidth = 1.0; + stroke.setLineWidth( lwidth ); + } + if( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) ) + { + VColor c; + parseColor( c, m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) ); + stroke.setColor( c ); + } + + obj.setStroke( stroke ); + } +} + +void +OoDrawImport::appendBrush( VObject &obj ) +{ + if( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) ) + { + const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" ); + VFill f; + + if( fill == "solid" ) + { + f.setType( VFill::solid ); + if( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) ) + { + VColor c; + parseColor( c, m_styleStack.attributeNS( ooNS::draw, "fill-color" ) ); + f.setColor( c ); + } + } + else if( fill == "gradient" ) + { + VGradient gradient; + gradient.clearStops(); + gradient.setRepeatMethod( VGradient::none ); + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" ); + + QDomElement* draw = m_draws[style]; + if( draw ) + { + double border = 0.0; + if( draw->hasAttributeNS( ooNS::draw, "border" ) ) + border += draw->attributeNS( ooNS::draw, "border", QString::null ).remove( '%' ).toDouble() / 100.0; + VColor c; + parseColor( c, draw->attributeNS( ooNS::draw, "start-color", QString::null ) ); + gradient.addStop( c, border, 0.5 ); + parseColor( c, draw->attributeNS( ooNS::draw, "end-color", QString::null ) ); + gradient.addStop( c, 1.0, 0.5 ); + + QString type = draw->attributeNS( ooNS::draw, "style", QString::null ); + if( type == "linear" || type == "axial" ) + { + gradient.setType( VGradient::linear ); + int angle = draw->attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10; + + // make sure the angle is between 0 and 359 + angle = abs( angle ); + angle -= ( (int) ( angle / 360 ) ) * 360; + + // What we are trying to do here is to find out if the given + // angle belongs to a horizontal, vertical or diagonal gradient. + int lower, upper, nearAngle = 0; + for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 ) + { + if( upper >= angle ) + { + int distanceToUpper = abs( angle - upper ); + int distanceToLower = abs( angle - lower ); + nearAngle = distanceToUpper > distanceToLower ? lower : upper; + break; + } + } + KoRect rect = obj.boundingBox(); + KoPoint origin, vector; + // nearAngle should now be one of: 0, 45, 90, 135, 180... + kdDebug() << "nearAngle: " << nearAngle << endl; + if( nearAngle == 0 || nearAngle == 180 ) + { + origin.setX( rect.x() + rect.width() ); + origin.setY( rect.y() + rect.height()); + vector.setX( rect.x() + rect.width() ); + vector.setY( rect.y() ); + } + else if( nearAngle == 90 || nearAngle == 270 ) + { + origin.setX( rect.x() ); + origin.setY( rect.y() + rect.height() ); + vector.setX( rect.x() + rect.width() ); + vector.setY( rect.y() + rect.height() ); + } + else if( nearAngle == 45 || nearAngle == 225 ) + { + origin.setX( rect.x() ); + origin.setY( rect.y() ); + vector.setX( rect.x() + rect.width() ); + vector.setY( rect.y() + rect.height() ); + } + else if( nearAngle == 135 || nearAngle == 315 ) + { + origin.setX( rect.x() + rect.width() ); + origin.setY( rect.y() + rect.height() ); + vector.setX( rect.x() ); + vector.setY( rect.y() ); + } + + gradient.setOrigin( origin ); + gradient.setVector( vector ); + } + else if( type == "radial" || type == "ellipsoid" ) + { + gradient.setType( VGradient::radial ); +//else if( type == "square" || type == "rectangular" ) +//gradient.setAttribute( "type", 6 ); // rectangle +//else if( type == "axial" ) +//gradient.setAttribute( "type", 7 ); // pipecross + + // Hard to map between x- and y-center settings of oodraw + // and (un-)balanced settings of kpresenter. Let's try it. + double x, y; + if( draw->hasAttributeNS( ooNS::draw, "cx" ) ) + x = draw->attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toDouble() / 100.0; + else + x = 0.5; + + if( draw->hasAttributeNS( ooNS::draw, "cy" ) ) + y = draw->attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toDouble() / 100.0; + else + y = 0.5; + + KoRect rect = obj.boundingBox(); + gradient.setOrigin( KoPoint( rect.x() + x * rect.width(), + rect.y() + y * rect.height() ) ); + gradient.setFocalPoint( KoPoint( rect.x() + x * rect.width(), + rect.y() + y * rect.height() ) ); + gradient.setVector( KoPoint( rect.x() + rect.width(), + rect.y() + y * rect.height() ) ); + } + f.gradient() = gradient; + f.setType( VFill::grad ); + } + } + obj.setFill( f ); + } +/*else if( fill == "hatch" ) +{ +QDomElement brush = doc.createElement( "BRUSH" ); +QString style = m_styleStack.attributeNS( "fill-hatch-name" ); +if( style == "Black 0 Degrees" ) +brush.setAttribute( "style", 9 ); +else if( style == "Black 90 Degrees" ) +brush.setAttribute( "style", 10 ); +else if( style == "Red Crossed 0 Degrees" || style == "Blue Crossed 0 Degrees" ) +brush.setAttribute( "style", 11 ); +else if( style == "Black 45 Degrees" || style == "Black 45 Degrees Wide" ) +brush.setAttribute( "style", 12 ); +else if( style == "Black -45 Degrees" ) +brush.setAttribute( "style", 13 ); +else if( style == "Red Crossed 45 Degrees" || style == "Blue Crossed 45 Degrees" ) +brush.setAttribute( "style", 14 ); + +QDomElement* draw = m_draws[style]; +if( draw && draw->hasAttributeNS( "color" ) ) +brush.setAttribute( "color", draw->attributeNS( "color" ) ); +e.appendChild( brush ); +}*/ +} + +void +OoDrawImport::createStyleMap( QDomDocument &docstyles ) +{ + QDomElement styles = docstyles.documentElement(); + if( styles.isNull() ) + return; + + QDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" ); + if( !fixedStyles.isNull() ) + { + insertDraws( fixedStyles.toElement() ); + insertStyles( fixedStyles.toElement() ); + } + QDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" ); + if( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + QDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" ); + if( !masterStyles.isNull() ) + insertStyles( masterStyles.toElement() ); +} + +void +OoDrawImport::insertDraws( const QDomElement& styles ) +{ + for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + + if( !e.hasAttributeNS( ooNS::draw, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::draw, "name", QString::null ); + m_draws.insert( name, new QDomElement( e ) ); + } +} + + +void +OoDrawImport::insertStyles( const QDomElement& styles ) +{ + for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + + if( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::style, "name", QString::null ); + m_styles.insert( name, new QDomElement( e ) ); + //kdDebug() << "Style: '" << name << "' loaded " << endl; + } +} + +void +OoDrawImport::fillStyleStack( const QDomElement& object ) +{ + // find all styles associated with an object and push them on the stack + if( object.hasAttributeNS( ooNS::presentation, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::presentation, "style-name", QString::null )] ); + + if( object.hasAttributeNS( ooNS::draw, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", QString::null )] ); + + if( object.hasAttributeNS( ooNS::draw, "text-style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", QString::null )] ); + + if( object.hasAttributeNS( ooNS::text, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::text, "style-name", QString::null )] ); +} + +void +OoDrawImport::addStyles( const QDomElement* style ) +{ + // this function is necessary as parent styles can have parents themself + if( style->hasAttributeNS( ooNS::style, "parent-style-name" ) ) + addStyles( m_styles[style->attributeNS( ooNS::style, "parent-style-name", QString::null )] ); + + m_styleStack.push( *style ); +} + +void +OoDrawImport::storeObjectStyles( const QDomElement& object ) +{ + //m_styleStack.clearPageMark(); // remove styles of previous object + fillStyleStack( object ); + //m_styleStack.setObjectMark(); +} + +KoRect +OoDrawImport::parseViewBox( const QDomElement& object ) +{ + KoRect rect; + if( !object.attributeNS( ooNS::svg, "viewBox", QString::null ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + QString viewbox( object.attributeNS( ooNS::svg, "viewBox", QString::null ) ); + QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() ); + + rect.setX( points[0].toFloat() ); + rect.setY( points[1].toFloat() ); + rect.setWidth( points[2].toFloat() ); + rect.setHeight( points[3].toFloat() ); + } + return rect; +} + +void +OoDrawImport::appendPoints(VPath &path, const QDomElement& object) +{ + double x = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", QString::null ) ); + double w = KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", QString::null ) ); + + KoRect rect = parseViewBox( object ); + rect.setX( rect.x() + x ); + rect.setY( rect.y() + y ); + + QStringList ptList = QStringList::split( ' ', object.attributeNS( ooNS::draw, "points", QString::null ) ); + + QString pt_x, pt_y; + double tmp_x, tmp_y; + KoPoint point; + bool bFirst = true; + for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it ) + { + tmp_x = rect.x() + ( (*it).section( ',', 0, 0 ).toInt() * w ) / rect.width(); + tmp_y = rect.y() + ( (*it).section( ',', 1, 1 ).toInt() * h ) / rect.height(); + + point.setX( tmp_x ); + point.setY( ymirror( tmp_y ) ); + if( bFirst ) + { + path.moveTo( point ); + bFirst = false; + } + else + path.lineTo( point ); + } +} + +void +OoDrawImport::parseColor( VColor &color, const QString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + QString parse = s.stripWhiteSpace(); + QStringList colors = QStringList::split( ',', parse ); + QString r = colors[0].right( ( colors[0].length() - 4 ) ); + QString g = colors[1]; + QString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + QColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else + { + QString rgbColor = s.stripWhiteSpace(); + QColor c; + if( rgbColor.startsWith( "#" ) ) + c.setNamedColor( rgbColor ); + //else + // c = parseColor( rgbColor ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } +} + +double +OoDrawImport::ymirror( double y ) +{ + return m_document.height() - y; +} + +#include "oodrawimport.moc" diff --git a/filters/karbon/oodraw/oodrawimport.h b/filters/karbon/oodraw/oodrawimport.h new file mode 100644 index 00000000..06e664ac --- /dev/null +++ b/filters/karbon/oodraw/oodrawimport.h @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (c) 2003 Rob Buis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef OODRAW_IMPORT_H__ +#define OODRAW_IMPORT_H__ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +class KZip; + +class VGroup; + +class OoDrawImport : public KoFilter +{ + Q_OBJECT +public: + OoDrawImport( KoFilter *parent, const char *name, const QStringList & ); + virtual ~OoDrawImport(); + + virtual KoFilter::ConversionStatus convert( QCString const & from, QCString const & to ); + +private: + void createDocumentInfo( QDomDocument &docinfo ); + + void createStyleMap( QDomDocument &docstyles ); + void insertStyles( const QDomElement& styles ); + void insertDraws( const QDomElement& styles ); + void fillStyleStack( const QDomElement& object ); + void addStyles( const QDomElement* style ); + void storeObjectStyles( const QDomElement& object ); + void appendPen( VObject &obj ); + void appendBrush( VObject &obj ); + void appendPoints(VPath &path, const QDomElement& object); + void convert(); + void parseGroup( VGroup *parent, const QDomElement& object ); + void parseColor( VColor &color, const QString &s ); + double ymirror( double y ); + KoRect parseViewBox( const QDomElement& object ); + + KoFilter::ConversionStatus openFile(); + KoFilter::ConversionStatus loadAndParse(const QString& filename, QDomDocument& doc); + + VDocument m_document; + QDomDocument m_content; + QDomDocument m_meta; + QDomDocument m_settings; + QDict m_styles, m_draws; + KoStyleStack m_styleStack; + KZip * m_zip; + +}; + +#endif diff --git a/filters/karbon/png/Makefile.am b/filters/karbon/png/Makefile.am new file mode 100644 index 00000000..5d8a4efb --- /dev/null +++ b/filters/karbon/png/Makefile.am @@ -0,0 +1,27 @@ +kde_module_LTLIBRARIES = libkarbonpngexport.la + +libkarbonpngexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonpngexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/render \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_png_export.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + pngexport.h + +libkarbonpngexport_la_SOURCES = \ + pngexport.cc + +libkarbonpngexport_la_METASOURCES = \ + AUTO + diff --git a/filters/karbon/png/karbon_png_export.desktop b/filters/karbon/png/karbon_png_export.desktop new file mode 100644 index 00000000..e3715bc0 --- /dev/null +++ b/filters/karbon/png/karbon_png_export.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Icon= +Name=Karbon14 PNG Export Filter +Name[af]=Karbon14 Png Voer uit Filter +Name[ar]=賲賽乇賿卮賻丨 鬲氐丿賷乇 PNG 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 械泻褋锌芯褉褌懈褉邪薪械 芯褌 Karbon14 胁 PNG +Name[br]=Sil ezporzh PNG evit Karbon14 +Name[ca]=Filtre d'exportaci贸 PNG per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu PNG pro Karbon14 +Name[cy]=Hidlen Allforio PNG Karbon14 +Name[da]=Karbon14 SVG-eksportfilter +Name[de]=Karbon14 PNG-Exportfilter +Name[el]=桅委位蟿蟻慰 蔚尉伪纬蠅纬萎蟼 PNG 蟿慰蠀 Karbon14 +Name[eo]=Karbon-PNG-eksportfiltrilo +Name[es]=Filtro de exportaci贸n Karbon14 PNG +Name[et]=Karbon14 PNG ekspordifilter +Name[eu]=Karbon14-en PNG esportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 氐丕丿乇丕鬲 Karbon14 PNG +Name[fi]=Karbon14 PNG -vientisuodin +Name[fr]=Filtre d'exportation PNG de Karbon 14 +Name[fy]=PNG-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easp贸rt谩la PNG Karbon14 +Name[gl]=Filtro de Exportaci贸n de PNG para Karbon14 +Name[he]=诪住谞谉 讬讬爪讜讗 诪志Karbon14 诇志PNG +Name[hr]=Karbon14 SVG filtar izvoza +Name[hu]=Karbon14 PNG exportsz疟r艖 +Name[is]=Karbon14 PNG 煤tflutningss铆a +Name[it]=Filtro di esportazione PNG per Karbon14 +Name[ja]=Karbon14 PNG 銈ㄣ偗銈广儩銉笺儓銉曘偅銉偪 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩焷釣 PNG 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權邯嗪秽粓嗪囙涵嗪簛 PNG 嗪傕涵嗪 Karbon14 +Name[lt]=Karbon14 PNG eksportavimo filtras +Name[lv]=Karbon14 PNG eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 PNG +Name[mt]=Filtru g魔all-esportazzjoni ta' PNG minn 摹o Karbon14 +Name[nb]=PNG-eksportfilter for Karbon14 +Name[nds]=PNG-Exportfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶啶忇え啶溹 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=PNG-exportfilter voor Karbon14 +Name[nn]=PNG-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu PNG z Karbon14 +Name[pt]=Filtro de Exporta莽茫o de PNG para o Karbon14 +Name[pt_BR]=Filtro de Exporta莽茫o PNG do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru SVG +Name[ru]=肖懈谢褜褌褉 褝泻褋锌芯褉褌邪 褉懈褋褍薪泻芯胁 Karbon 胁 PNG +Name[se]=Karbon14:a PNG-olggosfievrridansilli +Name[sk]=PNG filter pre export z Karbon14 +Name[sl]=Izvozni filter PNG za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 懈蟹胁芯蟹 褍 PNG +Name[sr@Latn]=Karbon14-ov filter za izvoz u PNG +Name[sv]=Karbon14 PNG-exportfilter +Name[ta]=Karbon 14 PNG S 喈忇喁嵿喁佮喈む 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 PNG 肖懈谢褌褉懈 小芯写懈褉芯褌 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔箞喔囙腑喔竵 PNG 喔傕腑喔 Karbon14 +Name[tr]=Karbon14 PNG Aktarma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 SVG 写谢褟 Karbon14 +Name[uz]=Karbon14 PNG eksport filteri +Name[uz@cyrillic]=Karbon14 PNG 褝泻褋锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba ngaphandle se Karbon14 PNG +Name[zh_CN]=Karbon14 PNG 瀵煎嚭杩囨护鍣 +Name[zh_TW]=Karbon14 EPS 鍖嚭閬庢烤绋嬪紡 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/png +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonpngexport +X-KDE-Weight=1 diff --git a/filters/karbon/png/pngexport.cc b/filters/karbon/png/pngexport.cc new file mode 100644 index 00000000..652074e9 --- /dev/null +++ b/filters/karbon/png/pngexport.cc @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pngexport.h" +#include "vdocument.h" +#include "vselection.h" +#include "vkopainter.h" +#include "vlayer.h" +#include "vcomputeboundingbox.h" + +#include + + +typedef KGenericFactory PngExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonpngexport, PngExportFactory( "kofficefilters" ) ) + + +PngExport::PngExport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ +} + +KoFilter::ConversionStatus +PngExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/png" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if( !storeIn ) + return KoFilter::StupidError; + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + // load the document and export it: + VDocument doc; + doc.load( docNode ); + + // calculate the documents bounding box + VComputeBoundingBox bbox( true ); + doc.accept( bbox ); + const KoRect &rect = bbox.boundingRect(); + + // create image with correct width and height + QImage img( int( rect.width() ), int( rect.height() ), 32 ); + //img.setAlphaBuffer( true ); + + // Create painter and set up objects to draw + VKoPainter p( img.bits(), rect.width(), rect.height() ); + p.clear( qRgba( 0xFF, 0xFF, 0xFF, 0xFF ) ); + p.setWorldMatrix( QWMatrix().translate( -rect.x(), -rect.y() ) ); + + doc.draw( &p, &rect ); + + QImage image = img.swapRGB(); + QImage mirrored = image.mirror( false, true ); + // save png + mirrored.save( m_chain->outputFile(), "PNG" ); + + return KoFilter::OK; +} + +#include "pngexport.moc" + diff --git a/filters/karbon/png/pngexport.h b/filters/karbon/png/pngexport.h new file mode 100644 index 00000000..a14e81c8 --- /dev/null +++ b/filters/karbon/png/pngexport.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __PNGEXPORT_H__ +#define __PNGEXPORT_H__ + +#include + +#include "vvisitor.h" + +class PngExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + PngExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~PngExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif + diff --git a/filters/karbon/svg/Makefile.am b/filters/karbon/svg/Makefile.am new file mode 100644 index 00000000..a1b01f9b --- /dev/null +++ b/filters/karbon/svg/Makefile.am @@ -0,0 +1,34 @@ +kde_module_LTLIBRARIES = libkarbonsvgexport.la libkarbonsvgimport.la + +libkarbonsvgexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonsvgexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +libkarbonsvgimport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonsvgimport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_svg_export.desktop karbon_svg_import.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + svgexport.h + +libkarbonsvgexport_la_SOURCES = \ + svgexport.cc + +METASOURCES = AUTO + +libkarbonsvgimport_la_SOURCES = \ + svgimport.cc + diff --git a/filters/karbon/svg/TODO b/filters/karbon/svg/TODO new file mode 100644 index 00000000..999f37a6 --- /dev/null +++ b/filters/karbon/svg/TODO @@ -0,0 +1,8 @@ +SVG export +- patterns +- text + +SVG import +- units (cm, mm) +- trafo's +- fix text diff --git a/filters/karbon/svg/color.h b/filters/karbon/svg/color.h new file mode 100644 index 00000000..bfdc93c6 --- /dev/null +++ b/filters/karbon/svg/color.h @@ -0,0 +1,306 @@ + +#define TORGB( red, green, blue ) \ +{ \ + r = red; \ + b = blue; \ + g = green; \ +} + +void keywordToRGB( QString rgbColor, int &r, int &g, int &b ) +{ + if( rgbColor == "aliceblue" ) + TORGB( 240, 248, 255) + else if( rgbColor == "antiquewhite" ) + TORGB( 250, 235, 215) + else if( rgbColor == "aqua" ) + TORGB( 0, 255, 255) + else if( rgbColor == "aquamarine" ) + TORGB( 127, 255, 212 ) + else if( rgbColor == "azure" ) + TORGB( 240, 255, 255 ) + else if( rgbColor == "beige" ) + TORGB( 245, 245, 220 ) + else if( rgbColor == "bisque" ) + TORGB( 255, 228, 196 ) + else if( rgbColor == "black" ) + TORGB( 0, 0, 0 ) + else if( rgbColor == "blanchedalmond" ) + TORGB( 255, 235, 205 ) + else if( rgbColor == "blue" ) + TORGB( 0, 0, 255 ) + else if( rgbColor == "blueviolet" ) + TORGB( 138, 43, 226 ) + else if( rgbColor == "brown" ) + TORGB( 165, 42, 42 ) + else if( rgbColor == "burlywood" ) + TORGB( 222, 184, 135 ) + else if( rgbColor == "cadetblue" ) + TORGB( 95, 158, 160 ) + else if( rgbColor == "chartreuse" ) + TORGB( 127, 255, 0 ) + else if( rgbColor == "chocolate" ) + TORGB( 210, 105, 30 ) + else if( rgbColor == "coral" ) + TORGB( 255, 127, 80 ) + else if( rgbColor == "cornflowerblue" ) + TORGB( 100, 149, 237 ) + else if( rgbColor == "cornsilk" ) + TORGB( 255, 248, 220 ) + else if( rgbColor == "crimson" ) + TORGB( 220, 20, 60 ) + else if( rgbColor == "cyan" ) + TORGB( 0, 255, 255 ) + else if( rgbColor == "darkblue" ) + TORGB( 0, 0, 139 ) + else if( rgbColor == "darkcyan" ) + TORGB( 0, 139, 139 ) + else if( rgbColor == "darkgoldenrod" ) + TORGB( 184, 134, 11 ) + else if( rgbColor == "darkgray" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgrey" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgreen" ) + TORGB( 0, 100, 0 ) + else if( rgbColor == "darkkhaki" ) + TORGB( 189, 183, 107 ) + else if( rgbColor == "darkmagenta" ) + TORGB( 139, 0, 139 ) + else if( rgbColor == "darkolivegreen" ) + TORGB( 85, 107, 47 ) + else if( rgbColor == "darkorange" ) + TORGB( 255, 140, 0 ) + else if( rgbColor == "darkorchid" ) + TORGB( 153, 50, 204 ) + else if( rgbColor == "darkred" ) + TORGB( 139, 0, 0 ) + else if( rgbColor == "darksalmon" ) + TORGB( 233, 150, 122 ) + else if( rgbColor == "darkseagreen" ) + TORGB( 143, 188, 143 ) + else if( rgbColor == "darkslateblue" ) + TORGB( 72, 61, 139 ) + else if( rgbColor == "darkslategray" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkslategrey" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkturquoise" ) + TORGB( 0, 206, 209 ) + else if( rgbColor == "darkviolet" ) + TORGB( 148, 0, 211 ) + else if( rgbColor == "deeppink" ) + TORGB( 255, 20, 147 ) + else if( rgbColor == "deepskyblue" ) + TORGB( 0, 191, 255 ) + else if( rgbColor == "dimgray" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dimgrey" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dodgerblue" ) + TORGB( 30, 144, 255 ) + else if( rgbColor == "firebrick" ) + TORGB( 178, 34, 34 ) + else if( rgbColor == "floralwhite" ) + TORGB( 255, 250, 240 ) + else if( rgbColor == "forestgreen" ) + TORGB( 34, 139, 34 ) + else if( rgbColor == "fuchsia" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "gainsboro" ) + TORGB( 220, 220, 220 ) + else if( rgbColor == "ghostwhite" ) + TORGB( 248, 248, 255 ) + else if( rgbColor == "gold" ) + TORGB( 255, 215, 0 ) + else if( rgbColor == "goldenrod" ) + TORGB( 218, 165, 32 ) + else if( rgbColor == "gray" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "grey" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "green" ) + TORGB( 0, 128, 0 ) + else if( rgbColor == "greenyellow" ) + TORGB( 173, 255, 47 ) + else if( rgbColor == "honeydew" ) + TORGB( 240, 255, 240 ) + else if( rgbColor == "hotpink" ) + TORGB( 255, 105, 180 ) + else if( rgbColor == "indianred" ) + TORGB( 205, 92, 92 ) + else if( rgbColor == "indigo" ) + TORGB( 75, 0, 130 ) + else if( rgbColor == "ivory" ) + TORGB( 255, 255, 240 ) + else if( rgbColor == "khaki" ) + TORGB( 240, 230, 140 ) + else if( rgbColor == "lavender" ) + TORGB( 230, 230, 250 ) + else if( rgbColor == "lavenderblush" ) + TORGB( 255, 240, 245 ) + else if( rgbColor == "lawngreen" ) + TORGB( 124, 252, 0 ) + else if( rgbColor == "lemonchiffon" ) + TORGB( 255, 250, 205 ) + else if( rgbColor == "lightblue" ) + TORGB( 173, 216, 230 ) + else if( rgbColor == "lightcoral" ) + TORGB( 240, 128, 128 ) + else if( rgbColor == "lightcyan" ) + TORGB( 224, 255, 255 ) + else if( rgbColor == "lightgoldenrodyellow" ) + TORGB( 250, 250, 210 ) + else if( rgbColor == "lightgray" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgrey" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgreen" ) + TORGB( 144, 238, 144 ) + else if( rgbColor == "lightpink" ) + TORGB( 255, 182, 193 ) + else if( rgbColor == "lightsalmon" ) + TORGB( 255, 160, 122 ) + else if( rgbColor == "lightseagreen" ) + TORGB( 32, 178, 170 ) + else if( rgbColor == "lightskyblue" ) + TORGB( 135, 206, 250 ) + else if( rgbColor == "lightslategray" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightslategrey" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightsteelblue" ) + TORGB( 176, 196, 222 ) + else if( rgbColor == "lightyellow" ) + TORGB( 255, 255, 224 ) + else if( rgbColor == "lime" ) + TORGB( 0, 255, 0 ) + else if( rgbColor == "limegreen" ) + TORGB( 50, 205, 50 ) + else if( rgbColor == "linen" ) + TORGB( 250, 240, 230 ) + else if( rgbColor == "magenta" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "maroon" ) + TORGB( 128, 0, 0 ) + else if( rgbColor == "mediumaquamarine" ) + TORGB( 102, 205, 170 ) + else if( rgbColor == "mediumblue" ) + TORGB( 0, 0, 205 ) + else if( rgbColor == "mediumorchid" ) + TORGB( 186, 85, 211 ) + else if( rgbColor == "mediumpurple" ) + TORGB( 147, 112, 219 ) + else if( rgbColor == "mediumseagreen" ) + TORGB( 60, 179, 113 ) + else if( rgbColor == "mediumslateblue" ) + TORGB( 123, 104, 238 ) + else if( rgbColor == "mediumspringgreen" ) + TORGB( 0, 250, 154 ) + else if( rgbColor == "mediumturquoise" ) + TORGB( 72, 209, 204 ) + else if( rgbColor == "mediumvioletred" ) + TORGB( 199, 21, 133 ) + else if( rgbColor == "midnightblue" ) + TORGB( 25, 25, 112 ) + else if( rgbColor == "mintcream" ) + TORGB( 245, 255, 250 ) + else if( rgbColor == "mistyrose" ) + TORGB( 255, 228, 225 ) + else if( rgbColor == "moccasin" ) + TORGB( 255, 228, 181 ) + else if( rgbColor == "navajowhite" ) + TORGB( 255, 222, 173 ) + else if( rgbColor == "navy" ) + TORGB( 0, 0, 128 ) + else if( rgbColor == "oldlace" ) + TORGB( 253, 245, 230 ) + else if( rgbColor == "olive" ) + TORGB( 128, 128, 0 ) + else if( rgbColor == "olivedrab" ) + TORGB( 107, 142, 35 ) + else if( rgbColor == "orange" ) + TORGB( 255, 165, 0 ) + else if( rgbColor == "orangered" ) + TORGB( 255, 69, 0 ) + else if( rgbColor == "orchid" ) + TORGB( 218, 112, 214 ) + else if( rgbColor == "palegoldenrod" ) + TORGB( 238, 232, 170 ) + else if( rgbColor == "palegreen" ) + TORGB( 152, 251, 152 ) + else if( rgbColor == "paleturquoise" ) + TORGB( 175, 238, 238 ) + else if( rgbColor == "palevioletred" ) + TORGB( 219, 112, 147 ) + else if( rgbColor == "papayawhip" ) + TORGB( 255, 239, 213 ) + else if( rgbColor == "peachpuff" ) + TORGB( 255, 218, 185 ) + else if( rgbColor == "peru" ) + TORGB( 205, 133, 63 ) + else if( rgbColor == "pink" ) + TORGB( 255, 192, 203 ) + else if( rgbColor == "plum" ) + TORGB( 221, 160, 221 ) + else if( rgbColor == "powderblue" ) + TORGB( 176, 224, 230 ) + else if( rgbColor == "purple" ) + TORGB( 128, 0, 128 ) + else if( rgbColor == "red" ) + TORGB( 255, 0, 0 ) + else if( rgbColor == "rosybrown" ) + TORGB( 188, 143, 143 ) + else if( rgbColor == "royalblue" ) + TORGB( 65, 105, 225 ) + else if( rgbColor == "saddlebrown" ) + TORGB( 139, 69, 19 ) + else if( rgbColor == "salmon" ) + TORGB( 250, 128, 114 ) + else if( rgbColor == "sandybrown" ) + TORGB( 244, 164, 96 ) + else if( rgbColor == "seagreen" ) + TORGB( 46, 139, 87 ) + else if( rgbColor == "seashell" ) + TORGB( 255, 245, 238 ) + else if( rgbColor == "sienna" ) + TORGB( 160, 82, 45 ) + else if( rgbColor == "silver" ) + TORGB( 192, 192, 192 ) + else if( rgbColor == "skyblue" ) + TORGB( 135, 206, 235 ) + else if( rgbColor == "slateblue" ) + TORGB( 106, 90, 205 ) + else if( rgbColor == "slategray" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "slategrey" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "snow" ) + TORGB( 255, 250, 250 ) + else if( rgbColor == "springgreen" ) + TORGB( 0, 255, 127 ) + else if( rgbColor == "steelblue" ) + TORGB( 70, 130, 180 ) + else if( rgbColor == "tan" ) + TORGB( 210, 180, 140 ) + else if( rgbColor == "teal" ) + TORGB( 0, 128, 128 ) + else if( rgbColor == "thistle" ) + TORGB( 216, 191, 216 ) + else if( rgbColor == "tomato" ) + TORGB( 255, 99, 71 ) + else if( rgbColor == "turquoise" ) + TORGB( 64, 224, 208 ) + else if( rgbColor == "violet" ) + TORGB( 238, 130, 238 ) + else if( rgbColor == "wheat" ) + TORGB( 245, 222, 179 ) + else if( rgbColor == "white" ) + TORGB( 255, 255, 255 ) + else if( rgbColor == "whitesmoke" ) + TORGB( 245, 245, 245 ) + else if( rgbColor == "yellow" ) + TORGB( 255, 255, 0 ) + else if( rgbColor == "yellowgreen" ) + TORGB( 154, 205, 50 ) +} + diff --git a/filters/karbon/svg/karbon_svg_export.desktop b/filters/karbon/svg/karbon_svg_export.desktop new file mode 100644 index 00000000..e0990478 --- /dev/null +++ b/filters/karbon/svg/karbon_svg_export.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Icon= +Name=Karbon14 SVG Export Filter +Name[af]=Karbon14 Svg Voer uit Filter +Name[ar]=賲賽乇賿卮賻丨 鬲氐丿賷乇 SVG 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 械泻褋锌芯褉褌懈褉邪薪械 芯褌 Karbon14 胁 SVG +Name[br]=Sil ezporzh SVG evit Karbon14 +Name[ca]=Filtre d'exportaci贸 SVG per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu SVG pro Karbon14 +Name[cy]=Hidlen Allforio SVG Karbon14 +Name[da]=Karbon14 SVG-eksportfilter +Name[de]=Karbon14 SVG-Exportfilter +Name[el]=桅委位蟿蟻慰 蔚尉伪纬蠅纬萎蟼 SVG 蟿慰蠀 Karbon14 +Name[eo]=Karbon-SVG-eksportfiltrilo +Name[es]=Filtro de exportaci贸n Karbon14 SVG +Name[et]=Karbon14 SVG ekspordifilter +Name[eu]=Karbon14-en SVG esportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 氐丕丿乇丕鬲 Karbon14 SVG +Name[fi]=Karbon14 SVG -vientisuodin +Name[fr]=Filtre d'exportation SVG de Karbon 14 +Name[fy]=SVG-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easp贸rt谩la SVG Karbon14 +Name[gl]=Filtro de Exportaci贸n de SVG para Karbon14 +Name[he]=诪住谞谉 讬讬爪讜讗 诪志Karbon14 诇志SVG +Name[hr]=Karbon14 SVG filtar izvoza +Name[hu]=Karbon14 SVG exportsz疟r艖 +Name[is]=Karbon14 SVG 煤tflutningss铆a +Name[it]=Filtro di esportazione SVG per Karbon14 +Name[ja]=Karbon14 SVG 銈ㄣ偗銈广儩銉笺儓銉曘偅銉偪 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩焷釣 SVG 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lo]= 嗪曕夯嗪о簳嗪簢嗪佮翰嗪權邯嗪秽粓嗪囙涵嗪簛 SVG 嗪傕涵嗪 Karbon14 +Name[lt]=Karbon14 SVG eksportavimo filtras +Name[lv]=Karbon14 SVG eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 SVG +Name[mt]=Filtru g魔all-esportazzjoni ta' SVG minn 摹o Karbon14 +Name[nb]=SVG-eksportfiler for Karbon14 +Name[nds]=SVG-Exportfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶忇じ啶啶溹 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=SVG-exportfilter voor Karbon14 +Name[nn]=SVG-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu SVG z Karbon14 +Name[pt]=Filtro de Exporta莽茫o de SVG para o Karbon14 +Name[pt_BR]=Filtro de Exporta莽茫o SVG do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru SVG +Name[ru]=肖懈谢褜褌褉 褝泻褋锌芯褉褌邪 褉懈褋褍薪泻芯胁 Karbon 胁 SVG +Name[se]=Karbon14:a SVG-olggosfievrridansilli +Name[sk]=SVG filter pre export z Karbon14 +Name[sl]=Izvozni filter SVG za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 懈蟹胁芯蟹 褍 SVG +Name[sr@Latn]=Karbon14-ov filter za izvoz u SVG +Name[sv]=Karbon14 SVG-exportfilter +Name[ta]=Karbon 14 SVG 喈忇喁嵿喁佮喈む 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 SVG 肖懈谢褌褉懈 小芯写懈褉芯褌 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔箞喔囙腑喔竵 SVG 喔傕腑喔 Karbon14 +Name[tr]=Karbon14 SVG Aktarma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 SVG 写谢褟 Karbon14 +Name[uz]=Karbon14 SVG eksport filteri +Name[uz@cyrillic]=Karbon14 SVG 褝泻褋锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba Sangaphandle se Karbon14 SVG +Name[zh_CN]=Karbon14 SVG 瀵煎嚭杩囨护鍣 +Name[zh_TW]=Karbon14 SVG 鍖嚭閬庢烤绋嬪紡 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/svg+xml +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonsvgexport +X-KDE-Weight=1 diff --git a/filters/karbon/svg/karbon_svg_import.desktop b/filters/karbon/svg/karbon_svg_import.desktop new file mode 100644 index 00000000..a1f7eaea --- /dev/null +++ b/filters/karbon/svg/karbon_svg_import.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +Type=Service +Name=Karbon SVG Import Filter +Name[af]=Karbon Svg In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 SVG 賱丿賶 Karbon +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 SVG 胁 Karbon +Name[br]=Sil enporzh SVG evit Karbon +Name[ca]=Filtre d'importaci贸 SVG per a Karbon +Name[cs]=Exportn铆 filtr do form谩tu SVG pro Karbon +Name[cy]=Hidlen Fewnforio SVG Karbon +Name[da]=Karbon SVG-importfilter +Name[de]=Karbon14 SVG-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 SVG 蟿慰蠀 Karbon +Name[eo]=Karbon-SVG-importfiltrilo +Name[es]=Filtro de importaci贸n de SVG de Karbon +Name[et]=Karboni SVG impordifilter +Name[eu]=Karbon-en SVG inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon SVG +Name[fi]=Karbon SVG -tuontisuodin +Name[fr]=Filtre d'exportation SVG de Karbon 14 +Name[fy]=SVG-Ymportfilter foar Karbon +Name[ga]=Scagaire Iomp贸rt谩la Karbon SVG +Name[gl]=Filtro de Importaci贸n de SVG para Karbon +Name[he]=诪住谞谉 讬讬讘讜讗 诪志SVG 诇志Karbon +Name[hr]=Karbon SVG filtar uvoza +Name[hu]=Karbon SVG importsz疟r艖 +Name[is]=Karbon SVG innflutningss铆a +Name[it]=Filtro di importazione SVG per Karbon14 +Name[ja]=Karbon SVG 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 SVG 釣熱灅釤掅灇釣夺灁釤 Karbon +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰 EPS 嗪傕涵嗪囙簞嗪侧寒嗷屶簹嗪簷14 +Name[lt]=Karbon SVG importavimo filtras +Name[lv]=Karbon SVG importa filtrs +Name[ms]=Penapis Import Karbon SVG +Name[nb]=SVG-importfilter for Karbon +Name[nds]=SVG-Importfilter f枚r Karbon +Name[ne]=啶曕ぞ啶班啶え 啶忇じ啶啶溹 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=SVG-importfilter voor Karbon14 +Name[nn]=SVG-importfilter for Karbon +Name[pl]=Filtr importu formatu SVG do Karbon +Name[pt]=Filtro de Importa莽茫o de SVG para o Karbon +Name[pt_BR]=Filtro de Importa莽茫o SVG do Karbon +Name[ro]=Filtru importare Karbon14 pentru SVG +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褉懈褋褍薪泻芯胁 SVG 胁 Karbon +Name[se]=Karbon:a SVG-sisafievrridansilli +Name[sk]=SVG filter pre import do Karbon +Name[sl]=Uvozni filter SVG za Karbon +Name[sr]=Karbon-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 SVG-邪 +Name[sr@Latn]=Karbon-ov filter za uvoz iz SVG-a +Name[sv]=Karbon SVG-importfilter +Name[ta]=Karbon SVG 喈忇喁嵿喁佮喈む 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon SVG I 肖懈谢褌褉懈 袙芯褉懈写芯褌 +Name[tr]=Karbon SVG Alma Filtresi +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 屑邪谢褞薪泻褨胁 SVG 褍 Karbon +Name[uz]=Karbon SVG import filteri +Name[uz@cyrillic]=Karbon SVG 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba se Karbon SVG +Name[zh_CN]=Karbon SVG 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon SVG 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/svg+xml +X-KDE-Weight=1 +X-KDE-Library=libkarbonsvgimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/svg/svgexport.cc b/filters/karbon/svg/svgexport.cc new file mode 100644 index 00000000..4f434d4d --- /dev/null +++ b/filters/karbon/svg/svgexport.cc @@ -0,0 +1,512 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "svgexport.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vfill.h" +#include "vgradient.h" +#include "vgroup.h" +#include "vimage.h" +#include "vlayer.h" +#include "vpath.h" +#include "vpattern.h" +#include "vsegment.h" +#include "vselection.h" +#include "vstroke.h" +#include "vtext.h" +#include + +#include + +QString INDENT(" "); + +void +printIndentation( QTextStream *stream, unsigned int indent ) +{ + for( unsigned int i = 0; i < indent;++i) + *stream << INDENT; +} + +typedef KGenericFactory SvgExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonsvgexport, SvgExportFactory( "kofficefilters" ) ) + + +SvgExport::SvgExport( KoFilter*, const char*, const QStringList& ) + : KoFilter(), m_indent( 0 ), m_indent2( 0 ), m_trans( 0L ) +{ + m_gc.setAutoDelete( true ); +} + +KoFilter::ConversionStatus +SvgExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/svg+xml" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if( !storeIn ) + return KoFilter::StupidError; + + QFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + delete storeIn; + return KoFilter::StupidError; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QTextStream( &fileOut ); + QString body; + m_body = new QTextStream( &body, IO_ReadWrite ); + QString defs; + m_defs = new QTextStream( &defs, IO_ReadWrite ); + + // load the document and export it: + VDocument doc; + doc.load( docNode ); + doc.accept( *this ); + + *m_stream << defs; + *m_stream << body; + + fileOut.close(); + + delete m_stream; + delete m_defs; + delete m_body; + + return KoFilter::OK; +} + +void +SvgExport::visitVDocument( VDocument& document ) +{ + // select all objects: + document.selection()->append(); + + // get the bounding box of the page + KoRect rect( 0, 0, document.width(), document.height() ); + + // standard header: + *m_defs << + "\n" << + "" + << endl; + + // add some PR. one line is more than enough. + *m_defs << + "" << endl; + + *m_defs << + "" << endl; + printIndentation( m_defs, ++m_indent2 ); + *m_defs << "" << endl; + + m_indent++; + m_indent2++; + + // we dont need the selection anymore: + document.selection()->clear(); + + // set up gc + SvgGraphicsContext *gc = new SvgGraphicsContext; + m_gc.push( gc ); + + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -document.height() ); + + m_trans = new VTransformCmd( 0L, mat, false ); + + // export layers: + VVisitor::visitVDocument( document ); + + delete m_trans; + m_trans = 0L; + + // end tag: + printIndentation( m_defs, --m_indent2 ); + *m_defs << "" << endl; + *m_body << "" << endl; +} + +QString +SvgExport::getID( VObject *obj ) +{ + if( obj && !obj->name().isEmpty() ) + return QString( " id=\"%1\"" ).arg( obj->name() ); + return QString(); +} + +void +SvgExport::visitVGroup( VGroup& group ) +{ + printIndentation( m_body, m_indent++ ); + *m_body << "" << endl; + VVisitor::visitVGroup( group ); + printIndentation( m_body, --m_indent ); + *m_body << "" << endl; +} + +// horrible but at least something gets exported now +// will need this for patterns +void +SvgExport::visitVImage( VImage& image ) +{ + printIndentation( m_body, m_indent ); + *m_body << "" << endl; +} + +void +SvgExport::visitVLayer( VLayer& layer ) +{ + printIndentation( m_body, m_indent++ ); + *m_body << "" << endl; + //*m_body << " transform=\"scale(1, -1) translate(0, -" << layer.document()->height() << ")\">" << endl; + VVisitor::visitVLayer( layer ); + printIndentation( m_body, --m_indent ); + *m_body << "" << endl; +} + +void +SvgExport::writePathToStream( VPath &composite, const QString &id, QTextStream *stream, unsigned int indent ) +{ + if( ! stream ) + return; + + printIndentation( stream, indent ); + *stream << "fillRule ) + { + if( composite.fillRule() == evenOdd ) + *stream << " fill-rule=\"evenodd\""; + else + *stream << " fill-rule=\"nonzero\""; + } + + *stream << " />" << endl; +} + +void +SvgExport::visitVPath( VPath& composite ) +{ + m_trans->visitVPath( composite ); + writePathToStream( composite, getID( &composite ), m_body, m_indent ); + m_trans->visitVPath( composite ); +} + +void +SvgExport::visitVSubpath( VSubpath& ) +{ +} + +QString createUID() +{ + static unsigned int nr = 0; + + return "defitem" + QString().setNum( nr++ ); +} + +void +SvgExport::getColorStops( const QPtrVector &colorStops ) +{ + m_indent2++; + for( unsigned int i = 0; i < colorStops.count() ; i++ ) + { + printIndentation( m_defs, m_indent2 ); + *m_defs << "color ); + *m_defs << "\" offset=\"" << QString().setNum( colorStops.at( i )->rampPoint ); + *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl; + } + m_indent2--; +} + +void +SvgExport::getGradient( const VGradient& grad ) +{ + QString uid = createUID(); + if( grad.type() == VGradient::linear ) + { + printIndentation( m_defs, m_indent2 ); + // do linear grad + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } + else if( grad.type() == VGradient::radial ) + { + // do radial grad + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } + // gah! pointless abbreviation of conical to conic + else if( grad.type() == VGradient::conic ) + { + // fake conical grad as radial. + // fugly but better than data loss. + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } +} + +// better than nothing +void +SvgExport::getPattern( const VPattern & ) +{ + QString uid = createUID(); + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + // TODO: insert hard work here ;) + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; +} + +void +SvgExport::getFill( const VFill& fill, QTextStream *stream ) +{ + *stream << " fill=\""; + if( fill.type() == VFill::none ) + *stream << "none"; + else if( fill.type() == VFill::grad ) + getGradient( fill.gradient() ); + else if( fill.type() == VFill::patt ) + getPattern( fill.pattern() ); + else + getHexColor( stream, fill.color() ); + *stream << "\""; + + if( fill.color().opacity() != m_gc.current()->fill.color().opacity() ) + *stream << " fill-opacity=\"" << fill.color().opacity() << "\""; +} + +void +SvgExport::getStroke( const VStroke& stroke, QTextStream *stream ) +{ + if( stroke.type() != m_gc.current()->stroke.type() ) + { + *stream << " stroke=\""; + if( stroke.type() == VStroke::none ) + *stream << "none"; + else if( stroke.type() == VStroke::grad ) + getGradient( stroke.gradient() ); + else + getHexColor( stream, stroke.color() ); + *stream << "\""; + } + + if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() ) + *stream << " stroke-opacity=\"" << stroke.color().opacity() << "\""; + + if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() ) + *stream << " stroke-width=\"" << stroke.lineWidth() << "\""; + + if( stroke.lineCap() != m_gc.current()->stroke.lineCap() ) + { + if( stroke.lineCap() == VStroke::capButt ) + *stream << " stroke-linecap=\"butt\""; + else if( stroke.lineCap() == VStroke::capRound ) + *stream << " stroke-linecap=\"round\""; + else if( stroke.lineCap() == VStroke::capSquare ) + *stream << " stroke-linecap=\"square\""; + } + + if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() ) + { + if( stroke.lineJoin() == VStroke::joinMiter ) + { + *stream << " stroke-linejoin=\"miter\""; + *stream << " stroke-miterlimit=\"" << stroke.miterLimit() << "\""; + } + else if( stroke.lineJoin() == VStroke::joinRound ) + *stream << " stroke-linejoin=\"round\""; + else if( stroke.lineJoin() == VStroke::joinBevel ) + *stream << " stroke-linejoin=\"bevel\""; + } + + // dash + if( stroke.dashPattern().array().count() > 0 ) + { + *stream << " stroke-dashoffset=\"" << stroke.dashPattern().offset() << "\""; + *stream << " stroke-dasharray=\" "; + + QValueListConstIterator itr; + for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) + { + *stream << *itr << " "; + } + *stream << "\""; + } +} + +void +SvgExport::getHexColor( QTextStream *stream, const VColor& color ) +{ + // Convert the various color-spaces to hex + + QString Output; + + VColor copy( color ); + copy.setColorSpace( VColor::rgb ); + + Output.sprintf( "#%02x%02x%02x", int( copy[0] * 255.0 ), int( copy[1] * 255.0 ), int( copy[2] * 255.0 ) ); + + *stream << Output; +} + +void +SvgExport::visitVText( VText& text ) +{ + VPath path( 0L ); + path.combinePath( text.basePath() ); + + m_trans->visitVPath( path ); + + QString id = createUID(); + writePathToStream( path, " id=\""+ id + "\"", m_defs, m_indent2 ); + + printIndentation( m_body, m_indent++ ); + *m_body << "height() << ")\""; + getFill( *( text.fill() ), m_body ); + getStroke( *( text.stroke() ), m_body ); + + *m_body << " font-family=\"" << text.font().family() << "\""; + *m_body << " font-size=\"" << text.font().pointSize() << "\""; + if( text.font().bold() ) + *m_body << " font-weight=\"bold\""; + if( text.font().italic() ) + *m_body << " font-style=\"italic\""; + if( text.alignment() == VText::Center ) + *m_body << " text-anchor=\"middle\""; + else if( text.alignment() == VText::Right ) + *m_body << " text-anchor=\"end\""; + + *m_body << ">" << endl; + + printIndentation( m_body, m_indent ); + *m_body << " 0.0 ) + *m_body << " startOffset=\"" << text.offset() * 100.0 << "%\""; + *m_body << ">"; + *m_body << text.text(); + *m_body << "" << endl; + printIndentation( m_body, --m_indent ); + *m_body << "" << endl; +} + +#include "svgexport.moc" + diff --git a/filters/karbon/svg/svgexport.h b/filters/karbon/svg/svgexport.h new file mode 100644 index 00000000..8a4eab63 --- /dev/null +++ b/filters/karbon/svg/svgexport.h @@ -0,0 +1,88 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __SVGEXPORT_H__ +#define __SVGEXPORT_H__ + +#include + +#include "vvisitor.h" +#include "vgradient.h" + +#include "svggraphiccontext.h" + +#include + +class QTextStream; +class VColor; +class VPath; +class VDocument; +class VFill; +class VGroup; +class VImage; +class VLayer; +class VSubpath; +class VStroke; +class VText; +class VTransformCmd; + + +class SvgExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + SvgExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~SvgExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + virtual void visitVPath( VPath& composite ); + virtual void visitVDocument( VDocument& document ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVImage( VImage& image ); + virtual void visitVLayer( VLayer& layer ); + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVText( VText& text ); + + void getStroke( const VStroke& stroke, QTextStream *stream ); + void getColorStops( const QPtrVector &colorStops ); + void getFill( const VFill& fill, QTextStream *stream ); + void getGradient( const VGradient& grad ); + void getPattern( const VPattern& patt ); + void getHexColor( QTextStream *, const VColor& color ); + QString getID( VObject *obj ); + + void writePathToStream( VPath &composite, const QString &id, QTextStream *stream, unsigned int indent ); + + QTextStream* m_stream; + QTextStream* m_defs; + QTextStream* m_body; + + QPtrStack m_gc; + + unsigned int m_indent; + unsigned int m_indent2; + + VTransformCmd *m_trans; +}; + +#endif + diff --git a/filters/karbon/svg/svggraphiccontext.h b/filters/karbon/svg/svggraphiccontext.h new file mode 100644 index 00000000..96737fd9 --- /dev/null +++ b/filters/karbon/svg/svggraphiccontext.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __SVGGRAPHICSCONTEXT_H__ +#define __SVGGRAPHICSCONTEXT_H__ + +#include +#include +#include + +class SvgGraphicsContext +{ +public: + SvgGraphicsContext() + { + stroke.setType( VStroke::none ); // default is no stroke + stroke.setLineWidth( 1.0 ); + stroke.setLineCap( VStroke::capButt ); + stroke.setLineJoin( VStroke::joinMiter ); + fill.setColor( VColor( Qt::black ) ); + fillRule = winding; + color = Qt::black; + } + VFill fill; + VFillRule fillRule; + VStroke stroke; + QWMatrix matrix; + QFont font; + QColor color; +}; + +#endif diff --git a/filters/karbon/svg/svgimport.cc b/filters/karbon/svg/svgimport.cc new file mode 100644 index 00000000..f97546c6 --- /dev/null +++ b/filters/karbon/svg/svgimport.cc @@ -0,0 +1,1389 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include "color.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory SvgImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonsvgimport, SvgImportFactory( "kofficefilters" ) ) + +SvgImport::SvgImport(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ + m_gc.setAutoDelete( true ); +} + +SvgImport::~SvgImport() +{ +} + +KoFilter::ConversionStatus SvgImport::convert(const QCString& from, const QCString& to) +{ + // check for proper conversion + if( to != "application/x-karbon" || from != "image/svg+xml" ) + return KoFilter::NotImplemented; + + //Find the last extension + QString strExt; + QString fileIn ( m_chain->inputFile() ); + const int result=fileIn.findRev('.'); + if (result>=0) + strExt=fileIn.mid(result).lower(); + + QString strMime; // Mime type of the compressor + if ((strExt==".gz") //in case of .svg.gz (logical extension) + ||(strExt==".svgz")) //in case of .svgz (extension used prioritary) + strMime="application/x-gzip"; // Compressed with gzip + else if (strExt==".bz2") //in case of .svg.bz2 (logical extension) + strMime="application/x-bzip2"; // Compressed with bzip2 + else + strMime="text/plain"; + + /*kdDebug(30514) << "File extension: -" << strExt << "- Compression: " << strMime << endl;*/ + + QIODevice* in = KFilterDev::deviceForFile(fileIn,strMime); + + if (!in->open(IO_ReadOnly)) + { + kdError(30514) << "Cannot open file! Aborting!" << endl; + delete in; + return KoFilter::FileNotFound; + } + + int line, col; + QString errormessage; + + const bool parsed=inpdoc.setContent( in, &errormessage, &line, &col ); + + in->close(); + delete in; + + if ( ! parsed ) + { + kdError(30514) << "Error while parsing file: " + << "at line " << line << " column: " << col + << " message: " << errormessage << endl; + // ### TODO: feedback to the user + return KoFilter::ParsingError; + } + + // Do the conversion! + convert(); + // add paper info, we always need custom for svg (Rob) + QDomElement paper = outdoc.createElement( "PAPER" ); + outdoc.documentElement().appendChild( paper ); + paper.setAttribute( "format", PG_CUSTOM ); + paper.setAttribute( "width", m_document.width() ); + paper.setAttribute( "height", m_document.height() ); + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if( !out ) + { + kdError(30514) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void SvgImport::convert() +{ + SvgGraphicsContext *gc = new SvgGraphicsContext; + QDomElement docElem = inpdoc.documentElement(); + KoRect bbox( 0, 0, 550.0, 841.0 ); + double width = !docElem.attribute( "width" ).isEmpty() ? parseUnit( docElem.attribute( "width" ), true, false, bbox ) : 550.0; + double height = !docElem.attribute( "height" ).isEmpty() ? parseUnit( docElem.attribute( "height" ), false, true, bbox ) : 841.0; + m_document.setWidth( width ); + m_document.setHeight( height ); + + m_outerRect = m_document.boundingBox(); + + // undo y-mirroring + //m_debug->append(QString("%1\tUndo Y-mirroring.").arg(m_time.elapsed())); + if( !docElem.attribute( "viewBox" ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + QString viewbox( docElem.attribute( "viewBox" ) ); + QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() ); + + gc->matrix.scale( width / points[2].toFloat() , height / points[3].toFloat() ); + m_outerRect.setWidth( m_outerRect.width() * ( points[2].toFloat() / width ) ); + m_outerRect.setHeight( m_outerRect.height() * ( points[3].toFloat() / height ) ); + } + + m_gc.push( gc ); + parseGroup( 0L, docElem ); + + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -m_document.height() ); + VTransformCmd trafo( 0L, mat ); + trafo.visit( m_document ); + outdoc = m_document.saveXML(); +} + +#define DPI 90 + +// Helper functions +// --------------------------------------------------------------------------------------- + +double SvgImport::toPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble(); + else + return s.toDouble() * 100.0; +} + +double SvgImport::fromPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble() / 100.0; + else + return s.toDouble(); +} + +double SvgImport::getScalingFromMatrix( QWMatrix &matrix ) +{ + double xscale = matrix.m11() + matrix.m12(); + double yscale = matrix.m22() + matrix.m21(); + return sqrt( xscale*xscale + yscale*yscale ) / sqrt( 2.0 ); +} + +// parses the number into parameter number +const char * getNumber( const char *ptr, double &number ) +{ + int integer, exponent; + double decimal, frac; + int sign, expsign; + + exponent = 0; + integer = 0; + frac = 1.0; + decimal = 0; + sign = 1; + expsign = 1; + + // read the sign + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + sign = -1; + } + + // read the integer part + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + integer = (integer * 10) + *(ptr++) - '0'; + if(*ptr == '.') // read the decimals + { + ptr++; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + decimal += (*(ptr++) - '0') * (frac *= 0.1); + } + + if(*ptr == 'e' || *ptr == 'E') // read the exponent part + { + ptr++; + + // read the sign of the exponent + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + expsign = -1; + } + + exponent = 0; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + { + exponent *= 10; + exponent += *ptr - '0'; + ptr++; + } + } + number = integer + decimal; + number *= sign * pow( (double)10, double( expsign * exponent ) ); + + return ptr; +} + +void SvgImport::addGraphicContext() +{ + SvgGraphicsContext *gc = new SvgGraphicsContext; + // set as default + if( m_gc.current() ) + *gc = *( m_gc.current() ); + m_gc.push( gc ); +} + +void SvgImport::setupTransform( const QDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + + QWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); + gc->matrix = mat * gc->matrix; +} + +VObject* SvgImport::findObject( const QString &name, VGroup* group ) +{ + if( ! group ) + return 0L; + + VObjectListIterator itr = group->objects(); + + for( uint objcount = 1; itr.current(); ++itr, objcount++ ) + if( itr.current()->state() != VObject::deleted ) + { + if( itr.current()->name() == name ) + return itr.current(); + + if( dynamic_cast( itr.current() ) ) + { + VObject *obj = findObject( name, dynamic_cast( itr.current() ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +VObject* SvgImport::findObject( const QString &name ) +{ + QPtrVector vector; + m_document.layers().toVector( &vector ); + for( int i = vector.count() - 1; i >= 0; i-- ) + { + if ( vector[i]->state() != VObject::deleted ) + { + VObject* obj = findObject( name, dynamic_cast( vector[i] ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +SvgImport::GradientHelper* SvgImport::findGradient( const QString &id, const QString &href) +{ + // check if gradient was already parsed, and return it + if( m_gradients.contains( id ) ) + return &m_gradients[ id ]; + + // check if gradient was stored for later parsing + if( !m_defs.contains( id ) ) + return 0L; + + QDomElement e = m_defs[ id ]; + if(e.childNodes().count() == 0) + { + QString mhref = e.attribute("xlink:href").mid(1); + + if(m_defs.contains(mhref)) + return findGradient(mhref, id); + else + return 0L; + } + else + { + // ok parse gradient now + parseGradient( m_defs[ id ], m_defs[ href ] ); + } + + // return successfully parsed gradient or NULL + QString n; + if(href.isEmpty()) + n = id; + else + n = href; + + if( m_gradients.contains( n ) ) + return &m_gradients[ n ]; + else + return 0L; +} + +QDomElement SvgImport::mergeStyles( const QDomElement &referencedBy, const QDomElement &referencedElement ) +{ + // First use all the style attributes of the element being referenced. + QDomElement e = referencedElement; + + // Now go through the style attributes of the element that is referencing and substitute the original ones. + if( !referencedBy.attribute( "color" ).isEmpty() ) + e.setAttribute( "color", referencedBy.attribute( "color" ) ); + if( !referencedBy.attribute( "fill" ).isEmpty() ) + e.setAttribute( "fill", referencedBy.attribute( "fill" ) ); + if( !referencedBy.attribute( "fill-rule" ).isEmpty() ) + e.setAttribute( "fill-rule", referencedBy.attribute( "fill-rule" ) ); + if( !referencedBy.attribute( "stroke" ).isEmpty() ) + e.setAttribute( "stroke", referencedBy.attribute( "stroke" ) ); + if( !referencedBy.attribute( "stroke-width" ).isEmpty() ) + e.setAttribute( "stroke-width", referencedBy.attribute( "stroke-width" ) ); + if( !referencedBy.attribute( "stroke-linejoin" ).isEmpty() ) + e.setAttribute( "stroke-linejoin", referencedBy.attribute( "stroke-linejoin" ) ); + if( !referencedBy.attribute( "stroke-linecap" ).isEmpty() ) + e.setAttribute( "stroke-linecap", referencedBy.attribute( "stroke-linecap" ) ); + if( !referencedBy.attribute( "stroke-dasharray" ).isEmpty() ) + e.setAttribute( "stroke-dasharray", referencedBy.attribute( "stroke-dasharray" ) ); + if( !referencedBy.attribute( "stroke-dashoffset" ).isEmpty() ) + e.setAttribute( "stroke-dashoffset", referencedBy.attribute( "stroke-dashoffset" ) ); + if( !referencedBy.attribute( "stroke-opacity" ).isEmpty() ) + e.setAttribute( "stroke-opacity", referencedBy.attribute( "stroke-opacity" ) ); + if( !referencedBy.attribute( "stroke-miterlimit" ).isEmpty() ) + e.setAttribute( "stroke-miterlimit", referencedBy.attribute( "stroke-miterlimit" ) ); + if( !referencedBy.attribute( "fill-opacity" ).isEmpty() ) + e.setAttribute( "fill-opacity", referencedBy.attribute( "fill-opacity" ) ); + if( !referencedBy.attribute( "opacity" ).isEmpty() ) + e.setAttribute( "opacity", referencedBy.attribute( "opacity" ) ); + + // TODO merge style attribute too. + + return e; +} + + +// Parsing functions +// --------------------------------------------------------------------------------------- + +double SvgImport::parseUnit( const QString &unit, bool horiz, bool vert, KoRect bbox ) +{ + // TODO : percentage? + double value = 0; + const char *start = unit.latin1(); + if(!start) { + return 0; + } + const char *end = getNumber( start, value ); + + if( uint( end - start ) < unit.length() ) + { + if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "cm" ) + value = ( value / 2.54 ) * DPI; + else if( unit.right( 2 ) == "pc" ) + value = ( value / 6.0 ) * DPI; + else if( unit.right( 2 ) == "mm" ) + value = ( value / 25.4 ) * DPI; + else if( unit.right( 2 ) == "in" ) + value = value * DPI; + else if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "em" ) + value = value * m_gc.current()->font.pointSize() / ( sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) ); + else if( unit.right( 1 ) == "%" ) + { + if( horiz && vert ) + value = ( value / 100.0 ) * (sqrt( pow( bbox.width(), 2 ) + pow( bbox.height(), 2 ) ) / sqrt( 2.0 ) ); + else if( horiz ) + value = ( value / 100.0 ) * bbox.width(); + else if( vert ) + value = ( value / 100.0 ) * bbox.height(); + } + } + /*else + { + if( m_gc.current() ) + { + if( horiz && vert ) + value *= sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ); + else if( horiz ) + value /= m_gc.current()->matrix.m11(); + else if( vert ) + value /= m_gc.current()->matrix.m22(); + } + }*/ + return value; +} + +QColor SvgImport::parseColor( const QString &rgbColor ) +{ + int r, g, b; + keywordToRGB( rgbColor, r, g, b ); + return QColor( r, g, b ); +} + +void SvgImport::parseColor( VColor &color, const QString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + QString parse = s.stripWhiteSpace(); + QStringList colors = QStringList::split( ',', parse ); + QString r = colors[0].right( ( colors[0].length() - 4 ) ); + QString g = colors[1]; + QString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + QColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else if( s == "currentColor" ) + { + SvgGraphicsContext *gc = m_gc.current(); + color = gc->color; + } + else + { + QString rgbColor = s.stripWhiteSpace(); + QColor c; + if( rgbColor.startsWith( "#" ) ) + c.setNamedColor( rgbColor ); + else + c = parseColor( rgbColor ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } +} + +void SvgImport::parseColorStops( VGradient *gradient, const QDomElement &e ) +{ + VColor c; + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement stop = n.toElement(); + if( stop.tagName() == "stop" ) + { + float offset; + QString temp = stop.attribute( "offset" ); + if( temp.contains( '%' ) ) + { + temp = temp.left( temp.length() - 1 ); + offset = temp.toFloat() / 100.0; + } + else + offset = temp.toFloat(); + + if( !stop.attribute( "stop-color" ).isEmpty() ) + parseColor( c, stop.attribute( "stop-color" ) ); + else + { + // try style attr + QString style = stop.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + if( command == "stop-color" ) + parseColor( c, params ); + if( command == "stop-opacity" ) + c.setOpacity( params.toDouble() ); + } + + } + if( !stop.attribute( "stop-opacity" ).isEmpty() ) + c.setOpacity( stop.attribute( "stop-opacity" ).toDouble() ); + gradient->addStop( c, offset, 0.5 ); + } + } +} + +void SvgImport::parseGradient( const QDomElement &e , const QDomElement &referencedBy) +{ + // IMPROVEMENTS: + // - Store the parsed colorstops in some sort of a cache so they don't need to be parsed again. + // - A gradient inherits attributes it does not have from the referencing gradient. + // - Gradients with no color stops have no fill or stroke. + // - Gradients with one color stop have a solid color. + + SvgGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + GradientHelper gradhelper; + gradhelper.gradient.clearStops(); + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + if(e.childNodes().count() == 0) + { + QString href = e.attribute("xlink:href").mid(1); + + if(href.isEmpty()) + { + //gc->fill.setType( VFill::none ); // <--- TODO Fill OR Stroke are none + return; + } + else + { + // copy the referenced gradient if found + GradientHelper *pGrad = findGradient( href ); + if( pGrad ) + gradhelper = *pGrad; + } + } + + // Use the gradient that is referencing, or if there isn't one, the original gradient. + QDomElement b; + if( !referencedBy.isNull() ) + b = referencedBy; + else + b = e; + + QString id = b.attribute("id"); + if( !id.isEmpty() ) + { + // Copy existing gradient if it exists + if( m_gradients.find( id ) != m_gradients.end() ) + gradhelper.gradient = m_gradients[ id ].gradient; + } + + gradhelper.bbox = b.attribute( "gradientUnits" ) != "userSpaceOnUse"; + + // parse color prop + VColor c = m_gc.current()->color; + + if( !b.attribute( "color" ).isEmpty() ) + { + parseColor( c, b.attribute( "color" ) ); + } + else + { + // try style attr + QString style = b.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + if( command == "color" ) + parseColor( c, params ); + } + } + m_gc.current()->color = c; + + if( b.tagName() == "linearGradient" ) + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( b.attribute( "x1", "0%" ) ), toPercentage( b.attribute( "y1", "0%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( b.attribute( "x2", "100%" ) ), toPercentage( b.attribute( "y2", "0%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( b.attribute( "x1" ).toDouble(), b.attribute( "y1" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( b.attribute( "x2" ).toDouble(), b.attribute( "y2" ).toDouble() ) ); + } + gradhelper.gradient.setType( VGradient::linear ); + } + else + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( b.attribute( "cx", "50%" ) ), toPercentage( b.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( b.attribute( "cx", "50%" ) ) + toPercentage( b.attribute( "r", "50%" ) ), toPercentage( b.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setFocalPoint( KoPoint( toPercentage( b.attribute( "fx", "50%" ) ), toPercentage( b.attribute( "fy", "50%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( b.attribute( "cx" ).toDouble(), b.attribute( "cy" ).toDouble() ) ); + gradhelper.gradient.setFocalPoint( KoPoint( b.attribute( "fx" ).toDouble(), b.attribute( "fy" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( b.attribute( "cx" ).toDouble() + b.attribute( "r" ).toDouble(), b.attribute( "cy" ).toDouble() ) ); + } + gradhelper.gradient.setType( VGradient::radial ); + } + // handle spread method + QString spreadMethod = b.attribute( "spreadMethod" ); + if( !spreadMethod.isEmpty() ) + { + if( spreadMethod == "reflect" ) + gradhelper.gradient.setRepeatMethod( VGradient::reflect ); + else if( spreadMethod == "repeat" ) + gradhelper.gradient.setRepeatMethod( VGradient::repeat ); + else + gradhelper.gradient.setRepeatMethod( VGradient::none ); + } + else + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + // Parse the color stops. The referencing gradient does not have colorstops, + // so use the stops from the gradient it references to (e in this case and not b) + parseColorStops( &gradhelper.gradient, e ); + //gradient.setGradientTransform( parseTransform( e.attribute( "gradientTransform" ) ) ); + gradhelper.gradientTransform = VPath::parseTransform( b.attribute( "gradientTransform" ) ); + m_gradients.insert( b.attribute( "id" ), gradhelper ); +} + +void SvgImport::parsePA( VObject *obj, SvgGraphicsContext *gc, const QString &command, const QString ¶ms ) +{ + VColor fillcolor = gc->fill.color(); + VColor strokecolor = gc->stroke.color(); + + if( params == "inherit" ) return; + + if( command == "fill" ) + { + if( params == "none" ) + gc->fill.setType( VFill::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + GradientHelper *gradHelper = findGradient( key ); + if( gradHelper ) + { + gc->fill.gradient() = gradHelper->gradient; + + if( gradHelper->bbox ) + { + // adjust to bbox + KoRect bbox = obj->boundingBox(); + //kdDebug() << "bbox x : " << bbox.x() << endl; + //kdDebug() << "!!!!!!bbox y : " << bbox.y() << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + double offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); + double offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox ); + gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + if(gc->fill.gradient().type() == VGradient::radial) + { + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); + gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + } + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().y() ), false, true, bbox ); + gc->fill.gradient().setVector( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + //kdDebug() << offsety << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().origin().y() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + //kdDebug() << gc->fill.gradient().vector().y() << endl; + } + gc->fill.gradient().transform( gradHelper->gradientTransform ); + + if( !gradHelper->bbox ) + gc->fill.gradient().transform( gc->matrix ); + + gc->fill.setType( VFill::grad ); + } + else + gc->fill.setType( VFill::none ); + } + else + { + parseColor( fillcolor, params ); + gc->fill.setType( VFill::solid ); + } + } + else if( command == "fill-rule" ) + { + if( params == "nonzero" ) + gc->fillRule = winding; + else if( params == "evenodd" ) + gc->fillRule = evenOdd; + } + else if( command == "stroke" ) + { + if( params == "none" ) + gc->stroke.setType( VStroke::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + + GradientHelper *gradHelper = findGradient( key ); + if( gradHelper ) + { + gc->stroke.gradient() = gradHelper->gradient; + gc->stroke.gradient().transform( gradHelper->gradientTransform ); + gc->stroke.gradient().transform( gc->matrix ); + gc->stroke.setType( VStroke::grad ); + } + else + gc->stroke.setType( VStroke::none ); + } + else + { + parseColor( strokecolor, params ); + gc->stroke.setType( VStroke::solid ); + } + } + else if( command == "stroke-width" ) + gc->stroke.setLineWidth( parseUnit( params, true, true, m_outerRect ) ); + else if( command == "stroke-linejoin" ) + { + if( params == "miter" ) + gc->stroke.setLineJoin( VStroke::joinMiter ); + else if( params == "round" ) + gc->stroke.setLineJoin( VStroke::joinRound ); + else if( params == "bevel" ) + gc->stroke.setLineJoin( VStroke::joinBevel ); + } + else if( command == "stroke-linecap" ) + { + if( params == "butt" ) + gc->stroke.setLineCap( VStroke::capButt ); + else if( params == "round" ) + gc->stroke.setLineCap( VStroke::capRound ); + else if( params == "square" ) + gc->stroke.setLineCap( VStroke::capSquare ); + } + else if( command == "stroke-miterlimit" ) + gc->stroke.setMiterLimit( params.toFloat() ); + else if( command == "stroke-dasharray" ) + { + QValueList array; + if(params != "none") + { + // with "stroke-dasharray", the separator is a white space + // inside style attribute, stroke-dasharray is separated by comma (,) + QStringList dashes = QStringList::split( QRegExp("[\\s,]"), params ); + for( QStringList::Iterator it = dashes.begin(); it != dashes.end(); ++it ) + array.append( (*it).toFloat() ); + } + gc->stroke.dashPattern().setArray( array ); + } + else if( command == "stroke-dashoffset" ) + gc->stroke.dashPattern().setOffset( params.toFloat() ); + // handle opacity + else if( command == "stroke-opacity" ) + strokecolor.setOpacity( fromPercentage( params ) ); + else if( command == "fill-opacity" ) + fillcolor.setOpacity( fromPercentage( params ) ); + else if( command == "opacity" ) + { + fillcolor.setOpacity( fromPercentage( params ) ); + strokecolor.setOpacity( fromPercentage( params ) ); + } + else if( command == "font-family" ) + { + QString family = params; + family.replace( '\'' , ' ' ); + gc->font.setFamily( family ); + } + else if( command == "font-size" ) + { + float pointSize = parseUnit( params ); + gc->font.setPointSizeFloat( pointSize * getScalingFromMatrix( gc->matrix ) ); + } + else if( command == "font-weight" ) + { + int weight = QFont::Normal; + + // map svg weight to qt weight + // svg value qt value + // 100,200,300 1, 17, 33 + // 400 50 (normal) + // 500,600 58,66 + // 700 75 (bold) + // 800,900 87,99 + + if( params == "bold" ) + weight = QFont::Bold; + else if( params == "lighter" ) + { + weight = gc->font.weight(); + if( weight <= 17 ) + weight = 1; + else if( weight <= 33 ) + weight = 17; + else if( weight <= 50 ) + weight = 33; + else if( weight <= 58 ) + weight = 50; + else if( weight <= 66 ) + weight = 58; + else if( weight <= 75 ) + weight = 66; + else if( weight <= 87 ) + weight = 75; + else if( weight <= 99 ) + weight = 87; + } + else if( params == "bolder" ) + { + weight = gc->font.weight(); + if( weight >= 87 ) + weight = 99; + else if( weight >= 75 ) + weight = 87; + else if( weight >= 66 ) + weight = 75; + else if( weight >= 58 ) + weight = 66; + else if( weight >= 50 ) + weight = 58; + else if( weight >= 33 ) + weight = 50; + else if( weight >= 17 ) + weight = 50; + else if( weight >= 1 ) + weight = 17; + } + else + { + bool ok; + // try to read numerical weight value + weight = params.toInt( &ok, 10 ); + + if( !ok ) + return; + + switch( weight ) + { + case 100: weight = 1; break; + case 200: weight = 17; break; + case 300: weight = 33; break; + case 400: weight = 50; break; + case 500: weight = 58; break; + case 600: weight = 66; break; + case 700: weight = 75; break; + case 800: weight = 87; break; + case 900: weight = 99; break; + } + } + gc->font.setWeight( weight ); + } + else if( command == "text-decoration" ) + { + if( params == "line-through" ) + gc->font.setStrikeOut( true ); + else if( params == "underline" ) + gc->font.setUnderline( true ); + } + else if( command == "color" ) + { + VColor color; + parseColor( color, params ); + gc->color = color; + } + if( gc->fill.type() != VFill::none ) + gc->fill.setColor( fillcolor, false ); + //if( gc->stroke.type() == VStroke::solid ) + gc->stroke.setColor( strokecolor ); +} + +void SvgImport::parseStyle( VObject *obj, const QDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + // try normal PA + if( !e.attribute( "color" ).isEmpty() ) + parsePA( obj, gc, "color", e.attribute( "color" ) ); + if( !e.attribute( "fill" ).isEmpty() ) + parsePA( obj, gc, "fill", e.attribute( "fill" ) ); + if( !e.attribute( "fill-rule" ).isEmpty() ) + parsePA( obj, gc, "fill-rule", e.attribute( "fill-rule" ) ); + if( !e.attribute( "stroke" ).isEmpty() ) + parsePA( obj, gc, "stroke", e.attribute( "stroke" ) ); + if( !e.attribute( "stroke-width" ).isEmpty() ) + parsePA( obj, gc, "stroke-width", e.attribute( "stroke-width" ) ); + if( !e.attribute( "stroke-linejoin" ).isEmpty() ) + parsePA( obj, gc, "stroke-linejoin", e.attribute( "stroke-linejoin" ) ); + if( !e.attribute( "stroke-linecap" ).isEmpty() ) + parsePA( obj, gc, "stroke-linecap", e.attribute( "stroke-linecap" ) ); + if( !e.attribute( "stroke-dasharray" ).isEmpty() ) + parsePA( obj, gc, "stroke-dasharray", e.attribute( "stroke-dasharray" ) ); + if( !e.attribute( "stroke-dashoffset" ).isEmpty() ) + parsePA( obj, gc, "stroke-dashoffset", e.attribute( "stroke-dashoffset" ) ); + if( !e.attribute( "stroke-opacity" ).isEmpty() ) + parsePA( obj, gc, "stroke-opacity", e.attribute( "stroke-opacity" ) ); + if( !e.attribute( "stroke-miterlimit" ).isEmpty() ) + parsePA( obj, gc, "stroke-miterlimit", e.attribute( "stroke-miterlimit" ) ); + if( !e.attribute( "fill-opacity" ).isEmpty() ) + parsePA( obj, gc, "fill-opacity", e.attribute( "fill-opacity" ) ); + if( !e.attribute( "opacity" ).isEmpty() ) + parsePA( obj, gc, "opacity", e.attribute( "opacity" ) ); + + // try style attr + QString style = e.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + parsePA( obj, gc, command, params ); + } + + if(!obj) + return; + + obj->setFill( gc->fill ); + if( dynamic_cast( obj ) ) + dynamic_cast( obj )->setFillRule( gc->fillRule ); + // stroke scaling + double lineWidth = gc->stroke.lineWidth(); + gc->stroke.setLineWidth( lineWidth * getScalingFromMatrix( gc->matrix ) ); + obj->setStroke( gc->stroke ); + gc->stroke.setLineWidth( lineWidth ); +} + +void SvgImport::parseFont( const QDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + if( ! e.attribute( "font-family" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-family", e.attribute( "font-family" ) ); + if( ! e.attribute( "font-size" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-size", e.attribute( "font-size" ) ); + if( ! e.attribute( "font-weight" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-weight", e.attribute( "font-weight" ) ); + if( ! e.attribute( "text-decoration" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "text-decoration", e.attribute( "text-decoration" ) ); +} + +void SvgImport::parseUse( VGroup *grp, const QDomElement &e ) +{ + QString id = e.attribute( "xlink:href" ); + + if( !id.isEmpty() ) + { + addGraphicContext(); + setupTransform( e ); + + QString key = id.mid( 1 ); + + if( !e.attribute( "x" ).isEmpty() && !e.attribute( "y" ).isEmpty() ) + { + double tx = e.attribute( "x" ).toDouble(); + double ty = e.attribute( "y" ).toDouble(); + + m_gc.current()->matrix.translate(tx,ty); + } + + if(m_defs.contains(key)) + { + QDomElement a = m_defs[key]; + if(a.tagName() == "g" || a.tagName() == "a") + parseGroup( grp, a); + else + { + // Create the object with the merged styles. + // The object inherits all style attributes from the use tag, but keeps it's own attributes. + // So, not just use the style attributes of the use tag, but merge them first. + createObject( grp, a, VObject::normal, mergeStyles(e, a) ); + } + } + delete( m_gc.pop() ); + } +} + +void SvgImport::parseGroup( VGroup *grp, const QDomElement &e ) +{ + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement b = n.toElement(); + if( b.isNull() ) continue; + + // treat svg link as group so we don't miss its child elements + if( b.tagName() == "g" || b.tagName() == "a" ) + { + VGroup *group; + if ( grp ) + group = new VGroup( grp ); + else + group = new VGroup( &m_document ); + + addGraphicContext(); + setupTransform( b ); + parseStyle( group, b ); + parseFont( b ); + parseGroup( group, b ); + + // handle id + if( !b.attribute("id").isEmpty() ) + group->setName( b.attribute("id") ); + if( grp ) + grp->append( group ); + else + m_document.append( group ); + delete( m_gc.pop() ); + continue; + } + if( b.tagName() == "defs" ) + { + parseDefs( b ); + continue; + } + else if( b.tagName() == "linearGradient" || b.tagName() == "radialGradient" ) + { + parseGradient( b ); + continue; + } + if( b.tagName() == "rect" || + b.tagName() == "ellipse" || + b.tagName() == "circle" || + b.tagName() == "line" || + b.tagName() == "polyline" || + b.tagName() == "polygon" || + b.tagName() == "path" || + b.tagName() == "image" ) + { + createObject( grp, b ); + continue; + } + else if( b.tagName() == "text" ) + { + createText( grp, b ); + continue; + } + else if( b.tagName() == "use" ) + { + parseUse( grp, b ); + continue; + } + } +} + +void SvgImport::parseDefs( const QDomElement &e ) +{ + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement b = n.toElement(); + if( b.isNull() ) continue; + + QString definition = b.attribute( "id" ); + if( !definition.isEmpty() ) + { + if( !m_defs.contains( definition ) ) + m_defs.insert( definition, b ); + } + } +} + + +// Creating functions +// --------------------------------------------------------------------------------------- + +void SvgImport::createText( VGroup *grp, const QDomElement &b ) +{ + const double pathLength = 10.0; + + VText *text = 0L; + QString content; + QString anchor; + VSubpath base( 0L ); + VPath *path = 0L; + double offset = 0.0; + + addGraphicContext(); + setupTransform( b ); + + parseFont( b ); + + if( ! b.attribute( "text-anchor" ).isEmpty() ) + anchor = b.attribute( "text-anchor" ); + + if( b.hasChildNodes() ) + { + if( base.isEmpty() && ! b.attribute( "x" ).isEmpty() && ! b.attribute( "y" ).isEmpty() ) + { + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + pathLength, y ) ); + } + + for( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + if( e.isNull() ) + { + content += n.toCharacterData().data(); + } + else if( e.tagName() == "textPath" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString key = e.attribute( "xlink:href" ).mid( 1 ); + if( ! m_defs.contains(key) ) + { + // try to find referenced object in document + VObject* obj = findObject( key ); + // try to find referenced object in actual group, which is not yet part of document + if( ! obj ) + obj = findObject( key, grp ); + if( obj ) + path = dynamic_cast( obj ); + } + else + { + QDomElement p = m_defs[key]; + createObject( grp, p, VObject::deleted); + } + if( ! path ) + continue; + base = *path->paths().getFirst(); + content += e.text(); + + if( ! e.attribute( "startOffset" ).isEmpty() ) + { + QString start = e.attribute( "startOffset" ); + if( start.endsWith( "%" ) ) + offset = 0.01 * start.remove( '%' ).toDouble(); + else + { + float pathLength = 0; + VSubpathIterator pIt( base ); + + for( ; pIt.current(); ++pIt ) + pathLength += pIt.current()->length(); + + if( pathLength > 0.0 ) + offset = start.toDouble() / pathLength; + } + } + } + else if( e.tagName() == "tspan" ) + { + // only use text of tspan element, as we are not supporting text + // with different styles + content += e.text(); + if( base.isEmpty() && ! e.attribute( "x" ).isEmpty() && ! e.attribute( "y" ).isEmpty() ) + { + QStringList posX = QStringList::split( ", ", e.attribute( "x" ) ); + QStringList posY = QStringList::split( ", ", e.attribute( "y" ) ); + if( posX.count() && posY.count() ) + { + double x = parseUnit( posX.first() ); + double y = parseUnit( posY.first() ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + pathLength, y ) ); + } + } + } + else if( e.tagName() == "tref" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString key = e.attribute( "xlink:href" ).mid( 1 ); + if( ! m_defs.contains(key) ) + { + // try to find referenced object in document + VObject* obj = findObject( key ); + // try to find referenced object in actual group, which is not yet part of document + if( ! obj ) + obj = findObject( key, grp ); + if( obj ) + content += dynamic_cast( obj )->text(); + } + else + { + QDomElement p = m_defs[key]; + content += p.text(); + } + } + else + continue; + + if( ! e.attribute( "text-anchor" ).isEmpty() ) + anchor = e.attribute( "text-anchor" ); + } + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, content.simplifyWhiteSpace() ); + } + else + { + VSubpath base( 0L ); + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + pathLength, y ) ); + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, b.text().simplifyWhiteSpace() ); + } + + if( text ) + { + text->setParent( &m_document ); + + parseStyle( text, b ); + + text->setFont( m_gc.current()->font ); + + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + trafo.visit( *text ); + + if( !b.attribute("id").isEmpty() ) + text->setName( b.attribute("id") ); + + if( anchor == "middle" ) + text->setAlignment( VText::Center ); + else if( anchor == "end" ) + text->setAlignment( VText::Right ); + + if( offset > 0.0 ) + text->setOffset( offset ); + + if( grp ) + grp->append( text ); + else + m_document.append( text ); + } + + delete( m_gc.pop() ); +} + +void SvgImport::createObject( VGroup *grp, const QDomElement &b, const VObject::VState state, const QDomElement &style ) +{ + VObject *obj = 0L; + + addGraphicContext(); + setupTransform( b ); + + if( b.tagName() == "rect" ) + { + double x = parseUnit( b.attribute( "x" ), true, false, m_outerRect ); + double y = parseUnit( b.attribute( "y" ), false, true, m_outerRect ); + double width = parseUnit( b.attribute( "width" ), true, false, m_outerRect ); + double height = parseUnit( b.attribute( "height" ), false, true, m_outerRect ); + double rx = parseUnit( b.attribute( "rx" ) ); + double ry = parseUnit( b.attribute( "ry" ) ); + obj = new VRectangle( 0L, KoPoint( x, height + y ) , width, height, rx, ry ); + } + else if( b.tagName() == "ellipse" ) + { + double rx = parseUnit( b.attribute( "rx" ) ); + double ry = parseUnit( b.attribute( "ry" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - rx; + double top = parseUnit( b.attribute( "cy" ) ) - ry; + obj = new VEllipse( 0L, KoPoint( left, top ), rx * 2.0, ry * 2.0 ); + } + else if( b.tagName() == "circle" ) + { + double r = parseUnit( b.attribute( "r" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - r; + double top = parseUnit( b.attribute( "cy" ) ) - r; + obj = new VEllipse( 0L, KoPoint( left, top ), r * 2.0, r * 2.0 ); + } + else if( b.tagName() == "line" ) + { + VPath *path = new VPath( &m_document ); + double x1 = b.attribute( "x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x1" ) ); + double y1 = b.attribute( "y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y1" ) ); + double x2 = b.attribute( "x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x2" ) ); + double y2 = b.attribute( "y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y2" ) ); + path->moveTo( KoPoint( x1, y1 ) ); + path->lineTo( KoPoint( x2, y2 ) ); + obj = path; + } + else if( b.tagName() == "polyline" || b.tagName() == "polygon" ) + { + VPath *path = new VPath( &m_document ); + bool bFirst = true; + + QString points = b.attribute( "points" ).simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + QStringList pointList = QStringList::split( ' ', points ); + for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); ++it) + { + KoPoint point; + point.setX( (*it).toDouble() ); + ++it; + point.setY( (*it).toDouble() ); + if( bFirst ) + { + path->moveTo( point ); + bFirst = false; + } + else + path->lineTo( point ); + } + if( b.tagName() == "polygon" ) path->close(); + obj = path; + } + else if( b.tagName() == "path" ) + { + VPath *path = new VPath( &m_document ); + path->loadSvgPath( b.attribute( "d" ) ); + obj = path; + } + else if( b.tagName() == "image" ) + { + QString fname = b.attribute("xlink:href"); + obj = new VImage( 0L, fname ); + } + + if( !obj ) + return; + + if (state != VObject::normal) + obj->setState(state); + + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + trafo.visit( *obj ); + + if( !style.isNull() ) + parseStyle( obj, style ); + else + parseStyle( obj, b ); + + // handle id + if( !b.attribute("id").isEmpty() ) + obj->setName( b.attribute("id") ); + if( grp ) + grp->append( obj ); + else + m_document.append( obj ); + + delete( m_gc.pop() ); +} + +#include diff --git a/filters/karbon/svg/svgimport.h b/filters/karbon/svg/svgimport.h new file mode 100644 index 00000000..a558c1fc --- /dev/null +++ b/filters/karbon/svg/svgimport.h @@ -0,0 +1,102 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __SVGIMPORT_H__ +#define __SVGIMPORT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "svggraphiccontext.h" + +#include + +class VGroup; +class VPath; + +class SvgImport : public KoFilter +{ + Q_OBJECT + +public: + SvgImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~SvgImport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + +protected: + class GradientHelper + { + public: + GradientHelper() + { + bbox = true; + } + VGradient gradient; + bool bbox; + QWMatrix gradientTransform; + }; + + void parseGroup( VGroup *, const QDomElement & ); + void parseDefs( const QDomElement & ); + void parseUse( VGroup *, const QDomElement & ); + void parseStyle( VObject *, const QDomElement & ); + void parsePA( VObject *, SvgGraphicsContext *, const QString &, const QString & ); + void parseGradient( const QDomElement &, const QDomElement &referencedBy = QDomElement() ); + void parseColorStops( VGradient *, const QDomElement & ); + double parseUnit( const QString &, bool horiz = false, bool vert = false, KoRect bbox = KoRect() ); + void parseColor( VColor &, const QString & ); + QColor parseColor( const QString & ); + double toPercentage( QString ); + double fromPercentage( QString ); + void setupTransform( const QDomElement & ); + void addGraphicContext(); + QDomDocument inpdoc; + QDomDocument outdoc; + void convert(); + void createObject( VGroup *grp, const QDomElement &, VObject::VState state = VObject::normal, const QDomElement &style = QDomElement() ); + void createText( VGroup *, const QDomElement & ); + void parseFont( const QDomElement & ); + // find object with given id in document + VObject* findObject( const QString &name ); + // find object with given id in given group + VObject* findObject( const QString &name, VGroup * ); + // find gradient with given id in gradient map + GradientHelper* findGradient( const QString &id, const QString &href = 0 ); + + // Determine scaling factor from given matrix + double getScalingFromMatrix( QWMatrix &matrix ); + + QDomElement mergeStyles( const QDomElement &, const QDomElement & ); + +private: + VDocument m_document; + QPtrStack m_gc; + QMap m_gradients; + QMap m_defs; + KoRect m_outerRect; +}; + +#endif diff --git a/filters/karbon/wmf/Makefile.am b/filters/karbon/wmf/Makefile.am new file mode 100644 index 00000000..38acbe44 --- /dev/null +++ b/filters/karbon/wmf/Makefile.am @@ -0,0 +1,27 @@ + +INCLUDES= \ + -I$(srcdir) \ + $(KWMF_INCLUDES) \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/commands \ + $(all_includes) + +kde_module_LTLIBRARIES = libwmfimport.la libwmfexport.la + +libwmfimport_la_LDFLAGS = -module $(KDE_PLUGIN) +libwmfimport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KOWMF) ../../../karbon/libkarboncommon.la +libwmfimport_la_SOURCES = wmfimport.cc wmfimportparser.cc + +libwmfexport_la_LDFLAGS = -module $(KDE_PLUGIN) +libwmfexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KOWMF) ../../../karbon/libkarboncommon.la +libwmfexport_la_SOURCES = wmfexport.cc + +noinst_HEADERS = wmfimport.h wmfimportparser.h wmfexport.h + +METASOURCES = AUTO + +service_DATA = karbon_wmf_import.desktop karbon_wmf_export.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/karbon/wmf/karbon_wmf_export.desktop b/filters/karbon/wmf/karbon_wmf_export.desktop new file mode 100644 index 00000000..d859d274 --- /dev/null +++ b/filters/karbon/wmf/karbon_wmf_export.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Icon= +Name=Karbon14 WMF Export Filter +Name[ar]=賲賽乇賿卮賻丨 鬲氐丿賷乇 WMF 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 械泻褋锌芯褉褌懈褉邪薪械 芯褌 Karbon14 胁 WMF +Name[br]=Sil ezporzh WMF evit Karbon14 +Name[ca]=Filtre d'exportaci贸 WMF per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu WMF pro Karbon14 +Name[cy]=Hidlen Allforio WMF Karbon14 +Name[da]=Karbon14 WMF-eksportfilter +Name[de]=Karbon14 WMF-Exportfilter +Name[el]=桅委位蟿蟻慰 蔚尉伪纬蠅纬萎蟼 WMF 蟿慰蠀 Karbon14 +Name[eo]=Karbon14-WMF-eksportfiltrilo +Name[es]=Filtro de exportaci贸n WMF de Karbon14 +Name[et]=Karbon14 WMF-i ekspordifilter +Name[eu]=Karbon14-en WMF esportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 氐丕丿乇丕鬲 Karbon14 WMF +Name[fi]=Karbon14 WMF -vientisuodin +Name[fr]=Filtre d'exportation WMF de Karbon 14 +Name[fy]=WMF-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easp贸rt谩la WMF Karbon14 +Name[gl]=Filtro de Exportaci贸n de WMF para Karbon14 +Name[he]=诪住谞谉 讬讬爪讜讗 诪志Karbon14 诇志WMF +Name[hr]=Karbon14 WMF filtar izvoza +Name[hu]=Karbon14 WMF exportsz疟r艖 +Name[is]=Karbon14 WMF 煤tflutningss铆a +Name[it]=Filtro di esportazione WMF per Karbon14 +Name[ja]=Karbon14 WMF 銈ㄣ偗銈广儩銉笺儓銉曘偅銉偪 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩焷釣 WMF 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lt]=Karbon14 WMF eksportavimo filtras +Name[lv]=Karbon14 WMF eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 WMF +Name[nb]=WMF-eksportfilter for Karbon14 +Name[nds]=WMF-Exportfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶∴が啷嵿げ啷佮啶啶 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=WMF-exportfilter voor Karbon14 +Name[nn]=WMF-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu WMF z Karbon14 +Name[pt]=Filtro de Exporta莽茫o de WMF para o Karbon14 +Name[pt_BR]=Filtro de Exporta莽茫o WMF do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru WMF +Name[ru]=肖懈谢褜褌褉 褝泻褋锌芯褉褌邪 褉懈褋褍薪泻芯胁 Karbon14 胁 WMF +Name[se]=Karbon14:a WMF-olggosfievrridansilli +Name[sk]=WFM filter pre export z Karbon14 +Name[sl]=Izvozni filter WMF za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 懈蟹胁芯蟹 褍 WMF +Name[sr@Latn]=Karbon14-ov filter za izvoz u WMF +Name[sv]=Karbon14 WMF-exportfilter +Name[ta]=Karbon 14 WNF 喈忇喁嵿喁佮喈む 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 WMF 肖懈谢褌褉懈 小芯写懈褉芯褌 +Name[tr]=Karbon14 WMF Aktarma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 WMF 写谢褟 Karbon14 +Name[uz]=Karbon14 WMF eksport filteri +Name[uz@cyrillic]=Karbon14 WMF 褝泻褋锌芯褉褌 褎懈谢褌械褉懈 +Name[zh_CN]=Karbon14 WMF 瀵煎嚭杩囨护鍣 +Name[zh_TW]=Karbon14 WMF 鍖嚭閬庢烤绋嬪紡 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/x-wmf +X-KDE-Import=application/x-karbon +X-KDE-Weight=1 +X-KDE-Library=libwmfexport + diff --git a/filters/karbon/wmf/karbon_wmf_import.desktop b/filters/karbon/wmf/karbon_wmf_import.desktop new file mode 100644 index 00000000..d1711ff9 --- /dev/null +++ b/filters/karbon/wmf/karbon_wmf_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon WMF Import Filter +Name[af]=Karbon Wmf In voer Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 WMF 賱丿賶 Karbon +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 WMF 胁 Karbon +Name[br]=Sil enporzh WMF evit Karbon +Name[ca]=Filtre d'importaci贸 WMF per a Karbon +Name[cs]=Importn铆 filtr WMF pro Karbon14 +Name[cy]=Hidlen Fewnforio WMF Karbon +Name[da]=Karbon WMF-importfilter +Name[de]=Karbon14 WMF-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 WMF 蟿慰蠀 Karbon +Name[eo]=Karbon-WMF-importfiltrilo +Name[es]=Filtro de importaci贸n WMF de Karbon +Name[et]=Karboni WMF-i impordifilter +Name[eu]=Karbon-en WMF inportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon WMF +Name[fi]=Karbon WMF- tuontisuodin +Name[fr]=Filtre d'importation WMF de Karbon 14 +Name[fy]=WMF-Ymportfilter foar Karbon +Name[ga]=Scagaire Iomp贸rt谩la Karbon WMF +Name[gl]=Filtro de Importaci贸n de WMF para Karbon14 +Name[he]=诪住谞谉 讬讬讘讜讗 诪志WMF 诇志Karbon +Name[hr]=Kontour WMF filtar uvoza +Name[hu]=Karbon WMF importsz疟r艖 +Name[is]=Karbon WMF innflutningss铆a +Name[it]=Filtro di importazione WMF per Karbon +Name[ja]=Karbon WMF 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 WMF 釣熱灅釤掅灇釣夺灁釤 Karbon +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權簷嗪赤粈嗪傕夯嗷夃翰 WMF 嗪傕涵嗪 Karbon +Name[lt]=Karbon WMF importavimo filtras +Name[lv]=Karbon WMF importa filtrs +Name[ms]=Penapis Import Karbon WMF +Name[mt]=Filtru g魔all-importazzjoni ta' WMF 摹o Karbon14 +Name[nb]=WMF-importfilter for Karbon +Name[nds]=WMF-Importfilter f枚r Karbon +Name[ne]=啶曕ぞ啶班啶え 啶∴が啷嵿げ啷佮啶啶 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=WMF-importfilter voor Karbon +Name[nn]=WMF-importfilter for Karbon14 +Name[pl]=Filtr importu formatu WMF do Karbon +Name[pt]=Filtro de Importa莽茫o de WMF para o Karbon14 +Name[pt_BR]=Filtro de Importa莽茫o WMF do Karbon +Name[ro]=Filtru importare Karbon14 pentru WMF +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褉懈褋褍薪泻芯胁 WMF 胁 Karbon +Name[se]=Karbon:a WMF-sisafievrridansilli +Name[sk]=WMF filter pre import pre Karbon +Name[sl]=Uvozni filter WMF za Karbon +Name[sr]=Karbon-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 WMF-邪 +Name[sr@Latn]=Karbon-ov filter za uvoz iz WMF-a +Name[sv]=Karbon WMF-importfilter +Name[ta]=Karbon wmf 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon WMF I肖懈谢褌褉懈 袙芯褉懈写芯褌 +Name[th]=喔曕副喔о竵喔`腑喔囙竵喔侧福喔權赋喙喔傕箟喔 WMF 喔傕腑喔 Karbon +Name[tr]=Karbon WMF Alma Filtresi +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 WMF 写谢褟 Karbon +Name[uz]=Karbon WMF import filteri +Name[uz@cyrillic]=Karbon WMF 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba se Karbon WMF +Name[zh_CN]=Karbon WMF 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon WMF 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/x-wmf +X-KDE-Weight=1 +X-KDE-Library=libwmfimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/wmf/wmfexport.cc b/filters/karbon/wmf/wmfexport.cc new file mode 100644 index 00000000..5f1e94d7 --- /dev/null +++ b/filters/karbon/wmf/wmfexport.cc @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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 WmfExportFactory; +K_EXPORT_COMPONENT_FACTORY( libwmfexport, WmfExportFactory( "kofficefilters" ) ) + + +WmfExport::WmfExport( KoFilter *, const char *, const QStringList&) : + KoFilter() +{ +} + +WmfExport::~WmfExport() +{ +} + +KoFilter::ConversionStatus WmfExport::convert( const QCString& from, const QCString& 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; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement 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 ) { + QPen pen; + QBrush brush; + + getPen( pen, composite.stroke() ); + getBrush( brush, composite.fill() ); + + VVisitor::visitVPath( composite ); + + if ( mListPa.count() > 0 ) { + mWmf->setPen( pen ); + if( (brush.style() == Qt::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) ); + QPointArray *pa = new QPointArray( 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( QBrush& 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( QPen& 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 + diff --git a/filters/karbon/wmf/wmfexport.h b/filters/karbon/wmf/wmfexport.h new file mode 100644 index 00000000..8f107ee0 --- /dev/null +++ b/filters/karbon/wmf/wmfexport.h @@ -0,0 +1,71 @@ +/* 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. +*/ + +#ifndef WMFEXPORT_H +#define WMFEXPORT_H + +#include +#include +#include +#include +#include +#include "vvisitor.h" + +class KoWmfWrite; +class VPath; +class VDocument; +class VSubpath; +class VText; + +class WmfExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + WmfExport( KoFilter *parent, const char *name, const QStringList&); + virtual ~WmfExport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + void visitVPath( VPath& composite ); + void visitVDocument( VDocument& document ); + void visitVSubpath( VSubpath& path ); + void visitVText( VText& text ); + void getBrush( QBrush& brush, const VFill *fill ); + void getPen( QPen& pen, const VStroke *stroke ); + + // coordinate transformation + // translate origin from (left,bottom) to (left,top) -> scale to wmf size + // Wmf origin is (left,top) corner + // Karbon origin is (left,bottom) corner + int coordX( double left ) + { return (int)(left * mScaleX); } + int coordY( double top ) + { return (int)((mDoc->height() - top) * mScaleY); } + +private: + KoWmfWrite *mWmf; + VDocument *mDoc; + int mDpi; + double mScaleX; + double mScaleY; + QPtrList mListPa; +}; + +#endif diff --git a/filters/karbon/wmf/wmfimport.cc b/filters/karbon/wmf/wmfimport.cc new file mode 100644 index 00000000..eadad26b --- /dev/null +++ b/filters/karbon/wmf/wmfimport.cc @@ -0,0 +1,78 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wmfimport.h" +#include "wmfimportparser.h" + +typedef KGenericFactory WMFImportFactory; +K_EXPORT_COMPONENT_FACTORY( libwmfimport, WMFImportFactory( "kofficefilters" ) ) + + +WMFImport::WMFImport( KoFilter *, const char *, const QStringList&) : + KoFilter() +{ +} + +WMFImport::~WMFImport() +{ +} + +KoFilter::ConversionStatus WMFImport::convert( const QCString& from, const QCString& to ) +{ + if( to != "application/x-karbon" || from != "image/x-wmf" ) + return KoFilter::NotImplemented; + + WMFImportParser wmfParser; + if( !wmfParser.load( m_chain->inputFile() ) ) { + return KoFilter::WrongFormat; + } + + // Do the conversion! + VDocument document; + if (!wmfParser.play( document )) { + return KoFilter::WrongFormat; + } + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if( !out ) { + kdError(3800) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QDomDocument outdoc = document.saveXML(); + QCString content = outdoc.toCString(); + // kdDebug() << " content : " << content << endl; + out->writeBlock( content , content.length() ); + + return KoFilter::OK; +} + + +#include diff --git a/filters/karbon/wmf/wmfimport.h b/filters/karbon/wmf/wmfimport.h new file mode 100644 index 00000000..e1290422 --- /dev/null +++ b/filters/karbon/wmf/wmfimport.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#ifndef WMFIMPORT_H +#define WMFIMPORT_H + +#include +#include + + +class WMFImport : public KoFilter +{ + Q_OBJECT + +public: + WMFImport( KoFilter *parent, const char *name, const QStringList&); + virtual ~WMFImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +}; + +#endif diff --git a/filters/karbon/wmf/wmfimportparser.cc b/filters/karbon/wmf/wmfimportparser.cc new file mode 100644 index 00000000..2eb380a4 --- /dev/null +++ b/filters/karbon/wmf/wmfimportparser.cc @@ -0,0 +1,371 @@ +/* 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 +#include +#include +#include +#include +#include + +#include "wmfimportparser.h" + +/* +bug : see motar.wmf +*/ + +WMFImportParser::WMFImportParser() : KoWmfRead() { +} + + +bool WMFImportParser::play( VDocument& doc ) +{ + mDoc = &doc; + mScaleX = mScaleY = 1; + + // Play the wmf file + return KoWmfRead::play( ); +} + + +//----------------------------------------------------------------------------- +// Virtual Painter + +bool WMFImportParser::begin() { + QRect bounding = boundingRect(); + + mBackgroundMode = Qt::TransparentMode; + mCurrentOrg.setX( bounding.left() ); + mCurrentOrg.setY( bounding.top() ); + + if ( isStandard() ) { + mDoc->setUnit( KoUnit::U_PT ); + mDoc->setWidth( bounding.width() ); + mDoc->setHeight( bounding.height() ); + } + else { + // Placeable Wmf store the boundingRect() in pixel and the default DPI + // The placeable format doesn't have informations on witch Unit to use + // so we choose millimeters by default + mDoc->setUnit( KoUnit::U_MM ); + mDoc->setWidth( INCH_TO_POINT( (double)bounding.width() / defaultDpi() ) ); + mDoc->setHeight( INCH_TO_POINT( (double)bounding.height() / defaultDpi() ) ); + } + if ( (bounding.width() != 0) && (bounding.height() != 0) ) { + mScaleX = mDoc->width() / (double)bounding.width(); + mScaleY = mDoc->height() / (double)bounding.height(); + } + return true; +} + + +bool WMFImportParser::end() { + return true; +} + + +void WMFImportParser::save() { +} + + +void WMFImportParser::restore() { +} + + +void WMFImportParser::setFont( const QFont & ) { +} + + +void WMFImportParser::setPen( const QPen &pen ) { + mPen = pen; +} + + +const QPen &WMFImportParser::pen() const { + return mPen; +} + + +void WMFImportParser::setBrush( const QBrush &brush ) { + mBrush = brush; +} + + +void WMFImportParser::setBackgroundColor( const QColor &c ) { + mBackgroundColor = c; +} + + +void WMFImportParser::setBackgroundMode( Qt::BGMode mode ) { + mBackgroundMode = mode; +} + + +void WMFImportParser::setRasterOp( Qt::RasterOp ) { +} + + +void WMFImportParser::setWindowOrg( int left, int top ) { + mCurrentOrg.setX( left ); + mCurrentOrg.setY( top ); +} + + +void WMFImportParser::setWindowExt( int width, int height ) { + // the wmf file can change width/height during the drawing + if ( (width != 0) && (height != 0) ) { + mScaleX = mDoc->width() / (double)width; + mScaleY = mDoc->height() / (double)height; + } +} + + +void WMFImportParser::setWorldMatrix( const QWMatrix &, bool ) { +} + + +void WMFImportParser::setClipRegion( const QRegion & ) { +} + + +QRegion WMFImportParser::clipRegion() { + return mClippingRegion; +} + + +void WMFImportParser::moveTo( int left, int top ) { + mCurrentPoint.setX( left ); + mCurrentPoint.setY( top ); +} + + +void WMFImportParser::lineTo( int left, int top ) { + VPath *line = new VPath( mDoc ); + line->moveTo( KoPoint( coordX(mCurrentPoint.x()), coordY(mCurrentPoint.y()) ) ); + line->lineTo( KoPoint( coordX(left), coordY(top) ) ); + appendPen( *line ); + + mDoc->append( line ); + mCurrentPoint.setX( left ); + mCurrentPoint.setY( top ); +} + + +void WMFImportParser::drawRect( int left, int top, int width, int height ) { + VRectangle *rectangle; + + rectangle = new VRectangle( mDoc, KoPoint( coordX(left), coordY(top) ), scaleW(width), scaleH(height), 0 ); + appendPen( *rectangle ); + appendBrush( *rectangle ); + + mDoc->append( rectangle ); +} + + +void WMFImportParser::drawRoundRect( int left, int top, int width, int height, int roudw, int ) { + VRectangle *rectangle; + + // TODO : round rectangle + rectangle = new VRectangle( mDoc, KoPoint( coordX(left), coordY(top) ), scaleW(width), scaleH(height), roudw ); + appendPen( *rectangle ); + appendBrush( *rectangle ); + + mDoc->append( rectangle ); +} + + +void WMFImportParser::drawEllipse( int left, int top, int width, int height ) { + VEllipse *ellipse; + + ellipse = new VEllipse( mDoc, KoPoint( coordX(left), coordY(top+height) ), scaleW(width), scaleH(height) ); + appendPen( *ellipse ); + appendBrush( *ellipse ); + + mDoc->append( ellipse ); +} + + +void WMFImportParser::drawArc( int x, int y, int w, int h, int aStart, int aLen ) { + double start = (aStart * 180) / 2880.0; + double end = (aLen * 180) / 2880.0; + end += start; + VEllipse::VEllipseType type = VEllipse::arc; + + VEllipse *arc = new VEllipse( mDoc, KoPoint( coordX(x), coordY(y+h) ), scaleW(w), scaleH(h), type, start, end ); + appendPen( *arc ); + + mDoc->append( arc ); +} + + +void WMFImportParser::drawPie( int x, int y, int w, int h, int aStart, int aLen ) { + double start = (aStart * 180) / 2880.0; + double end = (aLen * 180) / 2880.0; + end += start; + VEllipse::VEllipseType type = VEllipse::cut; + + VEllipse *arc = new VEllipse( mDoc, KoPoint( coordX(x), coordY(y+h) ), scaleW(w), scaleH(h), type, start, end ); + appendPen( *arc ); + appendBrush( *arc ); + + mDoc->append( arc ); +} + + +void WMFImportParser::drawChord( int x, int y, int w, int h, int aStart, int aLen ) { + double start = (aStart * 180) / 2880.0; + double end = (aLen * 180) / 2880.0; + end += start; + VEllipse::VEllipseType type = VEllipse::section; + + VEllipse *arc = new VEllipse( mDoc, KoPoint( coordX(x), coordY(y+h) ), scaleW(w), scaleH(h), type, start, end ); + appendPen( *arc ); + appendBrush( *arc ); + + mDoc->append( arc ); +} + + +void WMFImportParser::drawPolyline( const QPointArray &pa ) { + VPath *polyline = new VPath( mDoc ); + appendPen( *polyline ); + appendPoints( *polyline, pa ); + + mDoc->append( polyline ); +} + + +void WMFImportParser::drawPolygon( const QPointArray &pa, bool ) { + VPath *polygon = new VPath( mDoc ); + appendPen( *polygon ); + appendBrush( *polygon ); + appendPoints( *polygon, pa ); + + polygon->close(); + mDoc->append( polygon ); +} + + +void WMFImportParser::drawPolyPolygon( QPtrList& listPa, bool ) { + VPath *path = new VPath( mDoc ); + + if ( listPa.count() > 0 ) { + appendPen( *path ); + appendBrush( *path ); + appendPoints( *path, *listPa.first() ); + path->close(); + + while ( listPa.next() ) { + VPath *newPath = new VPath( mDoc ); + appendPoints( *newPath, *listPa.current() ); + newPath->close(); + path->combine( *newPath ); + } + + mDoc->append( path ); + } +} + + +void WMFImportParser::drawImage( int , int , const QImage &, int , int , int , int ) {} + + +void WMFImportParser::drawText( int , int , int , int , int , const QString& , double ) {} + + +//----------------------------------------------------------------------------- +// Utilities + +void WMFImportParser::appendPen( VObject& obj ) +{ + VStroke stroke( mDoc ); + stroke.setLineCap( VStroke::capRound ); + + if ( mPen.style() == Qt::NoPen ) { + stroke.setType( VStroke::none ); + } + else { + QValueList dashes; + stroke.setType( VStroke::solid ); + switch ( mPen.style() ) { + case Qt::DashLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(2) ); + break; + case Qt::DotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + case Qt::DashDotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + case Qt::DashDotDotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + default: + break; + } + } + stroke.setColor( mPen.color() ); + double width = mPen.width() * mScaleX; + stroke.setLineWidth( ((width < 0.99) ? 1 : width) ); + obj.setStroke( stroke ); +} + + +void WMFImportParser::appendBrush( VObject& obj ) +{ + VFill fill( mBackgroundColor ); + fill.setColor( mBrush.color() ); + + switch ( mBrush.style() ) { + case Qt::NoBrush : + fill.setType( VFill::none ); + break; + case Qt::SolidPattern : + fill.setType( VFill::solid ); + break; + case Qt::CustomPattern : + // TODO: bitmap pattern brush + fill.setType( VFill::solid ); + //fill.pattern(). + break; + default : + // TODO: pattern brush + if ( mBackgroundMode == Qt::OpaqueMode ) { + fill.setColor( mBackgroundColor ); + fill.setType( VFill::solid ); + } + else { + fill.setType( VFill::none ); + } + break; + } + obj.setFill( fill ); +} + + +void WMFImportParser::appendPoints(VPath &path, const QPointArray& pa) +{ + // list of point array + if ( pa.size() > 0 ) { + path.moveTo( KoPoint( coordX(pa.point(0).x()), coordY(pa.point(0).y()) ) ); + } + for ( uint i=1 ; i < pa.size() ; i++ ) { + path.lineTo( KoPoint( coordX(pa.point(i).x()), coordY(pa.point(i).y()) ) ); + } +} + diff --git a/filters/karbon/wmf/wmfimportparser.h b/filters/karbon/wmf/wmfimportparser.h new file mode 100644 index 00000000..fcb1fbe2 --- /dev/null +++ b/filters/karbon/wmf/wmfimportparser.h @@ -0,0 +1,141 @@ +/* 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. +*/ +#ifndef _WMFIMPORTPARSER_H_ +#define _WMFIMPORTPARSER_H_ + +#include +#include +#include +#include +#include + + +/** + * WMFImportParser inherit KoWmfRead + * and translate WMF functions + * + */ + +class WMFImportParser : public KoWmfRead +{ +public: + WMFImportParser(); + ~WMFImportParser() { } + + /** + * play WMF file on a VDocument. Return true on success. + */ + bool play( VDocument& doc ); + + +private: + // ------------------------------------------------------------------------- + // A virtual QPainter + bool begin(); + bool end(); + void save(); + void restore(); + + // Drawing tools + void setFont( const QFont &font ); + // the pen : the width of the pen is in logical coordinate + void setPen( const QPen &pen ); + const QPen &pen() const; + void setBrush( const QBrush &brush ); + + // Drawing attributes/modes + void setBackgroundColor( const QColor &c ); + void setBackgroundMode( Qt::BGMode mode ); + void setRasterOp( Qt::RasterOp op ); + + /** + * Change logical Coordinate + * some wmf files call those functions several times in the middle of a drawing + * others wmf files doesn't call setWindow* at all + * negative width and height are possible + */ + void setWindowOrg( int left, int top ); + void setWindowExt( int width, int height ); + + // Clipping + // the 'CoordinateMode' is ommitted : always CoordPainter in wmf + // setClipRegion() is often used with save() and restore() => implement all or none + void setClipRegion( const QRegion &rec ); + QRegion clipRegion(); + + // Graphics drawing functions + void moveTo( int x, int y ); + void lineTo( int x, int y ); + void drawRect( int x, int y, int w, int h ); + void drawRoundRect( int x, int y, int w, int h, int = 25, int = 25 ); + void drawEllipse( int x, int y, int w, int h ); + void drawArc( int x, int y, int w, int h, int a, int alen ); + void drawPie( int x, int y, int w, int h, int a, int alen ); + void drawChord( int x, int y, int w, int h, int a, int alen ); + void drawPolyline( const QPointArray &pa ); + void drawPolygon( const QPointArray &pa, bool winding=FALSE ); + /** + * drawPolyPolygon draw the XOR of a list of polygons + * listPa : list of polygons + */ + void drawPolyPolygon( QPtrList& listPa, bool winding=FALSE ); + void drawImage( int x, int y, const QImage &, int sx = 0, int sy = 0, int sw = -1, int sh = -1 ); + + // Text drawing + // rotation = the degrees of rotation in counterclockwise + // not yet implemented in KWinMetaFile + void drawText( int x, int y, int w, int h, int flags, const QString &s, double rotation ); + + // matrix transformation : only used in some bitmap manipulation + void setWorldMatrix( const QWMatrix &, bool combine=FALSE ); + + //----------------------------------------------------------------------------- + // Utilities + // Add pen, brush and points to a path + void appendPen( VObject& obj ); + void appendBrush( VObject& obj ); + void appendPoints(VPath& path, const QPointArray& pa); + // coordinate transformation + // translate wmf to (0,0) -> scale to document size -> translate to karbon (0,0) + // Wmf origin is (left,top) corner + // Karbon origin is (left,bottom) corner + double coordX( int left ) + { return ((double)(left - mCurrentOrg.x()) * mScaleX); } + double coordY( int top ) + { return (mDoc->height() - ((double)(top - mCurrentOrg.y()) * mScaleY)); } + double scaleW( int width ) + { return (width * mScaleX); } + double scaleH( int height ) + { return (height * mScaleY); } + +private: + VDocument *mDoc; + QRegion mClippingRegion; + QPen mPen; + QBrush mBrush; + Qt::BGMode mBackgroundMode; + QColor mBackgroundColor; + // current origin of WMF logical coordinate + QPoint mCurrentOrg; + double mScaleX; + double mScaleY; + // current position in WMF coordinate (INT16) + QPoint mCurrentPoint; +}; + +#endif diff --git a/filters/karbon/xaml/Makefile.am b/filters/karbon/xaml/Makefile.am new file mode 100644 index 00000000..f7036ada --- /dev/null +++ b/filters/karbon/xaml/Makefile.am @@ -0,0 +1,35 @@ +kde_module_LTLIBRARIES = libkarbonxamlexport.la libkarbonxamlimport.la + +libkarbonxamlexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonxamlexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +libkarbonxamlimport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonxamlimport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_xaml_export.desktop karbon_xaml_import.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + xamlexport.h \ + xamlimport.h + +libkarbonxamlexport_la_SOURCES = \ + xamlexport.cc + +libkarbonxamlimport_la_SOURCES = \ + xamlimport.cc + +METASOURCES = AUTO + diff --git a/filters/karbon/xaml/color.h b/filters/karbon/xaml/color.h new file mode 100644 index 00000000..bfdc93c6 --- /dev/null +++ b/filters/karbon/xaml/color.h @@ -0,0 +1,306 @@ + +#define TORGB( red, green, blue ) \ +{ \ + r = red; \ + b = blue; \ + g = green; \ +} + +void keywordToRGB( QString rgbColor, int &r, int &g, int &b ) +{ + if( rgbColor == "aliceblue" ) + TORGB( 240, 248, 255) + else if( rgbColor == "antiquewhite" ) + TORGB( 250, 235, 215) + else if( rgbColor == "aqua" ) + TORGB( 0, 255, 255) + else if( rgbColor == "aquamarine" ) + TORGB( 127, 255, 212 ) + else if( rgbColor == "azure" ) + TORGB( 240, 255, 255 ) + else if( rgbColor == "beige" ) + TORGB( 245, 245, 220 ) + else if( rgbColor == "bisque" ) + TORGB( 255, 228, 196 ) + else if( rgbColor == "black" ) + TORGB( 0, 0, 0 ) + else if( rgbColor == "blanchedalmond" ) + TORGB( 255, 235, 205 ) + else if( rgbColor == "blue" ) + TORGB( 0, 0, 255 ) + else if( rgbColor == "blueviolet" ) + TORGB( 138, 43, 226 ) + else if( rgbColor == "brown" ) + TORGB( 165, 42, 42 ) + else if( rgbColor == "burlywood" ) + TORGB( 222, 184, 135 ) + else if( rgbColor == "cadetblue" ) + TORGB( 95, 158, 160 ) + else if( rgbColor == "chartreuse" ) + TORGB( 127, 255, 0 ) + else if( rgbColor == "chocolate" ) + TORGB( 210, 105, 30 ) + else if( rgbColor == "coral" ) + TORGB( 255, 127, 80 ) + else if( rgbColor == "cornflowerblue" ) + TORGB( 100, 149, 237 ) + else if( rgbColor == "cornsilk" ) + TORGB( 255, 248, 220 ) + else if( rgbColor == "crimson" ) + TORGB( 220, 20, 60 ) + else if( rgbColor == "cyan" ) + TORGB( 0, 255, 255 ) + else if( rgbColor == "darkblue" ) + TORGB( 0, 0, 139 ) + else if( rgbColor == "darkcyan" ) + TORGB( 0, 139, 139 ) + else if( rgbColor == "darkgoldenrod" ) + TORGB( 184, 134, 11 ) + else if( rgbColor == "darkgray" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgrey" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgreen" ) + TORGB( 0, 100, 0 ) + else if( rgbColor == "darkkhaki" ) + TORGB( 189, 183, 107 ) + else if( rgbColor == "darkmagenta" ) + TORGB( 139, 0, 139 ) + else if( rgbColor == "darkolivegreen" ) + TORGB( 85, 107, 47 ) + else if( rgbColor == "darkorange" ) + TORGB( 255, 140, 0 ) + else if( rgbColor == "darkorchid" ) + TORGB( 153, 50, 204 ) + else if( rgbColor == "darkred" ) + TORGB( 139, 0, 0 ) + else if( rgbColor == "darksalmon" ) + TORGB( 233, 150, 122 ) + else if( rgbColor == "darkseagreen" ) + TORGB( 143, 188, 143 ) + else if( rgbColor == "darkslateblue" ) + TORGB( 72, 61, 139 ) + else if( rgbColor == "darkslategray" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkslategrey" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkturquoise" ) + TORGB( 0, 206, 209 ) + else if( rgbColor == "darkviolet" ) + TORGB( 148, 0, 211 ) + else if( rgbColor == "deeppink" ) + TORGB( 255, 20, 147 ) + else if( rgbColor == "deepskyblue" ) + TORGB( 0, 191, 255 ) + else if( rgbColor == "dimgray" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dimgrey" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dodgerblue" ) + TORGB( 30, 144, 255 ) + else if( rgbColor == "firebrick" ) + TORGB( 178, 34, 34 ) + else if( rgbColor == "floralwhite" ) + TORGB( 255, 250, 240 ) + else if( rgbColor == "forestgreen" ) + TORGB( 34, 139, 34 ) + else if( rgbColor == "fuchsia" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "gainsboro" ) + TORGB( 220, 220, 220 ) + else if( rgbColor == "ghostwhite" ) + TORGB( 248, 248, 255 ) + else if( rgbColor == "gold" ) + TORGB( 255, 215, 0 ) + else if( rgbColor == "goldenrod" ) + TORGB( 218, 165, 32 ) + else if( rgbColor == "gray" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "grey" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "green" ) + TORGB( 0, 128, 0 ) + else if( rgbColor == "greenyellow" ) + TORGB( 173, 255, 47 ) + else if( rgbColor == "honeydew" ) + TORGB( 240, 255, 240 ) + else if( rgbColor == "hotpink" ) + TORGB( 255, 105, 180 ) + else if( rgbColor == "indianred" ) + TORGB( 205, 92, 92 ) + else if( rgbColor == "indigo" ) + TORGB( 75, 0, 130 ) + else if( rgbColor == "ivory" ) + TORGB( 255, 255, 240 ) + else if( rgbColor == "khaki" ) + TORGB( 240, 230, 140 ) + else if( rgbColor == "lavender" ) + TORGB( 230, 230, 250 ) + else if( rgbColor == "lavenderblush" ) + TORGB( 255, 240, 245 ) + else if( rgbColor == "lawngreen" ) + TORGB( 124, 252, 0 ) + else if( rgbColor == "lemonchiffon" ) + TORGB( 255, 250, 205 ) + else if( rgbColor == "lightblue" ) + TORGB( 173, 216, 230 ) + else if( rgbColor == "lightcoral" ) + TORGB( 240, 128, 128 ) + else if( rgbColor == "lightcyan" ) + TORGB( 224, 255, 255 ) + else if( rgbColor == "lightgoldenrodyellow" ) + TORGB( 250, 250, 210 ) + else if( rgbColor == "lightgray" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgrey" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgreen" ) + TORGB( 144, 238, 144 ) + else if( rgbColor == "lightpink" ) + TORGB( 255, 182, 193 ) + else if( rgbColor == "lightsalmon" ) + TORGB( 255, 160, 122 ) + else if( rgbColor == "lightseagreen" ) + TORGB( 32, 178, 170 ) + else if( rgbColor == "lightskyblue" ) + TORGB( 135, 206, 250 ) + else if( rgbColor == "lightslategray" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightslategrey" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightsteelblue" ) + TORGB( 176, 196, 222 ) + else if( rgbColor == "lightyellow" ) + TORGB( 255, 255, 224 ) + else if( rgbColor == "lime" ) + TORGB( 0, 255, 0 ) + else if( rgbColor == "limegreen" ) + TORGB( 50, 205, 50 ) + else if( rgbColor == "linen" ) + TORGB( 250, 240, 230 ) + else if( rgbColor == "magenta" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "maroon" ) + TORGB( 128, 0, 0 ) + else if( rgbColor == "mediumaquamarine" ) + TORGB( 102, 205, 170 ) + else if( rgbColor == "mediumblue" ) + TORGB( 0, 0, 205 ) + else if( rgbColor == "mediumorchid" ) + TORGB( 186, 85, 211 ) + else if( rgbColor == "mediumpurple" ) + TORGB( 147, 112, 219 ) + else if( rgbColor == "mediumseagreen" ) + TORGB( 60, 179, 113 ) + else if( rgbColor == "mediumslateblue" ) + TORGB( 123, 104, 238 ) + else if( rgbColor == "mediumspringgreen" ) + TORGB( 0, 250, 154 ) + else if( rgbColor == "mediumturquoise" ) + TORGB( 72, 209, 204 ) + else if( rgbColor == "mediumvioletred" ) + TORGB( 199, 21, 133 ) + else if( rgbColor == "midnightblue" ) + TORGB( 25, 25, 112 ) + else if( rgbColor == "mintcream" ) + TORGB( 245, 255, 250 ) + else if( rgbColor == "mistyrose" ) + TORGB( 255, 228, 225 ) + else if( rgbColor == "moccasin" ) + TORGB( 255, 228, 181 ) + else if( rgbColor == "navajowhite" ) + TORGB( 255, 222, 173 ) + else if( rgbColor == "navy" ) + TORGB( 0, 0, 128 ) + else if( rgbColor == "oldlace" ) + TORGB( 253, 245, 230 ) + else if( rgbColor == "olive" ) + TORGB( 128, 128, 0 ) + else if( rgbColor == "olivedrab" ) + TORGB( 107, 142, 35 ) + else if( rgbColor == "orange" ) + TORGB( 255, 165, 0 ) + else if( rgbColor == "orangered" ) + TORGB( 255, 69, 0 ) + else if( rgbColor == "orchid" ) + TORGB( 218, 112, 214 ) + else if( rgbColor == "palegoldenrod" ) + TORGB( 238, 232, 170 ) + else if( rgbColor == "palegreen" ) + TORGB( 152, 251, 152 ) + else if( rgbColor == "paleturquoise" ) + TORGB( 175, 238, 238 ) + else if( rgbColor == "palevioletred" ) + TORGB( 219, 112, 147 ) + else if( rgbColor == "papayawhip" ) + TORGB( 255, 239, 213 ) + else if( rgbColor == "peachpuff" ) + TORGB( 255, 218, 185 ) + else if( rgbColor == "peru" ) + TORGB( 205, 133, 63 ) + else if( rgbColor == "pink" ) + TORGB( 255, 192, 203 ) + else if( rgbColor == "plum" ) + TORGB( 221, 160, 221 ) + else if( rgbColor == "powderblue" ) + TORGB( 176, 224, 230 ) + else if( rgbColor == "purple" ) + TORGB( 128, 0, 128 ) + else if( rgbColor == "red" ) + TORGB( 255, 0, 0 ) + else if( rgbColor == "rosybrown" ) + TORGB( 188, 143, 143 ) + else if( rgbColor == "royalblue" ) + TORGB( 65, 105, 225 ) + else if( rgbColor == "saddlebrown" ) + TORGB( 139, 69, 19 ) + else if( rgbColor == "salmon" ) + TORGB( 250, 128, 114 ) + else if( rgbColor == "sandybrown" ) + TORGB( 244, 164, 96 ) + else if( rgbColor == "seagreen" ) + TORGB( 46, 139, 87 ) + else if( rgbColor == "seashell" ) + TORGB( 255, 245, 238 ) + else if( rgbColor == "sienna" ) + TORGB( 160, 82, 45 ) + else if( rgbColor == "silver" ) + TORGB( 192, 192, 192 ) + else if( rgbColor == "skyblue" ) + TORGB( 135, 206, 235 ) + else if( rgbColor == "slateblue" ) + TORGB( 106, 90, 205 ) + else if( rgbColor == "slategray" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "slategrey" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "snow" ) + TORGB( 255, 250, 250 ) + else if( rgbColor == "springgreen" ) + TORGB( 0, 255, 127 ) + else if( rgbColor == "steelblue" ) + TORGB( 70, 130, 180 ) + else if( rgbColor == "tan" ) + TORGB( 210, 180, 140 ) + else if( rgbColor == "teal" ) + TORGB( 0, 128, 128 ) + else if( rgbColor == "thistle" ) + TORGB( 216, 191, 216 ) + else if( rgbColor == "tomato" ) + TORGB( 255, 99, 71 ) + else if( rgbColor == "turquoise" ) + TORGB( 64, 224, 208 ) + else if( rgbColor == "violet" ) + TORGB( 238, 130, 238 ) + else if( rgbColor == "wheat" ) + TORGB( 245, 222, 179 ) + else if( rgbColor == "white" ) + TORGB( 255, 255, 255 ) + else if( rgbColor == "whitesmoke" ) + TORGB( 245, 245, 245 ) + else if( rgbColor == "yellow" ) + TORGB( 255, 255, 0 ) + else if( rgbColor == "yellowgreen" ) + TORGB( 154, 205, 50 ) +} + diff --git a/filters/karbon/xaml/karbon_xaml_export.desktop b/filters/karbon/xaml/karbon_xaml_export.desktop new file mode 100644 index 00000000..082c29e8 --- /dev/null +++ b/filters/karbon/xaml/karbon_xaml_export.desktop @@ -0,0 +1,54 @@ +[Desktop Entry] +Icon= +Name=Karbon14 WVG Export Filter +Name[ar]=賲賽乇賿卮賻丨 鬲氐丿賷乇 WVG 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 械泻褋锌芯褉褌懈褉邪薪械 芯褌 Karbon14 胁 WVG +Name[br]=Sil ezporzh WVG evit Karbon14 +Name[ca]=Filtre d'exportaci贸 WVG per a Karbon14 +Name[cy]=Hidlen Allforio WVG Karbon14 +Name[da]=Karbon14 WVG-eksportfilter +Name[de]=Karbon14 WVG-Exportfilter +Name[el]=桅委位蟿蟻慰 蔚尉伪纬蠅纬萎蟼 SVG 蟿慰蠀 Karbon14 +Name[eo]=Karbon14-WVG-eksportfiltrilo +Name[es]=Filtro de exportaci贸n a WVG de Karbon14 +Name[et]=Karbon14 WVG ekspordifilter +Name[fa]=倬丕賱丕蹖踿 氐丕丿乇丕鬲 Karbon14 WVG +Name[fi]=Karbon14 WVG -vientisuodin +Name[fr]=Filtre d'exportation WVG de Karbon 14 +Name[fy]=WVG-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easp贸rt谩la WVG Karbon14 +Name[gl]=Filtro de Exportaci贸n de WVG para Karbon14 +Name[he]=Karbon14 WVG 诪住谞谉 讬爪讜讗 +Name[hr]=Karbon14 WVG filtar izvoza +Name[hu]=Karbon14 WVG exportsz疟r艖 +Name[is]=Karbon14 WVG 煤tflutningss铆a +Name[it]=Filtro di esportazione WVG per Karbon14 +Name[ja]=Karbon14 WVG 銈ㄣ偗銈广儩銉笺儓銉曘偅銉偪 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩焷釣 WVG 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lt]=Karbon14 WVG eksportavimo filtras +Name[lv]=Karbon14 WVG eksporta filtrs +Name[nb]=WVG-eksportfiler for Karbon14 +Name[nds]=WVG-Exportfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶∴が啷嵿げ啷佮き啷啶溹 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]= WVG-exportfilter voor Karbon14 +Name[pl]=Filtr eksportu do formatu WVG z Karbon14 +Name[pt]=Filtro de Exporta莽茫o de WVG para o Karbon14 +Name[pt_BR]=Filtro de Exporta莽茫o de WVG para o Karbon14 +Name[ru]=肖懈谢褜褌褉 褝泻褋锌芯褉褌邪 褉懈褋褍薪泻芯胁 Karbon 胁 WVG +Name[se]=Karbon14:a WVG-olggosfievrridansilli +Name[sk]=WVG filter pre export z Karbon14 +Name[sl]=Izvozni filter WVG za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 懈蟹胁芯蟹 褍 WVG +Name[sr@Latn]=Karbon14-ov filter za izvoz u WVG +Name[sv]=Karbon14 WVG-exportfilter +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 WVG 写谢褟 Karbon14 +Name[uz]=Karbon14 WVG eksport filteri +Name[uz@cyrillic]=Karbon14 WVG 褝泻褋锌芯褉褌 褎懈谢褌械褉懈 +Name[zh_CN]=Karbon14 WVG 瀵煎嚭杩囨护鍣 +Name[zh_TW]=Karbon14 WVG 鍖嚭閬庢烤绋嬪紡 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/wvg+xml +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonxamlexport +X-KDE-Weight=1 diff --git a/filters/karbon/xaml/karbon_xaml_import.desktop b/filters/karbon/xaml/karbon_xaml_import.desktop new file mode 100644 index 00000000..6acd1f1f --- /dev/null +++ b/filters/karbon/xaml/karbon_xaml_import.desktop @@ -0,0 +1,53 @@ +[Desktop Entry] +Type=Service +Name=Karbon XAML Import Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 XAML 賱丿賶 Karbon +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 XAML 胁 Karbon +Name[br]=Sil enporzh XAML evit Karbon +Name[ca]=Filtre d'importaci贸 XAML per a Karbon +Name[cy]=Hidlen Fewnforio XAML Karbon +Name[da]=Karbon XAML-importfilter +Name[de]=Karbon14 XAML-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 XAML 蟿慰蠀 Karbon +Name[eo]=Karbon-XAML-importfiltrilo +Name[es]=Filtro de importaci贸n a XAML de Karbon +Name[et]=Karboni XAML-i impordifilter +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon XAML +Name[fi]=Karbon XAML -tuontisuodin +Name[fr]=Filtre d'importation XAML de Karbon 14 +Name[fy]=XAML-tmportfilter foar Karbon +Name[ga]=Scagaire Iomp贸rt谩la Karbon XAML +Name[gl]=Filtro de Importaci贸n de XAML para Karbon +Name[he]=Karbon XAML 诪住谞谉 讬讘讜讗 +Name[hr]=Karbon XAML filtar uvoza +Name[hu]=Karbon XAML importsz疟r艖 +Name[is]=Karbon XAML innflutningss铆a +Name[it]=Filtro di importazione XAML per Karbon +Name[ja]=Karbon XAML 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 XAML 釣熱灅釤掅灇釣夺灁釤 Karbon +Name[lt]=Karbon XAML importavimo filtras +Name[lv]=Karbon XAML importa filtrs +Name[nb]=XAML-importfilter for Karbon +Name[nds]=XAML-Importfilter f枚r Karbon +Name[ne]=啶曕ぞ啶班啶え 啶忇啷嵿じ啶忇啶啶 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=XAML-importfilter voor Karbon +Name[pl]=Filtr importu formatu XAML do Karbon +Name[pt]=Filtro de Importa莽茫o de XAML para o Karbon +Name[pt_BR]=Filtro de Importa莽茫o de XAML para o Karbon +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褎邪泄谢芯胁 XAML 胁 Karbon +Name[se]=Karbon:a XAML-sisafievrridansilli +Name[sk]=XAML importn媒 filter pre Karbon +Name[sl]=Uvozni filter XAML za Karbon +Name[sr]=Karbon-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 XAML-邪 +Name[sr@Latn]=Karbon-ov filter za uvoz iz XAML-a +Name[sv]=Karbon XAML-importfilter +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 XAML 写谢褟 Karbon +Name[uz]=Karbon XAML import filteri +Name[uz@cyrillic]=Karbon XAML 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[zh_CN]=Karbon XAML 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon XAML 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/wvg+xml +X-KDE-Weight=1 +X-KDE-Library=libkarbonxamlimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/xaml/xamlexport.cc b/filters/karbon/xaml/xamlexport.cc new file mode 100644 index 00000000..c4ccb467 --- /dev/null +++ b/filters/karbon/xaml/xamlexport.cc @@ -0,0 +1,371 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +// based on the SVG exporter. Not intended for public release +// Microsoft WVG renamed to XAML Graphics. Worry about that later. + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xamlexport.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vfill.h" +#include "vgradient.h" +#include "vgroup.h" +#include "vlayer.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vstroke.h" +//#include "vtext.h" // TODO Convert Text to Paths for basic export. Not our problem. +// TODO inline Images? + +#include + + +typedef KGenericFactory XAMLExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonxamlexport, XAMLExportFactory( "kofficefilters" ) ) + + +XAMLExport::XAMLExport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ + m_gc.setAutoDelete( true ); +} + +KoFilter::ConversionStatus +XAMLExport::convert( const QCString& from, const QCString& to ) +{ + // TODO: ??? + if ( to != "image/wvg+xml" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if( !storeIn ) + return KoFilter::StupidError; + + QFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + delete storeIn; + return KoFilter::StupidError; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QTextStream( &fileOut ); + QString body; + m_body = new QTextStream( &body, IO_ReadWrite ); + QString defs; + m_defs = new QTextStream( &defs, IO_ReadWrite ); + + + // load the document and export it: + VDocument doc; + doc.load( docNode ); + doc.accept( *this ); + + *m_stream << defs; + *m_stream << body; + + fileOut.close(); + + delete m_stream; + delete m_defs; + delete m_body; + + return KoFilter::OK; +} + +void +XAMLExport::visitVDocument( VDocument& document ) +{ + // select all objects: + document.selection()->append(); + + // get the bounding box of the page + KoRect rect( 0, 0, document.width(), document.height() ); + + // standard header: + *m_defs << + "\n" << + /* "" + /*<<*/ endl; + + // Add one line comment to identify Content Creator, + // probably remove this later + // TODO: schemas + // http://schemas.microsoft.com/winfx/avalon/2005 + // http://schemas.microsoft.com/2003/xaml + // need to mention defs too Defenitions namespace xmlns:def="Definition" + *m_defs << + "" << endl; + *m_defs << + "" << endl; + *m_defs << "" << endl; + + // bleuch: this is horrible, do something about it TODO + // Microsoft Acrylic has a transform group just like this + *m_body << "" << endl; + + // we dont need the selection anymore: + document.selection()->clear(); + + // set up gc + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + m_gc.push( gc ); + + // export layers: + VVisitor::visitVDocument( document ); + + // end tag: + *m_body << "" << endl; + *m_defs << "" << endl; + *m_body << "" << endl; +} + +QString +XAMLExport::getID( VObject *obj ) +{ + if( obj && !obj->name().isEmpty() ) + return QString( " Name=\"%1\"" ).arg( obj->name() ); + return QString(); +} + +// which markup to use? Group or Canvas? +// for now assume Group will work. TODO: Test properly! +void +XAMLExport::visitVGroup( VGroup& group ) +{ + *m_body << "" << endl; + VVisitor::visitVGroup( group ); + *m_body << "" << endl; +} + +void +XAMLExport::visitVPath( VPath& composite ) +{ + *m_body << "fillRule ) + { + if( composite.fillRule() == evenOdd ) + *m_body << " FillRule=\"EvenOdd\""; + else + *m_body << " FillRule=\"NonZero\""; + } + + *m_body << " />" << endl; +} + +void +XAMLExport::visitVSubpath( VSubpath& ) +{ +} + +QString createUID() +{ + static unsigned int nr = 0; + + return "defitem" + QString().setNum( nr++ ); +} + +void +XAMLExport::getColorStops( const QPtrVector &colorStops ) +{ + for( unsigned int i = 0; i < colorStops.count() ; i++ ) + { + *m_defs << "color ); + *m_defs << "\" Offset=\"" << QString().setNum( colorStops.at( i )->rampPoint ); + // XAML uses ARGB values and other methods such as masks for Transparency/Opacity # aa rrggbb + // *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl; + // Maybe this only applies to gradients, need to check. + } +} + +void +XAMLExport::getGradient( const VGradient& grad ) +{ + QString uid = createUID(); + if( grad.type() == VGradient::linear ) + { + // do linear grad + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } + else if( grad.type() == VGradient::radial ) + { + // do radial grad + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } +} + +void +XAMLExport::getFill( const VFill& fill ) +{ + *m_body << " Fill=\""; + if( fill.type() == VFill::none ) + *m_body << "none"; + else if( fill.type() == VFill::grad ) + getGradient( fill.gradient() ); + else + getHexColor( m_body, fill.color() ); + *m_body << "\""; + + if( fill.color().opacity() != m_gc.current()->fill.color().opacity() ) + *m_body << " FillOpacity=\"" << fill.color().opacity() << "\""; +} + +void +XAMLExport::getStroke( const VStroke& stroke ) +{ + if( stroke.type() != m_gc.current()->stroke.type() ) + { + *m_body << " Stroke=\""; + if( stroke.type() == VStroke::none ) + *m_body << "None"; + else if( stroke.type() == VStroke::grad ) + getGradient( stroke.gradient() ); + else + getHexColor( m_body, stroke.color() ); + *m_body << "\""; + } + + if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() ) + *m_body << " StrokeOpacity=\"" << stroke.color().opacity() << "\""; + + if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() ) + *m_body << " StrokeThickness=\"" << stroke.lineWidth() << "\""; + + if( stroke.lineCap() != m_gc.current()->stroke.lineCap() ) + { + if( stroke.lineCap() == VStroke::capButt ) + *m_body << " StrokeLineCap=\"Butt\""; + else if( stroke.lineCap() == VStroke::capRound ) + *m_body << " StrokeLineCap=\"round\""; + else if( stroke.lineCap() == VStroke::capSquare ) + *m_body << " StrokeLineCap=\"square\""; + } + + if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() ) + { + if( stroke.lineJoin() == VStroke::joinMiter ) + { + *m_body << " StrokeLineJoin=\"Miter\""; + *m_body << " StrokeMiterLimit=\"" << stroke.miterLimit() << "\""; + } + else if( stroke.lineJoin() == VStroke::joinRound ) + *m_body << " StrokeLineJoin=\"Round\""; + else if( stroke.lineJoin() == VStroke::joinBevel ) + *m_body << " StrokeLineJoin=\"Bevel\""; + } + + // dash + if( stroke.dashPattern().array().count() > 0 ) + { + *m_body << " StrokeDashOffset=\"" << stroke.dashPattern().offset() << "\""; + *m_body << " StrokeDashArray=\" "; + + QValueListConstIterator itr; + for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) + { + *m_body << *itr << " "; + } + *m_body << "\""; + } +} + +void +XAMLExport::getHexColor( QTextStream *stream, const VColor& color ) +{ + // Convert the various color-spaces to hex + + QString Output; + + VColor copy( color ); + copy.setColorSpace( VColor::rgb ); + + Output.sprintf( "#%02x%02x%02x", int( copy[0] * 255.0 ), int( copy[1] * 255.0 ), int( copy[2] * 255.0 ) ); + + *stream << Output; +} + +#include "xamlexport.moc" + diff --git a/filters/karbon/xaml/xamlexport.h b/filters/karbon/xaml/xamlexport.h new file mode 100644 index 00000000..3d2701c6 --- /dev/null +++ b/filters/karbon/xaml/xamlexport.h @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __XAMLEXPORT_H__ +#define __XAMLEXPORT_H__ + +#include + +#include "vvisitor.h" +#include "vgradient.h" + +#include "xamlgraphiccontext.h" + +#include + +class QTextStream; +class VColor; +class VPath; +class VDocument; +class VFill; +class VGroup; +class VLayer; +class VSubpath; +class VStroke; +class VText; + + +class XAMLExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + XAMLExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~XAMLExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + virtual void visitVPath( VPath& composite ); + virtual void visitVDocument( VDocument& document ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVSubpath( VSubpath& path ); + //virtual void visitVText( VText& text ); + + void getStroke( const VStroke& stroke ); + void getColorStops( const QPtrVector &colorStops ); + void getFill( const VFill& fill ); + void getGradient( const VGradient& grad ); + void getHexColor( QTextStream *, const VColor& color ); + QString getID( VObject *obj ); + + QTextStream* m_stream; + QTextStream* m_defs; + QTextStream* m_body; + + QPtrStack m_gc; +}; + +#endif + diff --git a/filters/karbon/xaml/xamlgraphiccontext.h b/filters/karbon/xaml/xamlgraphiccontext.h new file mode 100644 index 00000000..db4a8363 --- /dev/null +++ b/filters/karbon/xaml/xamlgraphiccontext.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project + Copyright (C) 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __XAMLGRAPHICSCONTEXT_H__ +#define __XAMLGRAPHICSCONTEXT_H__ + +#include +#include +#include + +class XAMLGraphicsContext +{ +public: + XAMLGraphicsContext() + { + stroke.setType( VStroke::none ); // default is no stroke + stroke.setLineWidth( 1.0 ); + stroke.setLineCap( VStroke::capButt ); + stroke.setLineJoin( VStroke::joinMiter ); + fill.setColor( VColor( Qt::black ) ); + fillRule = winding; + } + VFill fill; + VFillRule fillRule; + VStroke stroke; + QWMatrix matrix; + QFont font; +}; + +#endif diff --git a/filters/karbon/xaml/xamlimport.cc b/filters/karbon/xaml/xamlimport.cc new file mode 100644 index 00000000..297ff68d --- /dev/null +++ b/filters/karbon/xaml/xamlimport.cc @@ -0,0 +1,1042 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 "xamlimport.h" +#include "color.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory XAMLImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonxamlimport, XAMLImportFactory( "kofficefilters" ) ) + +XAMLImport::XAMLImport(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ + m_gc.setAutoDelete( true ); +} + +XAMLImport::~XAMLImport() +{ +} + +KoFilter::ConversionStatus XAMLImport::convert(const QCString& from, const QCString& to) +{ + // check for proper conversion + if( to != "application/x-karbon" || from != "image/wvg+xml" ) + return KoFilter::NotImplemented; + + //Find the last extension + QString strExt; + QString fileIn ( m_chain->inputFile() ); + const int result=fileIn.findRev('.'); + if (result>=0) + { + strExt=fileIn.mid(result).lower(); + } + + QString strMime; // Mime type of the compressor + if ((strExt==".gz") //in case of .svg.gz (logical extension) + ||(strExt==".wvgz")) //in case of .svgz (extension used prioritary) + strMime="application/x-gzip"; // Compressed with gzip + else if (strExt==".bz2") //in case of .svg.bz2 (logical extension) + strMime="application/x-bzip2"; // Compressed with bzip2 + else + strMime="text/plain"; + + kdDebug(30514) << "File extension: -" << strExt << "- Compression: " << strMime << endl; + + QIODevice* in = KFilterDev::deviceForFile(fileIn,strMime); + + if (!in->open(IO_ReadOnly)) + { + kdError(30514) << "Cannot open file! Aborting!" << endl; + delete in; + return KoFilter::FileNotFound; + } + + int line, col; + QString errormessage; + const bool parsed=inpdoc.setContent( in, &errormessage, &line, &col ); + in->close(); + delete in; + if ( ! parsed ) + { + kdError(30514) << "Error while parsing file: " + << "at line " << line << " column: " << col + << " message: " << errormessage << endl; + // ### TODO: feedback to the user + return KoFilter::ParsingError; + } + + // Do the conversion! + convert(); + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if( !out ) + { + kdError(30514) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void +XAMLImport::convert() +{ + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + QDomElement docElem = inpdoc.documentElement(); + KoRect bbox( 0, 0, 550.0, 841.0 ); + double width = !docElem.attribute( "width" ).isEmpty() ? parseUnit( docElem.attribute( "width" ), true, false, bbox ) : 550.0; + double height = !docElem.attribute( "height" ).isEmpty() ? parseUnit( docElem.attribute( "height" ), false, true, bbox ) : 841.0; + m_document.setWidth( width ); + m_document.setHeight( height ); + m_outerRect = m_document.boundingBox(); + + // undo y-mirroring + if( !docElem.attribute( "viewBox" ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + QString viewbox( docElem.attribute( "viewBox" ) ); + QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() ); + + gc->matrix.scale( width / points[2].toFloat() , height / points[3].toFloat() ); + m_outerRect.setWidth( m_outerRect.width() * ( points[2].toFloat() / width ) ); + m_outerRect.setHeight( m_outerRect.height() * ( points[3].toFloat() / height ) ); + } + m_gc.push( gc ); + parseGroup( 0L, docElem ); + + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -m_document.height() ); + VTransformCmd trafo( 0L, mat ); + trafo.visit( m_document ); + outdoc = m_document.saveXML(); +} + +#define DPI 90 + +double +XAMLImport::toPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble(); + else + return s.toDouble() * 100.0; +} + +double +XAMLImport::fromPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble() / 100.0; + else + return s.toDouble(); +} + +// parses the number into parameter number +const char * +getNumber( const char *ptr, double &number ) +{ + int integer, exponent; + double decimal, frac; + int sign, expsign; + + exponent = 0; + integer = 0; + frac = 1.0; + decimal = 0; + sign = 1; + expsign = 1; + + // read the sign + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + sign = -1; + } + + // read the integer part + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + integer = (integer * 10) + *(ptr++) - '0'; + if(*ptr == '.') // read the decimals + { + ptr++; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + decimal += (*(ptr++) - '0') * (frac *= 0.1); + } + + if(*ptr == 'e' || *ptr == 'E') // read the exponent part + { + ptr++; + + // read the sign of the exponent + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + expsign = -1; + } + + exponent = 0; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + { + exponent *= 10; + exponent += *ptr - '0'; + ptr++; + } + } + number = integer + decimal; + number *= sign * pow( (double)10, double( expsign * exponent ) ); + + return ptr; +} + + +double +XAMLImport::parseUnit( const QString &unit, bool horiz, bool vert, KoRect bbox ) +{ + // TODO : percentage? + double value = 0; + const char *start = unit.latin1(); + if(!start) { + return 0; + } + const char *end = getNumber( start, value ); + + if( uint( end - start ) < unit.length() ) + { + if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "cm" ) + value = ( value / 2.54 ) * DPI; + else if( unit.right( 2 ) == "pc" ) + value = ( value / 6.0 ) * DPI; + else if( unit.right( 2 ) == "mm" ) + value = ( value / 25.4 ) * DPI; + else if( unit.right( 2 ) == "in" ) + value = value * DPI; + else if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "em" ) + value = value * m_gc.current()->font.pointSize() / ( sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) ); + else if( unit.right( 1 ) == "%" ) + { + if( horiz && vert ) + value = ( value / 100.0 ) * (sqrt( pow( bbox.width(), 2 ) + pow( bbox.height(), 2 ) ) / sqrt( 2.0 ) ); + else if( horiz ) + value = ( value / 100.0 ) * bbox.width(); + else if( vert ) + value = ( value / 100.0 ) * bbox.height(); + } + } + /*else + { + if( m_gc.current() ) + { + if( horiz && vert ) + value *= sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ); + else if( horiz ) + value /= m_gc.current()->matrix.m11(); + else if( vert ) + value /= m_gc.current()->matrix.m22(); + } + }*/ + return value; +} + +QColor +XAMLImport::parseColor( const QString &rgbColor ) +{ + int r, g, b; + keywordToRGB( rgbColor, r, g, b ); + return QColor( r, g, b ); +} + +void +XAMLImport::parseColor( VColor &color, const QString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + QString parse = s.stripWhiteSpace(); + QStringList colors = QStringList::split( ',', parse ); + QString r = colors[0].right( ( colors[0].length() - 4 ) ); + QString g = colors[1]; + QString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + QColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else + { + QString rgbColor = s.stripWhiteSpace(); + QColor c; + if( rgbColor.startsWith( "#" ) ) + c.setNamedColor( rgbColor ); + else + c = parseColor( rgbColor ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } +} + +void +XAMLImport::parseColorStops( VGradient *gradient, const QDomElement &e ) +{ + VColor c; + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement stop = n.toElement(); + if( stop.tagName() == "stop" ) + { + float offset; + QString temp = stop.attribute( "offset" ); + if( temp.contains( '%' ) ) + { + temp = temp.left( temp.length() - 1 ); + offset = temp.toFloat() / 100.0; + } + else + offset = temp.toFloat(); + + if( !stop.attribute( "stop-color" ).isEmpty() ) + parseColor( c, stop.attribute( "stop-color" ) ); + else + { + // try style attr + QString style = stop.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + if( command == "stop-color" ) + parseColor( c, params ); + if( command == "stop-opacity" ) + c.setOpacity( params.toDouble() ); + } + + } + if( !stop.attribute( "stop-opacity" ).isEmpty() ) + c.setOpacity( stop.attribute( "stop-opacity" ).toDouble() ); + gradient->addStop( c, offset, 0.5 ); + } + } +} + +void +XAMLImport::parseGradient( const QDomElement &e ) +{ + GradientHelper gradhelper; + gradhelper.gradient.clearStops(); + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + QString href = e.attribute( "xlink:href" ).mid( 1 ); + if( !href.isEmpty() ) + { + //kdDebug() << "Indexing with href : " << href.latin1() << endl; + gradhelper.gradient = m_gradients[ href ].gradient; + } + + gradhelper.bbox = e.attribute( "gradientUnits" ) != "userSpaceOnUse"; + + if( e.tagName() == "linearGradient" ) + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( e.attribute( "x1", "0%" ) ), toPercentage( e.attribute( "y1", "0%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( e.attribute( "x2", "100%" ) ), toPercentage( e.attribute( "y2", "0%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( e.attribute( "x1" ).toDouble(), e.attribute( "y1" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( e.attribute( "x2" ).toDouble(), e.attribute( "y2" ).toDouble() ) ); + } + } + else + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( e.attribute( "cx", "50%" ) ), toPercentage( e.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( e.attribute( "cx", "50%" ) ) + toPercentage( e.attribute( "r", "50%" ) ), + toPercentage( e.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setFocalPoint( KoPoint( toPercentage( e.attribute( "fx", "50%" ) ), toPercentage( e.attribute( "fy", "50%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( e.attribute( "cx" ).toDouble(), e.attribute( "cy" ).toDouble() ) ); + gradhelper.gradient.setFocalPoint( KoPoint( e.attribute( "fx" ).toDouble(), e.attribute( "fy" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( e.attribute( "cx" ).toDouble() + e.attribute( "r" ).toDouble(), e.attribute( "cy" ).toDouble() ) ); + } + gradhelper.gradient.setType( VGradient::radial ); + } + // handle spread method + QString spreadMethod = e.attribute( "spreadMethod" ); + if( !spreadMethod.isEmpty() ) + { + if( spreadMethod == "reflect" ) + gradhelper.gradient.setRepeatMethod( VGradient::reflect ); + else if( spreadMethod == "repeat" ) + gradhelper.gradient.setRepeatMethod( VGradient::repeat ); + } + parseColorStops( &gradhelper.gradient, e ); + //gradient.setGradientTransform( parseTransform( e.attribute( "gradientTransform" ) ) ); + gradhelper.gradientTransform = VPath::parseTransform( e.attribute( "gradientTransform" ) ); + m_gradients.insert( e.attribute( "id" ), gradhelper ); +} + +void +XAMLImport::parsePA( VObject *obj, XAMLGraphicsContext *gc, const QString &command, const QString ¶ms ) +{ + VColor fillcolor = gc->fill.color(); + VColor strokecolor = gc->stroke.color(); + + if( command == "fill" ) + { + if( params == "none" ) + gc->fill.setType( VFill::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + gc->fill.gradient() = m_gradients[ key ].gradient; + if( m_gradients[ key ].bbox ) + { + // adjust to bbox + KoRect bbox = obj->boundingBox(); + //kdDebug() << "bbox x : " << bbox.x() << endl; + //kdDebug() << "!!!!!!bbox y : " << bbox.y() << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + double offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); + double offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox ); + gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); + gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().y() ), false, true, bbox ); + gc->fill.gradient().setVector( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + //kdDebug() << offsety << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().origin().y() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + //kdDebug() << gc->fill.gradient().vector().y() << endl; + } + gc->fill.gradient().transform( m_gradients[ key ].gradientTransform ); + if( !m_gradients[ key ].bbox ) + gc->fill.gradient().transform( gc->matrix ); + gc->fill.setType( VFill::grad ); + } + else + { + parseColor( fillcolor, params ); + gc->fill.setType( VFill::solid ); + } + } + else if( command == "fill-rule" ) + { + if( params == "nonzero" ) + gc->fillRule = winding; + else if( params == "evenodd" ) + gc->fillRule = evenOdd; + } + else if( command == "stroke" ) + { + if( params == "none" ) + gc->stroke.setType( VStroke::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + gc->stroke.gradient() = m_gradients[ key ].gradient; + gc->stroke.gradient().transform( m_gradients[ key ].gradientTransform ); + gc->stroke.gradient().transform( gc->matrix ); + gc->stroke.setType( VStroke::grad ); + } + else + { + parseColor( strokecolor, params ); + gc->stroke.setType( VStroke::solid ); + } + } + else if( command == "stroke-width" ) + gc->stroke.setLineWidth( parseUnit( params, true, true, m_outerRect ) ); + else if( command == "stroke-linejoin" ) + { + if( params == "miter" ) + gc->stroke.setLineJoin( VStroke::joinMiter ); + else if( params == "round" ) + gc->stroke.setLineJoin( VStroke::joinRound ); + else if( params == "bevel" ) + gc->stroke.setLineJoin( VStroke::joinBevel ); + } + else if( command == "stroke-linecap" ) + { + if( params == "butt" ) + gc->stroke.setLineCap( VStroke::capButt ); + else if( params == "round" ) + gc->stroke.setLineCap( VStroke::capRound ); + else if( params == "square" ) + gc->stroke.setLineCap( VStroke::capSquare ); + } + else if( command == "stroke-miterlimit" ) + gc->stroke.setMiterLimit( params.toFloat() ); + else if( command == "stroke-dasharray" ) + { + QValueList array; + if(params != "none") + { + QStringList dashes = QStringList::split( ' ', params ); + for( QStringList::Iterator it = dashes.begin(); it != dashes.end(); ++it ) + array.append( (*it).toFloat() ); + } + gc->stroke.dashPattern().setArray( array ); + } + else if( command == "stroke-dashoffset" ) + gc->stroke.dashPattern().setOffset( params.toFloat() ); + // handle opacity + else if( command == "stroke-opacity" ) + strokecolor.setOpacity( fromPercentage( params ) ); + else if( command == "fill-opacity" ) + fillcolor.setOpacity( fromPercentage( params ) ); + else if( command == "opacity" ) + { + fillcolor.setOpacity( fromPercentage( params ) ); + strokecolor.setOpacity( fromPercentage( params ) ); + } + else if( command == "font-family" ) + { + QString family = params; + family.replace( '\'' , ' ' ); + gc->font.setFamily( family ); + } + else if( command == "font-size" ) + { + float pointSize = parseUnit( params ); + pointSize *= gc->matrix.m22() > 0 ? gc->matrix.m22() : -1.0 * gc->matrix.m22(); + gc->font.setPointSizeFloat( pointSize ); + } + else if( command == "text-decoration" ) + { + if( params == "line-through" ) + gc->font.setStrikeOut( true ); + else if( params == "underline" ) + gc->font.setUnderline( true ); + } + if( gc->fill.type() != VFill::none ) + gc->fill.setColor( fillcolor, false ); + //if( gc->stroke.type() == VStroke::solid ) + gc->stroke.setColor( strokecolor ); +} + +void +XAMLImport::addGraphicContext() +{ + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + // set as default + if( m_gc.current() ) + *gc = *( m_gc.current() ); + m_gc.push( gc ); +} + +void +XAMLImport::setupTransform( const QDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + + QWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); + gc->matrix = mat * gc->matrix; +} + +void +XAMLImport::parseStyle( VObject *obj, const QDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + // try normal PA + if( !e.attribute( "fill" ).isEmpty() ) + parsePA( obj, gc, "fill", e.attribute( "fill" ) ); + if( !e.attribute( "fill-rule" ).isEmpty() ) + parsePA( obj, gc, "fill-rule", e.attribute( "fill-rule" ) ); + if( !e.attribute( "stroke" ).isEmpty() ) + parsePA( obj, gc, "stroke", e.attribute( "stroke" ) ); + if( !e.attribute( "stroke-width" ).isEmpty() ) + parsePA( obj, gc, "stroke-width", e.attribute( "stroke-width" ) ); + if( !e.attribute( "stroke-linejoin" ).isEmpty() ) + parsePA( obj, gc, "stroke-linejoin", e.attribute( "stroke-linejoin" ) ); + if( !e.attribute( "stroke-linecap" ).isEmpty() ) + parsePA( obj, gc, "stroke-linecap", e.attribute( "stroke-linecap" ) ); + if( !e.attribute( "stroke-dasharray" ).isEmpty() ) + parsePA( obj, gc, "stroke-dasharray", e.attribute( "stroke-dasharray" ) ); + if( !e.attribute( "stroke-dashoffset" ).isEmpty() ) + parsePA( obj, gc, "stroke-dashoffset", e.attribute( "stroke-dashoffset" ) ); + if( !e.attribute( "stroke-opacity" ).isEmpty() ) + parsePA( obj, gc, "stroke-opacity", e.attribute( "stroke-opacity" ) ); + if( !e.attribute( "stroke-miterlimit" ).isEmpty() ) + parsePA( obj, gc, "stroke-miterlimit", e.attribute( "stroke-miterlimit" ) ); + if( !e.attribute( "fill-opacity" ).isEmpty() ) + parsePA( obj, gc, "fill-opacity", e.attribute( "fill-opacity" ) ); + if( !e.attribute( "opacity" ).isEmpty() ) + parsePA( obj, gc, "opacity", e.attribute( "opacity" ) ); + + // try style attr + QString style = e.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + parsePA( obj, gc, command, params ); + } + + obj->setFill( gc->fill ); + if( dynamic_cast( obj ) ) + dynamic_cast( obj )->setFillRule( gc->fillRule ); + // stroke scaling + double lineWidth = gc->stroke.lineWidth(); + gc->stroke.setLineWidth( lineWidth * sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) ); + obj->setStroke( gc->stroke ); + gc->stroke.setLineWidth( lineWidth ); +} + +void +XAMLImport::parseFont( const QDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + if( ! e.attribute( "font-family" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-family", e.attribute( "font-family" ) ); + if( ! e.attribute( "font-size" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-size", e.attribute( "font-size" ) ); + if( ! e.attribute( "text-decoration" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "text-decoration", e.attribute( "text-decoration" ) ); +} + +void +XAMLImport::parseGroup( VGroup *grp, const QDomElement &e ) +{ + bool isDef = false; + if( e.tagName() == "defs" ) + isDef = true; + + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement b = n.toElement(); + if( b.isNull() ) continue; + VObject *obj = 0L; + if( b.tagName() == "g" ) + { + VGroup *group; + if ( grp ) + group = new VGroup( grp ); + else + group = new VGroup( &m_document ); + + addGraphicContext(); + setupTransform( b ); + parseStyle( group, b ); + parseFont( b ); + parseGroup( group, b ); + + // handle id + if( !b.attribute("id").isEmpty() ) + group->setName( b.attribute("id") ); + if( grp ) + grp->append( group ); + else + m_document.append( group ); + delete( m_gc.pop() ); + continue; + } + if( b.tagName() == "defs" ) + { + parseGroup( 0L, b ); // try for gradients at least + continue; + } + else if( b.tagName() == "linearGradient" || b.tagName() == "radialGradient" ) + { + parseGradient( b ); + continue; + } + else if( b.tagName() == "rect" || + b.tagName() == "ellipse" || + b.tagName() == "circle" || + b.tagName() == "line" || + b.tagName() == "polyline" || + b.tagName() == "polygon" || + b.tagName() == "path" || + b.tagName() == "image" ) + { + if (!isDef) + obj = createObject( b ); + else + m_paths.insert( b.attribute( "id" ), b ); + } + else if( b.tagName() == "text" ) + { + if( isDef ) + m_paths.insert( b.attribute( "id" ), b ); + else + createText( grp, b ); + } + else if( b.tagName() == "use" ) + { + double tx = b.attribute( "x" ).toDouble(); + double ty = b.attribute( "y" ).toDouble(); + + if( !b.attribute( "xlink:href" ).isEmpty() ) + { + QString params = b.attribute( "xlink:href" ); + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + if(m_paths.contains(key)) + { + QDomElement a = m_paths[key]; + obj = createObject( a ); + m_gc.current()->matrix.translate(tx,ty); + parsePA( grp, m_gc.current(), "fill", b.attribute( "fill" ) ); + } + } + } + if( !obj ) continue; + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + trafo.visit( *obj ); + parseStyle( obj, b ); + // handle id + if( !b.attribute("id").isEmpty() ) + obj->setName( b.attribute("id") ); + if( grp ) + grp->append( obj ); + else + m_document.append( obj ); + delete( m_gc.pop() ); + } +} + +VObject* XAMLImport::findObject( const QString &name, VGroup* group ) +{ + if( ! group ) + return 0L; + + VObjectListIterator itr = group->objects(); + + for( uint objcount = 1; itr.current(); ++itr, objcount++ ) + if( itr.current()->state() != VObject::deleted ) + { + if( itr.current()->name() == name ) + return itr.current(); + + if( dynamic_cast( itr.current() ) ) + { + VObject *obj = findObject( name, dynamic_cast( itr.current() ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +VObject* XAMLImport::findObject( const QString &name ) +{ + QPtrVector vector; + m_document.layers().toVector( &vector ); + for( int i = vector.count() - 1; i >= 0; i-- ) + { + if ( vector[i]->state() != VObject::deleted ) + { + VObject* obj = findObject( name, dynamic_cast( vector[i] ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +void XAMLImport::createText( VGroup *grp, const QDomElement &b ) +{ + VText *text = 0L; + QString content; + VSubpath base( 0L ); + VPath *path = 0L; + + addGraphicContext(); + setupTransform( b ); + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + + parseFont( b ); + + if( b.hasChildNodes() ) + { + if( base.isEmpty() && ! b.attribute( "x" ).isEmpty() && ! b.attribute( "y" ).isEmpty() ) + { + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + 10, y ) ); + } + + for( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + if( e.isNull() ) + { + content += n.toCharacterData().data(); + } + else if( e.tagName() == "textPath" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString uri = e.attribute( "xlink:href" ); + unsigned int start = uri.find("#") + 1; + unsigned int end = uri.findRev(")"); + QString key = uri.mid( start, end - start ); + if( ! m_paths.contains(key) ) + { + VObject* obj = findObject( key ); + if( obj ) + path = dynamic_cast( obj ); + } + else + { + QDomElement p = m_paths[key]; + path = dynamic_cast( createObject( p ) ); + if( path ) + path->setState( VObject::deleted ); + } + if( ! path ) + continue; + base = *path->paths().getFirst(); + content += e.text(); + } + else if( e.tagName() == "tspan" ) + { + // only use text of tspan element, as we are not supporting text + // with different styles + content += e.text(); + if( base.isEmpty() && ! e.attribute( "x" ).isEmpty() && ! e.attribute( "y" ).isEmpty() ) + { + QStringList posX = QStringList::split( ", ", e.attribute( "x" ) ); + QStringList posY = QStringList::split( ", ", e.attribute( "y" ) ); + if( posX.count() && posY.count() ) + { + double x = parseUnit( posX.first() ); + double y = parseUnit( posY.first() ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + 10, y ) ); + } + } + } + else if( e.tagName() == "tref" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString uri = e.attribute( "xlink:href" ); + unsigned int start = uri.find("#") + 1; + unsigned int end = uri.findRev(")"); + QString key = uri.mid( start, end - start ); + + if( ! m_paths.contains(key) ) + { + VObject* obj = findObject( key ); + if( obj ) + content += dynamic_cast( obj )->text(); + } + else + { + QDomElement p = m_paths[key]; + content += p.text(); + } + } + else + continue; + } + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, content.simplifyWhiteSpace() ); + } + else + { + VSubpath base( 0L ); + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + 10, y ) ); + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, b.text().simplifyWhiteSpace() ); + } + + if( text ) + { + text->setParent( &m_document ); + + parseStyle( text, b ); + trafo.visit( *text ); + + if( !b.attribute("id").isEmpty() ) + text->setName( b.attribute("id") ); + + if( grp ) + grp->append( text ); + else + m_document.append( text ); + } + delete( m_gc.pop() ); +} + +VObject* XAMLImport::createObject( const QDomElement &b ) +{ + if( b.tagName() == "rect" ) + { + addGraphicContext(); + double x = parseUnit( b.attribute( "x" ), true, false, m_outerRect ); + double y = parseUnit( b.attribute( "y" ), false, true, m_outerRect ); + double width = parseUnit( b.attribute( "width" ), true, false, m_outerRect ); + double height = parseUnit( b.attribute( "height" ), false, true, m_outerRect ); + setupTransform( b ); + return new VRectangle( 0L, KoPoint( x, height + y ) , width, height ); + } + else if( b.tagName() == "ellipse" ) + { + addGraphicContext(); + setupTransform( b ); + double rx = parseUnit( b.attribute( "rx" ) ); + double ry = parseUnit( b.attribute( "ry" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - rx; + double top = parseUnit( b.attribute( "cy" ) ) - ry; + return new VEllipse( 0L, KoPoint( left, top ), rx * 2.0, ry * 2.0 ); + } + else if( b.tagName() == "circle" ) + { + addGraphicContext(); + setupTransform( b ); + double r = parseUnit( b.attribute( "r" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - r; + double top = parseUnit( b.attribute( "cy" ) ) - r; + return new VEllipse( 0L, KoPoint( left, top ), r * 2.0, r * 2.0 ); + } + else if( b.tagName() == "line" ) + { + addGraphicContext(); + setupTransform( b ); + VPath *path = new VPath( &m_document ); + double x1 = b.attribute( "x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x1" ) ); + double y1 = b.attribute( "y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y1" ) ); + double x2 = b.attribute( "x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x2" ) ); + double y2 = b.attribute( "y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y2" ) ); + path->moveTo( KoPoint( x1, y1 ) ); + path->lineTo( KoPoint( x2, y2 ) ); + return path; + } + else if( b.tagName() == "polyline" || b.tagName() == "polygon" ) + { + addGraphicContext(); + setupTransform( b ); + VPath *path = new VPath( &m_document ); + bool bFirst = true; + + QString points = b.attribute( "points" ).simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + QStringList pointList = QStringList::split( ' ', points ); + for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); ++it) + { + KoPoint point; + point.setX( (*it).toDouble() ); + point.setY( (*it).toDouble() ); + if( bFirst ) + { + path->moveTo( point ); + bFirst = false; + } + else + path->lineTo( point ); + } + if( b.tagName() == "polygon" ) path->close(); + return path; + } + else if( b.tagName() == "path" ) + { + addGraphicContext(); + setupTransform( b ); + VPath *path = new VPath( &m_document ); + path->loadSvgPath( b.attribute( "d" ) ); + return path; + } + else if( b.tagName() == "image" ) + { + addGraphicContext(); + setupTransform( b ); + QString fname = b.attribute("xlink:href"); + return new VImage( 0L, fname ); + } + + return 0L; +} + +#include diff --git a/filters/karbon/xaml/xamlimport.h b/filters/karbon/xaml/xamlimport.h new file mode 100644 index 00000000..05763419 --- /dev/null +++ b/filters/karbon/xaml/xamlimport.h @@ -0,0 +1,91 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __XAMLIMPORT_H__ +#define __XAMLIMPORT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xamlgraphiccontext.h" + +class VGroup; +class VPath; + +class XAMLImport : public KoFilter +{ + Q_OBJECT + +public: + XAMLImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~XAMLImport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + +protected: + class GradientHelper + { + public: + GradientHelper() + { + bbox = true; + } + VGradient gradient; + bool bbox; + QWMatrix gradientTransform; + }; + + void parseGroup( VGroup *, const QDomElement & ); + void parseStyle( VObject *, const QDomElement & ); + void parsePA( VObject *, XAMLGraphicsContext *, const QString &, const QString & ); + void parseGradient( const QDomElement & ); + void parseColorStops( VGradient *, const QDomElement & ); + double parseUnit( const QString &, bool horiz = false, bool vert = false, KoRect bbox = KoRect() ); + void parseColor( VColor &, const QString & ); + QColor parseColor( const QString & ); + double toPercentage( QString ); + double fromPercentage( QString ); + void setupTransform( const QDomElement & ); + void addGraphicContext(); + QDomDocument inpdoc; + QDomDocument outdoc; + void convert(); + VObject* createObject( const QDomElement & ); + void createText( VGroup *, const QDomElement & ); + void parseFont( const QDomElement & ); + // find object with given id in document + VObject* findObject( const QString &name ); + // find object with given id in given group + VObject* findObject( const QString &name, VGroup * ); + +private: + VDocument m_document; + QPtrStack m_gc; + QMap m_gradients; + QMap m_paths; + KoRect m_outerRect; +}; + +#endif diff --git a/filters/karbon/xcf/Makefile.am b/filters/karbon/xcf/Makefile.am new file mode 100644 index 00000000..83ef8229 --- /dev/null +++ b/filters/karbon/xcf/Makefile.am @@ -0,0 +1,27 @@ +kde_module_LTLIBRARIES = libkarbonxcfexport.la + +libkarbonxcfexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonxcfexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/render \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_xcf_export.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + xcfexport.h + +libkarbonxcfexport_la_SOURCES = \ + xcfexport.cc + +libkarbonxcfexport_la_METASOURCES = \ + AUTO + diff --git a/filters/karbon/xcf/karbon_xcf_export.desktop b/filters/karbon/xcf/karbon_xcf_export.desktop new file mode 100644 index 00000000..78772e8e --- /dev/null +++ b/filters/karbon/xcf/karbon_xcf_export.desktop @@ -0,0 +1,65 @@ +[Desktop Entry] +Icon= +Name=Karbon14 Gimp Export Filter +Name[af]=Karbon14 Gimp Voer uit Filter +Name[ar]=賲賽乇賿卮賻丨 鬲氐丿賷乇 Gimp 賱丿賶 Karbon14 +Name[bg]=肖懈谢褌褗褉 蟹邪 械泻褋锌芯褉褌懈褉邪薪械 芯褌 Karbon14 胁 Gimp +Name[br]=Sil ezporzh Gimp evit Karbon14 +Name[ca]=Filtre d'exportaci贸 Gimp per a Karbon14 +Name[cs]=Exportn铆 filtr do form谩tu Gimp pro Karbon +Name[cy]=Hidlen Allforio Gimp Karbon14 +Name[da]=Karbon14 Gimp-eksportfilter +Name[de]=Karbon14 Gimp-Exportfilter +Name[el]=桅委位蟿蟻慰 蔚尉伪纬蠅纬萎蟼 Gimp 蟿慰蠀 Karbon14 +Name[eo]=Karbon14-Gimp-eksportfiltrilo +Name[es]=Filtro de exportaci贸n Gimp de Karbon14 +Name[et]=Karbon14 Gimp'i ekspordifilter +Name[eu]=Karbon14-en Gimp esportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 氐丕丿乇丕鬲 Karbon14 Gimp +Name[fi]=Karbon14 Gimp -vientisuodin +Name[fr]=Filtre d'exportation Gimp de Karbon 14 +Name[fy]=Gimp-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easp贸rt谩la Gimp Karbon14 +Name[gl]=Filtro de Exportaci贸n de Gimp para Karbon14 +Name[he]=诪住谞谉 讬讬爪讜讗 诪志Karbon14 诇志Gimp +Name[hr]=Karbon14 Gimp filtar izvoza +Name[hu]=Karbon14 Gimp exportsz疟r艖 +Name[is]=Karbon14 Gimp 煤tflutningss铆a +Name[it]=Filtro di esportazione Gimp per Karbon14 +Name[ja]=Karbon14 Gimp 銈ㄣ偗銈广儩銉笺儓銉曘偅銉偪 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩焷釣 Gimp 釣熱灅釤掅灇釣夺灁釤 Karbon14 +Name[lo]=嗪曕夯嗪о簳嗪簢嗪佮翰嗪權邯嗪秽粓嗪囙涵嗪簛 SVG 嗪傕涵嗪 Karbon14 +Name[lt]=Karbon14 Gimp eksportavimo filtras +Name[lv]=Karbon14 Gimp eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 Gimp +Name[nb]=Gimp-eksportfiler for Karbon14 +Name[nds]=Gimp-Exportfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え啷оオ 啶椸た啶啶 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=Gimp-exportfilter voor Karbon14 +Name[nn]=Gimp-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu Gimpa z Karbon14 +Name[pt]=Filtro de Exporta莽茫o de Gimp para o Karbon14 +Name[pt_BR]=Filtro de Exporta莽茫o para o Gimp do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru Gimp +Name[ru]=肖懈谢褜褌褉 褝泻褋锌芯褉褌邪 褉懈褋褍薪泻芯胁 Karbon14 胁 褎芯褉屑邪褌 Gimp +Name[se]=Karbon14:a Gimp-olggosfievrridansilli +Name[sk]=GIMP filter pre export z Karbon14 +Name[sl]=Izvozni filter Gimp za Karbon14 +Name[sr]=Karbon14-芯胁 褎懈谢褌械褉 蟹邪 懈蟹胁芯蟹 褍 Gimp-邪 +Name[sr@Latn]=Karbon14-ov filter za izvoz u Gimp-a +Name[sv]=Karbon14 Gimp-exportfilter +Name[ta]=Karbon 14 gimp 喈忇喁嵿喁佮喈む 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon14 Gimp 肖懈谢褌褉懈 小芯写懈褉芯褌 +Name[tr]=Karbon14 Gimp Aktarma Filtresi +Name[uk]=肖褨谢褜褌褉 械泻褋锌芯褉褌褍 Gimp 写谢褟 Karbon +Name[uz]=Karbon14 Gimp eksport filteri +Name[uz@cyrillic]=Karbon14 Gimp 褝泻褋锌芯褉褌 褎懈谢褌械褉懈 +Name[xh]=Isihluzi Sokurhweba ngaphandle se Karbon14 Gimp +Name[zh_CN]=Karbon14 Gimp 瀵煎嚭杩囨护鍣 +Name[zh_TW]=Karbon14 Gimp 鍖嚭閬庢烤绋嬪紡 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/x-xcf-gimp +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonxcfexport +X-KDE-Weight=1 diff --git a/filters/karbon/xcf/xcfexport.cc b/filters/karbon/xcf/xcfexport.cc new file mode 100644 index 00000000..fde8bbd5 --- /dev/null +++ b/filters/karbon/xcf/xcfexport.cc @@ -0,0 +1,458 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "vdocument.h" +#include "vlayer.h" +#include "xcfexport.h" + +#include + + +// Tile size constants. +const unsigned XcfExport::m_tileWidth = 64; +const unsigned XcfExport::m_tileHeight = 64; + + +typedef KGenericFactory XcfExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonxcfexport, XcfExportFactory( "kofficefilters" ) ) + + +XcfExport::XcfExport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ + m_zoomX = 1.0; + m_zoomY = 1.0; +} + +KoFilter::ConversionStatus +XcfExport::convert( const QCString& from, const QCString& to ) +{ + if( to != "image/x-xcf-gimp" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + + if( !storeIn ) + return KoFilter::StupidError; + + + QFile fileOut( m_chain->outputFile() ); + + if( !fileOut.open( IO_WriteOnly ) ) + return KoFilter::StupidError; + + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QDataStream( &fileOut ); + + + // Load the document. + VDocument doc; + doc.load( docNode ); + + // Process the document. + doc.accept( *this ); + + + delete m_stream; + fileOut.close(); + + return KoFilter::OK; +} + +void +XcfExport::visitVDocument( VDocument& document ) +{ + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + // Save width and height for layer saving. + m_width = static_cast( document.width() * m_zoomX ); + m_height = static_cast( document.height() * m_zoomY ); + + + // Header tag (size 14 bytes). + m_stream->writeRawBytes( "gimp xcf file", 14 ); + + // Image width. + *m_stream << static_cast( m_width ); + + // Image height. + *m_stream << static_cast( m_height ); + + // Image type = RGB. + *m_stream << static_cast( 0 ); + + // Do not save any properties currently. + *m_stream + // "END". + << static_cast( 0 ) + // Property size in bytes. + << static_cast( 0 ); + + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for layer and channel offsets. + m_stream->device()->at( + // current position + (number layers + number channels + 2) * 4. + current + ( document.layers().count() + 3 + 2 ) * 4 ); + + + // Iterate over layers. + VLayerListIterator itr( document.layers() ); + + for( ; itr.current(); ++itr ) + { + // Save start offset. + start = m_stream->device()->at(); + + + // Write layer. + itr.current()->accept( *this ); + + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save layer offset. + *m_stream << start; + + // Increment offset. + current = m_stream->device()->at(); + + // Return to end offset. + m_stream->device()->at( end ); + } + + + // Return to current offset. + m_stream->device()->at( current ); + + // Append a zero offset to indicate end of layer offsets. + *m_stream << static_cast( 0 ); + + + // Return to end offset. + m_stream->device()->at( end ); + + // Append a zero offset to indicate end of channel offsets. + *m_stream << static_cast( 0 ); +} + +void +XcfExport::visitVLayer( VLayer& layer ) +{ + // Layer width = image width. + *m_stream << static_cast( m_width ); + + // Layer height = image height. + *m_stream << static_cast( m_height ); + + // Layer type = RGBA. + *m_stream << static_cast( 1 ); + + // Layer name. + *m_stream << layer.name().latin1(); + + // Layer opacity. + *m_stream << static_cast( 6 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // Fully opaque = 255. + *m_stream << static_cast( 255 ); + + // Layer visible? + *m_stream << static_cast( 8 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // True. + *m_stream << static_cast( 1 ); + + // Layer linked? + *m_stream << static_cast( 9 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Preserve transparency? + *m_stream << static_cast( 10 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Apply mask? + *m_stream << static_cast( 11 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Edit mask? + *m_stream << static_cast( 12 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Show mask? + *m_stream << static_cast( 13 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Layer offsets. + *m_stream << static_cast( 15 ); + // Property size in bytes. + *m_stream << static_cast( 8 ); + // X-Offset. + *m_stream << static_cast( 0 ); + // Y-Offset. + *m_stream << static_cast( 0 ); + + // Layer mode. + *m_stream << static_cast( 7 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // Normal mode. + *m_stream << static_cast( 0 ); + + // TODO: Tattoo. + *m_stream << static_cast( 20 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Layer properties end. + *m_stream << static_cast( 0 ); + // Property size in bytes. + *m_stream << static_cast( 0 ); + + + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for hierarchy offsets. + m_stream->device()->at( current + 8 ); + + // Save start offset. + start = m_stream->device()->at(); + + + // Write hierarchy. + writeHierarchy(); + + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save hierarchy offset. + *m_stream << start; + + + // Append a zero offset to indicate end of layer mask offsets. + *m_stream << static_cast( 0 ); +} + +void +XcfExport::writeHierarchy() +{ + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + // Width (again?). + *m_stream << m_width; + + // Height (again?). + *m_stream << m_height; + + // Color depth. + *m_stream << static_cast( 3 ); + + + // Calculate level number. + int levX = levels( m_width, m_tileWidth ); + int levY = levels( m_height, m_tileHeight ); + int levels = QMAX( levX, levY ); + + int width = m_width; + int height = m_height; + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for level offsets. + m_stream->device()->at( current + ( levels + 1 ) * 4 ); + + for( int i = 0; i < levels; ++i ) + { + // Save start offset. + start = m_stream->device()->at(); + + if( i == 0 ) + { + // Write level. + writeLevel(); + } + else + { + // Fake an empty level. + width /= 2; + height /= 2; + + *m_stream << static_cast( width ); + *m_stream << static_cast( height ); + *m_stream << static_cast( 0 ); + } + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save level offset. + *m_stream << start; + + // Increment offset. + current = m_stream->device()->at(); + + // Return to end offset. + m_stream->device()->at( end ); + } + + // Return to current offset. + m_stream->device()->at( current ); + + // Append a zero offset to indicate end of level offsets. + *m_stream << static_cast( 0 ); +} + +void +XcfExport::writeLevel() +{ + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + *m_stream << static_cast( m_width ); + *m_stream << static_cast( m_height ); + + int rows = ( m_height + m_tileHeight - 1 ) / m_tileHeight; + int cols = ( m_width + m_tileWidth - 1 ) / m_tileWidth; + int tiles = rows * cols; + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for tile offsets. + m_stream->device()->at( current + ( tiles + 1 ) * 4 ); + + for( int i = 0; i < tiles; ++i ) + { + // Save start offset. + start = m_stream->device()->at(); + + + // TODO: Save tile. + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save tile offset. + *m_stream << start; + + // Increment offset. + current = m_stream->device()->at(); + + // Return to end offset. + m_stream->device()->at( end ); + } +} + +int +XcfExport::levels( int layerSize, int tileSize ) +{ + int l = 1; + + while( layerSize > tileSize ) + { + layerSize /= 2; + l += 1; + } + + return l; +} + +#include "xcfexport.moc" diff --git a/filters/karbon/xcf/xcfexport.h b/filters/karbon/xcf/xcfexport.h new file mode 100644 index 00000000..92913cb4 --- /dev/null +++ b/filters/karbon/xcf/xcfexport.h @@ -0,0 +1,97 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. +*/ + +#ifndef __XCFEXPORT_H__ +#define __XCFEXPORT_H__ + + +#include + +#include "vvisitor.h" + + +class QDataStream; +class VDocument; +class VLayer; + + +class XcfExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + XcfExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~XcfExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + + virtual void visitVDocument( VDocument& document ); + virtual void visitVLayer( VLayer& layer ); + +private: + /** + * Writes a hierarchy. + */ + void writeHierarchy(); + + /** + * Writes a level. + */ + void writeLevel(); + + /** + * Calculates levels from layer and tile size. + */ + static int levels( int layerSize, int tileSize ); + + + /** + * Tile size constants. + */ + static const unsigned m_tileWidth; + static const unsigned m_tileHeight; + + /** + * Output stream. + */ + QDataStream* m_stream; + + /** + * Image width. + */ + unsigned m_width; + + /** + * Image height. + */ + unsigned m_height; + + /** + * X-zoom factor. + */ + double m_zoomX; + + /** + * Y-zoom factor. + */ + double m_zoomY; +}; + +#endif + diff --git a/filters/karbon/xfig/karbon_xfig_import.desktop b/filters/karbon/xfig/karbon_xfig_import.desktop new file mode 100644 index 00000000..227854c1 --- /dev/null +++ b/filters/karbon/xfig/karbon_xfig_import.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=Service +Name=Karbon XFig Import Filter +Name[ar]=賲賽乇賿卮賻丨 丕爻鬲賷乇丕丿 XFig 賱丿賶 Karbon +Name[bg]=肖懈谢褌褗褉 蟹邪 懈屑锌芯褉褌懈褉邪薪械 芯褌 XFig 胁 Karbon +Name[br]=Sil enporzh XFig evit Karbon +Name[ca]=Filtre d'importaci贸 XFig per a Karbon +Name[cs]=Importn铆 filtr Xfig pro Karbon +Name[cy]=Hidlen Fewnforio XFig Karbon +Name[da]=Karbon XFig-importfilter +Name[de]=Karbon14 XFig-Importfilter +Name[el]=桅委位蟿蟻慰 蔚喂蟽伪纬蠅纬萎蟼 XFig 蟿慰蠀 Karbon +Name[eo]=Karbon-XFig-importfiltrilo +Name[es]=Filtro de importaci贸n XFig de Karbon +Name[et]=Karboni XFig'i impordifilter +Name[eu]=Karbon14-en XFig esportaziorako iragazkia +Name[fa]=倬丕賱丕蹖踿 賵丕乇丿丕鬲 Karbon XFig +Name[fi]=Karbon XFig -tuontisuodin +Name[fr]=Filtre d'importation XFig de Karbon 14 +Name[fy]=Xfig-Ymportfilter foar Karbon +Name[ga]=Scagaire Iomp贸rt谩la Karbon XFig +Name[gl]=Filtro de Importaci贸n de XFig para Karbon +Name[he]=诪住谞谉 讬讬讘讜讗 诪志XFig 诇志Karbon +Name[hr]=Karbon XFig filtar uvoza +Name[hu]=Karbon XFig importsz疟r艖 +Name[is]=Karbon XFig innflutningss铆a +Name[it]=Filtro di importazione XFig per Karbon +Name[ja]=Karbon XFig 銈ゃ兂銉濄兗銉堛儠銈c儷銈 +Name[km]=釣忈灅釤掅灇釣勨嬦灀釣夺焼釣呩灱釣 XFig 釣熱灅釤掅灇釣夺灁釤 Karbon +Name[lt]=Karbon XFig importavimo filtras +Name[lv]=Karbon XFig importa filtrs +Name[ms]=Penapis Import Karbon XFig +Name[nb]=XFig-importfilter for Karbon +Name[nds]=XFig-Importfilter f枚r Karbon14 +Name[ne]=啶曕ぞ啶班啶え 啶忇啷嵿じ啶嗋啷冟い啶 啶ㄠた啶班啶ぞ啶 啶た啶侧啶熰ぐ +Name[nl]=Xfig-importfilter voor Karbon +Name[nn]=XFig-importfilter for Karbon +Name[pl]=Filtr importu formatu XFig do Karbon +Name[pt]=Filtro de Importa莽茫o de XFig para o Karbon +Name[pt_BR]=Filtro de Importa莽茫o XFig do Karbon +Name[ro]=Filtru importare Karbon14 pentru XFig +Name[ru]=肖懈谢褜褌褉 懈屑锌芯褉褌邪 褉懈褋褍薪泻芯胁 XFig 胁 Karbon +Name[se]=Karbon:a XFig-sisafievrridansilli +Name[sk]=XFig filter pre import pre Karbon +Name[sl]=Uvozni filter XFig za Karbon +Name[sr]=Karbon-芯胁 褎懈谢褌械褉 蟹邪 褍胁芯蟹 懈蟹 XFig-邪 +Name[sr@Latn]=Karbon-ov filter za uvoz iz XFig-a +Name[sv]=Karbon Xfig-importfilter +Name[ta]=karbon xfig 喈囙喈曕瘝喈曕瘉喈喈 喈掂疅喈苦畷喈熰瘝喈熰 +Name[tg]=Karbon XFig 肖懈谢褌褉懈 袙芯褉懈写芯褌 +Name[tr]=Karbon XFig Alma Filtresi +Name[uk]=肖褨谢褜褌褉 褨屑锌芯褉褌褍 XFig 写谢褟 Karbon +Name[uz]=Karbon XFig import filteri +Name[uz@cyrillic]=Karbon XFig 懈屑锌芯褉褌 褎懈谢褌械褉懈 +Name[zh_CN]=Karbon XFig 瀵煎叆杩囨护鍣 +Name[zh_TW]=Karbon XFig 鍖叆閬庢烤绋嬪紡 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/x-xfig +X-KDE-Weight=1 +X-KDE-Library=libxfigimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/xfig/status.html b/filters/karbon/xfig/status.html new file mode 100644 index 00000000..e86ff8d9 --- /dev/null +++ b/filters/karbon/xfig/status.html @@ -0,0 +1,157 @@ + + + + + KOffice filters status: XFig FILTER + + +  + +
+
+

+ KOffice filters status:   XFig FILTER +

+
+ +
+ + + Import | + Export + + +


+
+ +Up +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ Import XFig for karbon
+
+
+
Last update-
Features- Can import XFig documents.
TodoNeeds to be ported from kontour to karbon libs.
History-
Authors -
Links-
Progress report ---
+
+
+Up + +


+ +
+


+ + +
+ +
+ +Up +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
Export karbon file to XFig

+
+
Last update-
Features-
TodoEverything
History-
Authors-
Links
Progress report -
+
+
+Up + +
+






+ + + diff --git a/filters/karbon/xfig/xfigimport.cc b/filters/karbon/xfig/xfigimport.cc new file mode 100644 index 00000000..06301e01 --- /dev/null +++ b/filters/karbon/xfig/xfigimport.cc @@ -0,0 +1,760 @@ +/* + Copyright (C) 1998 Kai-Uwe Sattler + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +namespace std { }; +using namespace std; + +#define RAD_FACTOR 180.0 / M_PI + +unsigned int colors[] = { + 0x000090, + 0x0000b0, + 0x0000d0, + 0x87ceff, + 0x009000, + 0x00b000, + 0x00d000, + 0x009090, + 0x00b0b0, + 0x00d0d0, + 0x900000, + 0xb00000, + 0xd00000, + 0x900090, + 0xb000b0, + 0xd000d0, + 0x803000, + 0xa04000, + 0xc06000, + 0xff8080, + 0xffa0a0, + 0xffc0c0, + 0xffe0e0, + 0xffd700 +}; + +int arrow_ids[] = { + 6, 1, 2, 7 +}; + +struct PSFont { + const char* family; + QFont::Weight weight; + bool italic; +} psFontTable[] = { + { "times", QFont::Normal, false }, // Times Roman + { "times", QFont::Normal, true }, // Times Italic + { "times", QFont::Bold, false }, // Times Bold + { "times", QFont::Bold, true }, // Times Bold Italic + { "avantgarde", QFont::Normal, false }, // AvantGarde Book + { "avantgarde", QFont::Normal, true }, // AvantGarde Book Oblique + { "avantgarde", QFont::DemiBold, false }, // AvantGarde Demi + { "avantgarde", QFont::DemiBold, true }, // AvantGarde Demi Oblique + { "bookman", QFont::Light, false }, // Bookman Light + { "bookman", QFont::Light, true }, // Bookman Light Italic + { "bookman", QFont::DemiBold, false }, // Bookman Demi + { "bookman", QFont::DemiBold, true }, // Bookman Demi Italic + { "courier", QFont::Normal, false }, // Courier + { "courier", QFont::Normal, true }, // Courier Oblique + { "courier", QFont::Bold, false }, // Courier Bold + { "courier", QFont::Bold, true }, // Courier Bold Oblique + { "helvetica", QFont::Normal, false }, // Helvetica + { "helvetica", QFont::Normal, true }, // Helvetica Oblique + { "helvetica", QFont::Bold, false }, // Helvetica Bold + { "helvetica", QFont::Bold, true }, // Helvetica Bold Oblique + { "helvetica", QFont::Normal, false }, // Helvetica Narrow + { "helvetica", QFont::Normal, true }, // Helvetica Narrow Oblique + { "helvetica", QFont::Bold, false }, // Helvetica Narrow Bold + { "helvetica", QFont::Bold, true }, // Helvetica Narrow Bold Oblique + { "newcenturyschoolbook", QFont::Normal, false },// New Century Schoolbook + { "newcenturyschoolbook", QFont::Normal, true }, // New Century Italic + { "newcenturyschoolbook", QFont::Bold, false }, // New Century Bold + { "newcenturyschoolbook", QFont::Bold, true }, // New Century Bold Italic + { "palatino", QFont::Normal, false }, // Palatino Roman + { "palatino", QFont::Normal, true }, // Palatino Italic + { "palatino", QFont::Bold, false }, // Palatino Bold + { "palatino", QFont::Bold, true }, // Palatino Bold Italic + { "symbol", QFont::Normal, false }, // Symbol + { "zapfchancery", QFont::Normal, false }, // Zapf Chancery Medium Italic + { "zapfdingbats", QFont::Normal, false }, // Zapf Dingbats +}; + +int hexstrToInt (const char *str) { + const int fak[] = { 16, 1 }; + int value = 0, v; + + for (int i = 0; i < 2; i++) { + if (str[i] >= '0' && str[i] <= '9') + v = str[i] - '0'; + else + v = str[i] - 'a' + 10; + value += v * fak[i]; + } + + return value; +} + +XFIGImport::XFIGImport( KoFilter *parent, const char *name ) : KoFilter(parent, name) +{ + fig_resolution = 1200.0 / 72.0; + coordinate_system = 2; + + colorTable.insert (0, new QColor (Qt::black)); + colorTable.insert (1, new QColor (Qt::blue)); + colorTable.insert (2, new QColor (Qt::green)); + colorTable.insert (3, new QColor (Qt::cyan)); + colorTable.insert (4, new QColor (Qt::red)); + colorTable.insert (5, new QColor (Qt::magenta)); + colorTable.insert (6, new QColor (Qt::yellow)); + colorTable.insert (7, new QColor (Qt::white)); + + for (int i = 0; i <= 23; i++) + colorTable.insert (i + 8, new QColor (colors[i])); + + objList.clear (); +} + +XFIGImport::~XFIGImport() +{ +} + +bool XFIGImport::filterImport( const QString &file, KoDocument *doc, + const QString &from, const QString &to, + const QString & ) { + + if( to != "application/x-karbon" || from != "image/x-xfig" ) + return false; + + char buf[255]; + int value; + KoPageLayout layout; + + ifstream fin( file.local8Bit() ); + if (! fin) + return false; + + KIllustratorDocument *kidoc = (KIllustratorDocument *) doc; + GDocument *gdoc = kidoc->gdoc(); + //GPage *activePage = gdoc->activePage(); + + layout = gdoc->activePage()->pageLayout (); + + fin.getline (buf, 255); + if (::strncmp (buf, "#FIG 3", 6)) { + kdDebug() << "ERROR: no xfig file or wrong header" << endl; + return false; + } + + if (buf[7] == '2') { + version = 320; + } + else if (buf[7] == '1') { + version = 310; + } + else { + kdDebug() << "ERROR: unsupported xfig version" << endl; + return false; + } + + /* + * read the header + */ + + // orientation + fin.getline (buf, 255); + if (::strcmp (buf, "Landscape") == 0) + layout.orientation = PG_LANDSCAPE; + else if (::strcmp (buf, "Portrait") == 0) + layout.orientation = PG_PORTRAIT; + else + kdDebug() << "ERROR: invalid orientation" << endl; + + // justification (don't know how to handle this) + fin.getline (buf, 255); + + // units + fin.getline (buf, 255); + if (::strcmp (buf, "Metric") == 0) + layout.unit = PG_MM; + else if (::strcmp (buf, "Inches") == 0) + layout.unit = PG_INCH; + else + kdDebug() << "ERROR: invalid units" << endl; + + if (version >= 320) { + // paper size (don't know how to handle this) + fin.getline (buf, 255); + + // magnification + float magnification; + fin >> magnification; + fin.ignore (INT_MAX, '\n'); + + //multiple page (not supported yet) + fin.getline (buf, 255); + + // transparent color (not supported yet) + int transColor; + fin >> transColor; + fin.ignore (INT_MAX, '\n'); + } + + // resolution and coordinate system + fin >> value >> coordinate_system; + fig_resolution = value / 72.0; + fin.ignore (INT_MAX, '\n'); + + // now read in the objects + while (! fin.eof ()) { + int tag = -1; + fin >> tag; + if (tag == -1) { + // EOF + buildDocument (gdoc); + return true; + } + + switch (tag) { + case 0: + // a color pseudo object + parseColorObject (fin); + break; + case 1: + // a ellipse + parseEllipse (fin, gdoc); + break; + case 2: + // a polyline + parsePolyline (fin, gdoc); + break; + case 3: + // a spline + parseSpline (fin, gdoc); + break; + case 4: + // a text + parseText (fin, gdoc); + break; + case 5: + // an arc + parseArc (fin, gdoc); + break; + case 6: + // a compound object + parseCompoundObject (fin, gdoc); + break; + case -6: + // end of compound object --> ignore it + break; + default: + // should not occur + kdDebug() << "unknown object type: " << tag << endl; + break; + } + } + buildDocument (gdoc); + return true; +} + + +void XFIGImport::parseColorObject (istream& fin) { + int number, red, green, blue; + char buf[20], red_str[3], green_str[3], blue_str[3]; + + fin >> number >> buf; + strncpy (red_str, &buf[1], 2); red_str[2] = '\0'; + strncpy (green_str, &buf[3], 2); green_str[2] = '\0'; + strncpy (blue_str, &buf[5], 2); blue_str[2] = '\0'; + + red = hexstrToInt (red_str); + green = hexstrToInt (green_str); + blue = hexstrToInt (blue_str); + + colorTable.insert (number, new QColor (red, green, blue)); +} + +void XFIGImport::parseArc (istream& fin, GDocument* doc) { + int sub_type, line_style, thickness, pen_color, fill_color, + depth, pen_style, area_fill, cap_style, direction, + forward_arrow, backward_arrow, x1, y1, x2, y2, x3, y3; + float center_x, center_y; + float style_val; + GOval *obj = new GOval (doc); + + // first line + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> cap_style + >> direction >> forward_arrow >> backward_arrow + >> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3; + + if (forward_arrow > 0) { + // forward arow line + fin.ignore (INT_MAX, '\n'); + } + + if (backward_arrow > 0) { + // backward arrow line + fin.ignore (INT_MAX, '\n'); + } + + // compute radius + float dx = x1 - center_x; + float dy = y1 - center_y; + float radius = sqrt (dx * dx + dy * dy); + + if (radius==0) { + delete obj; + return; + } + + Coord p1 ((center_x - radius) / fig_resolution, + (center_y - radius) / fig_resolution); + Coord p2 ((center_x + radius) / fig_resolution, + (center_y + radius) / fig_resolution); + + obj->setStartPoint (p1); + obj->setEndPoint (p2); + + if (sub_type == 0) + obj->setOutlineShape (GObject::OutlineInfo::PieShape); + else if (sub_type == 1) + obj->setOutlineShape (GObject::OutlineInfo::ArcShape); + + p1 = Coord (center_x / fig_resolution, center_y /fig_resolution); + float m; + + float angle1; + p2 = Coord (x1 / fig_resolution, y1 /fig_resolution); + if (p2.x () == p1.x ()) { + if (p2.y () > p1.y ()) + angle1 = 90; + else + angle1 = -90; + } + else { + m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ())); + if ( p2.x () > p1.x ()) + angle1 = atan (m) * RAD_FACTOR; + else + angle1 = 180 + atan (m) * RAD_FACTOR; + } + + float angle2; + p2 = Coord (x3 / fig_resolution, y3 /fig_resolution); + if (p2.x () == p1.x ()) { + if (p2.y () > p1.y ()) + angle2 = 90; + else + angle2 = -90; + } + else { + m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ())); + if ( p2.x () > p1.x ()) + angle2 = atan (m) * RAD_FACTOR; + else + angle2 = 180 + atan (m) * RAD_FACTOR; + } + + if (direction==0) // clockwise + obj->setAngles (angle2, angle1); + else if (direction==1) // counterclockwise + obj->setAngles (angle1, angle2); + + // now set the properties + setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color); + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseEllipse (istream& fin, GDocument* doc) { + int sub_type, line_style, thickness, pen_color, fill_color, + depth, pen_style, area_fill, direction, center_x, center_y, + radius_x, radius_y, start_x, start_y, end_x, end_y; + float style_val, angle; + GOval *obj = new GOval (doc); + + // first line + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> direction + >> angle >> center_x >> center_y >> radius_x >> radius_y + >> start_x >> start_y >> end_x >> end_y; + Coord p1, p2; + + p1 = Coord ((center_x - radius_x) /fig_resolution, + (center_y - radius_y) /fig_resolution); + p2 = Coord ((center_x + radius_x) /fig_resolution, + (center_y + radius_y) /fig_resolution); + + obj->setStartPoint (p1); + obj->setEndPoint (p2); + + // now set the properties + setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color); + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parsePolyline (istream& fin, GDocument* doc) { + int sub_type, line_style, thickness, pen_color, fill_color, + depth, pen_style, area_fill, join_style, cap_style, radius, + forward_arrow, backward_arrow, npoints; + float style_val; + GPolyline *obj = NULL; + + // first line + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> join_style + >> cap_style >> radius >> forward_arrow >> backward_arrow + >> npoints; + fin.ignore (INT_MAX, '\n'); + + switch (sub_type) { + case 1: // polyline + obj = new GPolyline (doc); + break; + case 2: // box + obj = new GPolygon (doc); + break; + case 3: // polygon + obj = new GPolygon (doc); + break; + case 4: // arc-box + obj = new GPolygon (doc); + break; + case 5: // imported picture + return; + break; + default: + // doesn't occur + kdDebug() << "unknown subtype: " << sub_type << endl; + break; + } + + assert (obj != NULL); + + int arrow_type, arrow_style; + float arrow_thickness, arrow_width, arrow_height; + GObject::OutlineInfo oinfo; + oinfo.mask = GObject::OutlineInfo::Custom; + oinfo.startArrowId = oinfo.endArrowId = 0; + + if (forward_arrow > 0) { + + // forward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.endArrowId = arrow_ids[arrow_type]; + if (oinfo.endArrowId == 1 && arrow_style == 0) + oinfo.endArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + + if (backward_arrow > 0) { + // backward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.startArrowId = arrow_ids[arrow_type]; + if (oinfo.startArrowId == 1 && arrow_style == 0) + oinfo.startArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + // points line + for (int i = 0; i < npoints; i++) { + int x, y; + fin >> x >> y; + if ((sub_type == 2 || sub_type == 3) && i == npoints -1) + // first point == last point + break; + + Coord p (x / fig_resolution, y / fig_resolution); + obj->_addPoint (i, p); + } + + if (oinfo.startArrowId || oinfo.endArrowId) + obj->setOutlineInfo (oinfo); + + // now set the properties + setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color); + + // and insert the object + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseSpline (istream& fin, GDocument* doc) +{ + int sub_type, line_style, thickness, pen_color, fill_color, depth, + pen_style, area_fill, cap_style, forward_arrow, backward_arrow, npoints; + float style_val; + + // this should be a spline + GPolyline *obj = 0L; + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> cap_style + >> forward_arrow >> backward_arrow >> npoints; + if (sub_type == 1 || sub_type == 3 || sub_type == 5) + obj = new GPolygon (doc); + else + obj = new GPolyline (doc); + + int arrow_type, arrow_style; + float arrow_thickness, arrow_width, arrow_height; + GObject::OutlineInfo oinfo; + oinfo.mask = GObject::OutlineInfo::Custom; + oinfo.startArrowId = oinfo.endArrowId = 0; + + if (forward_arrow > 0) { + + // forward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.endArrowId = arrow_ids[arrow_type]; + if (oinfo.endArrowId == 1 && arrow_style == 0) + oinfo.endArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + + if (backward_arrow > 0) { + // backward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.startArrowId = arrow_ids[arrow_type]; + if (oinfo.startArrowId == 1 && arrow_style == 0) + oinfo.startArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + + // points line + for (int i = 0; i < npoints; i++) { + int x, y; + fin >> x >> y; + if ((sub_type == 1 || sub_type == 3 || sub_type == 5) && i == npoints -1) + // first point == last point + break; + + Coord p (x / fig_resolution, y / fig_resolution); + obj->_addPoint (i, p); + } + + // control points line + for (int i = 0; i < npoints; i++) { + float fac; + fin >> fac; + // ignore it now + // fin.ignore (INT_MAX, '\n'); + } + + if (oinfo.startArrowId || oinfo.endArrowId) + obj->setOutlineInfo (oinfo); + + // now set the properties + setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color); + + // and insert the object + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseText (istream& fin, GDocument* doc) +{ + int sub_type, color, depth, pen_style, font, font_flags, x, y; + float font_size, angle, height, length; + GText *obj = new GText (doc); + char c; + char ocode[4]; + bool finished = false; + QString text; + QFont qfont; + + fin >> sub_type >> color >> depth >> pen_style >> font >> font_size + >> angle >> font_flags >> height >> length >> x >> y; + + if (font_flags & 4) { + // PostScript font + if (font == -1) + font = 0; + qfont = QFont (psFontTable[font].family, qRound (font_size), + psFontTable[font].weight, psFontTable[font].italic); + } + else { + // LaTeX font + switch (font) { + case 1: // Roman + qfont.setFamily ("times"); + break; + case 2: // Bold + qfont.setBold (true); + break; + case 3: // Italic + qfont.setItalic (true); + break; + case 4: // Sans Serif + qfont.setFamily ("helvetica"); + break; + case 5: // Typewriter + qfont.setFamily ("Courier"); + break; + default: + break; + } + } + qfont.setPointSize (qRound (font_size)); + obj->setFont (qfont); + + while (! finished) { + fin.get (c); + if (c == '\\') { + fin.get (ocode, 4); + int code = (ocode[0] - '0') * 64 + + (ocode[1] - '0') * 8 + + (ocode[2] - '0'); + if (code == 1) + finished = true; + else + text += (char) code; + } + else + text += c; + } + obj->setText (text); + + if (sub_type == 1) { + GText::TextInfo ti = obj->getTextInfo (); + ti.align = GText::TextInfo::AlignCenter; + obj->setTextInfo (ti); + } + else if (sub_type == 2) { + GText::TextInfo ti = obj->getTextInfo (); + ti.align = GText::TextInfo::AlignRight; + obj->setTextInfo (ti); + } + Coord origin (x / fig_resolution, y / fig_resolution - qfont.pointSize ()); + obj->setOrigin (origin); + + if (angle != 0) { + // rotate the text + float nangle = angle * RAD_FACTOR; + QWMatrix m1, m2, m3; + Coord rotCenter; + + if (sub_type == 0) { + rotCenter = Coord (obj->boundingBox ().left (), + obj->boundingBox ().bottom ()); + } + else if (sub_type == 1) { + rotCenter = Coord (obj->boundingBox ().width () / 2, + obj->boundingBox ().bottom ()); + } + else if (sub_type == 2) { + rotCenter = Coord (obj->boundingBox ().right (), + obj->boundingBox ().bottom ()); + } + m1.translate (-rotCenter.x (), -rotCenter.y ()); + m2.rotate (-nangle); + m3.translate (rotCenter.x (), rotCenter.y ()); + obj->transform (m1); + obj->transform (m2); + obj->transform (m3, true); + } + + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseCompoundObject (istream& fin, GDocument* /*doc*/) { + int upperright_x, upperright_y, lowerleft_x, lowerleft_y; + + fin >> upperright_x >> upperright_y >> lowerleft_x >> lowerleft_y; + fin.ignore (INT_MAX, '\n'); +} + + +/** + * Copy all parsed objects from the sorted list to the document. + */ +void XFIGImport::buildDocument (GDocument *doc) { + doc->setAutoUpdate (false); + // This will sort all object, by decreasing depth + qBubbleSort(objList); + + // Now all we need to do is insert them in the document, in that order + QValueList::Iterator it=objList.begin(); + for ( ; it != objList.end() ; ++it ) + { + //kdDebug() << "Inserting object with depth=" << (*it).depth << endl; + GObject* obj = (*it).object; + obj->ref (); + doc->activePage()->insertObject (obj); + } + doc->setAutoUpdate (true); + objList.clear(); // save memory +} + +void XFIGImport::setProperties (GObject* obj, int pen_color, int style, + int thickness, int area_fill, int fill_color) { + if (pen_color >= 0) + obj->setOutlineColor (*colorTable[pen_color]); + + if (style < 1) + obj->setOutlineStyle (Qt::SolidLine); + else if (style == 1) + obj->setOutlineStyle (Qt::DashLine); + else if (style == 2) + obj->setOutlineStyle (Qt::DotLine); + + obj->setOutlineWidth (thickness * 72.0 / 80.0); + + if (area_fill == -1) + obj->setFillStyle (GObject::FillInfo::NoFill); + else { + obj->setFillStyle (GObject::FillInfo::SolidFill); + if (fill_color < 1) { + // for BLACK or DEFAULT color + int val = qRound ((20 - area_fill) * 255.0 / 20.0); + obj->setFillColor (QColor (val, val, val)); + } + else if (fill_color == 7) { + // for WHITE color + int val = qRound ( area_fill * 255.0 / 20.0); + obj->setFillColor (QColor (val, val, val)); + } + else + obj->setFillColor (*colorTable[fill_color]); + } +} + diff --git a/filters/karbon/xfig/xfigimport.h b/filters/karbon/xfig/xfigimport.h new file mode 100644 index 00000000..bf959315 --- /dev/null +++ b/filters/karbon/xfig/xfigimport.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 1998 Kai-Uwe Sattler + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#ifndef XFIGIMPORT_H +#define XFIGIMPORT_H + +#include +#include +#include + +class GDocument; +class GObject; +class QColor; + +#include +#include +#include + +class XFIGImport : public KoFilter +{ + Q_OBJECT + +public: + XFIGImport( KoFilter *parent, const char *name ); + virtual ~XFIGImport(); + + virtual bool filterImport( const QString &file, KoDocument *, + const QString &from, const QString &to, + const QString &config=QString::null ); + +private: + void parseColorObject (istream& fin); + void parseArc (istream& fin, GDocument* doc); + void parseEllipse (istream& fin, GDocument* doc); + void parsePolyline (istream& fin, GDocument* doc); + void parseSpline (istream& fin, GDocument* doc); + void parseText (istream& fin, GDocument* doc); + void parseCompoundObject (istream& fin, GDocument* doc); + void buildDocument (GDocument *doc); + + void setProperties (GObject* obj, int pen_color, int style, int thickness, + int area_fill, int fill_color); + + float fig_resolution; + int coordinate_system; + int version; + QIntDict colorTable; + + // An object and the depth. Used for sorting objects + // in the object list + struct GObjectListItem + { + GObjectListItem() : object(0L) {} // for QValueList + + GObjectListItem( int d, GObject * obj ) : + object(obj), depth(d) {} + + GObject * object; + int depth; + bool operator < (const GObjectListItem & item ) const + { + // We want to sort by decreasing depths + return depth > item.depth; + } + bool operator == (const GObjectListItem & item ) const + { + return depth == item.depth; + } + }; + QValueList objList; +}; + +#endif diff --git a/filters/karbon/xfig/xfigimport_factory.cc b/filters/karbon/xfig/xfigimport_factory.cc new file mode 100644 index 00000000..7783072d --- /dev/null +++ b/filters/karbon/xfig/xfigimport_factory.cc @@ -0,0 +1,67 @@ +/* + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#include "xfigimport_factory.h" +#include "xfigimport_factory.moc" +#include "xfigimport.h" + +#include +#include + +K_EXPORT_COMPONENT_FACTORY( libxfigimport, XFIGImportFactory ) + +KInstance *XFIGImportFactory::s_global = 0; + +XFIGImportFactory::XFIGImportFactory( + QObject *parent, + const char *name) : + KLibFactory(parent, name) +{ + s_global = new KInstance("xfigimport"); +} + +XFIGImportFactory::~XFIGImportFactory() +{ + delete s_global; + s_global = 0L; +} + +QObject *XFIGImportFactory::createObject( + QObject *parent, + const char *name, + const char*, + const QStringList &) +{ + if (parent && !parent->inherits("KoFilter")) + { + kdDebug(30502) << "XFIGImportFactory: parent does not inherit KoFilter" << endl; + return 0L; + } + XFIGImport *f = new XFIGImport((KoFilter*)parent, name); + return f; +} + +KInstance *XFIGImportFactory::global() +{ + return s_global; +} diff --git a/filters/karbon/xfig/xfigimport_factory.h b/filters/karbon/xfig/xfigimport_factory.h new file mode 100644 index 00000000..8da70040 --- /dev/null +++ b/filters/karbon/xfig/xfigimport_factory.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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. + +DESCRIPTION +*/ + +#ifndef XFIGIMPORT_FACTORY_H +#define XFIGIMPORT_FACTORY_H + +#include + +class KInstance; + +class XFIGImportFactory : + public KLibFactory +{ + Q_OBJECT +public: + XFIGImportFactory(QObject* parent = 0, const char* name = 0); + virtual ~XFIGImportFactory(); + + virtual QObject* createObject(QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList()); + + static KInstance* global(); + +private: + static KInstance* s_global; +}; +#endif -- cgit v1.2.1