From 8b78a8791bc539bcffe7159f9d9714d577cb3d7d Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sun, 23 May 2021 20:48:35 +0900 Subject: Renaming of files in preparation for code style tools. Signed-off-by: Michele Calgaro --- filters/karbon/ai/Makefile.am | 16 +- filters/karbon/ai/ai3handler.cc | 74 -- filters/karbon/ai/ai3handler.cpp | 74 ++ filters/karbon/ai/ai88handler.cc | 564 -------- filters/karbon/ai/ai88handler.cpp | 564 ++++++++ filters/karbon/ai/aicolor.cc | 100 -- filters/karbon/ai/aicolor.cpp | 100 ++ filters/karbon/ai/aielement.cc | 804 ----------- filters/karbon/ai/aielement.cpp | 804 +++++++++++ filters/karbon/ai/aiimport.cc | 101 -- filters/karbon/ai/aiimport.cpp | 101 ++ filters/karbon/ai/ailexer.cc | 514 -------- filters/karbon/ai/ailexer.cpp | 514 ++++++++ filters/karbon/ai/aiparserbase.cc | 1337 ------------------- filters/karbon/ai/aiparserbase.cpp | 1337 +++++++++++++++++++ filters/karbon/ai/karbonaiparserbase.cc | 637 --------- filters/karbon/ai/karbonaiparserbase.cpp | 637 +++++++++ filters/karbon/applixgraphics/Makefile.am | 4 +- .../karbon/applixgraphics/applixgraphicimport.cc | 832 ------------ .../karbon/applixgraphics/applixgraphicimport.cpp | 832 ++++++++++++ filters/karbon/eps/Makefile.am | 6 +- filters/karbon/eps/epsexport.cc | 481 ------- filters/karbon/eps/epsexport.cpp | 481 +++++++ filters/karbon/eps/epsexportdlg.cc | 65 - filters/karbon/eps/epsexportdlg.cpp | 65 + filters/karbon/eps/epsimport.cc | 117 -- filters/karbon/eps/epsimport.cpp | 117 ++ filters/karbon/eps/pscommentlexer.cc | 324 ----- filters/karbon/eps/pscommentlexer.cpp | 324 +++++ filters/karbon/kontour/Makefile.am | 2 +- filters/karbon/msod/Makefile.am | 2 +- filters/karbon/msod/msod.cc | 1340 ------------------- filters/karbon/msod/msod.cpp | 1340 +++++++++++++++++++ filters/karbon/msod/msodimport.cc | 313 ----- filters/karbon/msod/msodimport.cpp | 313 +++++ filters/karbon/oodraw/Makefile.am | 2 +- filters/karbon/oodraw/oodrawimport.cc | 757 ----------- filters/karbon/oodraw/oodrawimport.cpp | 757 +++++++++++ filters/karbon/png/Makefile.am | 2 +- filters/karbon/png/pngexport.cc | 96 -- filters/karbon/png/pngexport.cpp | 96 ++ filters/karbon/svg/Makefile.am | 4 +- filters/karbon/svg/svgexport.cc | 512 -------- filters/karbon/svg/svgexport.cpp | 512 ++++++++ filters/karbon/svg/svgimport.cc | 1389 -------------------- filters/karbon/svg/svgimport.cpp | 1389 ++++++++++++++++++++ filters/karbon/wmf/Makefile.am | 4 +- filters/karbon/wmf/wmfexport.cc | 263 ---- filters/karbon/wmf/wmfexport.cpp | 263 ++++ filters/karbon/wmf/wmfimport.cc | 78 -- filters/karbon/wmf/wmfimport.cpp | 78 ++ filters/karbon/wmf/wmfimportparser.cc | 371 ------ filters/karbon/wmf/wmfimportparser.cpp | 371 ++++++ filters/karbon/xaml/Makefile.am | 4 +- filters/karbon/xaml/xamlexport.cc | 371 ------ filters/karbon/xaml/xamlexport.cpp | 371 ++++++ filters/karbon/xaml/xamlimport.cc | 1042 --------------- filters/karbon/xaml/xamlimport.cpp | 1042 +++++++++++++++ filters/karbon/xcf/Makefile.am | 2 +- filters/karbon/xcf/xcfexport.cc | 458 ------- filters/karbon/xcf/xcfexport.cpp | 458 +++++++ filters/karbon/xfig/xfigimport.cc | 760 ----------- filters/karbon/xfig/xfigimport.cpp | 760 +++++++++++ filters/karbon/xfig/xfigimport_factory.cc | 67 - filters/karbon/xfig/xfigimport_factory.cpp | 67 + 65 files changed, 13791 insertions(+), 13791 deletions(-) delete mode 100644 filters/karbon/ai/ai3handler.cc create mode 100644 filters/karbon/ai/ai3handler.cpp delete mode 100644 filters/karbon/ai/ai88handler.cc create mode 100644 filters/karbon/ai/ai88handler.cpp delete mode 100644 filters/karbon/ai/aicolor.cc create mode 100644 filters/karbon/ai/aicolor.cpp delete mode 100644 filters/karbon/ai/aielement.cc create mode 100644 filters/karbon/ai/aielement.cpp delete mode 100644 filters/karbon/ai/aiimport.cc create mode 100644 filters/karbon/ai/aiimport.cpp delete mode 100644 filters/karbon/ai/ailexer.cc create mode 100644 filters/karbon/ai/ailexer.cpp delete mode 100644 filters/karbon/ai/aiparserbase.cc create mode 100644 filters/karbon/ai/aiparserbase.cpp delete mode 100644 filters/karbon/ai/karbonaiparserbase.cc create mode 100644 filters/karbon/ai/karbonaiparserbase.cpp delete mode 100644 filters/karbon/applixgraphics/applixgraphicimport.cc create mode 100644 filters/karbon/applixgraphics/applixgraphicimport.cpp delete mode 100644 filters/karbon/eps/epsexport.cc create mode 100644 filters/karbon/eps/epsexport.cpp delete mode 100644 filters/karbon/eps/epsexportdlg.cc create mode 100644 filters/karbon/eps/epsexportdlg.cpp delete mode 100644 filters/karbon/eps/epsimport.cc create mode 100644 filters/karbon/eps/epsimport.cpp delete mode 100644 filters/karbon/eps/pscommentlexer.cc create mode 100644 filters/karbon/eps/pscommentlexer.cpp delete mode 100644 filters/karbon/msod/msod.cc create mode 100644 filters/karbon/msod/msod.cpp delete mode 100644 filters/karbon/msod/msodimport.cc create mode 100644 filters/karbon/msod/msodimport.cpp delete mode 100644 filters/karbon/oodraw/oodrawimport.cc create mode 100644 filters/karbon/oodraw/oodrawimport.cpp delete mode 100644 filters/karbon/png/pngexport.cc create mode 100644 filters/karbon/png/pngexport.cpp delete mode 100644 filters/karbon/svg/svgexport.cc create mode 100644 filters/karbon/svg/svgexport.cpp delete mode 100644 filters/karbon/svg/svgimport.cc create mode 100644 filters/karbon/svg/svgimport.cpp delete mode 100644 filters/karbon/wmf/wmfexport.cc create mode 100644 filters/karbon/wmf/wmfexport.cpp delete mode 100644 filters/karbon/wmf/wmfimport.cc create mode 100644 filters/karbon/wmf/wmfimport.cpp delete mode 100644 filters/karbon/wmf/wmfimportparser.cc create mode 100644 filters/karbon/wmf/wmfimportparser.cpp delete mode 100644 filters/karbon/xaml/xamlexport.cc create mode 100644 filters/karbon/xaml/xamlexport.cpp delete mode 100644 filters/karbon/xaml/xamlimport.cc create mode 100644 filters/karbon/xaml/xamlimport.cpp delete mode 100644 filters/karbon/xcf/xcfexport.cc create mode 100644 filters/karbon/xcf/xcfexport.cpp delete mode 100644 filters/karbon/xfig/xfigimport.cc create mode 100644 filters/karbon/xfig/xfigimport.cpp delete mode 100644 filters/karbon/xfig/xfigimport_factory.cc create mode 100644 filters/karbon/xfig/xfigimport_factory.cpp (limited to 'filters/karbon') diff --git a/filters/karbon/ai/Makefile.am b/filters/karbon/ai/Makefile.am index 761feaff..2bbc124d 100644 --- a/filters/karbon/ai/Makefile.am +++ b/filters/karbon/ai/Makefile.am @@ -30,14 +30,14 @@ noinst_HEADERS = \ karbonaiparserbase.h libkarbonaiimport_la_SOURCES = \ - aicolor.cc \ - aielement.cc \ - aiimport.cc \ - ailexer.cc \ - aiparserbase.cc \ - ai88handler.cc \ - ai3handler.cc \ - karbonaiparserbase.cc + aicolor.cpp \ + aielement.cpp \ + aiimport.cpp \ + ailexer.cpp \ + aiparserbase.cpp \ + ai88handler.cpp \ + ai3handler.cpp \ + karbonaiparserbase.cpp libkarbonaiimport_la_METASOURCES = \ AUTO diff --git a/filters/karbon/ai/ai3handler.cc b/filters/karbon/ai/ai3handler.cc deleted file mode 100644 index c014d930..00000000 --- a/filters/karbon/ai/ai3handler.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* 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 "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) tqDebug ("got end group noclip"); - if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (false); - if (m_delegate->m_debug) tqDebug ("/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.cpp b/filters/karbon/ai/ai3handler.cpp new file mode 100644 index 00000000..c014d930 --- /dev/null +++ b/filters/karbon/ai/ai3handler.cpp @@ -0,0 +1,74 @@ +/* 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 "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) tqDebug ("got end group noclip"); + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (false); + if (m_delegate->m_debug) tqDebug ("/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/ai88handler.cc b/filters/karbon/ai/ai88handler.cc deleted file mode 100644 index 87a937ae..00000000 --- a/filters/karbon/ai/ai88handler.cc +++ /dev/null @@ -1,564 +0,0 @@ -/* 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 -#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) tqDebug ("got end group clip"); - if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (true); - if (m_delegate->m_debug) tqDebug ("/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) tqDebug ("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 TQValueVector 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 TQString &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 TQValueVector 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 TQString &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) tqDebug ("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) tqDebug ("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) tqDebug ("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 TQString 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) tqDebug ("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() -{ -// tqDebug ("found dash operation"); - double fval = m_delegate->getDoubleValue(); - - AIElement elem (m_delegate->m_stack.top()); - m_delegate->m_stack.pop(); - - const TQValueVector aval = elem.toElementArray(); - if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotDash (aval, fval); -// tqDebug ("dash operation finished"); -} - -void AI88Handler::_handlePatternDefinition() -{ - AIElement elem (m_delegate->m_stack.top()); - m_delegate->m_stack.pop(); - - const TQValueVector 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 TQString &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 TQString &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 TQValueVector 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 TQString &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()); - tqDebug ("to element is (%s)",elem.typeName()); - m_delegate->m_stack.pop(); - - const TQValueVector 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 TQString &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 TQString &oldFont = elem.toReference(); - - AIElement elem2 (m_delegate->m_stack.top()); - m_delegate->m_stack.pop(); - const TQString &newFont = elem2.toReference(); - - AIElement elem3 (m_delegate->m_stack.top()); - m_delegate->m_stack.pop(); - const TQValueVector 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 TQString 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) tqDebug ("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.cpp b/filters/karbon/ai/ai88handler.cpp new file mode 100644 index 00000000..87a937ae --- /dev/null +++ b/filters/karbon/ai/ai88handler.cpp @@ -0,0 +1,564 @@ +/* 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 +#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) tqDebug ("got end group clip"); + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (true); + if (m_delegate->m_debug) tqDebug ("/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) tqDebug ("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 TQValueVector 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 TQString &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 TQValueVector 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 TQString &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) tqDebug ("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) tqDebug ("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) tqDebug ("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 TQString 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) tqDebug ("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() +{ +// tqDebug ("found dash operation"); + double fval = m_delegate->getDoubleValue(); + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const TQValueVector aval = elem.toElementArray(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotDash (aval, fval); +// tqDebug ("dash operation finished"); +} + +void AI88Handler::_handlePatternDefinition() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const TQValueVector 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 TQString &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 TQString &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 TQValueVector 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 TQString &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()); + tqDebug ("to element is (%s)",elem.typeName()); + m_delegate->m_stack.pop(); + + const TQValueVector 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 TQString &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 TQString &oldFont = elem.toReference(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const TQString &newFont = elem2.toReference(); + + AIElement elem3 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const TQValueVector 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 TQString 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) tqDebug ("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/aicolor.cc b/filters/karbon/ai/aicolor.cc deleted file mode 100644 index cabc932f..00000000 --- a/filters/karbon/ai/aicolor.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* 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 "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 : - tqDebug ("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 : - tqDebug ("unknown colortype %d", ctype); - } -} - - diff --git a/filters/karbon/ai/aicolor.cpp b/filters/karbon/ai/aicolor.cpp new file mode 100644 index 00000000..cabc932f --- /dev/null +++ b/filters/karbon/ai/aicolor.cpp @@ -0,0 +1,100 @@ +/* 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 "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 : + tqDebug ("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 : + tqDebug ("unknown colortype %d", ctype); + } +} + + diff --git a/filters/karbon/ai/aielement.cc b/filters/karbon/ai/aielement.cc deleted file mode 100644 index 2f514d06..00000000 --- a/filters/karbon/ai/aielement.cc +++ /dev/null @@ -1,804 +0,0 @@ -/* 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 "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 TQString( *((TQString*)d->value.ptr) ); - break; - case AIElement::CString: - // TQCString is explicit shared - value.ptr = new TQCString( *((TQCString*)d->value.ptr) ); - break; -/* case AIElement::List: - value.ptr = new TQValueList( *((TQValueList*)d->value.ptr) ); - break; */ - case AIElement::ElementArray: - value.ptr = new TQValueVector( *((TQValueVector*)d->value.ptr) ); - break; - case AIElement::Block: - value.ptr = new TQValueVector( *((TQValueVector*)d->value.ptr) ); - break; - case AIElement::ByteArray: - value.ptr = new TQByteArray( *((TQByteArray*)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 (TQString*)value.ptr; - break; - case AIElement::CString: - delete (TQCString*)value.ptr; - break; -/* case AIElement::List: - delete (TQValueList*)value.ptr; - break; */ - case AIElement::ElementArray: - delete (TQValueVector*)value.ptr; - break; - case AIElement::Block: - delete (TQValueVector*)value.ptr; - break; - case AIElement::ByteArray: - delete (TQByteArray*)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. TQImage is. -*/ -AIElement::AIElement( const AIElement& p ) -{ - d = new Private; - *this = p; -} - -/*! - Constructs a new aielement with a string value, \a val. -*/ -AIElement::AIElement( const TQString& val, Type type ) -{ - d = new Private; - d->typ = type; - d->value.ptr = new TQString( val ); -} - -/*! - Constructs a new aielement with a C-string value, \a val. - - If you want to modify the TQCString after you've passed it to this - constructor, we recommend passing a deep copy (see - TQCString::copy()). -*/ -AIElement::AIElement( const TQCString& val ) -{ - d = new Private; - d->typ = CString; - d->value.ptr = new TQCString( 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 TQCString( 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 TQValueList& val ) -{ - d = new Private; - d->typ = List; - d->value.ptr = new TQValueList( val ); -} */ - -AIElement::AIElement( const TQValueVector& val, Type type ) -{ - d = new Private; - d->typ = type; - d->value.ptr = new TQValueVector( val ); -} - -AIElement::AIElement( const TQByteArray& val ) -{ - d = new Private; - d->typ = ByteArray; - d->value.ptr = new TQByteArray( 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 TQImage, 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, "TQFont", TQSTRING_OBJECT_NAME_STRING, or "TQValueList". - 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, -// "TQValueList", - TQSTRING_OBJECT_NAME_STRING, - "int", - "uint", - "double", - "TQCString", - "Operator", - "Reference", - "TQValueVector", - TQBYTEARRAY_OBJECT_NAME_STRING, - "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 TQString if the aielement has type() - String, CString, ByteArray, Int, Uint, Double, - or TQString() otherwise. - - \sa asString() -*/ -const TQString AIElement::toString() const -{ - if ( d->typ == CString ) - return TQString::fromLatin1( toCString() ); - if ( d->typ == Int ) - return TQString::number( toInt() ); - if ( d->typ == UInt ) - return TQString::number( toUInt() ); - if ( d->typ == Double ) - return TQString::number( toDouble() ); - if ( d->typ == Byte ) - return TQString::number( toByte() ); - if ( d->typ != String ) - return TQString(); - return *((TQString*)d->value.ptr); -} - -const TQString AIElement::toReference() const -{ - if ( d->typ != Reference ) - return TQString(); - return *((TQString*)d->value.ptr); -} - -const TQString AIElement::toOperator() const -{ - if ( d->typ != Operator ) - return TQString(); - return *((TQString*)d->value.ptr); -} - -/*! - Returns the aielement as a TQCString if the aielement has type() - CString or String, or a 0 otherwise. - - \sa asCString() -*/ -const TQCString AIElement::toCString() const -{ - if ( d->typ == CString ) - return *((TQCString*)d->value.ptr); - if ( d->typ == String ) - return ((TQString*)d->value.ptr)->latin1(); - if ( d->typ == Operator ) - return ((TQString*)d->value.ptr)->latin1(); - if ( d->typ == Reference ) - return ((TQString*)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 ((TQString*)d->value.ptr)->toInt( ok ); - if ( d->typ == CString ) - return ((TQCString*)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 ((TQString*)d->value.ptr)->toShort( ok ); - if ( d->typ == CString ) - return ((TQCString*)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 ((TQString*)d->value.ptr)->toUInt( ok ); - if ( d->typ == CString ) - return ((TQCString*)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 ((TQString*)d->value.ptr)->toDouble( ok ); - if ( d->typ == CString ) - return ((TQCString*)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 TQValueList 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 - TQValueList list = myAIElement.toList(); - TQValueList::Iterator it = list.begin(); - while( it != list.end() ) { - myProcessing( *it ); - ++it; - } - \endcode - - \sa asList() -*/ -/* const TQValueList AIElement::toList() const -{ - if ( d->typ == List ) - return *((TQValueList*)d->value.ptr); - return TQValueList(); -} */ - -const TQValueVector AIElement::toElementArray() const -{ - if ( d->typ == ElementArray ) - return *((TQValueVector*)d->value.ptr); - return TQValueVector(); -} - -const TQValueVector AIElement::toBlock() const -{ - if ( d->typ == Block ) - return *((TQValueVector*)d->value.ptr); - return TQValueVector(); -} - - -const TQByteArray AIElement::toByteArray() const -{ - if ( d->typ == ByteArray ) - return *((TQByteArray*)d->value.ptr); - return TQByteArray(); -} - -#define TQ_VARIANT_AS( f ) TQ##f& AIElement::as##f() { \ - if ( d->typ != f ) *this = AIElement( to##f() ); else detach(); return *((TQ##f*)d->value.ptr);} - -TQ_VARIANT_AS(String) -TQ_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 - TQValueList list = myAIElement.asList(); - TQValueList::Iterator it = list.begin(); - while( it != list.end() ) { - myProcessing( *it ); - ++it; - } - \endcode -*/ -/* TQValueList& AIElement::asList() -{ - if ( d->typ != List ) - *this = AIElement( toList() ); - return *((TQValueList*)d->value.ptr); -} */ - -TQValueVector& AIElement::asElementArray() -{ - if ( d->typ != ElementArray ) - *this = AIElement( toElementArray() ); - return *((TQValueVector*)d->value.ptr); -} - -TQValueVector& AIElement::asBlock() -{ - if ( d->typ != Block ) - *this = AIElement( toBlock() ); - return *((TQValueVector*)d->value.ptr); -} - - -TQByteArray& AIElement::asByteArray() -{ - if ( d->typ != ByteArray ) - *this = AIElement( toByteArray() ); - return *((TQByteArray*)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.cpp b/filters/karbon/ai/aielement.cpp new file mode 100644 index 00000000..2f514d06 --- /dev/null +++ b/filters/karbon/ai/aielement.cpp @@ -0,0 +1,804 @@ +/* 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 "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 TQString( *((TQString*)d->value.ptr) ); + break; + case AIElement::CString: + // TQCString is explicit shared + value.ptr = new TQCString( *((TQCString*)d->value.ptr) ); + break; +/* case AIElement::List: + value.ptr = new TQValueList( *((TQValueList*)d->value.ptr) ); + break; */ + case AIElement::ElementArray: + value.ptr = new TQValueVector( *((TQValueVector*)d->value.ptr) ); + break; + case AIElement::Block: + value.ptr = new TQValueVector( *((TQValueVector*)d->value.ptr) ); + break; + case AIElement::ByteArray: + value.ptr = new TQByteArray( *((TQByteArray*)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 (TQString*)value.ptr; + break; + case AIElement::CString: + delete (TQCString*)value.ptr; + break; +/* case AIElement::List: + delete (TQValueList*)value.ptr; + break; */ + case AIElement::ElementArray: + delete (TQValueVector*)value.ptr; + break; + case AIElement::Block: + delete (TQValueVector*)value.ptr; + break; + case AIElement::ByteArray: + delete (TQByteArray*)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. TQImage is. +*/ +AIElement::AIElement( const AIElement& p ) +{ + d = new Private; + *this = p; +} + +/*! + Constructs a new aielement with a string value, \a val. +*/ +AIElement::AIElement( const TQString& val, Type type ) +{ + d = new Private; + d->typ = type; + d->value.ptr = new TQString( val ); +} + +/*! + Constructs a new aielement with a C-string value, \a val. + + If you want to modify the TQCString after you've passed it to this + constructor, we recommend passing a deep copy (see + TQCString::copy()). +*/ +AIElement::AIElement( const TQCString& val ) +{ + d = new Private; + d->typ = CString; + d->value.ptr = new TQCString( 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 TQCString( 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 TQValueList& val ) +{ + d = new Private; + d->typ = List; + d->value.ptr = new TQValueList( val ); +} */ + +AIElement::AIElement( const TQValueVector& val, Type type ) +{ + d = new Private; + d->typ = type; + d->value.ptr = new TQValueVector( val ); +} + +AIElement::AIElement( const TQByteArray& val ) +{ + d = new Private; + d->typ = ByteArray; + d->value.ptr = new TQByteArray( 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 TQImage, 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, "TQFont", TQSTRING_OBJECT_NAME_STRING, or "TQValueList". + 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, +// "TQValueList", + TQSTRING_OBJECT_NAME_STRING, + "int", + "uint", + "double", + "TQCString", + "Operator", + "Reference", + "TQValueVector", + TQBYTEARRAY_OBJECT_NAME_STRING, + "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 TQString if the aielement has type() + String, CString, ByteArray, Int, Uint, Double, + or TQString() otherwise. + + \sa asString() +*/ +const TQString AIElement::toString() const +{ + if ( d->typ == CString ) + return TQString::fromLatin1( toCString() ); + if ( d->typ == Int ) + return TQString::number( toInt() ); + if ( d->typ == UInt ) + return TQString::number( toUInt() ); + if ( d->typ == Double ) + return TQString::number( toDouble() ); + if ( d->typ == Byte ) + return TQString::number( toByte() ); + if ( d->typ != String ) + return TQString(); + return *((TQString*)d->value.ptr); +} + +const TQString AIElement::toReference() const +{ + if ( d->typ != Reference ) + return TQString(); + return *((TQString*)d->value.ptr); +} + +const TQString AIElement::toOperator() const +{ + if ( d->typ != Operator ) + return TQString(); + return *((TQString*)d->value.ptr); +} + +/*! + Returns the aielement as a TQCString if the aielement has type() + CString or String, or a 0 otherwise. + + \sa asCString() +*/ +const TQCString AIElement::toCString() const +{ + if ( d->typ == CString ) + return *((TQCString*)d->value.ptr); + if ( d->typ == String ) + return ((TQString*)d->value.ptr)->latin1(); + if ( d->typ == Operator ) + return ((TQString*)d->value.ptr)->latin1(); + if ( d->typ == Reference ) + return ((TQString*)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 ((TQString*)d->value.ptr)->toInt( ok ); + if ( d->typ == CString ) + return ((TQCString*)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 ((TQString*)d->value.ptr)->toShort( ok ); + if ( d->typ == CString ) + return ((TQCString*)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 ((TQString*)d->value.ptr)->toUInt( ok ); + if ( d->typ == CString ) + return ((TQCString*)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 ((TQString*)d->value.ptr)->toDouble( ok ); + if ( d->typ == CString ) + return ((TQCString*)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 TQValueList 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 + TQValueList list = myAIElement.toList(); + TQValueList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa asList() +*/ +/* const TQValueList AIElement::toList() const +{ + if ( d->typ == List ) + return *((TQValueList*)d->value.ptr); + return TQValueList(); +} */ + +const TQValueVector AIElement::toElementArray() const +{ + if ( d->typ == ElementArray ) + return *((TQValueVector*)d->value.ptr); + return TQValueVector(); +} + +const TQValueVector AIElement::toBlock() const +{ + if ( d->typ == Block ) + return *((TQValueVector*)d->value.ptr); + return TQValueVector(); +} + + +const TQByteArray AIElement::toByteArray() const +{ + if ( d->typ == ByteArray ) + return *((TQByteArray*)d->value.ptr); + return TQByteArray(); +} + +#define TQ_VARIANT_AS( f ) TQ##f& AIElement::as##f() { \ + if ( d->typ != f ) *this = AIElement( to##f() ); else detach(); return *((TQ##f*)d->value.ptr);} + +TQ_VARIANT_AS(String) +TQ_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 + TQValueList list = myAIElement.asList(); + TQValueList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode +*/ +/* TQValueList& AIElement::asList() +{ + if ( d->typ != List ) + *this = AIElement( toList() ); + return *((TQValueList*)d->value.ptr); +} */ + +TQValueVector& AIElement::asElementArray() +{ + if ( d->typ != ElementArray ) + *this = AIElement( toElementArray() ); + return *((TQValueVector*)d->value.ptr); +} + +TQValueVector& AIElement::asBlock() +{ + if ( d->typ != Block ) + *this = AIElement( toBlock() ); + return *((TQValueVector*)d->value.ptr); +} + + +TQByteArray& AIElement::asByteArray() +{ + if ( d->typ != ByteArray ) + *this = AIElement( toByteArray() ); + return *((TQByteArray*)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/aiimport.cc b/filters/karbon/ai/aiimport.cc deleted file mode 100644 index 0af2cc93..00000000 --- a/filters/karbon/ai/aiimport.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* 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 -#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 ) - { - TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); - } -}; - -K_EXPORT_COMPONENT_FACTORY( libkarbonaiimport, AiImportFactory() ) - -AiImport::AiImport( KoFilter*, const char*, const TQStringList& ) - : KoFilter() -{ -} - -AiImport::~AiImport() -{ -} - -KoFilter::ConversionStatus -AiImport::convert( const TQCString& from, const TQCString& to ) -{ - if ( from != "application/illustrator" || to != "application/x-karbon" ) - { - return KoFilter::NotImplemented; - } - TQFile fileIn( m_chain->inputFile() ); - if( !fileIn.open( IO_ReadOnly ) ) - { - fileIn.close(); - return KoFilter::FileNotFound; - } - - TQDomDocument doc ("DOC"); - KarbonAIParserBase parser; - - if (!parser.parse (*TQT_TQIODEVICE(&fileIn), doc)) - { - fileIn.close(); - return KoFilter::CreationError; - } - TQString result = doc.toString(); - - kdDebug() << result << endl; - KoStoreDevice* storeOut = m_chain->storageFile( "root", KoStore::Write ); - if( !storeOut ) - { - fileIn.close(); - return KoFilter::StorageCreationError; - } - - TQCString cStr = result.latin1(); - storeOut->writeBlock( cStr, cStr.size() - 1 ); - - return KoFilter::OK; -} - - -#include "aiimport.moc" - - - diff --git a/filters/karbon/ai/aiimport.cpp b/filters/karbon/ai/aiimport.cpp new file mode 100644 index 00000000..0af2cc93 --- /dev/null +++ b/filters/karbon/ai/aiimport.cpp @@ -0,0 +1,101 @@ +/* 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 +#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 ) + { + TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libkarbonaiimport, AiImportFactory() ) + +AiImport::AiImport( KoFilter*, const char*, const TQStringList& ) + : KoFilter() +{ +} + +AiImport::~AiImport() +{ +} + +KoFilter::ConversionStatus +AiImport::convert( const TQCString& from, const TQCString& to ) +{ + if ( from != "application/illustrator" || to != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + TQFile fileIn( m_chain->inputFile() ); + if( !fileIn.open( IO_ReadOnly ) ) + { + fileIn.close(); + return KoFilter::FileNotFound; + } + + TQDomDocument doc ("DOC"); + KarbonAIParserBase parser; + + if (!parser.parse (*TQT_TQIODEVICE(&fileIn), doc)) + { + fileIn.close(); + return KoFilter::CreationError; + } + TQString result = doc.toString(); + + kdDebug() << result << endl; + KoStoreDevice* storeOut = m_chain->storageFile( "root", KoStore::Write ); + if( !storeOut ) + { + fileIn.close(); + return KoFilter::StorageCreationError; + } + + TQCString cStr = result.latin1(); + storeOut->writeBlock( cStr, cStr.size() - 1 ); + + return KoFilter::OK; +} + + +#include "aiimport.moc" + + + diff --git a/filters/karbon/ai/ailexer.cc b/filters/karbon/ai/ailexer.cc deleted file mode 100644 index 352b8f48..00000000 --- a/filters/karbon/ai/ailexer.cc +++ /dev/null @@ -1,514 +0,0 @@ -/* 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 -#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; - signed 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 (TQIODevice& fin){ - char c; - - m_buffer.clear(); - m_curState = State_Start; - - parsingStarted(); - - while (!fin.atEnd()) - { - c = fin.getch (); - -// tqDebug ("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 : - tqWarning ( "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 : - tqWarning ( "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: - tqWarning ( "unknown state: %d", m_curState ); - } - - m_buffer.clear(); -} - -void AILexer::gotComment (const char *value) { - tqDebug ( "gotComment: %s ", value ); -} - -void AILexer::gotIntValue (int value) { - tqDebug ( "gotInt: %d ", value ); -} - -void AILexer::gotDoubleValue (double value) { - tqDebug ( "gotDouble: %f ", value ); -} - -void AILexer::gotStringValue (const char *value) { - tqDebug ( "gotString: %s ", value ); -} - -void AILexer::gotToken (const char *value) { - tqDebug ( "gotToken: %s ", value ); -} - -void AILexer::gotReference (const char *value) { - tqDebug ( "gotReference: %s ", value ); -} - -void AILexer::gotBlockStart (){ - tqDebug ( "gotBlockStart" ); -} - -void AILexer::gotBlockEnd (){ - tqDebug ( "gotBlockEnd" ); -} - -void AILexer::gotArrayStart (){ - tqDebug ( "gotArrayStart" ); -} - -void AILexer::gotArrayEnd (){ - tqDebug ( "gotArrayEnd" ); -} - -void AILexer::parsingStarted() { - tqDebug ( "parsing started" ); -} - -void AILexer::parsingFinished() { - tqDebug ( "parsing finished" ); -} - -void AILexer::parsingAborted() { - tqDebug ( "parsing aborted" ); -} - -void AILexer::gotByte (uchar value) { - tqDebug ( "got byte %d" , value ); -} - -void AILexer::gotByteArray (const TQByteArray &data) { - tqDebug ( "got byte array" ); -/* for ( uint i = 0; i < data.size(); i++ ) - { - uchar value = data[i]; - tqDebug( "%d: %x", i, value ); - } - tqDebug ( "/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; - - TQByteArray data (m_buffer.length() >> 1); - - while (strIdx < m_buffer.length()) - { - const TQString &item = m_buffer.mid (strIdx, 2); - uchar val = item.toShort(NULL, 16); - data[arrayIdx] = val; - strIdx += 2; - arrayIdx++; - } - - gotByteArray (data); -} - -uchar AILexer::getByte() -{ -// tqDebug ("convert string to byte (%s)", m_buffer.latin1()); - - TQStringList list = TQStringList::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); -// tqDebug ("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() { - TQString data = toString(); - return data.toFloat(); -} - -int StringBuffer::toInt() { - TQString data = toString(); - return data.toInt(); -} - -const char *StringBuffer::latin1() { - return m_buffer; -} - -TQString StringBuffer::mid( uint index, uint len) const { - TQString data = toString(); - return data.mid(index,len); -} diff --git a/filters/karbon/ai/ailexer.cpp b/filters/karbon/ai/ailexer.cpp new file mode 100644 index 00000000..352b8f48 --- /dev/null +++ b/filters/karbon/ai/ailexer.cpp @@ -0,0 +1,514 @@ +/* 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 +#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; + signed 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 (TQIODevice& fin){ + char c; + + m_buffer.clear(); + m_curState = State_Start; + + parsingStarted(); + + while (!fin.atEnd()) + { + c = fin.getch (); + +// tqDebug ("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 : + tqWarning ( "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 : + tqWarning ( "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: + tqWarning ( "unknown state: %d", m_curState ); + } + + m_buffer.clear(); +} + +void AILexer::gotComment (const char *value) { + tqDebug ( "gotComment: %s ", value ); +} + +void AILexer::gotIntValue (int value) { + tqDebug ( "gotInt: %d ", value ); +} + +void AILexer::gotDoubleValue (double value) { + tqDebug ( "gotDouble: %f ", value ); +} + +void AILexer::gotStringValue (const char *value) { + tqDebug ( "gotString: %s ", value ); +} + +void AILexer::gotToken (const char *value) { + tqDebug ( "gotToken: %s ", value ); +} + +void AILexer::gotReference (const char *value) { + tqDebug ( "gotReference: %s ", value ); +} + +void AILexer::gotBlockStart (){ + tqDebug ( "gotBlockStart" ); +} + +void AILexer::gotBlockEnd (){ + tqDebug ( "gotBlockEnd" ); +} + +void AILexer::gotArrayStart (){ + tqDebug ( "gotArrayStart" ); +} + +void AILexer::gotArrayEnd (){ + tqDebug ( "gotArrayEnd" ); +} + +void AILexer::parsingStarted() { + tqDebug ( "parsing started" ); +} + +void AILexer::parsingFinished() { + tqDebug ( "parsing finished" ); +} + +void AILexer::parsingAborted() { + tqDebug ( "parsing aborted" ); +} + +void AILexer::gotByte (uchar value) { + tqDebug ( "got byte %d" , value ); +} + +void AILexer::gotByteArray (const TQByteArray &data) { + tqDebug ( "got byte array" ); +/* for ( uint i = 0; i < data.size(); i++ ) + { + uchar value = data[i]; + tqDebug( "%d: %x", i, value ); + } + tqDebug ( "/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; + + TQByteArray data (m_buffer.length() >> 1); + + while (strIdx < m_buffer.length()) + { + const TQString &item = m_buffer.mid (strIdx, 2); + uchar val = item.toShort(NULL, 16); + data[arrayIdx] = val; + strIdx += 2; + arrayIdx++; + } + + gotByteArray (data); +} + +uchar AILexer::getByte() +{ +// tqDebug ("convert string to byte (%s)", m_buffer.latin1()); + + TQStringList list = TQStringList::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); +// tqDebug ("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() { + TQString data = toString(); + return data.toFloat(); +} + +int StringBuffer::toInt() { + TQString data = toString(); + return data.toInt(); +} + +const char *StringBuffer::latin1() { + return m_buffer; +} + +TQString StringBuffer::mid( uint index, uint len) const { + TQString data = toString(); + return data.mid(index,len); +} diff --git a/filters/karbon/ai/aiparserbase.cc b/filters/karbon/ai/aiparserbase.cc deleted file mode 100644 index 24f9920e..00000000 --- a/filters/karbon/ai/aiparserbase.cc +++ /dev/null @@ -1,1337 +0,0 @@ -/* 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 (TQIODevice& 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) tqDebug ("start ignoring"); - m_ignoring = true; - break; - case CO_BeginResource : - if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Resource, value); - if (m_debug) tqDebug ("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) tqDebug ("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) tqDebug ("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) tqDebug ("stop ignoring"); - m_ignoring = false; - break; - case CO_EndResource : - if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Resource, value); - if (m_debug) tqDebug ("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 : tqWarning ("unknown continuation mode %d",m_continuationMode); - } - break; - - default : - tqWarning( "unhandled comment: %s", value ); - } -} - -void AIParserBase::handleElement (AIElement &element) -{ - if (m_ignoring) return; - - if (m_sink == DS_Array) - { - if (m_debug) tqDebug ("in mode array"); - TQValueVector &elementArray = m_arrayStack.top(); - elementArray.push_back(element); - } - if (m_sink == DS_Block) - { - if (m_debug) tqDebug ("in mode block"); - TQValueVector &elementArray = m_blockStack.top(); - elementArray.push_back(element); - } - else - { - if (m_debug) tqDebug ("in mode stack"); - m_stack.push (element); - } -} - -void AIParserBase::gotIntValue (int value) { - if (m_debug) tqDebug ("got int value"); - if (m_ignoring) return; - AIElement element (value); - handleElement (element); - if (m_debug) tqDebug ("/got int value"); -} - -void AIParserBase::gotDoubleValue (double value) { - if (m_debug) tqDebug ("got double value"); - if (m_ignoring) return; - AIElement element (value); - handleElement (element); - if (m_debug) tqDebug ("/got double value"); -} - -void AIParserBase::gotStringValue (const char *value) { - if (m_debug) tqDebug ("got string value"); - if (m_ignoring) return; - if (value == NULL) value = ""; - if (m_debug) tqDebug ("string: %s", value); - AIElement element (value); - handleElement (element); - if (m_debug) tqDebug ("/got string value"); - -} - -void AIParserBase::gotReference (const char *value) { - if (m_debug) tqDebug ("got reference value"); - - if (m_ignoring) return; - if (value == NULL) value = ""; - if (m_debug) tqDebug ("reference: %s", value); - TQString string(value); - AIElement element (string, AIElement::Reference); - handleElement (element); - if (m_debug) tqDebug ("/got reference value"); - -} - -void AIParserBase::gotByte (uchar value) { - if (m_debug) tqDebug ("got byte value"); - - if (m_ignoring) return; - AIElement element (value); - handleElement (element); - if (m_debug) tqDebug ("/got byte value"); -} - -void AIParserBase::gotByteArray (const TQByteArray &data) { - if (m_ignoring) return; - AIElement element (data); - handleElement (element); -} - - -void AIParserBase::gotArrayStart () { - if (m_ignoring) return; - if (m_debug) tqDebug ("got array start"); - - TQValueVector array; - m_arrayStack.push (array); - - m_sink = DS_Array; -} - -void AIParserBase::gotBlockStart () { - if (m_ignoring) return; - if (m_debug) tqDebug ("got block start"); - - TQValueVector array; - m_blockStack.push (array); - - m_sink = DS_Block; -} - -void AIParserBase::gotArrayEnd () { - if (m_ignoring) return; - if (m_debug) tqDebug ("got array end"); - - TQValueVector stackArray = m_arrayStack.pop(); - - if (m_arrayStack.empty()) - { - if (m_debug) tqDebug ("put elements to stack"); - AIElement realElement (stackArray); - - if (m_debug) { - tqDebug ("going to stack"); - elementtoa (realElement); - tqDebug ("done"); - } - m_stack.push (realElement); - - m_sink = DS_Other; - } - else - { - if (m_debug) tqDebug ("put elements to nest stack level"); - TQValueVector currentTOS = m_arrayStack.top(); - currentTOS.push_back (stackArray); - } -} - -void AIParserBase::gotBlockEnd () { - if (m_ignoring) return; - if (m_debug) tqDebug ("got block end"); - - TQValueVector stackArray = m_blockStack.pop(); - - if (m_blockStack.empty()) - { - if (m_debug) tqDebug ("put elements to stack"); - AIElement realElement (stackArray, AIElement::Block); - - if (m_debug) { - tqDebug ("going to stack"); - elementtoa (realElement); - tqDebug ("done"); - } - m_stack.push (realElement); - - m_sink = DS_Other; - } - else - { - if (m_debug) tqDebug ("put elements to nest stack level"); - TQValueVector currentTOS = m_blockStack.top(); - currentTOS.push_back (stackArray); - } -} - -/*Ai88*/ /* void AIParserBase::_handleSetDash() -{ - double fval = getDoubleValue(); - - AIElement elem (m_stack.top()); - m_stack.pop(); - - const TQValueVector 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) tqDebug ("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 TQValueVector 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 TQString &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 TQValueVector 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 TQString &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) tqDebug ("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) tqDebug ("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) tqDebug ("values 4 are %f",g); - - AIColor color (g); - - if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); -} */ - -/*Ai88*/ /* void AIParserBase::_handleSetFillColorCustom() -{ - double g = getDoubleValue(); - const TQString &name = getStringValue(); - double k = getDoubleValue(); - double y = getDoubleValue(); - double m = getDoubleValue(); - double c = getDoubleValue(); - if (m_debug) tqDebug ("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(); - - TQString name ("xxx"); - AIElement ref (name,AIElement::Reference); - m_stack.push (ref); -} - -void AIParserBase::_handlePSExec() { - m_stack.pop(); -} - -void AIParserBase::_handlePSString() { - m_stack.pop(); - - TQString name ("stringval"); - AIElement ref (name,AIElement::Reference); - m_stack.push (ref); -} - -void AIParserBase::_handlePSBind() { - m_stack.pop(); - - TQString name ("bindentry"); - AIElement ref (name,AIElement::Reference); - m_stack.push (ref); -} - -void AIParserBase::_handlePSUserdict() { - TQString name ("userdict"); - AIElement ref (name,AIElement::Reference); - m_stack.push (ref); -} - -void AIParserBase::_handlePSDict() { - m_stack.pop(); - m_stack.pop(); - m_stack.pop(); - - TQString 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(); - - TQString 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 TQValueVector aval = elem.toElementArray(); - - double ury = getDoubleValue(); - double urx = getDoubleValue(); - double lly = getDoubleValue(); - double llx = getDoubleValue(); - - AIElement elem2 (m_stack.top()); - m_stack.pop(); - - const TQString &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 TQString &name = getStringValue(); - double k = getDoubleValue(); - double y = getDoubleValue(); - double m = getDoubleValue(); - double c = getDoubleValue(); - if (m_debug) tqDebug ("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; - TQStringList items = TQStringList::split (' ', data); - - TQString itemType = items[1]; - TQString name = items[2]; - TQString version = items[3]; - TQString release = items[4]; -} - -void AIParserBase::_handleIncludeResource(const char *data) { - if (!data) return; - TQStringList items = TQStringList::split (' ', data); - - TQString itemType = items[1]; - TQString name = items[2]; - TQString version = items[3]; - TQString release = items[4]; - - m_modules.push_back (name); -} - -void AIParserBase::_handleDocumentProcessColors(const char *data) { - if (!data) return; - - int colorSet = 0; - TQString 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 TQString &name = elem2.toString(); - - int ury = getIntValue(); - int urx = getIntValue(); - int lly = getIntValue(); - int llx = getIntValue(); - - AIElement elem (m_stack.top()); - m_stack.pop(); - - const TQValueVector 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 TQString &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()); - tqDebug ("to element is (%s)",elem.typeName()); - m_stack.pop(); - - const TQValueVector aval = elem.toElementArray(); - - if (m_textHandler) m_textHandler->gotTextBlockBegin (aval, to); -} */ - -/*Ai88*/ /* void AIParserBase::_handleTextOutput () { - AIElement elem (m_stack.top()); - m_stack.pop(); - - const TQString &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; - - TQRegExp test ("\\((.+)\\) \\((.+)\\)"); - if (test.search (data)) - { - TQString val1 = test.cap(1); - TQString val2 = test.cap(2); - - if (m_documentHandler) m_documentHandler->gotCreationDate (val1.latin1(),val2.latin1()); - } -} - -void AIParserBase::gotToken (const char *value) { - if (m_debug) tqDebug ("got token"); - - if (m_ignoring) return; - if (m_debug) tqDebug ("token: %s", value); - - if (m_sink == DS_Array) - { - if (m_debug) tqDebug ("token in array"); - TQString op (value); - AIElement realElement (op, AIElement::Operator); - handleElement (realElement); - - return; - } - if (m_sink == DS_Block) - { - if (m_debug) tqDebug ("token in block"); - TQString op (value); - AIElement realElement (op, AIElement::Operator); - handleElement (realElement); - - return; - } - - if (m_debug) tqDebug ("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; - } - tqWarning ( "unknown operator: %s", value ); - - TQString string(value); - - if (m_modules.findIndex(string) != -1) - { - AIElement element (string, AIElement::Reference); - handleElement (element); - return; - } - - if (m_debug) stacktoa (m_stack); - tqWarning ( "pushing %s to stack", value ); - AIElement element (string, AIElement::Operator); - handleElement (element); - } - - if (m_debug) tqDebug ("/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 TQString AIParserBase::getStringValue(void) { - const AIElement &elem = m_stack.pop(); - - return elem.toString(); -} - -const TQString AIParserBase::getOperatorValue(void) { - const AIElement &elem = m_stack.pop(); - - return elem.toOperator(); -} - -AIOperation AIParserBase::getAIOperation (const char *operand) -{ - int i=0; - TQString 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; - TQString 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) { - TQString 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 TQValueVector& transformData) { - tqDebug ( "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); - tqDebug ("/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 TQValueVector& transformData) { - tqDebug ( "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); - tqDebug ("/got stroke pattern"); -} - -const char *AIParserBase::getValue (const char *input) { - TQString 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; - - TQString s(input); - if (s.contains ("(atend)")) return false; - TQStringList values = TQStringList::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; - - TQString s(input); - TQStringList values = TQStringList::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) tqDebug ("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 TQString &oldFont = elem.toReference(); - - AIElement elem2 (m_stack.top()); - m_stack.pop(); - const TQString &newFont = elem2.toReference(); - - AIElement elem3 (m_stack.top()); - m_stack.pop(); - const TQValueVector encodingData = elem3.toElementArray(); - - if (m_textHandler) m_textHandler->gotFontEncoding (encodingData, oldFont.latin1(), newFont.latin1()); -} */ - -void TextHandlerBase::gotFontEncoding (const TQValueVector& encodingData, const char*oldFontName, const char*newFontName) -{ - tqDebug ("font encoding %s to %s",oldFontName, newFontName); - arraytoa (encodingData); - tqDebug ("/font encoding"); -} - -void TextHandlerBase::gotFontDefinition (const char*fontName, double size, double leading, double kerning, TextAlign align) -{ - tqDebug ("font definition: name %s size %f leading %f kerning %f align %d", fontName, size, leading, kerning, align); -} - -void TextHandlerBase::gotTextBlockBegin (const TQValueVector& transData, TextOperation mode) -{ - tqDebug ("text block begin %d",mode); - arraytoa (transData); - tqDebug ("/text block begin"); -} - -void TextHandlerBase::gotTextOutput (const char*text, int length) -{ - tqDebug ("text output (%s) %d",text,length); -} - -void TextHandlerBase::gotTextBlockEnd () -{ - tqDebug ("text block end"); -} - -const void elementtoa (const AIElement &/*data*/) -{ -/* AIElement::Type type = data.type(); - tqDebug ("type: %s", AIElement::typeToName (type)); - - switch (type) - { - case AIElement::String : - case AIElement::CString : - case AIElement::Int : - case AIElement::UInt : - case AIElement::Double : - tqDebug ("string value : %s",data.toString().latin1()); - break; - case AIElement::Reference : - tqDebug ("string value : %s",data.toReference().latin1()); - break; - case AIElement::Operator : - tqDebug ("string value : %s",data.toOperator().latin1()); - break; - case AIElement::ElementArray : - arraytoa (data.toElementArray()); - break; - case AIElement::Block : - arraytoa (data.toBlock()); - break; - - default : - tqDebug ("could not fetch data"); - } */ -} - -const void arraytoa (const TQValueVector &/*data*/) -{ -/* tqDebug ("array size is %d ",data.size()); - if (data.size() > 0) - { - tqDebug ("[[[[[[[[[[[[[[[[[[[["); - for (uint i=0; i< data.size(); i++) - { - elementtoa (data[i]); - } - tqDebug ("]]]]]]]]]]]]]]]]]]]]"); - } */ -} - -const void stacktoa (const TQValueStack &/*data*/) -{ -/* tqDebug ("stack size is %d",data.size()); - if (data.size() > 0) - { - tqDebug ("<<<<<<<<<<<<<<<<<<"); - for (uint i=0; i< data.size(); i++) - { - elementtoa (data[i]); - } - } - tqDebug (">>>>>>>>>>>>>>>>>>"); */ -} - -const void stacktoa2 (const TQValueStack >&/*data*/) -{ -/* tqDebug ("stack size is %d",data.size()); - - if (data.size() > 0) - { - tqDebug ("((((((((((((((((((((((("); - for (uint i=0; i< data.size(); i++) - { - arraytoa (data[i]); - } - tqDebug (")))))))))))))))))))))))"); - } */ -} - -const void aiotoa (AIOperation &data) -{ - switch (data) - { - case AIO_SetFillColorCMYK : tqDebug ("AIO_SetFillColorCMYK"); break; - case AIO_SetStrokeColorCMYK : tqDebug ("AIO_SetStrokeColorCMYK"); break; - case AIO_SetFillColorGray : tqDebug ("AIO_SetFillColorGray"); break; - case AIO_SetStrokeColorGray : tqDebug ("AIO_SetStrokeColorGray"); break; - case AIO_SetFillColorCustom : tqDebug ("AIO_SetFillColorCustom"); break; - case AIO_SetStrokeColorCustom : tqDebug ("AIO_SetStrokeColorCustom"); break; - case AIO_SetFillPattern : tqDebug ("AIO_SetFillPattern"); break; - case AIO_SetStrokePattern : tqDebug ("AIO_SetStrokePattern"); break; - case AIO_SetFillOverprinting : tqDebug ("AIO_SetFillOverprinting"); break; - case AIO_SetStrokeOverprinting : tqDebug ("AIO_SetStrokeOverprinting"); break; - case AIO_SetFlatness : tqDebug ("AIO_SetFlatness"); break; - case AIO_SetLineCap : tqDebug ("AIO_SetLineCap"); break; - case AIO_SetLineJoin : tqDebug ("AIO_SetLineJoin"); break; - case AIO_SetLineWidth : tqDebug ("AIO_SetLineWidth"); break; - case AIO_SetMiterLimit : tqDebug ("AIO_SetMiterLimit"); break; - case AIO_SetDash : tqDebug ("AIO_SetDash"); break; - case AIO_BeginGroupClip : tqDebug ("AIO_BeginGroupClip"); break; - case AIO_EndGroupClip : tqDebug ("AIO_EndGroupClip"); break; - case AIO_MoveTo : tqDebug ("AIO_MoveTo"); break; - case AIO_LineToCorner : tqDebug ("AIO_LineToCorner"); break; - case AIO_LineToSmooth : tqDebug ("AIO_LineToSmooth"); break; - case AIO_CurveToSmooth : tqDebug ("AIO_CurveToSmooth"); break; - case AIO_CurveToCorner : tqDebug ("AIO_CurveToCorner"); break; - case AIO_CurveToOmitC1Smooth : tqDebug ("AIO_CurveToOmitC1Smooth"); break; - case AIO_CurveToOmitC1Corner : tqDebug ("AIO_CurveToOmitC1Corner"); break; - case AIO_CurveToOmitC2Smooth : tqDebug ("AIO_CurveToOmitC2Smooth"); break; - case AIO_CurveToOmitC2Corner : tqDebug ("AIO_CurveToOmitC2Corner"); break; - case AIO_PathIgnoreNoReset : tqDebug ("AIO_PathIgnoreNoReset"); break; - case AIO_PathIgnoreNoResetClose : tqDebug ("AIO_PathIgnoreNoResetClose"); break; - case AIO_PathClipPath : tqDebug ("AIO_PathClipPath"); break; - case AIO_PathIgnoreReset : tqDebug ("AIO_PathIgnoreReset"); break; - case AIO_PathIgnoreResetClose : tqDebug ("AIO_PathIgnoreResetClose"); break; - case AIO_PathFillNonZero : tqDebug ("AIO_PathFillNonZero"); break; - case AIO_PathFillNonZeroClose : tqDebug ("AIO_PathFillNonZeroClose"); break; - case AIO_PathStroke : tqDebug ("AIO_PathStroke"); break; - case AIO_PathStrokeClose : tqDebug ("AIO_PathStrokeClose"); break; - case AIO_PathFillNoReset : tqDebug ("AIO_PathFillNoReset"); break; - case AIO_PathFillNoResetClose : tqDebug ("AIO_PathFillNoResetClose"); break; - case AIO_FontEncoding : tqDebug ("AIO_FontEncoding"); break; - case AIO_PatternDefinition : tqDebug ("AIO_PatternDefinition"); break; - case AIO_SetCurrentText : tqDebug ("AIO_SetCurrentText"); break; - case AIO_TextBlockFillStroke : tqDebug ("AIO_TextBlockFillStroke"); break; - case AIO_TextBlockFill : tqDebug ("AIO_TextBlockFill"); break; - case AIO_TextBlockAppend : tqDebug ("AIO_TextBlockAppend"); break; - case AIO_TextBlockIgnore : tqDebug ("AIO_TextBlockIgnore"); break; - case AIO_TextBlockStroke : tqDebug ("AIO_TextBlockStroke"); break; - case AIO_TextOutput : tqDebug ("AIO_TextOutput"); break; - case AIO_TextBlockEnd : tqDebug ("AIO_TextBlockEnd"); break; - case AIO_GsaveIncludeDocument : tqDebug ("AIO_GsaveIncludeDocument"); break; - case AIO_Grestore : tqDebug ("AIO_Grestore"); break; - case AIO_LockElement : tqDebug ("AIO_LockElement"); break; - case AIO_SetWindingOrder : tqDebug ("AIO_SetWindingOrder"); break; - default : tqDebug ("unknown"); - } -} - -const void sttoa (SectionType &data, bool begin) -{ - switch (data) - { - case ST_Setup : begin ? tqDebug ("start setup") : tqDebug ("end setup"); break; - case ST_Prolog : begin ? tqDebug ("start prolog") : tqDebug ("end prolog"); break; - case ST_ProcSet : begin ? tqDebug ("start procset") : tqDebug ("end procset"); break; - case ST_Encoding : begin ? tqDebug ("start encoding") : tqDebug ("end encoding"); break; - case ST_Pattern : begin ? tqDebug ("start pattern") : tqDebug ("end pattern"); break; - case ST_Document : begin ? tqDebug ("start document") : tqDebug ("end document"); break; - case ST_BrushPattern : begin ? tqDebug ("start brush pattern") : tqDebug ("end brush pattern"); break; - case ST_Gradient : begin ? tqDebug ("start gradient") : tqDebug ("end gradient"); break; - case ST_Palette : begin ? tqDebug ("start palette") : tqDebug ("end palette"); break; - case ST_Resource : begin ? tqDebug ("start resource") : tqDebug ("end resouce"); break; - - default : begin ? tqDebug ("unknown") : tqDebug ("end unknown"); - } -} - diff --git a/filters/karbon/ai/aiparserbase.cpp b/filters/karbon/ai/aiparserbase.cpp new file mode 100644 index 00000000..24f9920e --- /dev/null +++ b/filters/karbon/ai/aiparserbase.cpp @@ -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 (TQIODevice& 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) tqDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginResource : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Resource, value); + if (m_debug) tqDebug ("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) tqDebug ("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) tqDebug ("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) tqDebug ("stop ignoring"); + m_ignoring = false; + break; + case CO_EndResource : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Resource, value); + if (m_debug) tqDebug ("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 : tqWarning ("unknown continuation mode %d",m_continuationMode); + } + break; + + default : + tqWarning( "unhandled comment: %s", value ); + } +} + +void AIParserBase::handleElement (AIElement &element) +{ + if (m_ignoring) return; + + if (m_sink == DS_Array) + { + if (m_debug) tqDebug ("in mode array"); + TQValueVector &elementArray = m_arrayStack.top(); + elementArray.push_back(element); + } + if (m_sink == DS_Block) + { + if (m_debug) tqDebug ("in mode block"); + TQValueVector &elementArray = m_blockStack.top(); + elementArray.push_back(element); + } + else + { + if (m_debug) tqDebug ("in mode stack"); + m_stack.push (element); + } +} + +void AIParserBase::gotIntValue (int value) { + if (m_debug) tqDebug ("got int value"); + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) tqDebug ("/got int value"); +} + +void AIParserBase::gotDoubleValue (double value) { + if (m_debug) tqDebug ("got double value"); + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) tqDebug ("/got double value"); +} + +void AIParserBase::gotStringValue (const char *value) { + if (m_debug) tqDebug ("got string value"); + if (m_ignoring) return; + if (value == NULL) value = ""; + if (m_debug) tqDebug ("string: %s", value); + AIElement element (value); + handleElement (element); + if (m_debug) tqDebug ("/got string value"); + +} + +void AIParserBase::gotReference (const char *value) { + if (m_debug) tqDebug ("got reference value"); + + if (m_ignoring) return; + if (value == NULL) value = ""; + if (m_debug) tqDebug ("reference: %s", value); + TQString string(value); + AIElement element (string, AIElement::Reference); + handleElement (element); + if (m_debug) tqDebug ("/got reference value"); + +} + +void AIParserBase::gotByte (uchar value) { + if (m_debug) tqDebug ("got byte value"); + + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) tqDebug ("/got byte value"); +} + +void AIParserBase::gotByteArray (const TQByteArray &data) { + if (m_ignoring) return; + AIElement element (data); + handleElement (element); +} + + +void AIParserBase::gotArrayStart () { + if (m_ignoring) return; + if (m_debug) tqDebug ("got array start"); + + TQValueVector array; + m_arrayStack.push (array); + + m_sink = DS_Array; +} + +void AIParserBase::gotBlockStart () { + if (m_ignoring) return; + if (m_debug) tqDebug ("got block start"); + + TQValueVector array; + m_blockStack.push (array); + + m_sink = DS_Block; +} + +void AIParserBase::gotArrayEnd () { + if (m_ignoring) return; + if (m_debug) tqDebug ("got array end"); + + TQValueVector stackArray = m_arrayStack.pop(); + + if (m_arrayStack.empty()) + { + if (m_debug) tqDebug ("put elements to stack"); + AIElement realElement (stackArray); + + if (m_debug) { + tqDebug ("going to stack"); + elementtoa (realElement); + tqDebug ("done"); + } + m_stack.push (realElement); + + m_sink = DS_Other; + } + else + { + if (m_debug) tqDebug ("put elements to nest stack level"); + TQValueVector currentTOS = m_arrayStack.top(); + currentTOS.push_back (stackArray); + } +} + +void AIParserBase::gotBlockEnd () { + if (m_ignoring) return; + if (m_debug) tqDebug ("got block end"); + + TQValueVector stackArray = m_blockStack.pop(); + + if (m_blockStack.empty()) + { + if (m_debug) tqDebug ("put elements to stack"); + AIElement realElement (stackArray, AIElement::Block); + + if (m_debug) { + tqDebug ("going to stack"); + elementtoa (realElement); + tqDebug ("done"); + } + m_stack.push (realElement); + + m_sink = DS_Other; + } + else + { + if (m_debug) tqDebug ("put elements to nest stack level"); + TQValueVector currentTOS = m_blockStack.top(); + currentTOS.push_back (stackArray); + } +} + +/*Ai88*/ /* void AIParserBase::_handleSetDash() +{ + double fval = getDoubleValue(); + + AIElement elem (m_stack.top()); + m_stack.pop(); + + const TQValueVector 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) tqDebug ("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 TQValueVector 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 TQString &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 TQValueVector 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 TQString &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) tqDebug ("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) tqDebug ("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) tqDebug ("values 4 are %f",g); + + AIColor color (g); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorCustom() +{ + double g = getDoubleValue(); + const TQString &name = getStringValue(); + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) tqDebug ("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(); + + TQString name ("xxx"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSExec() { + m_stack.pop(); +} + +void AIParserBase::_handlePSString() { + m_stack.pop(); + + TQString name ("stringval"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSBind() { + m_stack.pop(); + + TQString name ("bindentry"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSUserdict() { + TQString name ("userdict"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSDict() { + m_stack.pop(); + m_stack.pop(); + m_stack.pop(); + + TQString 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(); + + TQString 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 TQValueVector aval = elem.toElementArray(); + + double ury = getDoubleValue(); + double urx = getDoubleValue(); + double lly = getDoubleValue(); + double llx = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const TQString &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 TQString &name = getStringValue(); + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) tqDebug ("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; + TQStringList items = TQStringList::split (' ', data); + + TQString itemType = items[1]; + TQString name = items[2]; + TQString version = items[3]; + TQString release = items[4]; +} + +void AIParserBase::_handleIncludeResource(const char *data) { + if (!data) return; + TQStringList items = TQStringList::split (' ', data); + + TQString itemType = items[1]; + TQString name = items[2]; + TQString version = items[3]; + TQString release = items[4]; + + m_modules.push_back (name); +} + +void AIParserBase::_handleDocumentProcessColors(const char *data) { + if (!data) return; + + int colorSet = 0; + TQString 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 TQString &name = elem2.toString(); + + int ury = getIntValue(); + int urx = getIntValue(); + int lly = getIntValue(); + int llx = getIntValue(); + + AIElement elem (m_stack.top()); + m_stack.pop(); + + const TQValueVector 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 TQString &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()); + tqDebug ("to element is (%s)",elem.typeName()); + m_stack.pop(); + + const TQValueVector aval = elem.toElementArray(); + + if (m_textHandler) m_textHandler->gotTextBlockBegin (aval, to); +} */ + +/*Ai88*/ /* void AIParserBase::_handleTextOutput () { + AIElement elem (m_stack.top()); + m_stack.pop(); + + const TQString &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; + + TQRegExp test ("\\((.+)\\) \\((.+)\\)"); + if (test.search (data)) + { + TQString val1 = test.cap(1); + TQString val2 = test.cap(2); + + if (m_documentHandler) m_documentHandler->gotCreationDate (val1.latin1(),val2.latin1()); + } +} + +void AIParserBase::gotToken (const char *value) { + if (m_debug) tqDebug ("got token"); + + if (m_ignoring) return; + if (m_debug) tqDebug ("token: %s", value); + + if (m_sink == DS_Array) + { + if (m_debug) tqDebug ("token in array"); + TQString op (value); + AIElement realElement (op, AIElement::Operator); + handleElement (realElement); + + return; + } + if (m_sink == DS_Block) + { + if (m_debug) tqDebug ("token in block"); + TQString op (value); + AIElement realElement (op, AIElement::Operator); + handleElement (realElement); + + return; + } + + if (m_debug) tqDebug ("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; + } + tqWarning ( "unknown operator: %s", value ); + + TQString string(value); + + if (m_modules.findIndex(string) != -1) + { + AIElement element (string, AIElement::Reference); + handleElement (element); + return; + } + + if (m_debug) stacktoa (m_stack); + tqWarning ( "pushing %s to stack", value ); + AIElement element (string, AIElement::Operator); + handleElement (element); + } + + if (m_debug) tqDebug ("/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 TQString AIParserBase::getStringValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toString(); +} + +const TQString AIParserBase::getOperatorValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toOperator(); +} + +AIOperation AIParserBase::getAIOperation (const char *operand) +{ + int i=0; + TQString 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; + TQString 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) { + TQString 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 TQValueVector& transformData) { + tqDebug ( "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); + tqDebug ("/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 TQValueVector& transformData) { + tqDebug ( "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); + tqDebug ("/got stroke pattern"); +} + +const char *AIParserBase::getValue (const char *input) { + TQString 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; + + TQString s(input); + if (s.contains ("(atend)")) return false; + TQStringList values = TQStringList::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; + + TQString s(input); + TQStringList values = TQStringList::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) tqDebug ("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 TQString &oldFont = elem.toReference(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + const TQString &newFont = elem2.toReference(); + + AIElement elem3 (m_stack.top()); + m_stack.pop(); + const TQValueVector encodingData = elem3.toElementArray(); + + if (m_textHandler) m_textHandler->gotFontEncoding (encodingData, oldFont.latin1(), newFont.latin1()); +} */ + +void TextHandlerBase::gotFontEncoding (const TQValueVector& encodingData, const char*oldFontName, const char*newFontName) +{ + tqDebug ("font encoding %s to %s",oldFontName, newFontName); + arraytoa (encodingData); + tqDebug ("/font encoding"); +} + +void TextHandlerBase::gotFontDefinition (const char*fontName, double size, double leading, double kerning, TextAlign align) +{ + tqDebug ("font definition: name %s size %f leading %f kerning %f align %d", fontName, size, leading, kerning, align); +} + +void TextHandlerBase::gotTextBlockBegin (const TQValueVector& transData, TextOperation mode) +{ + tqDebug ("text block begin %d",mode); + arraytoa (transData); + tqDebug ("/text block begin"); +} + +void TextHandlerBase::gotTextOutput (const char*text, int length) +{ + tqDebug ("text output (%s) %d",text,length); +} + +void TextHandlerBase::gotTextBlockEnd () +{ + tqDebug ("text block end"); +} + +const void elementtoa (const AIElement &/*data*/) +{ +/* AIElement::Type type = data.type(); + tqDebug ("type: %s", AIElement::typeToName (type)); + + switch (type) + { + case AIElement::String : + case AIElement::CString : + case AIElement::Int : + case AIElement::UInt : + case AIElement::Double : + tqDebug ("string value : %s",data.toString().latin1()); + break; + case AIElement::Reference : + tqDebug ("string value : %s",data.toReference().latin1()); + break; + case AIElement::Operator : + tqDebug ("string value : %s",data.toOperator().latin1()); + break; + case AIElement::ElementArray : + arraytoa (data.toElementArray()); + break; + case AIElement::Block : + arraytoa (data.toBlock()); + break; + + default : + tqDebug ("could not fetch data"); + } */ +} + +const void arraytoa (const TQValueVector &/*data*/) +{ +/* tqDebug ("array size is %d ",data.size()); + if (data.size() > 0) + { + tqDebug ("[[[[[[[[[[[[[[[[[[[["); + for (uint i=0; i< data.size(); i++) + { + elementtoa (data[i]); + } + tqDebug ("]]]]]]]]]]]]]]]]]]]]"); + } */ +} + +const void stacktoa (const TQValueStack &/*data*/) +{ +/* tqDebug ("stack size is %d",data.size()); + if (data.size() > 0) + { + tqDebug ("<<<<<<<<<<<<<<<<<<"); + for (uint i=0; i< data.size(); i++) + { + elementtoa (data[i]); + } + } + tqDebug (">>>>>>>>>>>>>>>>>>"); */ +} + +const void stacktoa2 (const TQValueStack >&/*data*/) +{ +/* tqDebug ("stack size is %d",data.size()); + + if (data.size() > 0) + { + tqDebug ("((((((((((((((((((((((("); + for (uint i=0; i< data.size(); i++) + { + arraytoa (data[i]); + } + tqDebug (")))))))))))))))))))))))"); + } */ +} + +const void aiotoa (AIOperation &data) +{ + switch (data) + { + case AIO_SetFillColorCMYK : tqDebug ("AIO_SetFillColorCMYK"); break; + case AIO_SetStrokeColorCMYK : tqDebug ("AIO_SetStrokeColorCMYK"); break; + case AIO_SetFillColorGray : tqDebug ("AIO_SetFillColorGray"); break; + case AIO_SetStrokeColorGray : tqDebug ("AIO_SetStrokeColorGray"); break; + case AIO_SetFillColorCustom : tqDebug ("AIO_SetFillColorCustom"); break; + case AIO_SetStrokeColorCustom : tqDebug ("AIO_SetStrokeColorCustom"); break; + case AIO_SetFillPattern : tqDebug ("AIO_SetFillPattern"); break; + case AIO_SetStrokePattern : tqDebug ("AIO_SetStrokePattern"); break; + case AIO_SetFillOverprinting : tqDebug ("AIO_SetFillOverprinting"); break; + case AIO_SetStrokeOverprinting : tqDebug ("AIO_SetStrokeOverprinting"); break; + case AIO_SetFlatness : tqDebug ("AIO_SetFlatness"); break; + case AIO_SetLineCap : tqDebug ("AIO_SetLineCap"); break; + case AIO_SetLineJoin : tqDebug ("AIO_SetLineJoin"); break; + case AIO_SetLineWidth : tqDebug ("AIO_SetLineWidth"); break; + case AIO_SetMiterLimit : tqDebug ("AIO_SetMiterLimit"); break; + case AIO_SetDash : tqDebug ("AIO_SetDash"); break; + case AIO_BeginGroupClip : tqDebug ("AIO_BeginGroupClip"); break; + case AIO_EndGroupClip : tqDebug ("AIO_EndGroupClip"); break; + case AIO_MoveTo : tqDebug ("AIO_MoveTo"); break; + case AIO_LineToCorner : tqDebug ("AIO_LineToCorner"); break; + case AIO_LineToSmooth : tqDebug ("AIO_LineToSmooth"); break; + case AIO_CurveToSmooth : tqDebug ("AIO_CurveToSmooth"); break; + case AIO_CurveToCorner : tqDebug ("AIO_CurveToCorner"); break; + case AIO_CurveToOmitC1Smooth : tqDebug ("AIO_CurveToOmitC1Smooth"); break; + case AIO_CurveToOmitC1Corner : tqDebug ("AIO_CurveToOmitC1Corner"); break; + case AIO_CurveToOmitC2Smooth : tqDebug ("AIO_CurveToOmitC2Smooth"); break; + case AIO_CurveToOmitC2Corner : tqDebug ("AIO_CurveToOmitC2Corner"); break; + case AIO_PathIgnoreNoReset : tqDebug ("AIO_PathIgnoreNoReset"); break; + case AIO_PathIgnoreNoResetClose : tqDebug ("AIO_PathIgnoreNoResetClose"); break; + case AIO_PathClipPath : tqDebug ("AIO_PathClipPath"); break; + case AIO_PathIgnoreReset : tqDebug ("AIO_PathIgnoreReset"); break; + case AIO_PathIgnoreResetClose : tqDebug ("AIO_PathIgnoreResetClose"); break; + case AIO_PathFillNonZero : tqDebug ("AIO_PathFillNonZero"); break; + case AIO_PathFillNonZeroClose : tqDebug ("AIO_PathFillNonZeroClose"); break; + case AIO_PathStroke : tqDebug ("AIO_PathStroke"); break; + case AIO_PathStrokeClose : tqDebug ("AIO_PathStrokeClose"); break; + case AIO_PathFillNoReset : tqDebug ("AIO_PathFillNoReset"); break; + case AIO_PathFillNoResetClose : tqDebug ("AIO_PathFillNoResetClose"); break; + case AIO_FontEncoding : tqDebug ("AIO_FontEncoding"); break; + case AIO_PatternDefinition : tqDebug ("AIO_PatternDefinition"); break; + case AIO_SetCurrentText : tqDebug ("AIO_SetCurrentText"); break; + case AIO_TextBlockFillStroke : tqDebug ("AIO_TextBlockFillStroke"); break; + case AIO_TextBlockFill : tqDebug ("AIO_TextBlockFill"); break; + case AIO_TextBlockAppend : tqDebug ("AIO_TextBlockAppend"); break; + case AIO_TextBlockIgnore : tqDebug ("AIO_TextBlockIgnore"); break; + case AIO_TextBlockStroke : tqDebug ("AIO_TextBlockStroke"); break; + case AIO_TextOutput : tqDebug ("AIO_TextOutput"); break; + case AIO_TextBlockEnd : tqDebug ("AIO_TextBlockEnd"); break; + case AIO_GsaveIncludeDocument : tqDebug ("AIO_GsaveIncludeDocument"); break; + case AIO_Grestore : tqDebug ("AIO_Grestore"); break; + case AIO_LockElement : tqDebug ("AIO_LockElement"); break; + case AIO_SetWindingOrder : tqDebug ("AIO_SetWindingOrder"); break; + default : tqDebug ("unknown"); + } +} + +const void sttoa (SectionType &data, bool begin) +{ + switch (data) + { + case ST_Setup : begin ? tqDebug ("start setup") : tqDebug ("end setup"); break; + case ST_Prolog : begin ? tqDebug ("start prolog") : tqDebug ("end prolog"); break; + case ST_ProcSet : begin ? tqDebug ("start procset") : tqDebug ("end procset"); break; + case ST_Encoding : begin ? tqDebug ("start encoding") : tqDebug ("end encoding"); break; + case ST_Pattern : begin ? tqDebug ("start pattern") : tqDebug ("end pattern"); break; + case ST_Document : begin ? tqDebug ("start document") : tqDebug ("end document"); break; + case ST_BrushPattern : begin ? tqDebug ("start brush pattern") : tqDebug ("end brush pattern"); break; + case ST_Gradient : begin ? tqDebug ("start gradient") : tqDebug ("end gradient"); break; + case ST_Palette : begin ? tqDebug ("start palette") : tqDebug ("end palette"); break; + case ST_Resource : begin ? tqDebug ("start resource") : tqDebug ("end resouce"); break; + + default : begin ? tqDebug ("unknown") : tqDebug ("end unknown"); + } +} + diff --git a/filters/karbon/ai/karbonaiparserbase.cc b/filters/karbon/ai/karbonaiparserbase.cc deleted file mode 100644 index c4321252..00000000 --- a/filters/karbon/ai/karbonaiparserbase.cc +++ /dev/null @@ -1,637 +0,0 @@ -/* 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(){ -// tqDebug ( getHeader().latin1() ); -} - -// generic -void KarbonAIParserBase::parsingFinished(){ -// tqDebug ( 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()); - -/* TQWMatrix 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 -TQString KarbonAIParserBase::getParamList(Parameters& params){ - TQString 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){ - tqDebug ("<%s%s>", tagName, getParamList (params).latin1() ); -} - -// generic -void KarbonAIParserBase::gotEndTag (const char *tagName){ - tqDebug ("", tagName ); -} - -// generic -void KarbonAIParserBase::gotSimpleTag (const char *tagName, Parameters& params){ - tqDebug ("<%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*/){ -// tqDebug ("found fill path"); -// if (!reset) tqDebug ("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){ -// tqDebug ("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) { -// tqDebug ("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); -// tqDebug ("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); -// tqDebug ("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) -{ -// tqDebug ("start begin group"); - if (clipping) - { - VClipGroup *group = new VClipGroup( 0L ); - m_groupStack.push (group); - } - else - { - VGroup *group = new VGroup( 0L ); - m_groupStack.push (group); - } - -// tqDebug ("end begin group"); - -} - -void KarbonAIParserBase::gotEndGroup (bool /*clipping*/) -{ -// tqDebug ("start end group"); - - if (m_debug) tqDebug ("got end group"); - - if (m_groupStack.isEmpty()) return; - - if (m_debug) tqDebug ("got end group 2"); - - VGroup *group = m_groupStack.pop(); - - if (m_debug) tqDebug ("got end group 3"); - - if (m_debug) - { - if (!group) tqDebug ("group is NULL"); - } - - if (m_groupStack.isEmpty()) - { - if (m_debug) tqDebug ("insert object"); - ensureLayer(); - m_layer->append (group); - if (m_debug) tqDebug ("/insert object"); - } - else - { - if (m_debug) tqDebug ("insert object to group"); - - m_groupStack.top()->append (group); - if (m_debug) tqDebug ("/insert object to group"); - } - - if (m_debug) tqDebug ("/got end group"); - -// tqDebug ("end end group"); -} - -void KarbonAIParserBase::gotBeginCombination () { - m_ptt = PTT_Combine; -} - -void KarbonAIParserBase::gotEndCombination () { -// tqDebug ( "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); */ -// tqDebug ("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); */ -// tqDebug ("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 (TQIODevice& fin, TQDomDocument &doc) -{ - - bool res = AIParserBase::parse (fin); - -// tqDebug ("document is %s",doc.toString().latin1()); - if (res) - { - tqDebug ("before save document"); - doc = m_document->saveXML(); - // add paper info, we always need custom for svg (Rob) - TQDomElement 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() ); - - tqDebug ("after save document"); - } - else - { - TQDomDocument tempDoc; - doc = tempDoc; - } - - return res; -} - -void KarbonAIParserBase::ensureLayer () -{ - if (!m_layer) - { - m_layer = new VLayer( 0 ); - m_document->insertLayer (m_layer); - } -} - - -void KarbonAIParserBase::setupHandlers() -{ -// tqDebug("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() -{ -// tqDebug("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*/) -{ -// tqDebug ("got creation date [%s], [%s]",val1,val2); -} - -void KarbonDocumentHandler::gotProcessColors (int /*colors*/) -{ -/* if (colors && PC_Cyan) tqDebug ("contains cyan"); - if (colors && PC_Magenta) tqDebug ("contains magenta"); - if (colors && PC_Yellow) tqDebug ("contains yellow"); - if (colors && PC_Black) tqDebug ("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 : tqDebug ("filled"); break; - case POT_Stroked : tqDebug ("stroked"); break; - case POT_FilledStroked : tqDebug ("filled/stroked"); break; - case POT_Clip : tqDebug ("clip"); break; - case POT_Ignore : tqDebug ("ignore"); break; - case POT_Leave : tqDebug ("leave"); break; - default : tqDebug ("unknown"); - } -} - diff --git a/filters/karbon/ai/karbonaiparserbase.cpp b/filters/karbon/ai/karbonaiparserbase.cpp new file mode 100644 index 00000000..c4321252 --- /dev/null +++ b/filters/karbon/ai/karbonaiparserbase.cpp @@ -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(){ +// tqDebug ( getHeader().latin1() ); +} + +// generic +void KarbonAIParserBase::parsingFinished(){ +// tqDebug ( 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()); + +/* TQWMatrix 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 +TQString KarbonAIParserBase::getParamList(Parameters& params){ + TQString 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){ + tqDebug ("<%s%s>", tagName, getParamList (params).latin1() ); +} + +// generic +void KarbonAIParserBase::gotEndTag (const char *tagName){ + tqDebug ("", tagName ); +} + +// generic +void KarbonAIParserBase::gotSimpleTag (const char *tagName, Parameters& params){ + tqDebug ("<%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*/){ +// tqDebug ("found fill path"); +// if (!reset) tqDebug ("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){ +// tqDebug ("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) { +// tqDebug ("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); +// tqDebug ("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); +// tqDebug ("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) +{ +// tqDebug ("start begin group"); + if (clipping) + { + VClipGroup *group = new VClipGroup( 0L ); + m_groupStack.push (group); + } + else + { + VGroup *group = new VGroup( 0L ); + m_groupStack.push (group); + } + +// tqDebug ("end begin group"); + +} + +void KarbonAIParserBase::gotEndGroup (bool /*clipping*/) +{ +// tqDebug ("start end group"); + + if (m_debug) tqDebug ("got end group"); + + if (m_groupStack.isEmpty()) return; + + if (m_debug) tqDebug ("got end group 2"); + + VGroup *group = m_groupStack.pop(); + + if (m_debug) tqDebug ("got end group 3"); + + if (m_debug) + { + if (!group) tqDebug ("group is NULL"); + } + + if (m_groupStack.isEmpty()) + { + if (m_debug) tqDebug ("insert object"); + ensureLayer(); + m_layer->append (group); + if (m_debug) tqDebug ("/insert object"); + } + else + { + if (m_debug) tqDebug ("insert object to group"); + + m_groupStack.top()->append (group); + if (m_debug) tqDebug ("/insert object to group"); + } + + if (m_debug) tqDebug ("/got end group"); + +// tqDebug ("end end group"); +} + +void KarbonAIParserBase::gotBeginCombination () { + m_ptt = PTT_Combine; +} + +void KarbonAIParserBase::gotEndCombination () { +// tqDebug ( "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); */ +// tqDebug ("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); */ +// tqDebug ("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 (TQIODevice& fin, TQDomDocument &doc) +{ + + bool res = AIParserBase::parse (fin); + +// tqDebug ("document is %s",doc.toString().latin1()); + if (res) + { + tqDebug ("before save document"); + doc = m_document->saveXML(); + // add paper info, we always need custom for svg (Rob) + TQDomElement 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() ); + + tqDebug ("after save document"); + } + else + { + TQDomDocument tempDoc; + doc = tempDoc; + } + + return res; +} + +void KarbonAIParserBase::ensureLayer () +{ + if (!m_layer) + { + m_layer = new VLayer( 0 ); + m_document->insertLayer (m_layer); + } +} + + +void KarbonAIParserBase::setupHandlers() +{ +// tqDebug("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() +{ +// tqDebug("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*/) +{ +// tqDebug ("got creation date [%s], [%s]",val1,val2); +} + +void KarbonDocumentHandler::gotProcessColors (int /*colors*/) +{ +/* if (colors && PC_Cyan) tqDebug ("contains cyan"); + if (colors && PC_Magenta) tqDebug ("contains magenta"); + if (colors && PC_Yellow) tqDebug ("contains yellow"); + if (colors && PC_Black) tqDebug ("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 : tqDebug ("filled"); break; + case POT_Stroked : tqDebug ("stroked"); break; + case POT_FilledStroked : tqDebug ("filled/stroked"); break; + case POT_Clip : tqDebug ("clip"); break; + case POT_Ignore : tqDebug ("ignore"); break; + case POT_Leave : tqDebug ("leave"); break; + default : tqDebug ("unknown"); + } +} + diff --git a/filters/karbon/applixgraphics/Makefile.am b/filters/karbon/applixgraphics/Makefile.am index b3c03f38..83fefb22 100644 --- a/filters/karbon/applixgraphics/Makefile.am +++ b/filters/karbon/applixgraphics/Makefile.am @@ -7,7 +7,7 @@ libapplixgraphicimport_la_LDFLAGS = -module -avoid-version -no-undefined $(all_l kde_module_LTLIBRARIES = libapplixgraphicimport.la -libapplixgraphicimport_la_SOURCES = applixgraphicimport.cc +libapplixgraphicimport_la_SOURCES = applixgraphicimport.cpp libapplixgraphicimport_la_LIBADD = $(KOFFICE_LIBS) noinst_HEADERS = applixgraphicimport.h @@ -17,4 +17,4 @@ service_DATA = kontour_applixgraphic_import.desktop servicedir = $(kde_servicesdir) messages: rc.cpp - $(XGETTEXT) *.cc *.cpp -o $(podir)/kontourapplixgraphicsfilter.pot + $(XGETTEXT) *.cpp -o $(podir)/kontourapplixgraphicsfilter.pot diff --git a/filters/karbon/applixgraphics/applixgraphicimport.cc b/filters/karbon/applixgraphics/applixgraphicimport.cc deleted file mode 100644 index fd81b108..00000000 --- a/filters/karbon/applixgraphics/applixgraphicimport.cc +++ /dev/null @@ -1,832 +0,0 @@ -/* 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 TQStringList&) : - KoFilter () -{ - -} - - - -/****************************************************************************** - * class: APPLIXGRAPHICImport function: filter * - ****************************************************************************** - * * - * Short description : - Read inputfile, * - * - convert it to kontour fileformat and * - * - save it * - * * - * * - ******************************************************************************/ -KoFilter::ConversionStatus APPLIXGRAPHICImport::convert( const TQCString& from, const TQCString& to ) -{ - - // Check MIME Types - if (to!="application/x-karbon" || from!="application/x-applixgraphic") - return KoFilter::NotImplemented; - - // Open Inputfile - TQFile in (m_chain->inputFile()); - if (!in.open (IO_ReadOnly) ) - { - kdError(30502) << "Unable to open input file!" << endl; - in.close (); - return KoFilter::FileNotFound; - } - - TQString str; - - // Create karbon header - str += "\n"; - str += "\n"; - str += " \n"; -// str += " \n"; -// str += " \n"; -// str += " \n"; -// str += " \n"; -// str += " \n"; -// str += " \n"; - str += " \n"; - - TQTextStream 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 - TQString 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; - - TQMessageBox::critical (0L, "Applixgraphics header problem", - TQString ("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; - } - - TQCString cstring = str.utf8(); - out->writeBlock ( (const char*)cstring, cstring.size() - 1 ); - - in.close (); - return KoFilter::OK; -} - -#include - - - - diff --git a/filters/karbon/applixgraphics/applixgraphicimport.cpp b/filters/karbon/applixgraphics/applixgraphicimport.cpp new file mode 100644 index 00000000..fd81b108 --- /dev/null +++ b/filters/karbon/applixgraphics/applixgraphicimport.cpp @@ -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 TQStringList&) : + KoFilter () +{ + +} + + + +/****************************************************************************** + * class: APPLIXGRAPHICImport function: filter * + ****************************************************************************** + * * + * Short description : - Read inputfile, * + * - convert it to kontour fileformat and * + * - save it * + * * + * * + ******************************************************************************/ +KoFilter::ConversionStatus APPLIXGRAPHICImport::convert( const TQCString& from, const TQCString& to ) +{ + + // Check MIME Types + if (to!="application/x-karbon" || from!="application/x-applixgraphic") + return KoFilter::NotImplemented; + + // Open Inputfile + TQFile in (m_chain->inputFile()); + if (!in.open (IO_ReadOnly) ) + { + kdError(30502) << "Unable to open input file!" << endl; + in.close (); + return KoFilter::FileNotFound; + } + + TQString str; + + // Create karbon header + str += "\n"; + str += "\n"; + str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; + str += " \n"; + + TQTextStream 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 + TQString 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; + + TQMessageBox::critical (0L, "Applixgraphics header problem", + TQString ("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; + } + + TQCString cstring = str.utf8(); + out->writeBlock ( (const char*)cstring, cstring.size() - 1 ); + + in.close (); + return KoFilter::OK; +} + +#include + + + + diff --git a/filters/karbon/eps/Makefile.am b/filters/karbon/eps/Makefile.am index 035a188e..ccf3503e 100644 --- a/filters/karbon/eps/Makefile.am +++ b/filters/karbon/eps/Makefile.am @@ -3,13 +3,13 @@ kde_module_LTLIBRARIES = \ libkarbonepsimport.la libkarbonepsexport_la_SOURCES = \ - epsexport.cc \ - epsexportdlg.cc + epsexport.cpp \ + epsexportdlg.cpp libkarbonepsexport_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -lkjs -ltdefx -ltdeio -ltdeparts libkarbonepsexport_la_LIBADD = $(KOFFICE_LIBS) ../../../karbon/libkarboncommon.la -libkarbonepsimport_la_SOURCES = epsimport.cc pscommentlexer.cc +libkarbonepsimport_la_SOURCES = epsimport.cpp pscommentlexer.cpp libkarbonepsimport_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -lkjs -ltdefx -ltdeio -ltdeparts libkarbonepsimport_la_LIBADD = $(KOFFICE_LIBS) diff --git a/filters/karbon/eps/epsexport.cc b/filters/karbon/eps/epsexport.cc deleted file mode 100644 index 023074da..00000000 --- a/filters/karbon/eps/epsexport.cc +++ /dev/null @@ -1,481 +0,0 @@ -/* 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 ) - { - TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); - } -}; - - -K_EXPORT_COMPONENT_FACTORY( libkarbonepsexport, EpsExportFactory() ) - - -EpsExport::EpsExport( KoFilter*, const char*, const TQStringList& ) - : KoFilter(), m_exportHidden( true ) -{ -} - -KoFilter::ConversionStatus -EpsExport::convert( const TQCString& from, const TQCString& 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(); - - TQApplication::setOverrideCursor( TQt::arrowCursor ); - - if( dialog->exec() ) - { - // Which PostScript level to support? - m_psLevel = dialog->psLevel() + 1; - m_exportHidden = dialog->exportHidden(); - - TQFile fileOut( m_chain->outputFile() ); - if( !fileOut.open( IO_WriteOnly ) ) - { - TQApplication::restoreOverrideCursor(); - delete( dialog ); - - return KoFilter::StupidError; - } - - TQDomDocument domIn; - domIn.setContent( storeIn ); - TQDomElement docNode = domIn.documentElement(); - - m_stream = new TQTextStream( &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; - } - - TQApplication::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. - tqRound( rect.left() - 0.5 ) << " " << - tqRound( rect.top() - 0.5 ) << " " << - // Round up. - tqRound( rect.right() + 0.5 ) << " " << - tqRound( 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 ) - { - TQDomDocument domIn; - domIn.setContent( storeIn ); - - KoDocumentInfo docInfo; - docInfo.load( domIn ); - - KoDocumentInfoAuthor* authorPage = - static_cast( docInfo.page( "author" ) ); - - // Get creation date/time = "now". - TQDateTime now( TQDateTime::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 TQValueList& - array( stroke.dashPattern().array() ); - - TQValueListConstIterator 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(); - TQPtrVector 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.cpp b/filters/karbon/eps/epsexport.cpp new file mode 100644 index 00000000..023074da --- /dev/null +++ b/filters/karbon/eps/epsexport.cpp @@ -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 ) + { + TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + + +K_EXPORT_COMPONENT_FACTORY( libkarbonepsexport, EpsExportFactory() ) + + +EpsExport::EpsExport( KoFilter*, const char*, const TQStringList& ) + : KoFilter(), m_exportHidden( true ) +{ +} + +KoFilter::ConversionStatus +EpsExport::convert( const TQCString& from, const TQCString& 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(); + + TQApplication::setOverrideCursor( TQt::arrowCursor ); + + if( dialog->exec() ) + { + // Which PostScript level to support? + m_psLevel = dialog->psLevel() + 1; + m_exportHidden = dialog->exportHidden(); + + TQFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + TQApplication::restoreOverrideCursor(); + delete( dialog ); + + return KoFilter::StupidError; + } + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement docNode = domIn.documentElement(); + + m_stream = new TQTextStream( &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; + } + + TQApplication::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. + tqRound( rect.left() - 0.5 ) << " " << + tqRound( rect.top() - 0.5 ) << " " << + // Round up. + tqRound( rect.right() + 0.5 ) << " " << + tqRound( 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 ) + { + TQDomDocument domIn; + domIn.setContent( storeIn ); + + KoDocumentInfo docInfo; + docInfo.load( domIn ); + + KoDocumentInfoAuthor* authorPage = + static_cast( docInfo.page( "author" ) ); + + // Get creation date/time = "now". + TQDateTime now( TQDateTime::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 TQValueList& + array( stroke.dashPattern().array() ); + + TQValueListConstIterator 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(); + TQPtrVector 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/epsexportdlg.cc b/filters/karbon/eps/epsexportdlg.cc deleted file mode 100644 index 4bf4aec7..00000000 --- a/filters/karbon/eps/epsexportdlg.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* 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( TQWidget* parent, const char* name ) - : KDialogBase( parent, name, true, i18n( "EPS Export" ), Ok | Cancel ) -{ - TQVBox* page = makeVBoxMainWidget(); - - m_psLevelButtons = new TQButtonGroup( 1, Qt::Horizontal, - i18n( "Options" ), page ); - - TQRadioButton* radio; - radio = new TQRadioButton( i18n( "PostScript level 1" ), m_psLevelButtons ); - radio = new TQRadioButton( i18n( "PostScript level 2" ), m_psLevelButtons ); - radio = new TQRadioButton( i18n( "PostScript level 3" ), m_psLevelButtons ); - - m_hiddenExport = new TQCheckBox( 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.cpp b/filters/karbon/eps/epsexportdlg.cpp new file mode 100644 index 00000000..4bf4aec7 --- /dev/null +++ b/filters/karbon/eps/epsexportdlg.cpp @@ -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( TQWidget* parent, const char* name ) + : KDialogBase( parent, name, true, i18n( "EPS Export" ), Ok | Cancel ) +{ + TQVBox* page = makeVBoxMainWidget(); + + m_psLevelButtons = new TQButtonGroup( 1, Qt::Horizontal, + i18n( "Options" ), page ); + + TQRadioButton* radio; + radio = new TQRadioButton( i18n( "PostScript level 1" ), m_psLevelButtons ); + radio = new TQRadioButton( i18n( "PostScript level 2" ), m_psLevelButtons ); + radio = new TQRadioButton( i18n( "PostScript level 3" ), m_psLevelButtons ); + + m_hiddenExport = new TQCheckBox( 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/epsimport.cc b/filters/karbon/eps/epsimport.cc deleted file mode 100644 index 72bb1334..00000000 --- a/filters/karbon/eps/epsimport.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* 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 ) - { - TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); - } -}; - -K_EXPORT_COMPONENT_FACTORY( libkarbonepsimport, EpsImportFactory() ) - -EpsImport::EpsImport( KoFilter*, const char*, const TQStringList& ) - : KoFilter() -{ -} - -EpsImport::~EpsImport() -{ -} - -KoFilter::ConversionStatus -EpsImport::convert( const TQCString& from, const TQCString& to ) -{ - if( - to != "application/illustrator" || - ( - from != "image/x-eps" && - from != "application/postscript" ) ) - { - return KoFilter::NotImplemented; - } - - // Copy input filename: - TQString input = m_chain->inputFile(); - - - // EPS original bounding box - int llx = -1, lly = -1, urx = -1, ury = -1; - BoundingBoxExtractor extractor; - - TQFile file (input); - - if ( file.open(IO_ReadOnly) ) - { - extractor.parse (*TQT_TQIODEVICE(&file)); - llx = extractor.llx(); - lly = extractor.lly(); - urx = extractor.urx(); - ury = extractor.ury(); - file.close(); - } - else - tqDebug ("file could not be opened"); - - // sed filter - TQString sedFilter = TQString ("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: - TQString command( - "gs -q -P- -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dNODISPLAY ps2ai.ps "); - command += TDEProcess::quote(input); - command += " | "; - command += sedFilter; - command += " > "; - command += TDEProcess::quote(m_chain->outputFile()); - - tqDebug ("command to execute is (%s)", TQFile::encodeName(command).data()); - - // Execute it: - if( !system( TQFile::encodeName(command)) ) - return KoFilter::OK; - else - return KoFilter::StupidError; -} - -#include "epsimport.moc" - diff --git a/filters/karbon/eps/epsimport.cpp b/filters/karbon/eps/epsimport.cpp new file mode 100644 index 00000000..72bb1334 --- /dev/null +++ b/filters/karbon/eps/epsimport.cpp @@ -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 ) + { + TDEGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libkarbonepsimport, EpsImportFactory() ) + +EpsImport::EpsImport( KoFilter*, const char*, const TQStringList& ) + : KoFilter() +{ +} + +EpsImport::~EpsImport() +{ +} + +KoFilter::ConversionStatus +EpsImport::convert( const TQCString& from, const TQCString& to ) +{ + if( + to != "application/illustrator" || + ( + from != "image/x-eps" && + from != "application/postscript" ) ) + { + return KoFilter::NotImplemented; + } + + // Copy input filename: + TQString input = m_chain->inputFile(); + + + // EPS original bounding box + int llx = -1, lly = -1, urx = -1, ury = -1; + BoundingBoxExtractor extractor; + + TQFile file (input); + + if ( file.open(IO_ReadOnly) ) + { + extractor.parse (*TQT_TQIODEVICE(&file)); + llx = extractor.llx(); + lly = extractor.lly(); + urx = extractor.urx(); + ury = extractor.ury(); + file.close(); + } + else + tqDebug ("file could not be opened"); + + // sed filter + TQString sedFilter = TQString ("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: + TQString command( + "gs -q -P- -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dNODISPLAY ps2ai.ps "); + command += TDEProcess::quote(input); + command += " | "; + command += sedFilter; + command += " > "; + command += TDEProcess::quote(m_chain->outputFile()); + + tqDebug ("command to execute is (%s)", TQFile::encodeName(command).data()); + + // Execute it: + if( !system( TQFile::encodeName(command)) ) + return KoFilter::OK; + else + return KoFilter::StupidError; +} + +#include "epsimport.moc" + diff --git a/filters/karbon/eps/pscommentlexer.cc b/filters/karbon/eps/pscommentlexer.cc deleted file mode 100644 index e15dcc59..00000000 --- a/filters/karbon/eps/pscommentlexer.cc +++ /dev/null @@ -1,324 +0,0 @@ -/* 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 -#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; - signed 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 (TQIODevice& fin){ - char c; - - m_buffer.clear(); - m_curState = State_Start; - - parsingStarted(); - - while (!fin.atEnd()) - { - c = fin.getch (); - -// tqDebug ("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 : - tqWarning ( "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 : - tqWarning ( "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: - tqWarning ( "unknown state: %d", m_curState ); - } - - m_buffer.clear(); -} - -void PSCommentLexer::gotComment (const char *value) { - tqDebug ( "gotComment: %s ", value ); -} - -void PSCommentLexer::parsingStarted() { - tqDebug ( "parsing started" ); -} - -void PSCommentLexer::parsingFinished() { - tqDebug ( "parsing finished" ); -} - -void PSCommentLexer::parsingAborted() { - tqDebug ( "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); -// tqDebug ("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() { - TQString data = toString(); - return data.toFloat(); -} - -int StringBuffer::toInt() { - TQString data = toString(); - return data.toInt(); -} - -const char *StringBuffer::latin1() { - return m_buffer; -} - -TQString StringBuffer::mid( uint index, uint len) const { - TQString 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) -{ - TQString 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; - - TQString s(input); - if (s.contains ("(atend)")) return false; - - TQString s2 = s.remove("%BoundingBox:"); - TQStringList values = TQStringList::split (" ", s2.latin1()); - tqDebug("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.cpp b/filters/karbon/eps/pscommentlexer.cpp new file mode 100644 index 00000000..e15dcc59 --- /dev/null +++ b/filters/karbon/eps/pscommentlexer.cpp @@ -0,0 +1,324 @@ +/* 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 +#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; + signed 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 (TQIODevice& fin){ + char c; + + m_buffer.clear(); + m_curState = State_Start; + + parsingStarted(); + + while (!fin.atEnd()) + { + c = fin.getch (); + +// tqDebug ("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 : + tqWarning ( "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 : + tqWarning ( "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: + tqWarning ( "unknown state: %d", m_curState ); + } + + m_buffer.clear(); +} + +void PSCommentLexer::gotComment (const char *value) { + tqDebug ( "gotComment: %s ", value ); +} + +void PSCommentLexer::parsingStarted() { + tqDebug ( "parsing started" ); +} + +void PSCommentLexer::parsingFinished() { + tqDebug ( "parsing finished" ); +} + +void PSCommentLexer::parsingAborted() { + tqDebug ( "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); +// tqDebug ("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() { + TQString data = toString(); + return data.toFloat(); +} + +int StringBuffer::toInt() { + TQString data = toString(); + return data.toInt(); +} + +const char *StringBuffer::latin1() { + return m_buffer; +} + +TQString StringBuffer::mid( uint index, uint len) const { + TQString 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) +{ + TQString 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; + + TQString s(input); + if (s.contains ("(atend)")) return false; + + TQString s2 = s.remove("%BoundingBox:"); + TQStringList values = TQStringList::split (" ", s2.latin1()); + tqDebug("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/kontour/Makefile.am b/filters/karbon/kontour/Makefile.am index be0b835f..d955dbef 100644 --- a/filters/karbon/kontour/Makefile.am +++ b/filters/karbon/kontour/Makefile.am @@ -5,7 +5,7 @@ INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) -I$(top_srcdir)/ ####### 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. +# than just fooimport.cpp please add them to the _SOURCES line. kde_module_LTLIBRARIES = libkarbonkontourimport.la diff --git a/filters/karbon/msod/Makefile.am b/filters/karbon/msod/Makefile.am index f7191cd1..a555234a 100644 --- a/filters/karbon/msod/Makefile.am +++ b/filters/karbon/msod/Makefile.am @@ -8,7 +8,7 @@ libkarbonmsodimport_la_LIBADD = $(KOFFICE_LIBS) $(LIBZ) kde_module_LTLIBRARIES = libkarbonmsodimport.la -libkarbonmsodimport_la_SOURCES = msodimport.cc msod.cc +libkarbonmsodimport_la_SOURCES = msodimport.cpp msod.cpp noinst_HEADERS = msodimport.h msod.h diff --git a/filters/karbon/msod/msod.cc b/filters/karbon/msod/msod.cc deleted file mode 100644 index 35445e18..00000000 --- a/filters/karbon/msod/msod.cc +++ /dev/null @@ -1,1340 +0,0 @@ -/* - 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, - TQ_UINT32 bytes, - TQDataStream &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 - { - TQ_UINT32 spid; // The shape id - union - { - TQ_UINT32 info; - struct - { - TQ_UINT32 fGroup : 1; // This shape is a group shape - TQ_UINT32 fChild : 1; // Not a top-level shape - TQ_UINT32 fPatriarch : 1; // This is the topmost group shape. - // Exactly one of these per drawing. - TQ_UINT32 fDeleted : 1; // The shape.has been deleted - TQ_UINT32 fOleShape : 1; // The shape is an OLE object - TQ_UINT32 fHaveMaster : 1; // Shape has a hspMaster property - TQ_UINT32 fFlipH : 1; // Shape is flipped horizontally - TQ_UINT32 fFlipV : 1; // Shape is flipped vertically - TQ_UINT32 fConnector : 1; // Connector type of shape - TQ_UINT32 fHaveAnchor : 1; // Shape has an anchor of some kind - TQ_UINT32 fBackground : 1; // Background shape - TQ_UINT32 fHaveSpt : 1; // Shape has a shape type property - TQ_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) - { - TQPoint topLeft; - TQSize size; - - topLeft = normalisePoint(operands); - size = normaliseSize(operands); - - TQRect rect(topLeft, size); - TQPointArray 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) - { - TQPoint lineFrom; - TQPoint lineTo; - - lineTo = normalisePoint(operands); - - TQPointArray points(2); - - points.setPoint(0, lineFrom); - points.setPoint(1, lineTo); - gotPolyline(m_dc, points); - } - break; - default: - break; - } -} - -void Msod::invokeHandler( - Header &op, - TQ_UINT32 bytes, - TQDataStream &operands) -{ - typedef void (Msod::*method)(Header &op, TQ_UINT32 bytes, TQDataStream &operands); - - typedef struct - { - const char *name; - TQ_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" << - TQString::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) - { - TQByteArray *record = new TQByteArray(bytes); - TQDataStream *body; - - operands.readRawBytes(record->data(), bytes); - body = new TQDataStream(*record, IO_ReadOnly); - body->setByteOrder(TQDataStream::LittleEndian); - (this->*result)(op, bytes, *body); - delete body; - delete record; - } - else - { - TQDataStream *body = new TQDataStream(); - - (this->*result)(op, bytes, *body); - delete body; - } - } -} - -TQPoint Msod::normalisePoint( - TQDataStream &operands) -{ - TQ_UINT16 x; - TQ_UINT16 y; - - operands >> x >> y; - return TQPoint(x / m_dpi, y / m_dpi); -} - -TQSize Msod::normaliseSize( - TQDataStream &operands) -{ - TQ_UINT16 width; - TQ_UINT16 height; - - operands >> width >> height; - return TQSize(width / m_dpi, height / m_dpi); -} - -bool Msod::parse( - unsigned shapeId, - const TQString &file, - const char *delayStream) -{ - TQFile in(file); - if (!in.open(IO_ReadOnly)) - { - kdError(s_area) << "Unable to open input file!" << endl; - in.close(); - return false; - } - TQDataStream stream(&in); - bool result = parse(shapeId, stream, in.size(), delayStream); - in.close(); - return result; -} - -bool Msod::parse( - unsigned shapeId, - TQDataStream &stream, - unsigned size, - const char *delayStream) -{ - stream.setByteOrder(TQDataStream::LittleEndian); // Great, I love TQt ! - m_requestedShapeId = shapeId; - m_isRequiredDrawing = false; - m_delayStream = delayStream; - - // Read bits. - - walk(size, stream); - return true; -} - -void Msod::opAlignrule( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opAnchor( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opArcrule( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opBlip(Header &, TQ_UINT32 bytes, TQDataStream &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; - TQ_UINT32 length = 0; - struct - { - TQ_UINT32 cb; - struct - { - TQ_UINT32 x; - TQ_UINT32 y; - TQ_UINT32 w; - TQ_UINT32 h; - } bounds; - struct - { - TQ_UINT32 w; - TQ_UINT32 h; - } ptSize; - TQ_UINT32 cbSave; - TQ_UINT8 compression; - TQ_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((TQ_UINT8 *)tmp, &destLen, (TQ_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, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT8 btWin32; // Required type on Win32. - TQ_UINT8 btMacOS; // Required type on Mac. - TQ_UINT8 rgbUid[16]; // Identifier of blip. - TQ_UINT16 tag; // currently unused. - TQ_UINT32 size; // Blip size in stream. - TQ_UINT32 cRef; // Reference count on the blip. - TQ_UINT32 foDelay; // File offset in the delay stream. - TQ_UINT8 usage; // How this blip is used (MSOBLIPUSAGE). - TQ_UINT8 cbName; // length of the blip name. - TQ_UINT8 unused2; // for the future. - TQ_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) - { - TQByteArray bytes; - bytes.setRawData(m_delayStream + data.foDelay, data.size); - TQDataStream stream(bytes, IO_ReadOnly); - stream.setByteOrder(TQDataStream::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 &, TQ_UINT32 bytes, TQDataStream &operands) -{ - walk(bytes, operands); -} - -void Msod::opCalloutrule( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opChildanchor( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opClientanchor(Header &, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT32 unknown; - } data; - - operands >> data.unknown; - kdDebug(s_area) << "client anchor: " << data.unknown << endl; -} - -void Msod::opClientdata(Header &, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT32 unknown; - } data; - - operands >> data.unknown; - kdDebug(s_area) << "client data: " << data.unknown << endl; -} - -void Msod::opClientrule( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opClienttextbox( - Header &, - TQ_UINT32, - TQDataStream &operands) -{ - struct - { - TQ_UINT32 unknown; - } data; - - operands >> data.unknown; - kdDebug(s_area) << "client textbox: 0x" << TQString::number(data.unknown,16) << endl; -} - -void Msod::opClsid( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opColormru( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opConnectorrule( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opDeletedpspl( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -// FDG - File DG - -void Msod::opDg(Header &, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT32 csp; // The number of shapes in this drawing. - TQ_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 &, TQ_UINT32 bytes, TQDataStream &operands) -{ - walk(bytes, operands); -} - -// FDGG - File DGG - -void Msod::opDgg(Header &, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT32 spidMax; // The current maximum shape ID. - TQ_UINT32 cidcl; // The number of ID clusters (FIDCLs). - TQ_UINT32 cspSaved; // The total number of shapes saved. - // (including deleted shapes, if undo - // information was saved). - TQ_UINT32 cdgSaved; // The total number of drawings saved. - } data; - - // File ID Cluster - used to save IDCLs - - struct - { - TQ_UINT32 dgid; // DG owning the SPIDs in this cluster - TQ_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 &, TQ_UINT32 bytes, TQDataStream &operands) -{ - walk(bytes, operands); -} - -void Msod::opOleobject( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opOpt(Header &, TQ_UINT32 bytes, TQDataStream &operands) -{ - m_opt->walk(bytes, operands); -} - -void Msod::opRegroupitems( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opSelection( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::opSolvercontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands) -{ - walk(bytes, operands); -} - -void Msod::opSp(Header &op, TQ_UINT32 bytes, TQDataStream &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 &, TQ_UINT32 bytes, TQDataStream &operands) -{ - walk(bytes, operands); - - // Having gathered all the information for this shape, we can now draw it. - - TQByteArray a; - - a.setRawData(m_shape.data, m_shape.length); - TQDataStream s(a, IO_ReadOnly); - s.setByteOrder(TQDataStream::LittleEndian); // Great, I love TQt ! - 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 &, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT32 x; - TQ_UINT32 y; - TQ_UINT32 w; - TQ_UINT32 h; - } data; - - operands >> data.x >> data.y >> data.w >> data.h; -} - -void Msod::opSpgrcontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands) -{ - walk(bytes, operands); -} - -void Msod::opSplitmenucolors(Header &, TQ_UINT32, TQDataStream &operands) -{ - struct - { - TQ_UINT32 fill; - TQ_UINT32 line; - TQ_UINT32 shadow; - TQ_UINT32 threeDee; - } data; - - operands >> data.fill >> data.line >> data.shadow >> data.threeDee; -} - -void Msod::opTextbox( - Header &, - TQ_UINT32, - TQDataStream &) -{ -} - -void Msod::skip(TQ_UINT32 bytes, TQDataStream &operands) -{ - if ((int)bytes < 0) - { - kdError(s_area) << "skip: " << (int)bytes << endl; - return; - } - if (bytes) - { - TQ_UINT32 i; - TQ_UINT8 discard; - - kdDebug(s_area) << "skip: " << bytes << endl; - for (i = 0; i < bytes; i++) - { - operands >> discard; - } - } -} - -void Msod::walk(TQ_UINT32 bytes, TQDataStream &operands) -{ - Header op; - TQ_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(TQ_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 = TQString(); - 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(TQ_UINT32 bytes, TQDataStream &operands) -{ - Header op; - TQ_UINT16 length = 0; - TQ_UINT16 complexLength = 0; - - // Reset all options to default values. - - initialise(); - - // First process all simple options, and add all complex options to a list. - - TQPtrList
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" << TQString::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") - { - TQByteArray a; - a.setRawData(image->data, image->length); - TQDataStream 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()) - { - TQ_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 += TQChar(t16); - }; - break; - case 325: - m_pVertices = new TQPointArray(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.cpp b/filters/karbon/msod/msod.cpp new file mode 100644 index 00000000..35445e18 --- /dev/null +++ b/filters/karbon/msod/msod.cpp @@ -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, + TQ_UINT32 bytes, + TQDataStream &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 + { + TQ_UINT32 spid; // The shape id + union + { + TQ_UINT32 info; + struct + { + TQ_UINT32 fGroup : 1; // This shape is a group shape + TQ_UINT32 fChild : 1; // Not a top-level shape + TQ_UINT32 fPatriarch : 1; // This is the topmost group shape. + // Exactly one of these per drawing. + TQ_UINT32 fDeleted : 1; // The shape.has been deleted + TQ_UINT32 fOleShape : 1; // The shape is an OLE object + TQ_UINT32 fHaveMaster : 1; // Shape has a hspMaster property + TQ_UINT32 fFlipH : 1; // Shape is flipped horizontally + TQ_UINT32 fFlipV : 1; // Shape is flipped vertically + TQ_UINT32 fConnector : 1; // Connector type of shape + TQ_UINT32 fHaveAnchor : 1; // Shape has an anchor of some kind + TQ_UINT32 fBackground : 1; // Background shape + TQ_UINT32 fHaveSpt : 1; // Shape has a shape type property + TQ_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) + { + TQPoint topLeft; + TQSize size; + + topLeft = normalisePoint(operands); + size = normaliseSize(operands); + + TQRect rect(topLeft, size); + TQPointArray 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) + { + TQPoint lineFrom; + TQPoint lineTo; + + lineTo = normalisePoint(operands); + + TQPointArray points(2); + + points.setPoint(0, lineFrom); + points.setPoint(1, lineTo); + gotPolyline(m_dc, points); + } + break; + default: + break; + } +} + +void Msod::invokeHandler( + Header &op, + TQ_UINT32 bytes, + TQDataStream &operands) +{ + typedef void (Msod::*method)(Header &op, TQ_UINT32 bytes, TQDataStream &operands); + + typedef struct + { + const char *name; + TQ_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" << + TQString::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) + { + TQByteArray *record = new TQByteArray(bytes); + TQDataStream *body; + + operands.readRawBytes(record->data(), bytes); + body = new TQDataStream(*record, IO_ReadOnly); + body->setByteOrder(TQDataStream::LittleEndian); + (this->*result)(op, bytes, *body); + delete body; + delete record; + } + else + { + TQDataStream *body = new TQDataStream(); + + (this->*result)(op, bytes, *body); + delete body; + } + } +} + +TQPoint Msod::normalisePoint( + TQDataStream &operands) +{ + TQ_UINT16 x; + TQ_UINT16 y; + + operands >> x >> y; + return TQPoint(x / m_dpi, y / m_dpi); +} + +TQSize Msod::normaliseSize( + TQDataStream &operands) +{ + TQ_UINT16 width; + TQ_UINT16 height; + + operands >> width >> height; + return TQSize(width / m_dpi, height / m_dpi); +} + +bool Msod::parse( + unsigned shapeId, + const TQString &file, + const char *delayStream) +{ + TQFile in(file); + if (!in.open(IO_ReadOnly)) + { + kdError(s_area) << "Unable to open input file!" << endl; + in.close(); + return false; + } + TQDataStream stream(&in); + bool result = parse(shapeId, stream, in.size(), delayStream); + in.close(); + return result; +} + +bool Msod::parse( + unsigned shapeId, + TQDataStream &stream, + unsigned size, + const char *delayStream) +{ + stream.setByteOrder(TQDataStream::LittleEndian); // Great, I love TQt ! + m_requestedShapeId = shapeId; + m_isRequiredDrawing = false; + m_delayStream = delayStream; + + // Read bits. + + walk(size, stream); + return true; +} + +void Msod::opAlignrule( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opAnchor( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opArcrule( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opBlip(Header &, TQ_UINT32 bytes, TQDataStream &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; + TQ_UINT32 length = 0; + struct + { + TQ_UINT32 cb; + struct + { + TQ_UINT32 x; + TQ_UINT32 y; + TQ_UINT32 w; + TQ_UINT32 h; + } bounds; + struct + { + TQ_UINT32 w; + TQ_UINT32 h; + } ptSize; + TQ_UINT32 cbSave; + TQ_UINT8 compression; + TQ_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((TQ_UINT8 *)tmp, &destLen, (TQ_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, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT8 btWin32; // Required type on Win32. + TQ_UINT8 btMacOS; // Required type on Mac. + TQ_UINT8 rgbUid[16]; // Identifier of blip. + TQ_UINT16 tag; // currently unused. + TQ_UINT32 size; // Blip size in stream. + TQ_UINT32 cRef; // Reference count on the blip. + TQ_UINT32 foDelay; // File offset in the delay stream. + TQ_UINT8 usage; // How this blip is used (MSOBLIPUSAGE). + TQ_UINT8 cbName; // length of the blip name. + TQ_UINT8 unused2; // for the future. + TQ_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) + { + TQByteArray bytes; + bytes.setRawData(m_delayStream + data.foDelay, data.size); + TQDataStream stream(bytes, IO_ReadOnly); + stream.setByteOrder(TQDataStream::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 &, TQ_UINT32 bytes, TQDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opCalloutrule( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opChildanchor( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opClientanchor(Header &, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client anchor: " << data.unknown << endl; +} + +void Msod::opClientdata(Header &, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client data: " << data.unknown << endl; +} + +void Msod::opClientrule( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opClienttextbox( + Header &, + TQ_UINT32, + TQDataStream &operands) +{ + struct + { + TQ_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client textbox: 0x" << TQString::number(data.unknown,16) << endl; +} + +void Msod::opClsid( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opColormru( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opConnectorrule( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opDeletedpspl( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +// FDG - File DG + +void Msod::opDg(Header &, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT32 csp; // The number of shapes in this drawing. + TQ_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 &, TQ_UINT32 bytes, TQDataStream &operands) +{ + walk(bytes, operands); +} + +// FDGG - File DGG + +void Msod::opDgg(Header &, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT32 spidMax; // The current maximum shape ID. + TQ_UINT32 cidcl; // The number of ID clusters (FIDCLs). + TQ_UINT32 cspSaved; // The total number of shapes saved. + // (including deleted shapes, if undo + // information was saved). + TQ_UINT32 cdgSaved; // The total number of drawings saved. + } data; + + // File ID Cluster - used to save IDCLs + + struct + { + TQ_UINT32 dgid; // DG owning the SPIDs in this cluster + TQ_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 &, TQ_UINT32 bytes, TQDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opOleobject( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opOpt(Header &, TQ_UINT32 bytes, TQDataStream &operands) +{ + m_opt->walk(bytes, operands); +} + +void Msod::opRegroupitems( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opSelection( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::opSolvercontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opSp(Header &op, TQ_UINT32 bytes, TQDataStream &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 &, TQ_UINT32 bytes, TQDataStream &operands) +{ + walk(bytes, operands); + + // Having gathered all the information for this shape, we can now draw it. + + TQByteArray a; + + a.setRawData(m_shape.data, m_shape.length); + TQDataStream s(a, IO_ReadOnly); + s.setByteOrder(TQDataStream::LittleEndian); // Great, I love TQt ! + 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 &, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT32 x; + TQ_UINT32 y; + TQ_UINT32 w; + TQ_UINT32 h; + } data; + + operands >> data.x >> data.y >> data.w >> data.h; +} + +void Msod::opSpgrcontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opSplitmenucolors(Header &, TQ_UINT32, TQDataStream &operands) +{ + struct + { + TQ_UINT32 fill; + TQ_UINT32 line; + TQ_UINT32 shadow; + TQ_UINT32 threeDee; + } data; + + operands >> data.fill >> data.line >> data.shadow >> data.threeDee; +} + +void Msod::opTextbox( + Header &, + TQ_UINT32, + TQDataStream &) +{ +} + +void Msod::skip(TQ_UINT32 bytes, TQDataStream &operands) +{ + if ((int)bytes < 0) + { + kdError(s_area) << "skip: " << (int)bytes << endl; + return; + } + if (bytes) + { + TQ_UINT32 i; + TQ_UINT8 discard; + + kdDebug(s_area) << "skip: " << bytes << endl; + for (i = 0; i < bytes; i++) + { + operands >> discard; + } + } +} + +void Msod::walk(TQ_UINT32 bytes, TQDataStream &operands) +{ + Header op; + TQ_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(TQ_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 = TQString(); + 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(TQ_UINT32 bytes, TQDataStream &operands) +{ + Header op; + TQ_UINT16 length = 0; + TQ_UINT16 complexLength = 0; + + // Reset all options to default values. + + initialise(); + + // First process all simple options, and add all complex options to a list. + + TQPtrList
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" << TQString::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") + { + TQByteArray a; + a.setRawData(image->data, image->length); + TQDataStream 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()) + { + TQ_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 += TQChar(t16); + }; + break; + case 325: + m_pVertices = new TQPointArray(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/msodimport.cc b/filters/karbon/msod/msodimport.cc deleted file mode 100644 index bd272271..00000000 --- a/filters/karbon/msod/msodimport.cc +++ /dev/null @@ -1,313 +0,0 @@ -/* - 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 TQStringList&) : - KoEmbeddingFilter(), Msod(100) -{ -} - -MSODImport::~MSODImport() -{ -} - -KoFilter::ConversionStatus MSODImport::convert( const TQCString& from, const TQCString& 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; -/* - TQString config = ""; // ###### FIXME: We aren't able to pass config data right now - TQStringList args = TQStringList::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; - } - TQCString cstring ( m_text.utf8() ); - dev->writeBlock(cstring.data(), cstring.size()-1); - - return KoFilter::OK; -} - -void MSODImport::gotEllipse( - const DrawContext &/*dc*/, - TQString /*type*/, - TQPoint /*topLeft*/, - TQSize /*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, - TQString 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( TQString::number( key ) ); - - if (partRef == -1) - { - m_embeddeeData = data; - m_embeddeeLength = length; - - TQString srcMime( KoEmbeddingFilter::mimeTypeByExtension( extension ) ); - if ( srcMime == KMimeType::defaultMimeType() ) - kdWarning( s_area ) << "Couldn't determine the mimetype from the extension" << endl; - - TQCString destMime; // intentionally empty, the filter manager will do the rest - KoFilter::ConversionStatus status; - partRef = embedPart( srcMime.latin1(), destMime, status, TQString::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( TQString(), '.' + 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 TQPointArray &points) -{ - kdDebug(s_area) << "MSODImport::gotPolygon" << endl; - kdDebug(s_area) << TQString::number(dc.m_penWidth, 16) << endl; - kdDebug(s_area) << dc.m_penStyle << endl; - m_text += "\n"; - if( dc.m_penWidth > 0 ) - { - m_text += "\n";// + TQString::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 TQPointArray &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 TQPointArray &points) -{ -// ### TODO -#if 0 - TQRect 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( TQIODevice* file ) -{ - if ( m_embeddeeData != 0 && m_embeddeeLength != 0 ) - file->writeBlock( m_embeddeeData, m_embeddeeLength ); -} - -void MSODImport::pointArray( - const TQPointArray &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.cpp b/filters/karbon/msod/msodimport.cpp new file mode 100644 index 00000000..bd272271 --- /dev/null +++ b/filters/karbon/msod/msodimport.cpp @@ -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 TQStringList&) : + KoEmbeddingFilter(), Msod(100) +{ +} + +MSODImport::~MSODImport() +{ +} + +KoFilter::ConversionStatus MSODImport::convert( const TQCString& from, const TQCString& 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; +/* + TQString config = ""; // ###### FIXME: We aren't able to pass config data right now + TQStringList args = TQStringList::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; + } + TQCString cstring ( m_text.utf8() ); + dev->writeBlock(cstring.data(), cstring.size()-1); + + return KoFilter::OK; +} + +void MSODImport::gotEllipse( + const DrawContext &/*dc*/, + TQString /*type*/, + TQPoint /*topLeft*/, + TQSize /*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, + TQString 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( TQString::number( key ) ); + + if (partRef == -1) + { + m_embeddeeData = data; + m_embeddeeLength = length; + + TQString srcMime( KoEmbeddingFilter::mimeTypeByExtension( extension ) ); + if ( srcMime == KMimeType::defaultMimeType() ) + kdWarning( s_area ) << "Couldn't determine the mimetype from the extension" << endl; + + TQCString destMime; // intentionally empty, the filter manager will do the rest + KoFilter::ConversionStatus status; + partRef = embedPart( srcMime.latin1(), destMime, status, TQString::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( TQString(), '.' + 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 TQPointArray &points) +{ + kdDebug(s_area) << "MSODImport::gotPolygon" << endl; + kdDebug(s_area) << TQString::number(dc.m_penWidth, 16) << endl; + kdDebug(s_area) << dc.m_penStyle << endl; + m_text += "\n"; + if( dc.m_penWidth > 0 ) + { + m_text += "\n";// + TQString::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 TQPointArray &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 TQPointArray &points) +{ +// ### TODO +#if 0 + TQRect 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( TQIODevice* file ) +{ + if ( m_embeddeeData != 0 && m_embeddeeLength != 0 ) + file->writeBlock( m_embeddeeData, m_embeddeeLength ); +} + +void MSODImport::pointArray( + const TQPointArray &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/oodraw/Makefile.am b/filters/karbon/oodraw/Makefile.am index 4cca1e32..3ace9839 100644 --- a/filters/karbon/oodraw/Makefile.am +++ b/filters/karbon/oodraw/Makefile.am @@ -11,7 +11,7 @@ INCLUDES= -I$(srcdir)/../../liboofilter \ kde_module_LTLIBRARIES = liboodrawimport.la -liboodrawimport_la_SOURCES = oodrawimport.cc +liboodrawimport_la_SOURCES = oodrawimport.cpp liboodrawimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined liboodrawimport_la_LIBADD = ../../liboofilter/liboofilter.la \ ../../../karbon/libkarboncommon.la \ diff --git a/filters/karbon/oodraw/oodrawimport.cc b/filters/karbon/oodraw/oodrawimport.cc deleted file mode 100644 index fba48867..00000000 --- a/filters/karbon/oodraw/oodrawimport.cc +++ /dev/null @@ -1,757 +0,0 @@ -/* 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 TQStringList & ) - : KoFilter(), - m_styles( 23, true ), - m_styleStack( ooNS::style, ooNS::fo ) -{ - m_styles.setAutoDelete( true ); -} - -OoDrawImport::~OoDrawImport() -{ -} - -KoFilter::ConversionStatus OoDrawImport::convert( TQCString const & from, TQCString 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; - } -/*TQDomDocument docinfo; - createDocumentInfo( docinfo ); - -// store document info -KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); -if( out ) -{ -TQCString info = docinfo.toCString(); -//kdDebug() << " info :" << info << endl; -// WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end. -out->writeBlock( info , info.length() ); -}*/ - TQDomDocument docinfo; - createDocumentInfo( docinfo ); - // store document info - KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); - if( out ) - { - TQCString info = docinfo.toCString(); - //kdDebug(30518) << " info :" << info << endl; - // WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end. - out->writeBlock( info , info.length() ); - } - - convert(); - TQDomDocument outdoc = m_document.saveXML(); - // add paper info, we always need custom for svg (Rob) - TQDomElement 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 ) - { - TQCString 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( TQDomDocument &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. - TQDomDocument 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 ); - - TQDomElement content = m_content.documentElement(); - - // content.xml contains some automatic-styles that we need to store - TQDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" ); - if( !automaticStyles.isNull() ) - insertStyles( automaticStyles.toElement() ); - - TQDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" ); - if( body.isNull() ) - return; - - // we take the settings of the first slide for the whole document. - TQDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" ); - if( drawPage.isNull() ) // no pages? give up. - return; - - TQDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", TQString() )]; - TQDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", TQString() )]; - TQDomElement 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", TQString() ) ) ); - m_document.setHeight( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", TQString() ) ) ); - } - - // parse all pages - for( TQDomNode drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() ) - { - TQDomElement dp = drawPage.toElement(); - m_styleStack.clear(); // remove all styles - fillStyleStack( dp ); - //m_styleStack.setPageMark(); - - // set the pagetitle - //TQDomElement titleElement = doc.createElement( "Title" ); - //titleElement.setAttribute( "title", dp.attributeNS( "name" ) ); - //pageTitleElement.appendChild( titleElement ); - - parseGroup( 0L, dp ); - } -} - - -KoFilter::ConversionStatus OoDrawImport::loadAndParse(const TQString& filename, TQDomDocument& doc) -{ - return OoUtils::loadAndParse( filename, doc, m_zip); -} - -void -OoDrawImport::parseGroup( VGroup *parent, const TQDomElement& parentobject ) -{ - // parse all objects - for( TQDomNode object = parentobject.firstChild(); !object.isNull(); object = object.nextSibling() ) - { - TQDomElement o = object.toElement(); - if( o.namespaceURI() != ooNS::draw ) continue; - TQString name = o.localName(); - TQString drawID = o.attributeNS( ooNS::draw, "id", TQString() ); - 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", TQString() ) ); - double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ); - double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) ); - double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) ); - int corner = static_cast( KoUnit::parseValue( o.attributeNS( ooNS::draw, "corner-radius", TQString() ) ) ); - 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", TQString() ) ); - double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) ); - double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) ); - double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ) - h; - double start = o.attributeNS( ooNS::draw, "start-angle", TQString() ).toDouble(); - double end = o.attributeNS( ooNS::draw, "end-angle", TQString() ).toDouble(); - TQString kind = o.attributeNS( ooNS::draw, "kind", TQString() ); - 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", TQString() ) ); - double y1 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y1", TQString() ) ) ); - double x2 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x2", TQString() ) ); - double y2 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y2", TQString() ) ) ); - 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", TQString() ) ); - KoRect rect = parseViewBox( o ); - double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) ); - double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ); - double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) ); - double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) ); - TQWMatrix 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" ) - { - TQValueList dashes; - stroke.setType( VStroke::solid ); - TQString 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 TQString 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 ); - TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" ); - - TQDomElement* draw = m_draws[style]; - if( draw ) - { - double border = 0.0; - if( draw->hasAttributeNS( ooNS::draw, "border" ) ) - border += draw->attributeNS( ooNS::draw, "border", TQString() ).remove( '%' ).toDouble() / 100.0; - VColor c; - parseColor( c, draw->attributeNS( ooNS::draw, "start-color", TQString() ) ); - gradient.addStop( c, border, 0.5 ); - parseColor( c, draw->attributeNS( ooNS::draw, "end-color", TQString() ) ); - gradient.addStop( c, 1.0, 0.5 ); - - TQString type = draw->attributeNS( ooNS::draw, "style", TQString() ); - if( type == "linear" || type == "axial" ) - { - gradient.setType( VGradient::linear ); - int angle = draw->attributeNS( ooNS::draw, "angle", TQString() ).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", TQString() ).remove( '%' ).toDouble() / 100.0; - else - x = 0.5; - - if( draw->hasAttributeNS( ooNS::draw, "cy" ) ) - y = draw->attributeNS( ooNS::draw, "cy", TQString() ).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" ) -{ -TQDomElement brush = doc.createElement( "BRUSH" ); -TQString 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 ); - -TQDomElement* draw = m_draws[style]; -if( draw && draw->hasAttributeNS( "color" ) ) -brush.setAttribute( "color", draw->attributeNS( "color" ) ); -e.appendChild( brush ); -}*/ -} - -void -OoDrawImport::createStyleMap( TQDomDocument &docstyles ) -{ - TQDomElement styles = docstyles.documentElement(); - if( styles.isNull() ) - return; - - TQDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" ); - if( !fixedStyles.isNull() ) - { - insertDraws( fixedStyles.toElement() ); - insertStyles( fixedStyles.toElement() ); - } - TQDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" ); - if( !automaticStyles.isNull() ) - insertStyles( automaticStyles.toElement() ); - - TQDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" ); - if( !masterStyles.isNull() ) - insertStyles( masterStyles.toElement() ); -} - -void -OoDrawImport::insertDraws( const TQDomElement& styles ) -{ - for( TQDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement e = n.toElement(); - - if( !e.hasAttributeNS( ooNS::draw, "name" ) ) - continue; - - TQString name = e.attributeNS( ooNS::draw, "name", TQString() ); - m_draws.insert( name, new TQDomElement( e ) ); - } -} - - -void -OoDrawImport::insertStyles( const TQDomElement& styles ) -{ - for ( TQDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement e = n.toElement(); - - if( !e.hasAttributeNS( ooNS::style, "name" ) ) - continue; - - TQString name = e.attributeNS( ooNS::style, "name", TQString() ); - m_styles.insert( name, new TQDomElement( e ) ); - //kdDebug() << "Style: '" << name << "' loaded " << endl; - } -} - -void -OoDrawImport::fillStyleStack( const TQDomElement& 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", TQString() )] ); - - if( object.hasAttributeNS( ooNS::draw, "style-name" ) ) - addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", TQString() )] ); - - if( object.hasAttributeNS( ooNS::draw, "text-style-name" ) ) - addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", TQString() )] ); - - if( object.hasAttributeNS( ooNS::text, "style-name" ) ) - addStyles( m_styles[object.attributeNS( ooNS::text, "style-name", TQString() )] ); -} - -void -OoDrawImport::addStyles( const TQDomElement* 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", TQString() )] ); - - m_styleStack.push( *style ); -} - -void -OoDrawImport::storeObjectStyles( const TQDomElement& object ) -{ - //m_styleStack.clearPageMark(); // remove styles of previous object - fillStyleStack( object ); - //m_styleStack.setObjectMark(); -} - -KoRect -OoDrawImport::parseViewBox( const TQDomElement& object ) -{ - KoRect rect; - if( !object.attributeNS( ooNS::svg, "viewBox", TQString() ).isEmpty() ) - { - // allow for viewbox def with ',' or whitespace - TQString viewbox( object.attributeNS( ooNS::svg, "viewBox", TQString() ) ); - TQStringList points = TQStringList::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 TQDomElement& object) -{ - double x = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", TQString() ) ); - double y = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", TQString() ) ); - double w = KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", TQString() ) ); - double h = KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", TQString() ) ); - - KoRect rect = parseViewBox( object ); - rect.setX( rect.x() + x ); - rect.setY( rect.y() + y ); - - TQStringList ptList = TQStringList::split( ' ', object.attributeNS( ooNS::draw, "points", TQString() ) ); - - TQString pt_x, pt_y; - double tmp_x, tmp_y; - KoPoint point; - bool bFirst = true; - for( TQStringList::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 TQString &s ) -{ - if( s.startsWith( "rgb(" ) ) - { - TQString parse = s.stripWhiteSpace(); - TQStringList colors = TQStringList::split( ',', parse ); - TQString r = colors[0].right( ( colors[0].length() - 4 ) ); - TQString g = colors[1]; - TQString b = colors[2].left( ( colors[2].length() - 1 ) ); - - if( r.contains( "%" ) ) - { - r = r.left( r.length() - 1 ); - r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); - } - - if( g.contains( "%" ) ) - { - g = g.left( g.length() - 1 ); - g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); - } - - if( b.contains( "%" ) ) - { - b = b.left( b.length() - 1 ); - b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); - } - - TQColor c( r.toInt(), g.toInt(), b.toInt() ); - color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); - } - else - { - TQString rgbColor = s.stripWhiteSpace(); - TQColor 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.cpp b/filters/karbon/oodraw/oodrawimport.cpp new file mode 100644 index 00000000..fba48867 --- /dev/null +++ b/filters/karbon/oodraw/oodrawimport.cpp @@ -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 TQStringList & ) + : KoFilter(), + m_styles( 23, true ), + m_styleStack( ooNS::style, ooNS::fo ) +{ + m_styles.setAutoDelete( true ); +} + +OoDrawImport::~OoDrawImport() +{ +} + +KoFilter::ConversionStatus OoDrawImport::convert( TQCString const & from, TQCString 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; + } +/*TQDomDocument docinfo; + createDocumentInfo( docinfo ); + +// store document info +KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); +if( out ) +{ +TQCString info = docinfo.toCString(); +//kdDebug() << " info :" << info << endl; +// WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end. +out->writeBlock( info , info.length() ); +}*/ + TQDomDocument docinfo; + createDocumentInfo( docinfo ); + // store document info + KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); + if( out ) + { + TQCString info = docinfo.toCString(); + //kdDebug(30518) << " info :" << info << endl; + // WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end. + out->writeBlock( info , info.length() ); + } + + convert(); + TQDomDocument outdoc = m_document.saveXML(); + // add paper info, we always need custom for svg (Rob) + TQDomElement 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 ) + { + TQCString 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( TQDomDocument &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. + TQDomDocument 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 ); + + TQDomElement content = m_content.documentElement(); + + // content.xml contains some automatic-styles that we need to store + TQDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" ); + if( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + TQDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" ); + if( body.isNull() ) + return; + + // we take the settings of the first slide for the whole document. + TQDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" ); + if( drawPage.isNull() ) // no pages? give up. + return; + + TQDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", TQString() )]; + TQDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", TQString() )]; + TQDomElement 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", TQString() ) ) ); + m_document.setHeight( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", TQString() ) ) ); + } + + // parse all pages + for( TQDomNode drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() ) + { + TQDomElement dp = drawPage.toElement(); + m_styleStack.clear(); // remove all styles + fillStyleStack( dp ); + //m_styleStack.setPageMark(); + + // set the pagetitle + //TQDomElement titleElement = doc.createElement( "Title" ); + //titleElement.setAttribute( "title", dp.attributeNS( "name" ) ); + //pageTitleElement.appendChild( titleElement ); + + parseGroup( 0L, dp ); + } +} + + +KoFilter::ConversionStatus OoDrawImport::loadAndParse(const TQString& filename, TQDomDocument& doc) +{ + return OoUtils::loadAndParse( filename, doc, m_zip); +} + +void +OoDrawImport::parseGroup( VGroup *parent, const TQDomElement& parentobject ) +{ + // parse all objects + for( TQDomNode object = parentobject.firstChild(); !object.isNull(); object = object.nextSibling() ) + { + TQDomElement o = object.toElement(); + if( o.namespaceURI() != ooNS::draw ) continue; + TQString name = o.localName(); + TQString drawID = o.attributeNS( ooNS::draw, "id", TQString() ); + 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", TQString() ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) ); + int corner = static_cast( KoUnit::parseValue( o.attributeNS( ooNS::draw, "corner-radius", TQString() ) ) ); + 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", TQString() ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ) - h; + double start = o.attributeNS( ooNS::draw, "start-angle", TQString() ).toDouble(); + double end = o.attributeNS( ooNS::draw, "end-angle", TQString() ).toDouble(); + TQString kind = o.attributeNS( ooNS::draw, "kind", TQString() ); + 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", TQString() ) ); + double y1 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y1", TQString() ) ) ); + double x2 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x2", TQString() ) ); + double y2 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y2", TQString() ) ) ); + 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", TQString() ) ); + KoRect rect = parseViewBox( o ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) ); + TQWMatrix 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" ) + { + TQValueList dashes; + stroke.setType( VStroke::solid ); + TQString 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 TQString 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 ); + TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" ); + + TQDomElement* draw = m_draws[style]; + if( draw ) + { + double border = 0.0; + if( draw->hasAttributeNS( ooNS::draw, "border" ) ) + border += draw->attributeNS( ooNS::draw, "border", TQString() ).remove( '%' ).toDouble() / 100.0; + VColor c; + parseColor( c, draw->attributeNS( ooNS::draw, "start-color", TQString() ) ); + gradient.addStop( c, border, 0.5 ); + parseColor( c, draw->attributeNS( ooNS::draw, "end-color", TQString() ) ); + gradient.addStop( c, 1.0, 0.5 ); + + TQString type = draw->attributeNS( ooNS::draw, "style", TQString() ); + if( type == "linear" || type == "axial" ) + { + gradient.setType( VGradient::linear ); + int angle = draw->attributeNS( ooNS::draw, "angle", TQString() ).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", TQString() ).remove( '%' ).toDouble() / 100.0; + else + x = 0.5; + + if( draw->hasAttributeNS( ooNS::draw, "cy" ) ) + y = draw->attributeNS( ooNS::draw, "cy", TQString() ).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" ) +{ +TQDomElement brush = doc.createElement( "BRUSH" ); +TQString 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 ); + +TQDomElement* draw = m_draws[style]; +if( draw && draw->hasAttributeNS( "color" ) ) +brush.setAttribute( "color", draw->attributeNS( "color" ) ); +e.appendChild( brush ); +}*/ +} + +void +OoDrawImport::createStyleMap( TQDomDocument &docstyles ) +{ + TQDomElement styles = docstyles.documentElement(); + if( styles.isNull() ) + return; + + TQDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" ); + if( !fixedStyles.isNull() ) + { + insertDraws( fixedStyles.toElement() ); + insertStyles( fixedStyles.toElement() ); + } + TQDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" ); + if( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + TQDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" ); + if( !masterStyles.isNull() ) + insertStyles( masterStyles.toElement() ); +} + +void +OoDrawImport::insertDraws( const TQDomElement& styles ) +{ + for( TQDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement e = n.toElement(); + + if( !e.hasAttributeNS( ooNS::draw, "name" ) ) + continue; + + TQString name = e.attributeNS( ooNS::draw, "name", TQString() ); + m_draws.insert( name, new TQDomElement( e ) ); + } +} + + +void +OoDrawImport::insertStyles( const TQDomElement& styles ) +{ + for ( TQDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement e = n.toElement(); + + if( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + TQString name = e.attributeNS( ooNS::style, "name", TQString() ); + m_styles.insert( name, new TQDomElement( e ) ); + //kdDebug() << "Style: '" << name << "' loaded " << endl; + } +} + +void +OoDrawImport::fillStyleStack( const TQDomElement& 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", TQString() )] ); + + if( object.hasAttributeNS( ooNS::draw, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", TQString() )] ); + + if( object.hasAttributeNS( ooNS::draw, "text-style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", TQString() )] ); + + if( object.hasAttributeNS( ooNS::text, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::text, "style-name", TQString() )] ); +} + +void +OoDrawImport::addStyles( const TQDomElement* 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", TQString() )] ); + + m_styleStack.push( *style ); +} + +void +OoDrawImport::storeObjectStyles( const TQDomElement& object ) +{ + //m_styleStack.clearPageMark(); // remove styles of previous object + fillStyleStack( object ); + //m_styleStack.setObjectMark(); +} + +KoRect +OoDrawImport::parseViewBox( const TQDomElement& object ) +{ + KoRect rect; + if( !object.attributeNS( ooNS::svg, "viewBox", TQString() ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + TQString viewbox( object.attributeNS( ooNS::svg, "viewBox", TQString() ) ); + TQStringList points = TQStringList::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 TQDomElement& object) +{ + double x = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", TQString() ) ); + double y = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", TQString() ) ); + double w = KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", TQString() ) ); + double h = KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", TQString() ) ); + + KoRect rect = parseViewBox( object ); + rect.setX( rect.x() + x ); + rect.setY( rect.y() + y ); + + TQStringList ptList = TQStringList::split( ' ', object.attributeNS( ooNS::draw, "points", TQString() ) ); + + TQString pt_x, pt_y; + double tmp_x, tmp_y; + KoPoint point; + bool bFirst = true; + for( TQStringList::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 TQString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + TQString parse = s.stripWhiteSpace(); + TQStringList colors = TQStringList::split( ',', parse ); + TQString r = colors[0].right( ( colors[0].length() - 4 ) ); + TQString g = colors[1]; + TQString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + TQColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else + { + TQString rgbColor = s.stripWhiteSpace(); + TQColor 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/png/Makefile.am b/filters/karbon/png/Makefile.am index 86d7e411..2a12d23b 100644 --- a/filters/karbon/png/Makefile.am +++ b/filters/karbon/png/Makefile.am @@ -20,7 +20,7 @@ noinst_HEADERS = \ pngexport.h libkarbonpngexport_la_SOURCES = \ - pngexport.cc + pngexport.cpp libkarbonpngexport_la_METASOURCES = \ AUTO diff --git a/filters/karbon/png/pngexport.cc b/filters/karbon/png/pngexport.cc deleted file mode 100644 index 89b43d03..00000000 --- a/filters/karbon/png/pngexport.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 TQStringList& ) - : KoFilter() -{ -} - -KoFilter::ConversionStatus -PngExport::convert( const TQCString& from, const TQCString& 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; - - TQDomDocument domIn; - domIn.setContent( storeIn ); - TQDomElement 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 - TQImage 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( tqRgba( 0xFF, 0xFF, 0xFF, 0xFF ) ); - p.setWorldMatrix( TQWMatrix().translate( -rect.x(), -rect.y() ) ); - - doc.draw( &p, &rect ); - - TQImage image = img.swapRGB(); - TQImage 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.cpp b/filters/karbon/png/pngexport.cpp new file mode 100644 index 00000000..89b43d03 --- /dev/null +++ b/filters/karbon/png/pngexport.cpp @@ -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 TQStringList& ) + : KoFilter() +{ +} + +KoFilter::ConversionStatus +PngExport::convert( const TQCString& from, const TQCString& 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; + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement 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 + TQImage 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( tqRgba( 0xFF, 0xFF, 0xFF, 0xFF ) ); + p.setWorldMatrix( TQWMatrix().translate( -rect.x(), -rect.y() ) ); + + doc.draw( &p, &rect ); + + TQImage image = img.swapRGB(); + TQImage mirrored = image.mirror( false, true ); + // save png + mirrored.save( m_chain->outputFile(), "PNG" ); + + return KoFilter::OK; +} + +#include "pngexport.moc" + diff --git a/filters/karbon/svg/Makefile.am b/filters/karbon/svg/Makefile.am index b8e08060..289f689a 100644 --- a/filters/karbon/svg/Makefile.am +++ b/filters/karbon/svg/Makefile.am @@ -25,10 +25,10 @@ noinst_HEADERS = \ svgexport.h libkarbonsvgexport_la_SOURCES = \ - svgexport.cc + svgexport.cpp METASOURCES = AUTO libkarbonsvgimport_la_SOURCES = \ - svgimport.cc + svgimport.cpp diff --git a/filters/karbon/svg/svgexport.cc b/filters/karbon/svg/svgexport.cc deleted file mode 100644 index 41fd6a54..00000000 --- a/filters/karbon/svg/svgexport.cc +++ /dev/null @@ -1,512 +0,0 @@ -/* 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 - -TQString INDENT(" "); - -void -printIndentation( TQTextStream *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 TQStringList& ) - : KoFilter(), m_indent( 0 ), m_indent2( 0 ), m_trans( 0L ) -{ - m_gc.setAutoDelete( true ); -} - -KoFilter::ConversionStatus -SvgExport::convert( const TQCString& from, const TQCString& 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; - - TQFile fileOut( m_chain->outputFile() ); - if( !fileOut.open( IO_WriteOnly ) ) - { - delete storeIn; - return KoFilter::StupidError; - } - - TQDomDocument domIn; - domIn.setContent( storeIn ); - TQDomElement docNode = domIn.documentElement(); - - m_stream = new TQTextStream( &fileOut ); - TQString body; - m_body = new TQTextStream( &body, IO_ReadWrite ); - TQString defs; - m_defs = new TQTextStream( &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 ); - - TQWMatrix 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; -} - -TQString -SvgExport::getID( VObject *obj ) -{ - if( obj && !obj->name().isEmpty() ) - return TQString( " id=\"%1\"" ).arg( obj->name() ); - return TQString(); -} - -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 TQString &id, TQTextStream *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& ) -{ -} - -TQString createUID() -{ - static unsigned int nr = 0; - - return "defitem" + TQString().setNum( nr++ ); -} - -void -SvgExport::getColorStops( const TQPtrVector &colorStops ) -{ - m_indent2++; - for( unsigned int i = 0; i < colorStops.count() ; i++ ) - { - printIndentation( m_defs, m_indent2 ); - *m_defs << "color ); - *m_defs << "\" offset=\"" << TQString().setNum( colorStops.at( i )->rampPoint ); - *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl; - } - m_indent2--; -} - -void -SvgExport::getGradient( const VGradient& grad ) -{ - TQString 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 & ) -{ - TQString 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, TQTextStream *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, TQTextStream *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=\" "; - - TQValueListConstIterator itr; - for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) - { - *stream << *itr << " "; - } - *stream << "\""; - } -} - -void -SvgExport::getHexColor( TQTextStream *stream, const VColor& color ) -{ - // Convert the various color-spaces to hex - - TQString 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 ); - - TQString 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.cpp b/filters/karbon/svg/svgexport.cpp new file mode 100644 index 00000000..41fd6a54 --- /dev/null +++ b/filters/karbon/svg/svgexport.cpp @@ -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 + +TQString INDENT(" "); + +void +printIndentation( TQTextStream *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 TQStringList& ) + : KoFilter(), m_indent( 0 ), m_indent2( 0 ), m_trans( 0L ) +{ + m_gc.setAutoDelete( true ); +} + +KoFilter::ConversionStatus +SvgExport::convert( const TQCString& from, const TQCString& 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; + + TQFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + delete storeIn; + return KoFilter::StupidError; + } + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement docNode = domIn.documentElement(); + + m_stream = new TQTextStream( &fileOut ); + TQString body; + m_body = new TQTextStream( &body, IO_ReadWrite ); + TQString defs; + m_defs = new TQTextStream( &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 ); + + TQWMatrix 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; +} + +TQString +SvgExport::getID( VObject *obj ) +{ + if( obj && !obj->name().isEmpty() ) + return TQString( " id=\"%1\"" ).arg( obj->name() ); + return TQString(); +} + +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 TQString &id, TQTextStream *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& ) +{ +} + +TQString createUID() +{ + static unsigned int nr = 0; + + return "defitem" + TQString().setNum( nr++ ); +} + +void +SvgExport::getColorStops( const TQPtrVector &colorStops ) +{ + m_indent2++; + for( unsigned int i = 0; i < colorStops.count() ; i++ ) + { + printIndentation( m_defs, m_indent2 ); + *m_defs << "color ); + *m_defs << "\" offset=\"" << TQString().setNum( colorStops.at( i )->rampPoint ); + *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl; + } + m_indent2--; +} + +void +SvgExport::getGradient( const VGradient& grad ) +{ + TQString 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 & ) +{ + TQString 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, TQTextStream *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, TQTextStream *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=\" "; + + TQValueListConstIterator itr; + for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) + { + *stream << *itr << " "; + } + *stream << "\""; + } +} + +void +SvgExport::getHexColor( TQTextStream *stream, const VColor& color ) +{ + // Convert the various color-spaces to hex + + TQString 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 ); + + TQString 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/svgimport.cc b/filters/karbon/svg/svgimport.cc deleted file mode 100644 index 9d323d3d..00000000 --- a/filters/karbon/svg/svgimport.cc +++ /dev/null @@ -1,1389 +0,0 @@ -/* 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 TQStringList&) : - KoFilter(), - outdoc( "DOC" ) -{ - m_gc.setAutoDelete( true ); -} - -SvgImport::~SvgImport() -{ -} - -KoFilter::ConversionStatus SvgImport::convert(const TQCString& from, const TQCString& to) -{ - // check for proper conversion - if( to != "application/x-karbon" || from != "image/svg+xml" ) - return KoFilter::NotImplemented; - - //Find the last extension - TQString strExt; - TQString fileIn ( m_chain->inputFile() ); - const int result=fileIn.findRev('.'); - if (result>=0) - strExt=fileIn.mid(result).lower(); - - TQString 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;*/ - - TQIODevice* 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; - TQString 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) - TQDomElement 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; - } - TQCString cstring = outdoc.toCString(); // utf-8 already - out->writeBlock( cstring.data(), cstring.length() ); - - return KoFilter::OK; // was successful -} - -void SvgImport::convert() -{ - SvgGraphicsContext *gc = new SvgGraphicsContext; - TQDomElement 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(TQString("%1\tUndo Y-mirroring.").arg(m_time.elapsed())); - if( !docElem.attribute( "viewBox" ).isEmpty() ) - { - // allow for viewbox def with ',' or whitespace - TQString viewbox( docElem.attribute( "viewBox" ) ); - TQStringList points = TQStringList::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 ); - - TQWMatrix 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( TQString s ) -{ - if( s.endsWith( "%" ) ) - return s.remove( '%' ).toDouble(); - else - return s.toDouble() * 100.0; -} - -double SvgImport::fromPercentage( TQString s ) -{ - if( s.endsWith( "%" ) ) - return s.remove( '%' ).toDouble() / 100.0; - else - return s.toDouble(); -} - -double SvgImport::getScalingFromMatrix( TQWMatrix &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 TQDomElement &e ) -{ - SvgGraphicsContext *gc = m_gc.current(); - - TQWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); - gc->matrix = mat * gc->matrix; -} - -VObject* SvgImport::findObject( const TQString &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 TQString &name ) -{ - TQPtrVector 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 TQString &id, const TQString &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; - - TQDomElement e = m_defs[ id ]; - if(e.childNodes().count() == 0) - { - TQString 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 - TQString n; - if(href.isEmpty()) - n = id; - else - n = href; - - if( m_gradients.contains( n ) ) - return &m_gradients[ n ]; - else - return 0L; -} - -TQDomElement SvgImport::mergeStyles( const TQDomElement &referencedBy, const TQDomElement &referencedElement ) -{ - // First use all the style attributes of the element being referenced. - TQDomElement 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 TQString &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; -} - -TQColor SvgImport::parseColor( const TQString &rgbColor ) -{ - int r, g, b; - keywordToRGB( rgbColor, r, g, b ); - return TQColor( r, g, b ); -} - -void SvgImport::parseColor( VColor &color, const TQString &s ) -{ - if( s.startsWith( "rgb(" ) ) - { - TQString parse = s.stripWhiteSpace(); - TQStringList colors = TQStringList::split( ',', parse ); - TQString r = colors[0].right( ( colors[0].length() - 4 ) ); - TQString g = colors[1]; - TQString b = colors[2].left( ( colors[2].length() - 1 ) ); - - if( r.contains( "%" ) ) - { - r = r.left( r.length() - 1 ); - r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); - } - - if( g.contains( "%" ) ) - { - g = g.left( g.length() - 1 ); - g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); - } - - if( b.contains( "%" ) ) - { - b = b.left( b.length() - 1 ); - b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); - } - - TQColor 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 - { - TQString rgbColor = s.stripWhiteSpace(); - TQColor 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 TQDomElement &e ) -{ - VColor c; - for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement stop = n.toElement(); - if( stop.tagName() == "stop" ) - { - float offset; - TQString 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 - TQString style = stop.attribute( "style" ).simplifyWhiteSpace(); - TQStringList substyles = TQStringList::split( ';', style ); - for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) - { - TQStringList substyle = TQStringList::split( ':', (*it) ); - TQString command = substyle[0].stripWhiteSpace(); - TQString 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 TQDomElement &e , const TQDomElement &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) - { - TQString 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. - TQDomElement b; - if( !referencedBy.isNull() ) - b = referencedBy; - else - b = e; - - TQString 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 - TQString style = b.attribute( "style" ).simplifyWhiteSpace(); - TQStringList substyles = TQStringList::split( ';', style ); - for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) - { - TQStringList substyle = TQStringList::split( ':', (*it) ); - TQString command = substyle[0].stripWhiteSpace(); - TQString 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 - TQString 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 TQString &command, const TQString ¶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(")"); - TQString 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( TQString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); - double offsety = parseUnit( TQString( "%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( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); - offsety = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); - gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); - } - offsetx = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); - offsety = parseUnit( TQString( "%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(")"); - TQString 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" ) - { - TQValueList array; - if(params != "none") - { - // with "stroke-dasharray", the separator is a white space - // inside style attribute, stroke-dasharray is separated by comma (,) - TQStringList dashes = TQStringList::split( TQRegExp("[\\s,]"), params ); - for( TQStringList::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" ) - { - TQString 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 = TQFont::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 = TQFont::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 TQDomElement &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 - TQString style = e.attribute( "style" ).simplifyWhiteSpace(); - TQStringList substyles = TQStringList::split( ';', style ); - for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) - { - TQStringList substyle = TQStringList::split( ':', (*it) ); - TQString command = substyle[0].stripWhiteSpace(); - TQString 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 TQDomElement &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 TQDomElement &e ) -{ - TQString id = e.attribute( "xlink:href" ); - - if( !id.isEmpty() ) - { - addGraphicContext(); - setupTransform( e ); - - TQString 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)) - { - TQDomElement 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 TQDomElement &e ) -{ - for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement 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 TQDomElement &e ) -{ - for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement b = n.toElement(); - if( b.isNull() ) continue; - - TQString 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 TQDomElement &b ) -{ - const double pathLength = 10.0; - - VText *text = 0L; - TQString content; - TQString 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( TQDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement e = n.toElement(); - if( e.isNull() ) - { - content += n.toCharacterData().data(); - } - else if( e.tagName() == "textPath" ) - { - if( e.attribute( "xlink:href" ).isEmpty() ) - continue; - - TQString 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 - { - TQDomElement p = m_defs[key]; - createObject( grp, p, VObject::deleted); - } - if( ! path ) - continue; - base = *path->paths().getFirst(); - content += e.text(); - - if( ! e.attribute( "startOffset" ).isEmpty() ) - { - TQString 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() ) - { - TQStringList posX = TQStringList::split( ", ", e.attribute( "x" ) ); - TQStringList posY = TQStringList::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; - - TQString 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 - { - TQDomElement 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 TQDomElement &b, const VObject::VState state, const TQDomElement &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; - - TQString points = b.attribute( "points" ).simplifyWhiteSpace(); - points.replace( ',', ' ' ); - points.remove( '\r' ); - points.remove( '\n' ); - TQStringList pointList = TQStringList::split( ' ', points ); - for( TQStringList::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" ) - { - TQString 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.cpp b/filters/karbon/svg/svgimport.cpp new file mode 100644 index 00000000..9d323d3d --- /dev/null +++ b/filters/karbon/svg/svgimport.cpp @@ -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 TQStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ + m_gc.setAutoDelete( true ); +} + +SvgImport::~SvgImport() +{ +} + +KoFilter::ConversionStatus SvgImport::convert(const TQCString& from, const TQCString& to) +{ + // check for proper conversion + if( to != "application/x-karbon" || from != "image/svg+xml" ) + return KoFilter::NotImplemented; + + //Find the last extension + TQString strExt; + TQString fileIn ( m_chain->inputFile() ); + const int result=fileIn.findRev('.'); + if (result>=0) + strExt=fileIn.mid(result).lower(); + + TQString 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;*/ + + TQIODevice* 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; + TQString 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) + TQDomElement 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; + } + TQCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void SvgImport::convert() +{ + SvgGraphicsContext *gc = new SvgGraphicsContext; + TQDomElement 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(TQString("%1\tUndo Y-mirroring.").arg(m_time.elapsed())); + if( !docElem.attribute( "viewBox" ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + TQString viewbox( docElem.attribute( "viewBox" ) ); + TQStringList points = TQStringList::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 ); + + TQWMatrix 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( TQString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble(); + else + return s.toDouble() * 100.0; +} + +double SvgImport::fromPercentage( TQString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble() / 100.0; + else + return s.toDouble(); +} + +double SvgImport::getScalingFromMatrix( TQWMatrix &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 TQDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + + TQWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); + gc->matrix = mat * gc->matrix; +} + +VObject* SvgImport::findObject( const TQString &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 TQString &name ) +{ + TQPtrVector 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 TQString &id, const TQString &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; + + TQDomElement e = m_defs[ id ]; + if(e.childNodes().count() == 0) + { + TQString 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 + TQString n; + if(href.isEmpty()) + n = id; + else + n = href; + + if( m_gradients.contains( n ) ) + return &m_gradients[ n ]; + else + return 0L; +} + +TQDomElement SvgImport::mergeStyles( const TQDomElement &referencedBy, const TQDomElement &referencedElement ) +{ + // First use all the style attributes of the element being referenced. + TQDomElement 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 TQString &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; +} + +TQColor SvgImport::parseColor( const TQString &rgbColor ) +{ + int r, g, b; + keywordToRGB( rgbColor, r, g, b ); + return TQColor( r, g, b ); +} + +void SvgImport::parseColor( VColor &color, const TQString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + TQString parse = s.stripWhiteSpace(); + TQStringList colors = TQStringList::split( ',', parse ); + TQString r = colors[0].right( ( colors[0].length() - 4 ) ); + TQString g = colors[1]; + TQString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + TQColor 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 + { + TQString rgbColor = s.stripWhiteSpace(); + TQColor 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 TQDomElement &e ) +{ + VColor c; + for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement stop = n.toElement(); + if( stop.tagName() == "stop" ) + { + float offset; + TQString 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 + TQString style = stop.attribute( "style" ).simplifyWhiteSpace(); + TQStringList substyles = TQStringList::split( ';', style ); + for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + TQStringList substyle = TQStringList::split( ':', (*it) ); + TQString command = substyle[0].stripWhiteSpace(); + TQString 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 TQDomElement &e , const TQDomElement &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) + { + TQString 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. + TQDomElement b; + if( !referencedBy.isNull() ) + b = referencedBy; + else + b = e; + + TQString 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 + TQString style = b.attribute( "style" ).simplifyWhiteSpace(); + TQStringList substyles = TQStringList::split( ';', style ); + for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + TQStringList substyle = TQStringList::split( ':', (*it) ); + TQString command = substyle[0].stripWhiteSpace(); + TQString 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 + TQString 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 TQString &command, const TQString ¶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(")"); + TQString 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( TQString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); + double offsety = parseUnit( TQString( "%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( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); + offsety = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); + gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + } + offsetx = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); + offsety = parseUnit( TQString( "%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(")"); + TQString 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" ) + { + TQValueList array; + if(params != "none") + { + // with "stroke-dasharray", the separator is a white space + // inside style attribute, stroke-dasharray is separated by comma (,) + TQStringList dashes = TQStringList::split( TQRegExp("[\\s,]"), params ); + for( TQStringList::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" ) + { + TQString 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 = TQFont::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 = TQFont::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 TQDomElement &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 + TQString style = e.attribute( "style" ).simplifyWhiteSpace(); + TQStringList substyles = TQStringList::split( ';', style ); + for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + TQStringList substyle = TQStringList::split( ':', (*it) ); + TQString command = substyle[0].stripWhiteSpace(); + TQString 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 TQDomElement &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 TQDomElement &e ) +{ + TQString id = e.attribute( "xlink:href" ); + + if( !id.isEmpty() ) + { + addGraphicContext(); + setupTransform( e ); + + TQString 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)) + { + TQDomElement 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 TQDomElement &e ) +{ + for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement 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 TQDomElement &e ) +{ + for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement b = n.toElement(); + if( b.isNull() ) continue; + + TQString 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 TQDomElement &b ) +{ + const double pathLength = 10.0; + + VText *text = 0L; + TQString content; + TQString 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( TQDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement e = n.toElement(); + if( e.isNull() ) + { + content += n.toCharacterData().data(); + } + else if( e.tagName() == "textPath" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + TQString 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 + { + TQDomElement p = m_defs[key]; + createObject( grp, p, VObject::deleted); + } + if( ! path ) + continue; + base = *path->paths().getFirst(); + content += e.text(); + + if( ! e.attribute( "startOffset" ).isEmpty() ) + { + TQString 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() ) + { + TQStringList posX = TQStringList::split( ", ", e.attribute( "x" ) ); + TQStringList posY = TQStringList::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; + + TQString 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 + { + TQDomElement 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 TQDomElement &b, const VObject::VState state, const TQDomElement &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; + + TQString points = b.attribute( "points" ).simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + TQStringList pointList = TQStringList::split( ' ', points ); + for( TQStringList::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" ) + { + TQString 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/wmf/Makefile.am b/filters/karbon/wmf/Makefile.am index 54bae415..976888ac 100644 --- a/filters/karbon/wmf/Makefile.am +++ b/filters/karbon/wmf/Makefile.am @@ -13,11 +13,11 @@ kde_module_LTLIBRARIES = libwmfimport.la libwmfexport.la libwmfimport_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -lkjs -ltdefx -ltdeio -ltdeparts libwmfimport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KOWMF) ../../../karbon/libkarboncommon.la -libwmfimport_la_SOURCES = wmfimport.cc wmfimportparser.cc +libwmfimport_la_SOURCES = wmfimport.cpp wmfimportparser.cpp libwmfexport_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -ltdecore -ltdeui $(LIB_TQT) -lkjs -ltdefx -ltdeio -ltdeparts libwmfexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KOWMF) ../../../karbon/libkarboncommon.la -libwmfexport_la_SOURCES = wmfexport.cc +libwmfexport_la_SOURCES = wmfexport.cpp noinst_HEADERS = wmfimport.h wmfimportparser.h wmfexport.h diff --git a/filters/karbon/wmf/wmfexport.cc b/filters/karbon/wmf/wmfexport.cc deleted file mode 100644 index de929ca8..00000000 --- a/filters/karbon/wmf/wmfexport.cc +++ /dev/null @@ -1,263 +0,0 @@ -/* 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 TQStringList&) : - KoFilter() -{ -} - -WmfExport::~WmfExport() -{ -} - -KoFilter::ConversionStatus WmfExport::convert( const TQCString& from, const TQCString& 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; - } - - TQDomDocument domIn; - domIn.setContent( storeIn ); - TQDomElement 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 ) { - TQPen pen; - TQBrush brush; - - getPen( pen, composite.stroke() ); - getBrush( brush, composite.fill() ); - - VVisitor::visitVPath( composite ); - - if ( mListPa.count() > 0 ) { - mWmf->setPen( pen ); - if( (brush.style() == TQt::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) ); - TQPointArray *pa = new TQPointArray( 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( TQBrush& 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( TQPen& 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.cpp b/filters/karbon/wmf/wmfexport.cpp new file mode 100644 index 00000000..de929ca8 --- /dev/null +++ b/filters/karbon/wmf/wmfexport.cpp @@ -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 TQStringList&) : + KoFilter() +{ +} + +WmfExport::~WmfExport() +{ +} + +KoFilter::ConversionStatus WmfExport::convert( const TQCString& from, const TQCString& 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; + } + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement 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 ) { + TQPen pen; + TQBrush brush; + + getPen( pen, composite.stroke() ); + getBrush( brush, composite.fill() ); + + VVisitor::visitVPath( composite ); + + if ( mListPa.count() > 0 ) { + mWmf->setPen( pen ); + if( (brush.style() == TQt::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) ); + TQPointArray *pa = new TQPointArray( 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( TQBrush& 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( TQPen& 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/wmfimport.cc b/filters/karbon/wmf/wmfimport.cc deleted file mode 100644 index f7dcdcf3..00000000 --- a/filters/karbon/wmf/wmfimport.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - 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 TQStringList&) : - KoFilter() -{ -} - -WMFImport::~WMFImport() -{ -} - -KoFilter::ConversionStatus WMFImport::convert( const TQCString& from, const TQCString& 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; - } - TQDomDocument outdoc = document.saveXML(); - TQCString content = outdoc.toCString(); - // kdDebug() << " content : " << content << endl; - out->writeBlock( content , content.length() ); - - return KoFilter::OK; -} - - -#include diff --git a/filters/karbon/wmf/wmfimport.cpp b/filters/karbon/wmf/wmfimport.cpp new file mode 100644 index 00000000..f7dcdcf3 --- /dev/null +++ b/filters/karbon/wmf/wmfimport.cpp @@ -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 TQStringList&) : + KoFilter() +{ +} + +WMFImport::~WMFImport() +{ +} + +KoFilter::ConversionStatus WMFImport::convert( const TQCString& from, const TQCString& 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; + } + TQDomDocument outdoc = document.saveXML(); + TQCString content = outdoc.toCString(); + // kdDebug() << " content : " << content << endl; + out->writeBlock( content , content.length() ); + + return KoFilter::OK; +} + + +#include diff --git a/filters/karbon/wmf/wmfimportparser.cc b/filters/karbon/wmf/wmfimportparser.cc deleted file mode 100644 index 275490fe..00000000 --- a/filters/karbon/wmf/wmfimportparser.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* 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() { - TQRect 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 TQFont & ) { -} - - -void WMFImportParser::setPen( const TQPen &pen ) { - mPen = pen; -} - - -const TQPen &WMFImportParser::pen() const { - return mPen; -} - - -void WMFImportParser::setBrush( const TQBrush &brush ) { - mBrush = brush; -} - - -void WMFImportParser::setBackgroundColor( const TQColor &c ) { - mBackgroundColor = c; -} - - -void WMFImportParser::setBackgroundMode( Qt::BGMode mode ) { - mBackgroundMode = mode; -} - - -void WMFImportParser::setRasterOp( TQt::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 TQWMatrix &, bool ) { -} - - -void WMFImportParser::setClipRegion( const TQRegion & ) { -} - - -TQRegion 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 TQPointArray &pa ) { - VPath *polyline = new VPath( mDoc ); - appendPen( *polyline ); - appendPoints( *polyline, pa ); - - mDoc->append( polyline ); -} - - -void WMFImportParser::drawPolygon( const TQPointArray &pa, bool ) { - VPath *polygon = new VPath( mDoc ); - appendPen( *polygon ); - appendBrush( *polygon ); - appendPoints( *polygon, pa ); - - polygon->close(); - mDoc->append( polygon ); -} - - -void WMFImportParser::drawPolyPolygon( TQPtrList& 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 TQImage &, int , int , int , int ) {} - - -void WMFImportParser::drawText( int , int , int , int , int , const TQString& , double ) {} - - -//----------------------------------------------------------------------------- -// Utilities - -void WMFImportParser::appendPen( VObject& obj ) -{ - VStroke stroke( mDoc ); - stroke.setLineCap( VStroke::capRound ); - - if ( mPen.style() == TQt::NoPen ) { - stroke.setType( VStroke::none ); - } - else { - TQValueList dashes; - stroke.setType( VStroke::solid ); - switch ( mPen.style() ) { - case TQt::DashLine : - stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(2) ); - break; - case TQt::DotLine : - stroke.dashPattern().setArray( dashes << MM_TO_POINT(1) << MM_TO_POINT(1) ); - break; - case TQt::DashDotLine : - stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) ); - break; - case TQt::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( TQColor(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( TQColor(mBrush.color()) ); - - switch ( mBrush.style() ) { - case TQt::NoBrush : - fill.setType( VFill::none ); - break; - case TQt::SolidPattern : - fill.setType( VFill::solid ); - break; - case TQt::CustomPattern : - // TODO: bitmap pattern brush - fill.setType( VFill::solid ); - //fill.pattern(). - break; - default : - // TODO: pattern brush - if ( mBackgroundMode == TQt::OpaqueMode ) { - fill.setColor( mBackgroundColor ); - fill.setType( VFill::solid ); - } - else { - fill.setType( VFill::none ); - } - break; - } - obj.setFill( fill ); -} - - -void WMFImportParser::appendPoints(VPath &path, const TQPointArray& 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.cpp b/filters/karbon/wmf/wmfimportparser.cpp new file mode 100644 index 00000000..275490fe --- /dev/null +++ b/filters/karbon/wmf/wmfimportparser.cpp @@ -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() { + TQRect 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 TQFont & ) { +} + + +void WMFImportParser::setPen( const TQPen &pen ) { + mPen = pen; +} + + +const TQPen &WMFImportParser::pen() const { + return mPen; +} + + +void WMFImportParser::setBrush( const TQBrush &brush ) { + mBrush = brush; +} + + +void WMFImportParser::setBackgroundColor( const TQColor &c ) { + mBackgroundColor = c; +} + + +void WMFImportParser::setBackgroundMode( Qt::BGMode mode ) { + mBackgroundMode = mode; +} + + +void WMFImportParser::setRasterOp( TQt::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 TQWMatrix &, bool ) { +} + + +void WMFImportParser::setClipRegion( const TQRegion & ) { +} + + +TQRegion 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 TQPointArray &pa ) { + VPath *polyline = new VPath( mDoc ); + appendPen( *polyline ); + appendPoints( *polyline, pa ); + + mDoc->append( polyline ); +} + + +void WMFImportParser::drawPolygon( const TQPointArray &pa, bool ) { + VPath *polygon = new VPath( mDoc ); + appendPen( *polygon ); + appendBrush( *polygon ); + appendPoints( *polygon, pa ); + + polygon->close(); + mDoc->append( polygon ); +} + + +void WMFImportParser::drawPolyPolygon( TQPtrList& 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 TQImage &, int , int , int , int ) {} + + +void WMFImportParser::drawText( int , int , int , int , int , const TQString& , double ) {} + + +//----------------------------------------------------------------------------- +// Utilities + +void WMFImportParser::appendPen( VObject& obj ) +{ + VStroke stroke( mDoc ); + stroke.setLineCap( VStroke::capRound ); + + if ( mPen.style() == TQt::NoPen ) { + stroke.setType( VStroke::none ); + } + else { + TQValueList dashes; + stroke.setType( VStroke::solid ); + switch ( mPen.style() ) { + case TQt::DashLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(2) ); + break; + case TQt::DotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + case TQt::DashDotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + case TQt::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( TQColor(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( TQColor(mBrush.color()) ); + + switch ( mBrush.style() ) { + case TQt::NoBrush : + fill.setType( VFill::none ); + break; + case TQt::SolidPattern : + fill.setType( VFill::solid ); + break; + case TQt::CustomPattern : + // TODO: bitmap pattern brush + fill.setType( VFill::solid ); + //fill.pattern(). + break; + default : + // TODO: pattern brush + if ( mBackgroundMode == TQt::OpaqueMode ) { + fill.setColor( mBackgroundColor ); + fill.setType( VFill::solid ); + } + else { + fill.setType( VFill::none ); + } + break; + } + obj.setFill( fill ); +} + + +void WMFImportParser::appendPoints(VPath &path, const TQPointArray& 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/xaml/Makefile.am b/filters/karbon/xaml/Makefile.am index f7036ada..9bf1e068 100644 --- a/filters/karbon/xaml/Makefile.am +++ b/filters/karbon/xaml/Makefile.am @@ -26,10 +26,10 @@ noinst_HEADERS = \ xamlimport.h libkarbonxamlexport_la_SOURCES = \ - xamlexport.cc + xamlexport.cpp libkarbonxamlimport_la_SOURCES = \ - xamlimport.cc + xamlimport.cpp METASOURCES = AUTO diff --git a/filters/karbon/xaml/xamlexport.cc b/filters/karbon/xaml/xamlexport.cc deleted file mode 100644 index e1599a8c..00000000 --- a/filters/karbon/xaml/xamlexport.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* 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 TQStringList& ) - : KoFilter() -{ - m_gc.setAutoDelete( true ); -} - -KoFilter::ConversionStatus -XAMLExport::convert( const TQCString& from, const TQCString& 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; - - TQFile fileOut( m_chain->outputFile() ); - if( !fileOut.open( IO_WriteOnly ) ) - { - delete storeIn; - return KoFilter::StupidError; - } - - TQDomDocument domIn; - domIn.setContent( storeIn ); - TQDomElement docNode = domIn.documentElement(); - - m_stream = new TQTextStream( &fileOut ); - TQString body; - m_body = new TQTextStream( &body, IO_ReadWrite ); - TQString defs; - m_defs = new TQTextStream( &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; -} - -TQString -XAMLExport::getID( VObject *obj ) -{ - if( obj && !obj->name().isEmpty() ) - return TQString( " Name=\"%1\"" ).arg( obj->name() ); - return TQString(); -} - -// 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& ) -{ -} - -TQString createUID() -{ - static unsigned int nr = 0; - - return "defitem" + TQString().setNum( nr++ ); -} - -void -XAMLExport::getColorStops( const TQPtrVector &colorStops ) -{ - for( unsigned int i = 0; i < colorStops.count() ; i++ ) - { - *m_defs << "color ); - *m_defs << "\" Offset=\"" << TQString().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 ) -{ - TQString 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=\" "; - - TQValueListConstIterator itr; - for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) - { - *m_body << *itr << " "; - } - *m_body << "\""; - } -} - -void -XAMLExport::getHexColor( TQTextStream *stream, const VColor& color ) -{ - // Convert the various color-spaces to hex - - TQString 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.cpp b/filters/karbon/xaml/xamlexport.cpp new file mode 100644 index 00000000..e1599a8c --- /dev/null +++ b/filters/karbon/xaml/xamlexport.cpp @@ -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 TQStringList& ) + : KoFilter() +{ + m_gc.setAutoDelete( true ); +} + +KoFilter::ConversionStatus +XAMLExport::convert( const TQCString& from, const TQCString& 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; + + TQFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + delete storeIn; + return KoFilter::StupidError; + } + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement docNode = domIn.documentElement(); + + m_stream = new TQTextStream( &fileOut ); + TQString body; + m_body = new TQTextStream( &body, IO_ReadWrite ); + TQString defs; + m_defs = new TQTextStream( &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; +} + +TQString +XAMLExport::getID( VObject *obj ) +{ + if( obj && !obj->name().isEmpty() ) + return TQString( " Name=\"%1\"" ).arg( obj->name() ); + return TQString(); +} + +// 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& ) +{ +} + +TQString createUID() +{ + static unsigned int nr = 0; + + return "defitem" + TQString().setNum( nr++ ); +} + +void +XAMLExport::getColorStops( const TQPtrVector &colorStops ) +{ + for( unsigned int i = 0; i < colorStops.count() ; i++ ) + { + *m_defs << "color ); + *m_defs << "\" Offset=\"" << TQString().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 ) +{ + TQString 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=\" "; + + TQValueListConstIterator itr; + for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) + { + *m_body << *itr << " "; + } + *m_body << "\""; + } +} + +void +XAMLExport::getHexColor( TQTextStream *stream, const VColor& color ) +{ + // Convert the various color-spaces to hex + + TQString 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/xamlimport.cc b/filters/karbon/xaml/xamlimport.cc deleted file mode 100644 index 002001e2..00000000 --- a/filters/karbon/xaml/xamlimport.cc +++ /dev/null @@ -1,1042 +0,0 @@ -/* 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 TQStringList&) : - KoFilter(), - outdoc( "DOC" ) -{ - m_gc.setAutoDelete( true ); -} - -XAMLImport::~XAMLImport() -{ -} - -KoFilter::ConversionStatus XAMLImport::convert(const TQCString& from, const TQCString& to) -{ - // check for proper conversion - if( to != "application/x-karbon" || from != "image/wvg+xml" ) - return KoFilter::NotImplemented; - - //Find the last extension - TQString strExt; - TQString fileIn ( m_chain->inputFile() ); - const int result=fileIn.findRev('.'); - if (result>=0) - { - strExt=fileIn.mid(result).lower(); - } - - TQString 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; - - TQIODevice* 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; - TQString 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; - } - TQCString cstring = outdoc.toCString(); // utf-8 already - out->writeBlock( cstring.data(), cstring.length() ); - - return KoFilter::OK; // was successful -} - -void -XAMLImport::convert() -{ - XAMLGraphicsContext *gc = new XAMLGraphicsContext; - TQDomElement 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 - TQString viewbox( docElem.attribute( "viewBox" ) ); - TQStringList points = TQStringList::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 ); - - TQWMatrix 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( TQString s ) -{ - if( s.endsWith( "%" ) ) - return s.remove( '%' ).toDouble(); - else - return s.toDouble() * 100.0; -} - -double -XAMLImport::fromPercentage( TQString 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 TQString &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; -} - -TQColor -XAMLImport::parseColor( const TQString &rgbColor ) -{ - int r, g, b; - keywordToRGB( rgbColor, r, g, b ); - return TQColor( r, g, b ); -} - -void -XAMLImport::parseColor( VColor &color, const TQString &s ) -{ - if( s.startsWith( "rgb(" ) ) - { - TQString parse = s.stripWhiteSpace(); - TQStringList colors = TQStringList::split( ',', parse ); - TQString r = colors[0].right( ( colors[0].length() - 4 ) ); - TQString g = colors[1]; - TQString b = colors[2].left( ( colors[2].length() - 1 ) ); - - if( r.contains( "%" ) ) - { - r = r.left( r.length() - 1 ); - r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); - } - - if( g.contains( "%" ) ) - { - g = g.left( g.length() - 1 ); - g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); - } - - if( b.contains( "%" ) ) - { - b = b.left( b.length() - 1 ); - b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); - } - - TQColor c( r.toInt(), g.toInt(), b.toInt() ); - color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); - } - else - { - TQString rgbColor = s.stripWhiteSpace(); - TQColor 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 TQDomElement &e ) -{ - VColor c; - for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement stop = n.toElement(); - if( stop.tagName() == "stop" ) - { - float offset; - TQString 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 - TQString style = stop.attribute( "style" ).simplifyWhiteSpace(); - TQStringList substyles = TQStringList::split( ';', style ); - for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) - { - TQStringList substyle = TQStringList::split( ':', (*it) ); - TQString command = substyle[0].stripWhiteSpace(); - TQString 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 TQDomElement &e ) -{ - GradientHelper gradhelper; - gradhelper.gradient.clearStops(); - gradhelper.gradient.setRepeatMethod( VGradient::none ); - - TQString 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 - TQString 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 TQString &command, const TQString ¶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(")"); - TQString 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( TQString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); - double offsety = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox ); - gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); - offsetx = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); - offsety = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); - gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); - offsetx = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); - offsety = parseUnit( TQString( "%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(")"); - TQString 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" ) - { - TQValueList array; - if(params != "none") - { - TQStringList dashes = TQStringList::split( ' ', params ); - for( TQStringList::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" ) - { - TQString 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 TQDomElement &e ) -{ - XAMLGraphicsContext *gc = m_gc.current(); - - TQWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); - gc->matrix = mat * gc->matrix; -} - -void -XAMLImport::parseStyle( VObject *obj, const TQDomElement &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 - TQString style = e.attribute( "style" ).simplifyWhiteSpace(); - TQStringList substyles = TQStringList::split( ';', style ); - for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) - { - TQStringList substyle = TQStringList::split( ':', (*it) ); - TQString command = substyle[0].stripWhiteSpace(); - TQString 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 TQDomElement &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 TQDomElement &e ) -{ - bool isDef = false; - if( e.tagName() == "defs" ) - isDef = true; - - for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement 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() ) - { - TQString params = b.attribute( "xlink:href" ); - unsigned int start = params.find("#") + 1; - unsigned int end = params.findRev(")"); - TQString key = params.mid( start, end - start ); - if(m_paths.contains(key)) - { - TQDomElement 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 TQString &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 TQString &name ) -{ - TQPtrVector 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 TQDomElement &b ) -{ - VText *text = 0L; - TQString 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( TQDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) - { - TQDomElement e = n.toElement(); - if( e.isNull() ) - { - content += n.toCharacterData().data(); - } - else if( e.tagName() == "textPath" ) - { - if( e.attribute( "xlink:href" ).isEmpty() ) - continue; - - TQString uri = e.attribute( "xlink:href" ); - unsigned int start = uri.find("#") + 1; - unsigned int end = uri.findRev(")"); - TQString key = uri.mid( start, end - start ); - if( ! m_paths.contains(key) ) - { - VObject* obj = findObject( key ); - if( obj ) - path = dynamic_cast( obj ); - } - else - { - TQDomElement 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() ) - { - TQStringList posX = TQStringList::split( ", ", e.attribute( "x" ) ); - TQStringList posY = TQStringList::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; - - TQString uri = e.attribute( "xlink:href" ); - unsigned int start = uri.find("#") + 1; - unsigned int end = uri.findRev(")"); - TQString key = uri.mid( start, end - start ); - - if( ! m_paths.contains(key) ) - { - VObject* obj = findObject( key ); - if( obj ) - content += dynamic_cast( obj )->text(); - } - else - { - TQDomElement 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 TQDomElement &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; - - TQString points = b.attribute( "points" ).simplifyWhiteSpace(); - points.replace( ',', ' ' ); - points.remove( '\r' ); - points.remove( '\n' ); - TQStringList pointList = TQStringList::split( ' ', points ); - for( TQStringList::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 ); - TQString fname = b.attribute("xlink:href"); - return new VImage( 0L, fname ); - } - - return 0L; -} - -#include diff --git a/filters/karbon/xaml/xamlimport.cpp b/filters/karbon/xaml/xamlimport.cpp new file mode 100644 index 00000000..002001e2 --- /dev/null +++ b/filters/karbon/xaml/xamlimport.cpp @@ -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 TQStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ + m_gc.setAutoDelete( true ); +} + +XAMLImport::~XAMLImport() +{ +} + +KoFilter::ConversionStatus XAMLImport::convert(const TQCString& from, const TQCString& to) +{ + // check for proper conversion + if( to != "application/x-karbon" || from != "image/wvg+xml" ) + return KoFilter::NotImplemented; + + //Find the last extension + TQString strExt; + TQString fileIn ( m_chain->inputFile() ); + const int result=fileIn.findRev('.'); + if (result>=0) + { + strExt=fileIn.mid(result).lower(); + } + + TQString 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; + + TQIODevice* 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; + TQString 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; + } + TQCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void +XAMLImport::convert() +{ + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + TQDomElement 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 + TQString viewbox( docElem.attribute( "viewBox" ) ); + TQStringList points = TQStringList::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 ); + + TQWMatrix 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( TQString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble(); + else + return s.toDouble() * 100.0; +} + +double +XAMLImport::fromPercentage( TQString 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 TQString &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; +} + +TQColor +XAMLImport::parseColor( const TQString &rgbColor ) +{ + int r, g, b; + keywordToRGB( rgbColor, r, g, b ); + return TQColor( r, g, b ); +} + +void +XAMLImport::parseColor( VColor &color, const TQString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + TQString parse = s.stripWhiteSpace(); + TQStringList colors = TQStringList::split( ',', parse ); + TQString r = colors[0].right( ( colors[0].length() - 4 ) ); + TQString g = colors[1]; + TQString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + TQColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else + { + TQString rgbColor = s.stripWhiteSpace(); + TQColor 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 TQDomElement &e ) +{ + VColor c; + for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement stop = n.toElement(); + if( stop.tagName() == "stop" ) + { + float offset; + TQString 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 + TQString style = stop.attribute( "style" ).simplifyWhiteSpace(); + TQStringList substyles = TQStringList::split( ';', style ); + for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + TQStringList substyle = TQStringList::split( ':', (*it) ); + TQString command = substyle[0].stripWhiteSpace(); + TQString 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 TQDomElement &e ) +{ + GradientHelper gradhelper; + gradhelper.gradient.clearStops(); + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + TQString 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 + TQString 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 TQString &command, const TQString ¶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(")"); + TQString 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( TQString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); + double offsety = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox ); + gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + offsetx = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); + offsety = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); + gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + offsetx = parseUnit( TQString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); + offsety = parseUnit( TQString( "%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(")"); + TQString 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" ) + { + TQValueList array; + if(params != "none") + { + TQStringList dashes = TQStringList::split( ' ', params ); + for( TQStringList::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" ) + { + TQString 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 TQDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + + TQWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); + gc->matrix = mat * gc->matrix; +} + +void +XAMLImport::parseStyle( VObject *obj, const TQDomElement &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 + TQString style = e.attribute( "style" ).simplifyWhiteSpace(); + TQStringList substyles = TQStringList::split( ';', style ); + for( TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + TQStringList substyle = TQStringList::split( ':', (*it) ); + TQString command = substyle[0].stripWhiteSpace(); + TQString 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 TQDomElement &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 TQDomElement &e ) +{ + bool isDef = false; + if( e.tagName() == "defs" ) + isDef = true; + + for( TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement 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() ) + { + TQString params = b.attribute( "xlink:href" ); + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + TQString key = params.mid( start, end - start ); + if(m_paths.contains(key)) + { + TQDomElement 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 TQString &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 TQString &name ) +{ + TQPtrVector 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 TQDomElement &b ) +{ + VText *text = 0L; + TQString 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( TQDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + TQDomElement e = n.toElement(); + if( e.isNull() ) + { + content += n.toCharacterData().data(); + } + else if( e.tagName() == "textPath" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + TQString uri = e.attribute( "xlink:href" ); + unsigned int start = uri.find("#") + 1; + unsigned int end = uri.findRev(")"); + TQString key = uri.mid( start, end - start ); + if( ! m_paths.contains(key) ) + { + VObject* obj = findObject( key ); + if( obj ) + path = dynamic_cast( obj ); + } + else + { + TQDomElement 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() ) + { + TQStringList posX = TQStringList::split( ", ", e.attribute( "x" ) ); + TQStringList posY = TQStringList::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; + + TQString uri = e.attribute( "xlink:href" ); + unsigned int start = uri.find("#") + 1; + unsigned int end = uri.findRev(")"); + TQString key = uri.mid( start, end - start ); + + if( ! m_paths.contains(key) ) + { + VObject* obj = findObject( key ); + if( obj ) + content += dynamic_cast( obj )->text(); + } + else + { + TQDomElement 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 TQDomElement &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; + + TQString points = b.attribute( "points" ).simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + TQStringList pointList = TQStringList::split( ' ', points ); + for( TQStringList::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 ); + TQString fname = b.attribute("xlink:href"); + return new VImage( 0L, fname ); + } + + return 0L; +} + +#include diff --git a/filters/karbon/xcf/Makefile.am b/filters/karbon/xcf/Makefile.am index f3a1b3ac..bc16ca76 100644 --- a/filters/karbon/xcf/Makefile.am +++ b/filters/karbon/xcf/Makefile.am @@ -20,7 +20,7 @@ noinst_HEADERS = \ xcfexport.h libkarbonxcfexport_la_SOURCES = \ - xcfexport.cc + xcfexport.cpp libkarbonxcfexport_la_METASOURCES = \ AUTO diff --git a/filters/karbon/xcf/xcfexport.cc b/filters/karbon/xcf/xcfexport.cc deleted file mode 100644 index 215c4f01..00000000 --- a/filters/karbon/xcf/xcfexport.cc +++ /dev/null @@ -1,458 +0,0 @@ -/* 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 TQStringList& ) - : KoFilter() -{ - m_zoomX = 1.0; - m_zoomY = 1.0; -} - -KoFilter::ConversionStatus -XcfExport::convert( const TQCString& from, const TQCString& 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; - - - TQFile fileOut( m_chain->outputFile() ); - - if( !fileOut.open( IO_WriteOnly ) ) - return KoFilter::StupidError; - - - TQDomDocument domIn; - domIn.setContent( storeIn ); - TQDomElement docNode = domIn.documentElement(); - - m_stream = new TQDataStream( &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. - TQIODevice::Offset current = 0; - TQIODevice::Offset start = 0; - TQIODevice::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. - TQIODevice::Offset current = 0; - TQIODevice::Offset start = 0; - TQIODevice::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. - TQIODevice::Offset current = 0; - TQIODevice::Offset start = 0; - TQIODevice::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 = TQMAX( 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. - TQIODevice::Offset current = 0; - TQIODevice::Offset start = 0; - TQIODevice::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.cpp b/filters/karbon/xcf/xcfexport.cpp new file mode 100644 index 00000000..215c4f01 --- /dev/null +++ b/filters/karbon/xcf/xcfexport.cpp @@ -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 TQStringList& ) + : KoFilter() +{ + m_zoomX = 1.0; + m_zoomY = 1.0; +} + +KoFilter::ConversionStatus +XcfExport::convert( const TQCString& from, const TQCString& 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; + + + TQFile fileOut( m_chain->outputFile() ); + + if( !fileOut.open( IO_WriteOnly ) ) + return KoFilter::StupidError; + + + TQDomDocument domIn; + domIn.setContent( storeIn ); + TQDomElement docNode = domIn.documentElement(); + + m_stream = new TQDataStream( &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. + TQIODevice::Offset current = 0; + TQIODevice::Offset start = 0; + TQIODevice::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. + TQIODevice::Offset current = 0; + TQIODevice::Offset start = 0; + TQIODevice::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. + TQIODevice::Offset current = 0; + TQIODevice::Offset start = 0; + TQIODevice::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 = TQMAX( 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. + TQIODevice::Offset current = 0; + TQIODevice::Offset start = 0; + TQIODevice::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/xfig/xfigimport.cc b/filters/karbon/xfig/xfigimport.cc deleted file mode 100644 index c3d6ab6a..00000000 --- a/filters/karbon/xfig/xfigimport.cc +++ /dev/null @@ -1,760 +0,0 @@ -/* - 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; - TQFont::Weight weight; - bool italic; -} psFontTable[] = { - { "times", TQFont::Normal, false }, // Times Roman - { "times", TQFont::Normal, true }, // Times Italic - { "times", TQFont::Bold, false }, // Times Bold - { "times", TQFont::Bold, true }, // Times Bold Italic - { "avantgarde", TQFont::Normal, false }, // AvantGarde Book - { "avantgarde", TQFont::Normal, true }, // AvantGarde Book Oblique - { "avantgarde", TQFont::DemiBold, false }, // AvantGarde Demi - { "avantgarde", TQFont::DemiBold, true }, // AvantGarde Demi Oblique - { "bookman", TQFont::Light, false }, // Bookman Light - { "bookman", TQFont::Light, true }, // Bookman Light Italic - { "bookman", TQFont::DemiBold, false }, // Bookman Demi - { "bookman", TQFont::DemiBold, true }, // Bookman Demi Italic - { "courier", TQFont::Normal, false }, // Courier - { "courier", TQFont::Normal, true }, // Courier Oblique - { "courier", TQFont::Bold, false }, // Courier Bold - { "courier", TQFont::Bold, true }, // Courier Bold Oblique - { "helvetica", TQFont::Normal, false }, // Helvetica - { "helvetica", TQFont::Normal, true }, // Helvetica Oblique - { "helvetica", TQFont::Bold, false }, // Helvetica Bold - { "helvetica", TQFont::Bold, true }, // Helvetica Bold Oblique - { "helvetica", TQFont::Normal, false }, // Helvetica Narrow - { "helvetica", TQFont::Normal, true }, // Helvetica Narrow Oblique - { "helvetica", TQFont::Bold, false }, // Helvetica Narrow Bold - { "helvetica", TQFont::Bold, true }, // Helvetica Narrow Bold Oblique - { "newcenturyschoolbook", TQFont::Normal, false },// New Century Schoolbook - { "newcenturyschoolbook", TQFont::Normal, true }, // New Century Italic - { "newcenturyschoolbook", TQFont::Bold, false }, // New Century Bold - { "newcenturyschoolbook", TQFont::Bold, true }, // New Century Bold Italic - { "palatino", TQFont::Normal, false }, // Palatino Roman - { "palatino", TQFont::Normal, true }, // Palatino Italic - { "palatino", TQFont::Bold, false }, // Palatino Bold - { "palatino", TQFont::Bold, true }, // Palatino Bold Italic - { "symbol", TQFont::Normal, false }, // Symbol - { "zapfchancery", TQFont::Normal, false }, // Zapf Chancery Medium Italic - { "zapfdingbats", TQFont::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 TQColor (TQt::black)); - colorTable.insert (1, new TQColor (TQt::blue)); - colorTable.insert (2, new TQColor (TQt::green)); - colorTable.insert (3, new TQColor (TQt::cyan)); - colorTable.insert (4, new TQColor (TQt::red)); - colorTable.insert (5, new TQColor (TQt::magenta)); - colorTable.insert (6, new TQColor (TQt::yellow)); - colorTable.insert (7, new TQColor (TQt::white)); - - for (int i = 0; i <= 23; i++) - colorTable.insert (i + 8, new TQColor (colors[i])); - - objList.clear (); -} - -XFIGImport::~XFIGImport() -{ -} - -bool XFIGImport::filterImport( const TQString &file, KoDocument *doc, - const TQString &from, const TQString &to, - const TQString & ) { - - 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 TQColor (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; - TQString text; - TQFont 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 = TQFont (psFontTable[font].family, tqRound (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 (tqRound (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; - TQWMatrix 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 - TQValueList::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 (TQt::SolidLine); - else if (style == 1) - obj->setOutlineStyle (TQt::DashLine); - else if (style == 2) - obj->setOutlineStyle (TQt::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 = tqRound ((20 - area_fill) * 255.0 / 20.0); - obj->setFillColor (TQColor (val, val, val)); - } - else if (fill_color == 7) { - // for WHITE color - int val = tqRound ( area_fill * 255.0 / 20.0); - obj->setFillColor (TQColor (val, val, val)); - } - else - obj->setFillColor (*colorTable[fill_color]); - } -} - diff --git a/filters/karbon/xfig/xfigimport.cpp b/filters/karbon/xfig/xfigimport.cpp new file mode 100644 index 00000000..c3d6ab6a --- /dev/null +++ b/filters/karbon/xfig/xfigimport.cpp @@ -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; + TQFont::Weight weight; + bool italic; +} psFontTable[] = { + { "times", TQFont::Normal, false }, // Times Roman + { "times", TQFont::Normal, true }, // Times Italic + { "times", TQFont::Bold, false }, // Times Bold + { "times", TQFont::Bold, true }, // Times Bold Italic + { "avantgarde", TQFont::Normal, false }, // AvantGarde Book + { "avantgarde", TQFont::Normal, true }, // AvantGarde Book Oblique + { "avantgarde", TQFont::DemiBold, false }, // AvantGarde Demi + { "avantgarde", TQFont::DemiBold, true }, // AvantGarde Demi Oblique + { "bookman", TQFont::Light, false }, // Bookman Light + { "bookman", TQFont::Light, true }, // Bookman Light Italic + { "bookman", TQFont::DemiBold, false }, // Bookman Demi + { "bookman", TQFont::DemiBold, true }, // Bookman Demi Italic + { "courier", TQFont::Normal, false }, // Courier + { "courier", TQFont::Normal, true }, // Courier Oblique + { "courier", TQFont::Bold, false }, // Courier Bold + { "courier", TQFont::Bold, true }, // Courier Bold Oblique + { "helvetica", TQFont::Normal, false }, // Helvetica + { "helvetica", TQFont::Normal, true }, // Helvetica Oblique + { "helvetica", TQFont::Bold, false }, // Helvetica Bold + { "helvetica", TQFont::Bold, true }, // Helvetica Bold Oblique + { "helvetica", TQFont::Normal, false }, // Helvetica Narrow + { "helvetica", TQFont::Normal, true }, // Helvetica Narrow Oblique + { "helvetica", TQFont::Bold, false }, // Helvetica Narrow Bold + { "helvetica", TQFont::Bold, true }, // Helvetica Narrow Bold Oblique + { "newcenturyschoolbook", TQFont::Normal, false },// New Century Schoolbook + { "newcenturyschoolbook", TQFont::Normal, true }, // New Century Italic + { "newcenturyschoolbook", TQFont::Bold, false }, // New Century Bold + { "newcenturyschoolbook", TQFont::Bold, true }, // New Century Bold Italic + { "palatino", TQFont::Normal, false }, // Palatino Roman + { "palatino", TQFont::Normal, true }, // Palatino Italic + { "palatino", TQFont::Bold, false }, // Palatino Bold + { "palatino", TQFont::Bold, true }, // Palatino Bold Italic + { "symbol", TQFont::Normal, false }, // Symbol + { "zapfchancery", TQFont::Normal, false }, // Zapf Chancery Medium Italic + { "zapfdingbats", TQFont::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 TQColor (TQt::black)); + colorTable.insert (1, new TQColor (TQt::blue)); + colorTable.insert (2, new TQColor (TQt::green)); + colorTable.insert (3, new TQColor (TQt::cyan)); + colorTable.insert (4, new TQColor (TQt::red)); + colorTable.insert (5, new TQColor (TQt::magenta)); + colorTable.insert (6, new TQColor (TQt::yellow)); + colorTable.insert (7, new TQColor (TQt::white)); + + for (int i = 0; i <= 23; i++) + colorTable.insert (i + 8, new TQColor (colors[i])); + + objList.clear (); +} + +XFIGImport::~XFIGImport() +{ +} + +bool XFIGImport::filterImport( const TQString &file, KoDocument *doc, + const TQString &from, const TQString &to, + const TQString & ) { + + 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 TQColor (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; + TQString text; + TQFont 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 = TQFont (psFontTable[font].family, tqRound (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 (tqRound (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; + TQWMatrix 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 + TQValueList::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 (TQt::SolidLine); + else if (style == 1) + obj->setOutlineStyle (TQt::DashLine); + else if (style == 2) + obj->setOutlineStyle (TQt::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 = tqRound ((20 - area_fill) * 255.0 / 20.0); + obj->setFillColor (TQColor (val, val, val)); + } + else if (fill_color == 7) { + // for WHITE color + int val = tqRound ( area_fill * 255.0 / 20.0); + obj->setFillColor (TQColor (val, val, val)); + } + else + obj->setFillColor (*colorTable[fill_color]); + } +} + diff --git a/filters/karbon/xfig/xfigimport_factory.cc b/filters/karbon/xfig/xfigimport_factory.cc deleted file mode 100644 index 1e231199..00000000 --- a/filters/karbon/xfig/xfigimport_factory.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - 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 ) - -TDEInstance *XFIGImportFactory::s_global = 0; - -XFIGImportFactory::XFIGImportFactory( - TQObject *parent, - const char *name) : - KLibFactory(parent, name) -{ - s_global = new TDEInstance("xfigimport"); -} - -XFIGImportFactory::~XFIGImportFactory() -{ - delete s_global; - s_global = 0L; -} - -TQObject *XFIGImportFactory::createObject( - TQObject *parent, - const char *name, - const char*, - const TQStringList &) -{ - 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; -} - -TDEInstance *XFIGImportFactory::global() -{ - return s_global; -} diff --git a/filters/karbon/xfig/xfigimport_factory.cpp b/filters/karbon/xfig/xfigimport_factory.cpp new file mode 100644 index 00000000..1e231199 --- /dev/null +++ b/filters/karbon/xfig/xfigimport_factory.cpp @@ -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 ) + +TDEInstance *XFIGImportFactory::s_global = 0; + +XFIGImportFactory::XFIGImportFactory( + TQObject *parent, + const char *name) : + KLibFactory(parent, name) +{ + s_global = new TDEInstance("xfigimport"); +} + +XFIGImportFactory::~XFIGImportFactory() +{ + delete s_global; + s_global = 0L; +} + +TQObject *XFIGImportFactory::createObject( + TQObject *parent, + const char *name, + const char*, + const TQStringList &) +{ + 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; +} + +TDEInstance *XFIGImportFactory::global() +{ + return s_global; +} -- cgit v1.2.1