diff options
-rw-r--r-- | include/filter/msfilter/rtfutil.hxx | 3 | ||||
-rw-r--r-- | sw/qa/extras/rtfexport/rtfexport.cxx | 10 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfsdrexport.cxx | 41 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsdrimport.cxx | 41 |
4 files changed, 90 insertions, 5 deletions
diff --git a/include/filter/msfilter/rtfutil.hxx b/include/filter/msfilter/rtfutil.hxx index 4db8c5243e11..515db949895f 100644 --- a/include/filter/msfilter/rtfutil.hxx +++ b/include/filter/msfilter/rtfutil.hxx @@ -17,6 +17,9 @@ #include <sal/types.h> #include <tools/solar.h> +// RTF values are often multiplied by 2^16 +#define RTF_MULTIPLIER 65536 + namespace msfilter { namespace rtfutil { diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx index 7386247ffd3d..0ab46d27f0ee 100644 --- a/sw/qa/extras/rtfexport/rtfexport.cxx +++ b/sw/qa/extras/rtfexport/rtfexport.cxx @@ -1209,9 +1209,19 @@ DECLARE_RTFEXPORT_TEST(testWatermark, "watermark.rtf") CPPUNIT_ASSERT_EQUAL(OUString("WatermarkRTF"), xShape->getString()); uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY); + OUString aFont; + float nFontSize; // Check transparency CPPUNIT_ASSERT_EQUAL(sal_Int16(50), getProperty<sal_Int16>(xShape, "FillTransparence")); + + // Check font family + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("CharFontName") >>= aFont); + CPPUNIT_ASSERT_EQUAL(OUString("DejaVu Serif"), aFont); + + // Check font size + CPPUNIT_ASSERT(xPropertySet->getPropertyValue("CharHeight") >>= nFontSize); + CPPUNIT_ASSERT_EQUAL((float)66, nFontSize); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/rtfsdrexport.cxx b/sw/source/filter/ww8/rtfsdrexport.cxx index 3a7b3397d0a2..beb8adc44cf6 100644 --- a/sw/source/filter/ww8/rtfsdrexport.cxx +++ b/sw/source/filter/ww8/rtfsdrexport.cxx @@ -21,14 +21,19 @@ #include <memory> #include "rtfattributeoutput.hxx" #include <svtools/rtfkeywd.hxx> +#include <svtools/unitconv.hxx> #include <filter/msfilter/rtfutil.hxx> #include <editeng/editobj.hxx> +#include <editeng/editids.hrc> +#include <editeng/fontitem.hxx> +#include <editeng/fhgtitem.hxx> #include <svx/svdotext.hxx> #include <svx/unoapi.hxx> #include <vcl/cvtgrf.hxx> #include <textboxhelper.hxx> #include <dcontact.hxx> #include <algorithm> +#include <filter/msfilter/rtfutil.hxx> using namespace css; @@ -554,9 +559,39 @@ sal_Int32 RtfSdrExport::StartShape() if (pParaObj) { - const EditTextObject& rEditObj = pParaObj->GetTextObject(); - lcl_AppendSP(m_rAttrOutput.RunText(), "gtextUNICODE", - msfilter::rtfutil::OutString(rEditObj.GetText(0), m_rExport.m_eCurrentEncoding)); + // this is reached only in case some text is attached to the shape + // Watermark or TextBox? + if (pTextObj->TakeObjNameSingul().match("Text Frame")) + WriteOutliner(*pParaObj, TXT_HFTXTBOX); + else + { + const EditTextObject& rEditObj = pParaObj->GetTextObject(); + const SfxItemSet& rItemSet = rEditObj.GetParaAttribs(0); + + lcl_AppendSP(m_rAttrOutput.RunText(), "gtextUNICODE", + msfilter::rtfutil::OutString(rEditObj.GetText(0), m_rExport.m_eCurrentEncoding)); + + const SvxFontItem* pFontFamily = static_cast<const SvxFontItem*>(rItemSet.GetItem(SID_ATTR_CHAR_FONT)); + if (pFontFamily) + { + lcl_AppendSP(m_rAttrOutput.RunText(), "gtextFont", + msfilter::rtfutil::OutString(pFontFamily->GetFamilyName(), m_rExport.m_eCurrentEncoding)); + } + + const SvxFontHeightItem* pFontHeight = static_cast<const SvxFontHeightItem*>(rItemSet.GetItem(SID_ATTR_CHAR_FONTHEIGHT)); + if (pFontHeight) + { + long nFontHeight = TransformMetric(pFontHeight->GetHeight(), FUNIT_TWIP, FUNIT_POINT); + lcl_AppendSP(m_rAttrOutput.RunText(), "gtextSize", + msfilter::rtfutil::OutString(OUString::number(nFontHeight * RTF_MULTIPLIER), m_rExport.m_eCurrentEncoding)); + } + + // RTF angle: 0-360 * 2^16 clockwise + // LO angle: 0-360 * 100 counter-clockwise + sal_Int32 nRotation = -1 * pTextObj->GetGeoStat().nRotationAngle * RTF_MULTIPLIER / 100; + lcl_AppendSP(m_rAttrOutput.RunText(), "rotation", + msfilter::rtfutil::OutString(OUString::number(nRotation), m_rExport.m_eCurrentEncoding)); + } } } diff --git a/writerfilter/source/rtftok/rtfsdrimport.cxx b/writerfilter/source/rtftok/rtfsdrimport.cxx index 6df5a0cf9f97..c3655358eef2 100644 --- a/writerfilter/source/rtftok/rtfsdrimport.cxx +++ b/writerfilter/source/rtftok/rtfsdrimport.cxx @@ -30,8 +30,11 @@ #include <ooxml/resourceids.hxx> #include <filter/msfilter/escherex.hxx> #include <filter/msfilter/util.hxx> +#include <filter/msfilter/rtfutil.hxx> #include <svx/svdtrans.hxx> #include <comphelper/sequence.hxx> +#include <comphelper/propertyvalue.hxx> +#include <comphelper/propertysequence.hxx> #include <rtfreferenceproperties.hxx> #include <oox/vml/vmlformatting.hxx> #include <oox/helper/modelobjecthelper.hxx> @@ -242,7 +245,7 @@ void RTFSdrImport::applyProperty(uno::Reference<drawing::XShape> const& xShape, { // See DffPropertyReader::Fix16ToAngle(): in RTF, positive rotation angles are clockwise, we have them as counter-clockwise. // Additionally, RTF type is 0..360*2^16, our is 0..360*100. - sal_Int32 nRotation = aValue.toInt32()*100/65536; + sal_Int32 nRotation = aValue.toInt32()*100/RTF_MULTIPLIER; uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY); if (!xServiceInfo->supportsService("com.sun.star.text.TextFrame")) xPropertySet->setPropertyValue("RotateAngle", uno::makeAny(sal_Int32(NormAngle360(static_cast<long>(nRotation) * -1)))); @@ -378,6 +381,9 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap boost::logic::tribool obFlipV(boost::logic::indeterminate); OUString aShapeText = ""; + OUString aFontFamily = ""; + float nFontSize = 1.0; + bool bCustom(false); int const nType = initShape(xShape, xPropertySet, bCustom, rShape, bClose, shapeOrPict); @@ -401,6 +407,13 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap xPropertySet->setPropertyValue("Description", uno::makeAny(rProperty.second)); else if (rProperty.first == "gtextUNICODE") aShapeText = rProperty.second; + else if (rProperty.first == "gtextFont") + aFontFamily = rProperty.second; + else if (rProperty.first == "gtextSize") + { + // RTF size is multiplied by 2^16 + nFontSize = (float) rProperty.second.toUInt32() / RTF_MULTIPLIER; + } else if (rProperty.first == "pib") { m_rImport.setDestinationText(rProperty.second); @@ -433,7 +446,7 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap resolveFLine(xPropertySet, rProperty.second.toInt32()); else if (rProperty.first == "fillOpacity" && xPropertySet.is()) { - int opacity = 100 - (rProperty.second.toInt32())*100/65536; + int opacity = 100 - (rProperty.second.toInt32())*100/RTF_MULTIPLIER; xPropertySet->setPropertyValue("FillTransparence", uno::Any(sal_uInt32(opacity))); } else if (rProperty.first == "lineWidth") @@ -864,6 +877,9 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap uno::Reference<text::XTextRange> xTextRange(xShape, uno::UNO_QUERY); if (xTextRange.is()) xTextRange->setString(aShapeText); + + xPropertySet->setPropertyValue("CharFontName", uno::makeAny(aFontFamily)); + xPropertySet->setPropertyValue("CharHeight", uno::makeAny(nFontSize)); } // Creating CustomShapeGeometry property @@ -884,6 +900,27 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shap } if (!aGeometry.empty() && xPropertySet.is() && !m_bTextFrame) xPropertySet->setPropertyValue("CustomShapeGeometry", uno::Any(comphelper::containerToSequence(aGeometry))); + + if (!aShapeText.isEmpty()) + { + auto aGeomPropSeq = xPropertySet->getPropertyValue("CustomShapeGeometry").get< uno::Sequence<beans::PropertyValue> >(); + auto aGeomPropVec = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(aGeomPropSeq); + uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence( + { + {"TextPath", uno::makeAny(true)}, + })); + auto it = std::find_if(aGeomPropVec.begin(), aGeomPropVec.end(), [](const beans::PropertyValue& rValue) + { + return rValue.Name == "TextPath"; + }); + if (it == aGeomPropVec.end()) + aGeomPropVec.push_back(comphelper::makePropertyValue("TextPath", aPropertyValues)); + else + it->Value <<= aPropertyValues; + + xPropertySet->setPropertyValue("CustomShapeGeometry", uno::makeAny(comphelper::containerToSequence(aGeomPropVec))); + } + if (!boost::logic::indeterminate(obRelFlipV) && xPropertySet.is()) { if (nType == ESCHER_ShpInst_Line) |