summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--writerfilter/Library_rtftok.mk1
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx334
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx29
-rw-r--r--writerfilter/source/rtftok/rtfsdrimport.cxx330
-rw-r--r--writerfilter/source/rtftok/rtfsdrimport.hxx55
5 files changed, 451 insertions, 298 deletions
diff --git a/writerfilter/Library_rtftok.mk b/writerfilter/Library_rtftok.mk
index b4345454a163..472ed9303168 100644
--- a/writerfilter/Library_rtftok.mk
+++ b/writerfilter/Library_rtftok.mk
@@ -62,6 +62,7 @@ $(eval $(call gb_Library_add_linked_libs,rtftok,\
$(eval $(call gb_Library_add_exception_objects,rtftok,\
writerfilter/source/rtftok/rtfdocumentfactory \
writerfilter/source/rtftok/rtfdocumentimpl \
+ writerfilter/source/rtftok/rtfsdrimport \
writerfilter/source/rtftok/rtfcontrolwords \
writerfilter/source/rtftok/rtfcharsets \
writerfilter/source/rtftok/rtfreferenceproperties \
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 8fdabc5e4146..ccb6766e33ee 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -26,6 +26,7 @@
*/
#include <rtfdocumentimpl.hxx>
+#include <rtfsdrimport.hxx>
#include <rtftypes.hxx>
#include <rtfcontrolwords.hxx>
#include <rtfvalue.hxx>
@@ -153,19 +154,6 @@ static void lcl_putBorderProperty(std::stack<RTFParserState>& aStates, Id nId, R
}
}
-static void lcl_Break(Stream& rMapper)
-{
- sal_uInt8 sBreak[] = { 0xd };
- rMapper.text(sBreak, 1);
-}
-
-static void lcl_TableBreak(Stream& rMapper)
-{
- lcl_Break(rMapper);
- rMapper.endParagraphGroup();
- rMapper.startParagraphGroup();
-}
-
// NEEDSWORK: DocxAttributeOutput's impl_AppendTwoDigits does the same.
static void lcl_AppendTwoDigits(OStringBuffer &rBuffer, sal_Int32 nNum)
{
@@ -263,18 +251,6 @@ static const char* lcl_RtfToString(RTFKeyword nKeyword)
return NULL;
}
-// NEEDSWORK: wwUtility::BGRToRGB does the same.
-sal_uInt32 lcl_BGRToRGB(sal_uInt32 nColor)
-{
- sal_uInt8
- r(static_cast<sal_uInt8>(nColor&0xFF)),
- g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
- b(static_cast<sal_uInt8>((nColor>>16)&0xFF)),
- t(static_cast<sal_uInt8>((nColor>>24)&0xFF));
- nColor = (t<<24) + (r<<16) + (g<<8) + b;
- return nColor;
-}
-
RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& xContext,
uno::Reference<io::XInputStream> const& xInputStream,
uno::Reference<lang::XComponent> const& xDstDoc,
@@ -316,10 +292,13 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
OSL_ASSERT(xDrawings.is());
m_xDrawPage.set(xDrawings->getDrawPage(), uno::UNO_QUERY);
OSL_ASSERT(m_xDrawPage.is());
+
+ m_pSdrImport = new RTFSdrImport(*this);
}
RTFDocumentImpl::~RTFDocumentImpl()
{
+ delete m_pSdrImport;
}
SvStream& RTFDocumentImpl::Strm()
@@ -385,12 +364,25 @@ void RTFDocumentImpl::checkFirstRun()
}
}
+void RTFDocumentImpl::runBreak()
+{
+ sal_uInt8 sBreak[] = { 0xd };
+ Mapper().text(sBreak, 1);
+}
+
+void RTFDocumentImpl::tableBreak()
+{
+ runBreak();
+ Mapper().endParagraphGroup();
+ Mapper().startParagraphGroup();
+}
+
void RTFDocumentImpl::parBreak()
{
checkFirstRun();
// end previous paragraph
Mapper().startCharacterGroup();
- lcl_Break(Mapper());
+ runBreak();
Mapper().endCharacterGroup();
Mapper().endParagraphGroup();
@@ -746,7 +738,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
new RTFReferenceProperties(m_aStates.top().aTableCellAttributes, m_aStates.top().aTableCellSprms)
);
Mapper().props(pTableCellProperties);
- lcl_TableBreak(Mapper());
+ tableBreak();
break;
}
else if (aPair.first == BUFFER_STARTRUN)
@@ -1075,7 +1067,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
);
Mapper().props(pTableRowProperties);
- lcl_TableBreak(Mapper());
+ tableBreak();
m_bNeedPap = true;
m_aTableBuffer.clear();
}
@@ -2347,7 +2339,7 @@ int RTFDocumentImpl::popState()
}
else if (m_aStates.top().nDestinationState == DESTINATION_PICPROP
|| m_aStates.top().nDestinationState == DESTINATION_SHAPEINSTRUCTION)
- resolveShapeProperties(m_aStates.top().aShape.aProperties);
+ m_pSdrImport->resolve(m_aStates.top().aShape);
else if (m_aStates.top().nDestinationState == DESTINATION_REVISIONENTRY)
m_aAuthors[m_aAuthors.size()] = m_aDestinationText.makeStringAndClear();
else if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART)
@@ -2435,264 +2427,6 @@ int RTFDocumentImpl::popState()
return 0;
}
-void RTFDocumentImpl::createShape(OUString aStr, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet)
-{
- xShape.set(m_xModelFactory->createInstance(aStr), uno::UNO_QUERY);
- xPropertySet.set(xShape, uno::UNO_QUERY);
-}
-
-void RTFDocumentImpl::resolveShapeProperties(std::vector< std::pair<rtl::OUString, rtl::OUString> >& rShapeProperties)
-{
- int nType = -1;
- bool bPib = false;
- bool bCustom = false;
-
- uno::Reference<drawing::XShape> xShape;
- uno::Reference<beans::XPropertySet> xPropertySet;
- // Create this early, as custom shapes may have properties before the type arrives.
- createShape(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CustomShape")), xShape, xPropertySet);
- uno::Any aAny;
- beans::PropertyValue aPropertyValue;
- awt::Rectangle aViewBox;
- std::vector<beans::PropertyValue> aPathPropVec;
-
- for (std::vector< std::pair<rtl::OUString, rtl::OUString> >::iterator i = rShapeProperties.begin(); i != rShapeProperties.end(); ++i)
- {
- if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("shapeType")))
- {
- nType = i->second.toInt32();
- switch (nType)
- {
- case 20: // Line
- createShape(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.LineShape")), xShape, xPropertySet);
- break;
- default:
- bCustom = true;
- break;
- }
-
- // Defaults
- aAny <<= (sal_uInt32)0xffffff; // White in Word, kind of blue in Writer.
- xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny);
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("wzName")))
- {
- RTFValue::Pointer_t pValue(new RTFValue(i->second));
- m_aStates.top().aCharacterAttributes.push_back(make_pair(NS_ooxml::LN_CT_NonVisualDrawingProps_name, pValue));
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("wzDescription")))
- {
- RTFValue::Pointer_t pValue(new RTFValue(i->second));
- m_aStates.top().aCharacterAttributes.push_back(make_pair(NS_ooxml::LN_CT_NonVisualDrawingProps_descr, pValue));
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("pib")))
- {
- m_aDestinationText.setLength(0);
- m_aDestinationText.append(i->second);
- bPib = true;
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillColor")))
- {
- aAny <<= lcl_BGRToRGB(i->second.toInt32());
- xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny);
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillBackColor")))
- ; // Ignore: complementer of fillColor
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineColor")))
- {
- aAny <<= lcl_BGRToRGB(i->second.toInt32());
- xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LineColor")), aAny);
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineBackColor")))
- ; // Ignore: complementer of lineColor
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("txflTextFlow")))
- {
- if (i->second.toInt32() == 1)
- {
- aAny <<= text::WritingMode_TB_RL;
- xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("TextWritingMode")), aAny);
- }
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fLine")))
- {
- if (i->second.toInt32() == 0)
- {
- aAny <<= drawing::LineStyle_NONE;
- xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LineStyle")), aAny);
- }
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("pVerticies")))
- {
- uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
- sal_Int32 nSize = 0; // Size of a token (it's value is hardwired in the exporter)
- sal_Int32 nCount = 0; // Number of tokens
- sal_Int32 nCharIndex = 0; // Character index
- sal_Int32 nIndex = 0; // Array index
- do
- {
- OUString aToken = i->second.getToken(0, ';', nCharIndex);
- if (!nSize)
- nSize = aToken.toInt32();
- else if (!nCount)
- {
- nCount = aToken.toInt32();
- aCoordinates.realloc(nCount);
- }
- else
- {
- // The coordinates are in an (x,y) form.
- aToken = aToken.copy(1, aToken.getLength() - 2);
- sal_Int32 nI = 0;
- sal_Int32 nX = 0;
- sal_Int32 nY = 0;
- do
- {
- OUString aPoint = aToken.getToken(0, ',', nI);
- if (!nX)
- nX = aPoint.toInt32();
- else
- nY = aPoint.toInt32();
- }
- while (nI >= 0);
- aCoordinates[nIndex].First.Value <<= nX;
- aCoordinates[nIndex].Second.Value <<= nY;
- nIndex++;
- }
- }
- while (nCharIndex >= 0);
- aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Coordinates"));
- aPropertyValue.Value <<= aCoordinates;
- aPathPropVec.push_back(aPropertyValue);
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("pSegmentInfo")))
- {
- uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
- sal_Int32 nSize = 0;
- sal_Int32 nCount = 0;
- sal_Int32 nCharIndex = 0;
- sal_Int32 nIndex = 0;
- do
- {
- sal_Int32 nSeg = i->second.getToken(0, ';', nCharIndex).toInt32();
- if (!nSize)
- nSize = nSeg;
- else if (!nCount)
- {
- nCount = nSeg;
- aSegments.realloc(nCount);
- }
- else
- {
- switch (nSeg)
- {
- case 0x0001: // lineto
- aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
- aSegments[nIndex].Count = sal_Int32(1);
- break;
- case 0x4000: // moveto
- aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
- aSegments[nIndex].Count = sal_Int32(1);
- break;
- case 0x2001: // curveto
- aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
- aSegments[nIndex].Count = sal_Int32(1);
- break;
- case 0xb300: // arcto
- aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
- aSegments[nIndex].Count = sal_Int32(0);
- break;
- case 0xac00:
- case 0xaa00: // nofill
- case 0xab00: // nostroke
- case 0x6001: // close
- break;
- case 0x8000: // end
- aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
- aSegments[nIndex].Count = sal_Int32(0);
- break;
- default:
- OSL_TRACE("%s: unhandled segment '%x' in the path", OSL_THIS_FUNC, nSeg);
- break;
- }
- nIndex++;
- }
- }
- while (nCharIndex >= 0);
- aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Segments"));
- aPropertyValue.Value <<= aSegments;
- aPathPropVec.push_back(aPropertyValue);
- }
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoLeft")))
- aViewBox.X = i->second.toInt32();
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoTop")))
- aViewBox.Y = i->second.toInt32();
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoRight")))
- aViewBox.Width = i->second.toInt32();
- else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoBottom")))
- aViewBox.Height = i->second.toInt32();
- else
- OSL_TRACE("%s: TODO handle shape property '%s':'%s'", OSL_THIS_FUNC,
- OUStringToOString( i->first, RTL_TEXTENCODING_UTF8 ).getStr(),
- OUStringToOString( i->second, RTL_TEXTENCODING_UTF8 ).getStr());
- }
-
- if (nType == 75) // picture frame
- {
- if (bPib)
- resolvePict(false);
- return;
- }
-
- m_xDrawPage->add(xShape);
- if (bCustom)
- {
- uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
- xDefaulter->createCustomShapeDefaults(OUString::valueOf(sal_Int32(nType)));
- }
-
- // Creating Path property
- uno::Sequence<beans::PropertyValue> aPathPropSeq(aPathPropVec.size());
- beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
- for (std::vector<beans::PropertyValue>::iterator i = aPathPropVec.begin(); i != aPathPropVec.end(); ++i)
- *pPathValues++ = *i;
-
- // Creating CustomShapeGeometry property
- std::vector<beans::PropertyValue> aGeomPropVec;
- if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
- {
- aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("ViewBox"));
- aPropertyValue.Value <<= aViewBox;
- aGeomPropVec.push_back(aPropertyValue);
- }
- if (aPathPropSeq.getLength())
- {
- aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Path"));
- aPropertyValue.Value <<= aPathPropSeq;
- aGeomPropVec.push_back(aPropertyValue);
- }
- uno::Sequence<beans::PropertyValue> aGeomPropSeq(aGeomPropVec.size());
- beans::PropertyValue* pGeomValues = aGeomPropSeq.getArray();
- for (std::vector<beans::PropertyValue>::iterator i = aGeomPropVec.begin(); i != aGeomPropVec.end(); ++i)
- *pGeomValues++ = *i;
- if (aGeomPropSeq.getLength())
- xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CustomShapeGeometry")), uno::Any(aGeomPropSeq));
-
- // Set position and size
- xShape->setPosition(awt::Point(m_aStates.top().aShape.nLeft, m_aStates.top().aShape.nTop));
- xShape->setSize(awt::Size(m_aStates.top().aShape.nRight - m_aStates.top().aShape.nLeft,
- m_aStates.top().aShape.nBottom - m_aStates.top().aShape.nTop));
-
- // Send it to dmapper
- Mapper().startShape(xShape);
- Mapper().startParagraphGroup();
- replayBuffer(m_aShapetextBuffer);
- Mapper().startCharacterGroup();
- lcl_Break(Mapper());
- Mapper().endCharacterGroup();
- Mapper().endParagraphGroup();
- Mapper().endShape();
-}
-
int RTFDocumentImpl::resolveParse()
{
OSL_TRACE("%s", OSL_THIS_FUNC);
@@ -2772,6 +2506,32 @@ int RTFDocumentImpl::resolveParse()
return "RTFDocumentImpl";
}
+com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> RTFDocumentImpl::getModelFactory()
+{
+ return m_xModelFactory;
+}
+
+RTFParserState& RTFDocumentImpl::getState()
+{
+ return m_aStates.top();
+}
+
+void RTFDocumentImpl::setDestinationText(OUString& rString)
+{
+ m_aDestinationText.setLength(0);
+ m_aDestinationText.append(rString);
+}
+
+void RTFDocumentImpl::replayShapetext()
+{
+ replayBuffer(m_aShapetextBuffer);
+}
+
+com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> RTFDocumentImpl::getDrawPage()
+{
+ return m_xDrawPage;
+}
+
RTFParserState::RTFParserState()
: nInternalState(INTERNAL_NORMAL),
nDestinationState(DESTINATION_NORMAL),
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index b9133ed80065..2daf9fd2c216 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -220,6 +220,8 @@ namespace writerfilter {
bool bIsCjk;
};
+ class RTFSdrImport;
+
/// Implementation of the RTFDocument interface.
class RTFDocumentImpl
: public RTFDocument
@@ -234,25 +236,30 @@ namespace writerfilter {
virtual void resolve(Stream & rHandler);
virtual std::string getType() const;
- SvStream& Strm();
Stream& Mapper();
+ void setSubstream(bool bIsSubtream);
+ void setIgnoreFirst(rtl::OUString& rIgnoreFirst);
+ void seek(sal_uInt32 nPos);
+ com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory> getModelFactory();
+ RTFParserState& getState();
+ void setDestinationText(rtl::OUString& rString);
+ /// Resolve a picture: If not inline, then anchored.
+ int resolvePict(bool bInline);
+ com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> getDrawPage();
+ void runBreak();
+ void replayShapetext();
+ private:
+ SvStream& Strm();
sal_uInt32 getColorTable(sal_uInt32 nIndex);
sal_uInt32 getEncodingTable(sal_uInt32 nFontIndex);
void skipDestination(bool bParsed);
RTFSprms_t mergeSprms();
RTFSprms_t mergeAttributes();
- void setSubstream(bool bIsSubtream);
- void setIgnoreFirst(rtl::OUString& rIgnoreFirst);
void resolveSubstream(sal_uInt32 nPos, Id nId);
void resolveSubstream(sal_uInt32 nPos, Id nId, rtl::OUString& rIgnoreFirst);
- void seek(sal_uInt32 nPos);
- private:
+
int resolveParse();
int resolveKeyword();
- void resolveShapeProperties(std::vector< std::pair<rtl::OUString, rtl::OUString> >& rShapeProperties);
- void createShape(rtl::OUString aService,
- com::sun::star::uno::Reference<drawing::XShape>& xShape,
- com::sun::star::uno::Reference<beans::XPropertySet>& xPropertySet);
int dispatchKeyword(rtl::OString& rKeyword, bool bParam, int nParam);
int dispatchFlag(RTFKeyword nKeyword);
@@ -262,12 +269,11 @@ namespace writerfilter {
int dispatchValue(RTFKeyword nKeyword, int nParam);
int resolveChars(char ch);
- /// Resolve a picture: If not inline, then anchored.
- int resolvePict(bool bInline);
int pushState();
int popState();
void text(rtl::OUString& rString);
void parBreak();
+ void tableBreak();
/// If this is the first run of the document, starts the initial paragraph.
void checkFirstRun();
void sectBreak(bool bFinal);
@@ -281,6 +287,7 @@ namespace writerfilter {
com::sun::star::uno::Reference<com::sun::star::drawing::XDrawPage> m_xDrawPage;
SvStream* m_pInStream;
Stream* m_pMapperStream;
+ RTFSdrImport* m_pSdrImport;
/// Same as m_aStates.size(), except that this can be negative for invalid input.
int m_nGroup;
std::stack<RTFParserState> m_aStates;
diff --git a/writerfilter/source/rtftok/rtfsdrimport.cxx b/writerfilter/source/rtftok/rtfsdrimport.cxx
new file mode 100644
index 000000000000..ba36fe2a5ee0
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfsdrimport.cxx
@@ -0,0 +1,330 @@
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Miklos Vajna <vmiklos@frugalware.org>
+ * Portions created by the Initial Developer are Copyright (C) 2011 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/text/WritingMode.hpp>
+
+#include <ooxml/resourceids.hxx> // NS_ooxml namespace
+
+#include <rtfsdrimport.hxx>
+
+using rtl::OString;
+using rtl::OStringBuffer;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OUStringToOString;
+
+// NEEDSWORK: wwUtility::BGRToRGB does the same.
+static sal_uInt32 lcl_BGRToRGB(sal_uInt32 nColor)
+{
+ sal_uInt8
+ r(static_cast<sal_uInt8>(nColor&0xFF)),
+ g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
+ b(static_cast<sal_uInt8>((nColor>>16)&0xFF)),
+ t(static_cast<sal_uInt8>((nColor>>24)&0xFF));
+ nColor = (t<<24) + (r<<16) + (g<<8) + b;
+ return nColor;
+}
+
+namespace writerfilter {
+namespace rtftok {
+
+RTFSdrImport::RTFSdrImport(RTFDocumentImpl& rDocument)
+ : m_rImport(rDocument)
+{
+}
+
+RTFSdrImport::~RTFSdrImport()
+{
+}
+
+void RTFSdrImport::createShape(OUString aStr, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet)
+{
+ xShape.set(m_rImport.getModelFactory()->createInstance(aStr), uno::UNO_QUERY);
+ xPropertySet.set(xShape, uno::UNO_QUERY);
+}
+
+void RTFSdrImport::resolve(RTFShape& rShape)
+{
+ int nType = -1;
+ bool bPib = false;
+ bool bCustom = false;
+
+ uno::Reference<drawing::XShape> xShape;
+ uno::Reference<beans::XPropertySet> xPropertySet;
+ // Create this early, as custom shapes may have properties before the type arrives.
+ createShape(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.CustomShape")), xShape, xPropertySet);
+ uno::Any aAny;
+ beans::PropertyValue aPropertyValue;
+ awt::Rectangle aViewBox;
+ std::vector<beans::PropertyValue> aPathPropVec;
+
+ for (std::vector< std::pair<rtl::OUString, rtl::OUString> >::iterator i = rShape.aProperties.begin();
+ i != rShape.aProperties.end(); ++i)
+ {
+ if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("shapeType")))
+ {
+ nType = i->second.toInt32();
+ switch (nType)
+ {
+ case 20: // Line
+ createShape(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.LineShape")), xShape, xPropertySet);
+ break;
+ default:
+ bCustom = true;
+ break;
+ }
+
+ // Defaults
+ aAny <<= (sal_uInt32)0xffffff; // White in Word, kind of blue in Writer.
+ xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny);
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("wzName")))
+ {
+ RTFValue::Pointer_t pValue(new RTFValue(i->second));
+ m_rImport.getState().aCharacterAttributes.push_back(make_pair(NS_ooxml::LN_CT_NonVisualDrawingProps_name, pValue));
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("wzDescription")))
+ {
+ RTFValue::Pointer_t pValue(new RTFValue(i->second));
+ m_rImport.getState().aCharacterAttributes.push_back(make_pair(NS_ooxml::LN_CT_NonVisualDrawingProps_descr, pValue));
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("pib")))
+ {
+ m_rImport.setDestinationText(i->second);
+ bPib = true;
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillColor")))
+ {
+ aAny <<= lcl_BGRToRGB(i->second.toInt32());
+ xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor")), aAny);
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fillBackColor")))
+ ; // Ignore: complementer of fillColor
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineColor")))
+ {
+ aAny <<= lcl_BGRToRGB(i->second.toInt32());
+ xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LineColor")), aAny);
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("lineBackColor")))
+ ; // Ignore: complementer of lineColor
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("txflTextFlow")))
+ {
+ if (i->second.toInt32() == 1)
+ {
+ aAny <<= text::WritingMode_TB_RL;
+ xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("TextWritingMode")), aAny);
+ }
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("fLine")))
+ {
+ if (i->second.toInt32() == 0)
+ {
+ aAny <<= drawing::LineStyle_NONE;
+ xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LineStyle")), aAny);
+ }
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("pVerticies")))
+ {
+ uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
+ sal_Int32 nSize = 0; // Size of a token (it's value is hardwired in the exporter)
+ sal_Int32 nCount = 0; // Number of tokens
+ sal_Int32 nCharIndex = 0; // Character index
+ sal_Int32 nIndex = 0; // Array index
+ do
+ {
+ OUString aToken = i->second.getToken(0, ';', nCharIndex);
+ if (!nSize)
+ nSize = aToken.toInt32();
+ else if (!nCount)
+ {
+ nCount = aToken.toInt32();
+ aCoordinates.realloc(nCount);
+ }
+ else
+ {
+ // The coordinates are in an (x,y) form.
+ aToken = aToken.copy(1, aToken.getLength() - 2);
+ sal_Int32 nI = 0;
+ sal_Int32 nX = 0;
+ sal_Int32 nY = 0;
+ do
+ {
+ OUString aPoint = aToken.getToken(0, ',', nI);
+ if (!nX)
+ nX = aPoint.toInt32();
+ else
+ nY = aPoint.toInt32();
+ }
+ while (nI >= 0);
+ aCoordinates[nIndex].First.Value <<= nX;
+ aCoordinates[nIndex].Second.Value <<= nY;
+ nIndex++;
+ }
+ }
+ while (nCharIndex >= 0);
+ aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Coordinates"));
+ aPropertyValue.Value <<= aCoordinates;
+ aPathPropVec.push_back(aPropertyValue);
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("pSegmentInfo")))
+ {
+ uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
+ sal_Int32 nSize = 0;
+ sal_Int32 nCount = 0;
+ sal_Int32 nCharIndex = 0;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ sal_Int32 nSeg = i->second.getToken(0, ';', nCharIndex).toInt32();
+ if (!nSize)
+ nSize = nSeg;
+ else if (!nCount)
+ {
+ nCount = nSeg;
+ aSegments.realloc(nCount);
+ }
+ else
+ {
+ switch (nSeg)
+ {
+ case 0x0001: // lineto
+ aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
+ aSegments[nIndex].Count = sal_Int32(1);
+ break;
+ case 0x4000: // moveto
+ aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
+ aSegments[nIndex].Count = sal_Int32(1);
+ break;
+ case 0x2001: // curveto
+ aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
+ aSegments[nIndex].Count = sal_Int32(1);
+ break;
+ case 0xb300: // arcto
+ aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
+ aSegments[nIndex].Count = sal_Int32(0);
+ break;
+ case 0xac00:
+ case 0xaa00: // nofill
+ case 0xab00: // nostroke
+ case 0x6001: // close
+ break;
+ case 0x8000: // end
+ aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
+ aSegments[nIndex].Count = sal_Int32(0);
+ break;
+ default:
+ OSL_TRACE("%s: unhandled segment '%x' in the path", OSL_THIS_FUNC, nSeg);
+ break;
+ }
+ nIndex++;
+ }
+ }
+ while (nCharIndex >= 0);
+ aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Segments"));
+ aPropertyValue.Value <<= aSegments;
+ aPathPropVec.push_back(aPropertyValue);
+ }
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoLeft")))
+ aViewBox.X = i->second.toInt32();
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoTop")))
+ aViewBox.Y = i->second.toInt32();
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoRight")))
+ aViewBox.Width = i->second.toInt32();
+ else if (i->first.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("geoBottom")))
+ aViewBox.Height = i->second.toInt32();
+ else
+ OSL_TRACE("%s: TODO handle shape property '%s':'%s'", OSL_THIS_FUNC,
+ OUStringToOString( i->first, RTL_TEXTENCODING_UTF8 ).getStr(),
+ OUStringToOString( i->second, RTL_TEXTENCODING_UTF8 ).getStr());
+ }
+
+ if (nType == 75) // picture frame
+ {
+ if (bPib)
+ m_rImport.resolvePict(false);
+ return;
+ }
+
+ m_rImport.getDrawPage()->add(xShape);
+ if (bCustom)
+ {
+ uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
+ xDefaulter->createCustomShapeDefaults(OUString::valueOf(sal_Int32(nType)));
+ }
+
+ // Creating Path property
+ uno::Sequence<beans::PropertyValue> aPathPropSeq(aPathPropVec.size());
+ beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
+ for (std::vector<beans::PropertyValue>::iterator i = aPathPropVec.begin(); i != aPathPropVec.end(); ++i)
+ *pPathValues++ = *i;
+
+ // Creating CustomShapeGeometry property
+ std::vector<beans::PropertyValue> aGeomPropVec;
+ if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
+ {
+ aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("ViewBox"));
+ aPropertyValue.Value <<= aViewBox;
+ aGeomPropVec.push_back(aPropertyValue);
+ }
+ if (aPathPropSeq.getLength())
+ {
+ aPropertyValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Path"));
+ aPropertyValue.Value <<= aPathPropSeq;
+ aGeomPropVec.push_back(aPropertyValue);
+ }
+ uno::Sequence<beans::PropertyValue> aGeomPropSeq(aGeomPropVec.size());
+ beans::PropertyValue* pGeomValues = aGeomPropSeq.getArray();
+ for (std::vector<beans::PropertyValue>::iterator i = aGeomPropVec.begin(); i != aGeomPropVec.end(); ++i)
+ *pGeomValues++ = *i;
+ if (aGeomPropSeq.getLength())
+ xPropertySet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("CustomShapeGeometry")), uno::Any(aGeomPropSeq));
+
+ // Set position and size
+ xShape->setPosition(awt::Point(rShape.nLeft, rShape.nTop));
+ xShape->setSize(awt::Size(rShape.nRight - rShape.nLeft, rShape.nBottom - rShape.nTop));
+
+ // Send it to dmapper
+ m_rImport.Mapper().startShape(xShape);
+ m_rImport.Mapper().startParagraphGroup();
+ m_rImport.replayShapetext();
+ m_rImport.Mapper().startCharacterGroup();
+ m_rImport.runBreak();
+ m_rImport.Mapper().endCharacterGroup();
+ m_rImport.Mapper().endParagraphGroup();
+ m_rImport.Mapper().endShape();
+}
+
+} // namespace rtftok
+} // namespace writerfilter
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfsdrimport.hxx b/writerfilter/source/rtftok/rtfsdrimport.hxx
new file mode 100644
index 000000000000..3c45950272de
--- /dev/null
+++ b/writerfilter/source/rtftok/rtfsdrimport.hxx
@@ -0,0 +1,55 @@
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Miklos Vajna <vmiklos@frugalware.org>
+ * Portions created by the Initial Developer are Copyright (C) 2011 the
+ * Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef _RTFSDRIMPORT_HXX_
+#define _RTFSDRIMPORT_HXX_
+
+#include <rtfdocumentimpl.hxx>
+
+namespace writerfilter {
+ namespace rtftok {
+ /// Handles the import of drawings using RTF markup.
+ class RTFSdrImport
+ {
+ public:
+ RTFSdrImport(RTFDocumentImpl& rDocument);
+ virtual ~RTFSdrImport();
+
+ void resolve(RTFShape& rShape);
+ private:
+ void createShape(rtl::OUString aService,
+ com::sun::star::uno::Reference<drawing::XShape>& xShape,
+ com::sun::star::uno::Reference<beans::XPropertySet>& xPropertySet);
+
+ RTFDocumentImpl& m_rImport;
+ };
+ } // namespace rtftok
+} // namespace writerfilter
+
+#endif // _RTFSDRIPORT_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */