summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2022-11-08 10:28:08 +0100
committerRegina Henschel <rb.henschel@t-online.de>2022-11-12 12:45:03 +0100
commitbd7f1270cf58eba7600d1b4c6c8ca9a901a04f66 (patch)
tree05f659c2c41a0eda0b1136547dd50d9c58d24746 /oox
parent34a90a7f56b7009bc95cf1b0a0e258fa0af2d52a (diff)
tdf#125085 PPTX WordArt import: get shape font from run
PPTX uses the settings at the run for the text in a WordArt shape. LO uses the settings of the shape. The patch copies the run font and language properties to the shape. In addition I have split the old method lcl_createPresetShape and renamed the parts. Now the method lcl_putCustomShapeIntoTextPathMode contains the geometry changes to put a CustomShape into text path mode and to adapt the OOXML values to the values needed for our preset Fontwork shapes, which are based on binary MS Office. MS Office has the style of the characters of a WordArt as properties of the run. LibreOffice ignores most of the properties specified in the style of a span element, when the text is displayed as Fontwork. Instead LO uses the properties defined for the shape for styling the text. Copying the text properties to the shape is now done in method lcl_copyCharPropsToShape. The values in testTdf125573_FontWorkScaleX depend on the used Font. Since on creation time wrong Fonts were used and now correct Fonts are imported, the values have to be updated. Import of fill and stroke of the characters is still missing, only a rudimentary import of color for solid fill exists. Change-Id: I6f31fe07fb0656b2ce8581e7123265fa598ac9c1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142421 Tested-by: Jenkins Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'oox')
-rw-r--r--oox/qa/unit/data/tdf125085_WordArtFontText.pptxbin0 -> 16891 bytes
-rw-r--r--oox/qa/unit/data/tdf125085_WordArtFontTheme.pptxbin0 -> 15548 bytes
-rw-r--r--oox/qa/unit/drawingml.cxx47
-rw-r--r--oox/source/drawingml/shape.cxx405
4 files changed, 321 insertions, 131 deletions
diff --git a/oox/qa/unit/data/tdf125085_WordArtFontText.pptx b/oox/qa/unit/data/tdf125085_WordArtFontText.pptx
new file mode 100644
index 000000000000..a9dab6d1ccf8
--- /dev/null
+++ b/oox/qa/unit/data/tdf125085_WordArtFontText.pptx
Binary files differ
diff --git a/oox/qa/unit/data/tdf125085_WordArtFontTheme.pptx b/oox/qa/unit/data/tdf125085_WordArtFontTheme.pptx
new file mode 100644
index 000000000000..f4c37692afcd
--- /dev/null
+++ b/oox/qa/unit/data/tdf125085_WordArtFontTheme.pptx
Binary files differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index 5c0b17e192f6..e25d980f09cb 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -27,6 +27,7 @@
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/text/XTextRange.hpp>
#include <com/sun/star/table/XCellRange.hpp>
@@ -549,6 +550,52 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf113187ConstantArcTo)
CPPUNIT_ASSERT_EQUAL(sal_Int32(3600000), aViewBox.Height);
}
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf125085WordArtFontTheme)
+{
+ // The font info for the shape is in the theme, the text run has no font settings.
+ loadFromURL(u"tdf125085_WordArtFontTheme.pptx");
+
+ // Get shape and its properties
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+
+ // Make sure shape has correct font and local.
+ // Without the fix some application defaults were used.
+ OUString sFontName;
+ xShapeProps->getPropertyValue("CharFontNameComplex") >>= sFontName;
+ CPPUNIT_ASSERT_EQUAL(OUString(u"Noto Serif Hebrew"), sFontName);
+ css::lang::Locale aLocal;
+ xShapeProps->getPropertyValue("CharLocaleComplex") >>= aLocal;
+ CPPUNIT_ASSERT_EQUAL(OUString(u"IL"), aLocal.Country);
+ CPPUNIT_ASSERT_EQUAL(OUString(u"he"), aLocal.Language);
+}
+
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf125085WordArtFontText)
+{
+ // The font info for the shape is in the text run inside the shape.
+ loadFromURL(u"tdf125085_WordArtFontText.pptx");
+
+ // Get shape and its properties
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+
+ // Make sure shape has correct font and local.
+ // Without the fix some application defaults were used.
+ OUString sFontName;
+ xShapeProps->getPropertyValue("CharFontNameComplex") >>= sFontName;
+ CPPUNIT_ASSERT_EQUAL(OUString(u"Noto Serif Hebrew"), sFontName);
+ css::lang::Locale aLocal;
+ xShapeProps->getPropertyValue("CharLocaleComplex") >>= aLocal;
+ CPPUNIT_ASSERT_EQUAL(OUString(u"IL"), aLocal.Country);
+ CPPUNIT_ASSERT_EQUAL(OUString(u"he"), aLocal.Language);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 99c1c5a979a5..a9b869e86af2 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -86,6 +86,8 @@
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
@@ -107,6 +109,8 @@
#include <sal/log.hxx>
#include <svx/sdtaitm.hxx>
#include <oox/drawingml/diagram/diagram.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
using namespace ::oox::core;
using namespace ::com::sun::star;
@@ -553,31 +557,31 @@ static SdrTextHorzAdjust lcl_convertAdjust( ParagraphAdjust eAdjust )
return SDRTEXTHORZADJUST_LEFT;
}
-static void lcl_createPresetShape(const uno::Reference<drawing::XShape>& xShape,
- const OUString& rClass, const OUString& rPresetType,
- const CustomShapePropertiesPtr& pCustomShapePropertiesPtr,
- const TextBodyPtr& pTextBody,
- const GraphicHelper& rGraphicHelper)
+static void
+lcl_putCustomShapeIntoTextPathMode(const uno::Reference<drawing::XShape>& xShape,
+ const CustomShapePropertiesPtr& pCustomShapePropertiesPtr,
+ const TextBodyPtr& pTextBody)
{
if (!xShape.is() || !pCustomShapePropertiesPtr || !pTextBody)
return;
- uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter( xShape,
- uno::UNO_QUERY );
-
- if (!xDefaulter.is() || rClass.isEmpty())
+ uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
+ if (!xDefaulter.is())
return;
- Reference<XPropertySet> xSet( xShape, UNO_QUERY );
+ Reference<XPropertySet> xSet(xShape, UNO_QUERY);
if (!xSet.is())
return;
+ const OUString sMSPresetType = pTextBody->getTextProperties().msPrst;
+ const OUString sFontworkType = PresetGeometryTypeNames::GetFontworkType(sMSPresetType);
+
// The DrawingML shapes from the presetTextWarpDefinitions are mapped to the definitions
// in svx/../EnhancedCustomShapeGeometry.cxx, which are used for WordArt shapes from
// binary MS Office. Therefore all adjustment values need to be adapted.
auto aAdjGdList = pCustomShapePropertiesPtr->getAdjustmentGuideList();
Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment(
- !aAdjGdList.empty() ? aAdjGdList.size() : 1 );
+ !aAdjGdList.empty() ? aAdjGdList.size() : 1);
auto pAdjustment = aAdjustment.getArray();
int nIndex = 0;
for (const auto& aEntry : aAdjGdList)
@@ -585,14 +589,14 @@ static void lcl_createPresetShape(const uno::Reference<drawing::XShape>& xShape,
double fValue = aEntry.maFormula.toDouble();
// then: polar-handle, else: XY-handle
// There exist only 8 polar-handles at all in presetTextWarp.
- if ((rClass == "fontwork-arch-down-curve")
- || (rClass == "fontwork-arch-down-pour" && aEntry.maName == "adj1")
- || (rClass == "fontwork-arch-up-curve")
- || (rClass == "fontwork-arch-up-pour" && aEntry.maName == "adj1")
- || (rClass == "fontwork-open-circle-curve")
- || (rClass == "fontwork-open-circle-pour" && aEntry.maName == "adj1")
- || (rClass == "fontwork-circle-curve")
- || (rClass == "fontwork-circle-pour" && aEntry.maName == "adj1"))
+ if ((sFontworkType == "fontwork-arch-down-curve")
+ || (sFontworkType == "fontwork-arch-down-pour" && aEntry.maName == "adj1")
+ || (sFontworkType == "fontwork-arch-up-curve")
+ || (sFontworkType == "fontwork-arch-up-pour" && aEntry.maName == "adj1")
+ || (sFontworkType == "fontwork-open-circle-curve")
+ || (sFontworkType == "fontwork-open-circle-pour" && aEntry.maName == "adj1")
+ || (sFontworkType == "fontwork-circle-curve")
+ || (sFontworkType == "fontwork-circle-pour" && aEntry.maName == "adj1"))
{
// DrawingML has 1/60000 degree unit, but WordArt simple degree. Range [0..360[
// or range ]-180..180] doesn't matter, because only cos(angle) and
@@ -606,20 +610,20 @@ static void lcl_createPresetShape(const uno::Reference<drawing::XShape>& xShape,
// so scale with 21600/100000 = 0.216, with two exceptions:
// X-handles of waves describe increase/decrease relative to horizontal center.
// The gdRefR of pour-shapes is not relative to viewBox but to radius.
- if ((rClass == "mso-spt158" && aEntry.maName == "adj2") // textDoubleWave1
- || (rClass == "fontwork-wave" && aEntry.maName == "adj2") // textWave1
- || (rClass == "mso-spt157" && aEntry.maName == "adj2") // textWave2
- || (rClass == "mso-spt159" && aEntry.maName == "adj2")) // textWave4
+ if ((sFontworkType == "mso-spt158" && aEntry.maName == "adj2") // textDoubleWave1
+ || (sFontworkType == "fontwork-wave" && aEntry.maName == "adj2") // textWave1
+ || (sFontworkType == "mso-spt157" && aEntry.maName == "adj2") // textWave2
+ || (sFontworkType == "mso-spt159" && aEntry.maName == "adj2")) // textWave4
{
fValue = (fValue + 50000.0) * 0.216;
}
- else if ( (rClass == "fontwork-arch-down-pour" && aEntry.maName == "adj2")
- || (rClass == "fontwork-arch-up-pour" && aEntry.maName == "adj2")
- || (rClass == "fontwork-open-circle-pour" && aEntry.maName == "adj2")
- || (rClass == "fontwork-circle-pour" && aEntry.maName == "adj2"))
- {
- fValue *= 0.108;
- }
+ else if ((sFontworkType == "fontwork-arch-down-pour" && aEntry.maName == "adj2")
+ || (sFontworkType == "fontwork-arch-up-pour" && aEntry.maName == "adj2")
+ || (sFontworkType == "fontwork-open-circle-pour" && aEntry.maName == "adj2")
+ || (sFontworkType == "fontwork-circle-pour" && aEntry.maName == "adj2"))
+ {
+ fValue *= 0.108;
+ }
else
{
fValue *= 0.216;
@@ -630,119 +634,255 @@ static void lcl_createPresetShape(const uno::Reference<drawing::XShape>& xShape,
pAdjustment[nIndex++].State = css::beans::PropertyState_DIRECT_VALUE;
}
- // Set properties
- xSet->setPropertyValue( UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::Any( false ) );
- xSet->setPropertyValue( UNO_NAME_TEXT_AUTOGROWWIDTH, uno::Any( false ) );
- xSet->setPropertyValue( UNO_NAME_FILLSTYLE, uno::Any( drawing::FillStyle_SOLID ) );
-
- // ToDo: Old binary WordArt does not allow different styles for different paragraphs, so it
- // was not necessary to examine all paragraphs. Solution for DrawingML is needed.
- // Currently different alignment of paragraphs are lost, for example.
- const TextParagraphVector& rParagraphs = pTextBody->getParagraphs();
- if (!rParagraphs.empty() && !rParagraphs[0]->getRuns().empty())
- {
- std::shared_ptr<TextParagraph> pParagraph = rParagraphs[0];
- std::shared_ptr<TextRun> pRun = pParagraph->getRuns()[0];
- TextCharacterProperties& pProperties = pRun->getTextCharacterProperties();
-
- if (pProperties.moBold.has_value() && pProperties.moBold.value())
- {
- xSet->setPropertyValue( UNO_NAME_CHAR_WEIGHT, uno::Any( css::awt::FontWeight::BOLD ) );
- }
- if (pProperties.moItalic.has_value() && pProperties.moItalic.value())
- {
- xSet->setPropertyValue( UNO_NAME_CHAR_POSTURE, uno::Any( css::awt::FontSlant::FontSlant_ITALIC ) );
- }
- if (pProperties.moHeight.has_value())
- {
- sal_Int32 nHeight = pProperties.moHeight.value() / 100;
- xSet->setPropertyValue( UNO_NAME_CHAR_HEIGHT, uno::Any( nHeight ) );
- }
- if (pProperties.maFillProperties.maFillColor.isUsed())
- {
- const sal_Int32 aFillColor = static_cast<sal_Int32>(
- pProperties.maFillProperties.maFillColor.getColor( rGraphicHelper ).GetRGBColor() );
- xSet->setPropertyValue( UNO_NAME_FILLCOLOR, uno::Any( aFillColor ) );
- }
- else
- {
- // Set default color
- xSet->setPropertyValue( UNO_NAME_FILLCOLOR, uno::Any( COL_BLACK ) );
- }
- {
- ParagraphAdjust eAdjust = ParagraphAdjust_LEFT;
- if (pParagraph->getProperties().getParaAdjust())
- eAdjust = *pParagraph->getProperties().getParaAdjust();
- xSet->setPropertyValue( "ParaAdjust", uno::Any( eAdjust ) );
- SdrObject* pShape = SdrObject::getSdrObjectFromXShape( xShape );
- assert(pShape);
- SdrTextHorzAdjust eHorzAdjust = lcl_convertAdjust( eAdjust );
- pShape->SetMergedItem( SdrTextHorzAdjustItem( eHorzAdjust ) );
- }
- }
-
- // Apply vertical adjustment for text on arc
- // ToDo: The property is currently not evaluated.
- SdrObject* pShape = SdrObject::getSdrObjectFromXShape(xShape);
- assert(pShape);
- if (rClass == "fontwork-arch-up-curve" || rClass == "fontwork-circle-curve")
- pShape->SetMergedItem( SdrTextVertAdjustItem( SdrTextVertAdjust::SDRTEXTVERTADJUST_BOTTOM ) );
- else if (rClass == "fontwork-arch-down-curve")
- pShape->SetMergedItem( SdrTextVertAdjustItem( SdrTextVertAdjust::SDRTEXTVERTADJUST_TOP ) );
-
- // Apply preset shape
- xDefaulter->createCustomShapeDefaults( rClass );
+ // Set attributes in CustomShapeGeometry
+ xDefaulter->createCustomShapeDefaults(sFontworkType);
- auto aGeomPropSeq = xSet->getPropertyValue( "CustomShapeGeometry" )
- .get<uno::Sequence<beans::PropertyValue>>();
+ auto aGeomPropSeq
+ = xSet->getPropertyValue("CustomShapeGeometry").get<uno::Sequence<beans::PropertyValue>>();
auto aGeomPropVec
- = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(
- aGeomPropSeq );
+ = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(aGeomPropSeq);
// Reset old properties
- static const OUStringLiteral sTextPath( u"TextPath" );
- static const OUStringLiteral sAdjustmentValues( u"AdjustmentValues" );
- static const OUStringLiteral sPresetTextWarp( u"PresetTextWarp" );
+ static const OUStringLiteral sTextPath(u"TextPath");
+ static const OUStringLiteral sAdjustmentValues(u"AdjustmentValues");
+ static const OUStringLiteral sPresetTextWarp(u"PresetTextWarp");
- lcl_resetPropertyValue( aGeomPropVec, "CoordinateSize" );
- lcl_resetPropertyValue( aGeomPropVec, "Equations" );
- lcl_resetPropertyValue( aGeomPropVec, "Path" );
- lcl_resetPropertyValue( aGeomPropVec, sAdjustmentValues);
+ lcl_resetPropertyValue(aGeomPropVec, "CoordinateSize");
+ lcl_resetPropertyValue(aGeomPropVec, "Equations");
+ lcl_resetPropertyValue(aGeomPropVec, "Path");
+ lcl_resetPropertyValue(aGeomPropVec, sAdjustmentValues);
bool bFromWordArt(false);
pTextBody->getTextProperties().maPropertyMap.getProperty(PROP_FromWordArt) >>= bFromWordArt;
bool bScaleX(false);
if (!bFromWordArt
- && (rPresetType == "textArchDown" || rPresetType == "textArchUp"
- || rPresetType == "textCircle" || rPresetType == "textButton"))
+ && (sMSPresetType == "textArchDown" || sMSPresetType == "textArchUp"
+ || sMSPresetType == "textCircle" || sMSPresetType == "textButton"))
{
bScaleX = true;
}
- // Apply geometry properties
- uno::Sequence<beans::PropertyValue> aPropertyValues(
- comphelper::InitPropertySequence(
- { { sTextPath, uno::Any( true ) },
- { "TextPathMode",
- uno::Any( drawing::EnhancedCustomShapeTextPathMode_PATH ) },
- { "ScaleX", uno::Any(bScaleX) } } ) );
+ // Apply new properties
+ uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
+ { { sTextPath, uno::Any(true) },
+ { "TextPathMode", uno::Any(drawing::EnhancedCustomShapeTextPathMode_PATH) },
+ { "ScaleX", uno::Any(bScaleX) } }));
- lcl_setPropertyValue( aGeomPropVec, sTextPath,
- comphelper::makePropertyValue( sTextPath, aPropertyValues ) );
+ lcl_setPropertyValue(aGeomPropVec, sTextPath,
+ comphelper::makePropertyValue(sTextPath, aPropertyValues));
- lcl_setPropertyValue( aGeomPropVec, sPresetTextWarp,
- comphelper::makePropertyValue( sPresetTextWarp, rPresetType ) );
+ lcl_setPropertyValue(aGeomPropVec, sPresetTextWarp,
+ comphelper::makePropertyValue(sPresetTextWarp, sMSPresetType));
if (!aAdjGdList.empty())
{
- lcl_setPropertyValue( aGeomPropVec, sAdjustmentValues,
- comphelper::makePropertyValue( sAdjustmentValues, aAdjustment ) );
+ lcl_setPropertyValue(aGeomPropVec, sAdjustmentValues,
+ comphelper::makePropertyValue(sAdjustmentValues, aAdjustment));
}
- xSet->setPropertyValue(
- "CustomShapeGeometry",
- uno::Any(comphelper::containerToSequence(aGeomPropVec)));
+ xSet->setPropertyValue("CustomShapeGeometry",
+ uno::Any(comphelper::containerToSequence(aGeomPropVec)));
+}
+
+// LO does not interpret properties in styles belonging to the text content of a FontWork shape,
+// but only those in the shape style. This method copies properties from the text content styles to
+// the shape style.
+static void lcl_copyCharPropsToShape(const uno::Reference<drawing::XShape>& xShape,
+ const TextBodyPtr& pTextBody,
+ const ::oox::core::XmlFilterBase& rFilter)
+{
+ if (!xShape.is() || !pTextBody)
+ return;
+
+ Reference<XPropertySet> xSet(xShape, UNO_QUERY);
+ if (!xSet.is())
+ return;
+
+ // Content stretches or scales to given width and height, thus disable autogrow.
+ xSet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWHEIGHT, uno::Any(false));
+ xSet->setPropertyValue(UNO_NAME_TEXT_AUTOGROWWIDTH, uno::Any(false));
+
+ // LibreOffice is not able (as of Nov 2022) to use different styles for the paragraphs or
+ // characters in FontWork, since that was not allowed in old binary WordArt. We use the
+ // properties of the first non empty paragraph for now.
+ const TextParagraphVector& rParagraphs = pTextBody->getParagraphs();
+ auto aParaIt = std::find_if_not(rParagraphs.cbegin(), rParagraphs.cend(),
+ [](const std::shared_ptr<TextParagraph> pParagraph) {
+ return pParagraph->getRuns().empty();
+ });
+ if (aParaIt != rParagraphs.cend())
+ {
+ std::shared_ptr<TextParagraph> pParagraph = *aParaIt;
+ const TextRunVector& rRuns = pParagraph->getRuns();
+ auto aRunIt = std::find_if_not(
+ rRuns.cbegin(), rRuns.cend(),
+ [](const std::shared_ptr<TextRun> pRun) { return pRun->getText().isEmpty(); });
+ if (aRunIt != rRuns.cend())
+ {
+ std::shared_ptr<TextRun> pRun = *aRunIt;
+ TextCharacterProperties& rCharProps = pRun->getTextCharacterProperties();
+
+ // set language
+ if (rCharProps.moLang.has_value() && !rCharProps.moLang.value().isEmpty())
+ {
+ LanguageTag aTag(rCharProps.moLang.value());
+ css::lang::Locale aLocale(aTag.getLocale(false));
+ switch (MsLangId::getScriptType(aTag.getLanguageType()))
+ {
+ case css::i18n::ScriptType::LATIN:
+ xSet->setPropertyValue(u"CharLocale", uno::Any(aLocale));
+ break;
+ case css::i18n::ScriptType::ASIAN:
+ xSet->setPropertyValue(u"CharLocaleAsian", uno::Any(aLocale));
+ break;
+ case css::i18n::ScriptType::COMPLEX:
+ xSet->setPropertyValue(u"CharLocaleComplex", uno::Any(aLocale));
+ break;
+ default:;
+ }
+ }
+
+ // Font Weight, Posture, Height
+ if (rCharProps.moBold.has_value() && rCharProps.moBold.value())
+ {
+ xSet->setPropertyValue(UNO_NAME_CHAR_WEIGHT, uno::Any(css::awt::FontWeight::BOLD));
+ }
+ if (rCharProps.moItalic.has_value() && rCharProps.moItalic.value())
+ {
+ xSet->setPropertyValue(UNO_NAME_CHAR_POSTURE,
+ uno::Any(css::awt::FontSlant::FontSlant_ITALIC));
+ }
+ if (rCharProps.moHeight.has_value())
+ {
+ sal_Int32 nHeight = rCharProps.moHeight.value() / 100;
+ xSet->setPropertyValue(UNO_NAME_CHAR_HEIGHT, uno::Any(nHeight));
+ }
+
+ // Put theme fonts into shape properties
+ OUString sFontName;
+ sal_Int16 nFontPitch = 0;
+ sal_Int16 nFontFamily = 0;
+ bool bRet(false);
+ if (const Theme* pTheme = rFilter.getCurrentTheme())
+ {
+ // minor Latin
+ if (const TextFont* pFont = pTheme->resolveFont(u"+mn-lt"))
+ {
+ bRet = pFont->getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
+ if (bRet)
+ {
+ xSet->setPropertyValue(u"CharFontName", uno::Any(sFontName));
+ xSet->setPropertyValue(u"CharFontPitch", uno::Any(nFontPitch));
+ xSet->setPropertyValue(u"CharFontFamily", uno::Any(nFontFamily));
+ }
+ }
+ // minor Asian
+ if (const TextFont* pFont = pTheme->resolveFont(u"+mn-ea"))
+ {
+ bRet = pFont->getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
+ if (bRet)
+ {
+ xSet->setPropertyValue(u"CharFontNameAsian", uno::Any(sFontName));
+ xSet->setPropertyValue(u"CharFontPitchAsian", uno::Any(nFontPitch));
+ xSet->setPropertyValue(u"CharFontFamilyAsian", uno::Any(nFontFamily));
+ }
+ }
+ // minor Complex
+ if (const TextFont* pFont = pTheme->resolveFont(u"+mn-cs"))
+ {
+ bRet = pFont->getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
+ if (bRet)
+ {
+ xSet->setPropertyValue(u"CharFontNameComplex", uno::Any(sFontName));
+ xSet->setPropertyValue(u"CharFontPitchComplex", uno::Any(nFontPitch));
+ xSet->setPropertyValue(u"CharFontFamilyComplex", uno::Any(nFontFamily));
+ }
+ }
+ }
+
+ // Replace theme fonts with formatting at run if any. ToDo: Inspect paragraph too?
+ // Latin
+ bRet = rCharProps.maLatinFont.getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
+ if (!bRet)
+ // In case there is no direct font, try to look it up as a theme reference.
+ bRet = rCharProps.maLatinThemeFont.getFontData(sFontName, nFontPitch, nFontFamily,
+ rFilter);
+
+ if (bRet)
+ {
+ xSet->setPropertyValue(u"CharFontName", uno::Any(sFontName));
+ xSet->setPropertyValue(u"CharFontPitch", uno::Any(nFontPitch));
+ xSet->setPropertyValue(u"CharFontFamily", uno::Any(nFontFamily));
+ }
+ // Asian
+ bRet = rCharProps.maAsianFont.getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
+ if (!bRet)
+ // In case there is no direct font, try to look it up as a theme reference.
+ bRet = rCharProps.maAsianThemeFont.getFontData(sFontName, nFontPitch, nFontFamily,
+ rFilter);
+ if (bRet)
+ {
+ xSet->setPropertyValue(u"CharFontNameAsian", uno::Any(sFontName));
+ xSet->setPropertyValue(u"CharFontPitchAsian", uno::Any(nFontPitch));
+ xSet->setPropertyValue(u"CharFontFamilyAsian", uno::Any(nFontFamily));
+ }
+ // Complex
+ bRet
+ = rCharProps.maComplexFont.getFontData(sFontName, nFontPitch, nFontFamily, rFilter);
+ if (!bRet)
+ // In case there is no direct font, try to look it up as a theme reference.
+ bRet = rCharProps.maComplexThemeFont.getFontData(sFontName, nFontPitch, nFontFamily,
+ rFilter);
+ if (bRet)
+ {
+ xSet->setPropertyValue(u"CharFontNameComplex", uno::Any(sFontName));
+ xSet->setPropertyValue(u"CharFontPitchComplex", uno::Any(nFontPitch));
+ xSet->setPropertyValue(u"CharFontFamilyComplex", uno::Any(nFontFamily));
+ }
+
+ // LO uses shape fill, MS Office character fill. Currently only this solid fill workaround
+ // is implemented.
+ // ToDo: Consider other fill styles
+ // ToDo: Consider Color Theme
+ xSet->setPropertyValue(UNO_NAME_FILLSTYLE, uno::Any(drawing::FillStyle_SOLID));
+ sal_Int32 aFillColor(COL_BLACK); //default
+ if (rCharProps.maFillProperties.maFillColor.isUsed())
+ {
+ aFillColor = static_cast<sal_Int32>(
+ rCharProps.maFillProperties.maFillColor.getColor(rFilter.getGraphicHelper())
+ .GetRGBColor());
+ }
+ xSet->setPropertyValue(UNO_NAME_FILLCOLOR, uno::Any(aFillColor));
+
+ // ToDo: copy character outline to shape stroke.
+ }
+
+ // LO does not evaluate paragraph alignment in text path mode. Use text area anchor instead.
+ {
+ ParagraphAdjust eAdjust = ParagraphAdjust_LEFT;
+ if (pParagraph->getProperties().getParaAdjust())
+ eAdjust = *pParagraph->getProperties().getParaAdjust();
+ xSet->setPropertyValue("ParaAdjust", uno::Any(eAdjust));
+ SdrObject* pShape = SdrObject::getSdrObjectFromXShape(xShape);
+ assert(pShape);
+ SdrTextHorzAdjust eHorzAdjust = lcl_convertAdjust(eAdjust);
+ pShape->SetMergedItem(SdrTextHorzAdjustItem(eHorzAdjust));
+ }
+ }
+
+ // Vertical adjustment is only meaningful for OOXML WordArt shapes of 'Follow Path' kinds. We set
+ // it so, that text position is approximately same as in MS Office.
+ const OUString sMSPresetType = pTextBody->getTextProperties().msPrst;
+ const OUString sFontworkType = PresetGeometryTypeNames::GetFontworkType(sMSPresetType);
+ SdrObject* pShape = SdrObject::getSdrObjectFromXShape(xShape);
+ assert(pShape);
+ if (sFontworkType == "fontwork-arch-up-curve" || sFontworkType == "fontwork-circle-curve")
+ pShape->SetMergedItem(SdrTextVertAdjustItem(SdrTextVertAdjust::SDRTEXTVERTADJUST_BOTTOM));
+ else if (sFontworkType == "fontwork-arch-down-curve")
+ pShape->SetMergedItem(SdrTextVertAdjustItem(SdrTextVertAdjust::SDRTEXTVERTADJUST_TOP));
+ else
+ pShape->SetMergedItem(SdrTextVertAdjustItem(SdrTextVertAdjust::SDRTEXTVERTADJUST_CENTER));
}
// Some helper methods for createAndInsert
@@ -1766,19 +1906,14 @@ Reference< XShape > const & Shape::createAndInsert(
// for these ==cscode== and ==csdata== markers, so don't "clean up" these SAL_INFOs
SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName << "'");
+
mpCustomShapePropertiesPtr->pushToPropSet(xSet, maSize);
- if (mpTextBody)
+ // Consider WordArt
+ if (mpTextBody && !mpTextBody->getTextProperties().msPrst.isEmpty()
+ && mpTextBody->getTextProperties().msPrst != u"textNoShape")
{
- bool bIsPresetShape = !mpTextBody->getTextProperties().msPrst.isEmpty();
- if (bIsPresetShape)
- {
- OUString sClass;
- const OUString sPresetType = mpTextBody->getTextProperties().msPrst;
- sClass = PresetGeometryTypeNames::GetFontworkType( sPresetType );
-
- lcl_createPresetShape( mxShape, sClass, sPresetType, mpCustomShapePropertiesPtr, mpTextBody, rGraphicHelper );
- }
+ lcl_putCustomShapeIntoTextPathMode(mxShape, mpCustomShapePropertiesPtr, mpTextBody);
}
}
else if( getTextBody() )
@@ -1847,6 +1982,14 @@ Reference< XShape > const & Shape::createAndInsert(
aTextCharacterProps.pushToPropSet(aPropertySet, rFilterBase);
}
}
+
+ // MS Office has e.g. fill and stroke of WordArt in the character properties,
+ // LibreOffice uses shape properties.
+ if (!mpTextBody->getTextProperties().msPrst.isEmpty()
+ && mpTextBody->getTextProperties().msPrst != u"textNoShape")
+ {
+ lcl_copyCharPropsToShape(mxShape, mpTextBody, rFilterBase);
+ }
}
}
else if (mbTextBox)