44bd87fd78
Change-Id: Ic5bcb44fbe56804e23bcdfd039a77c010858ca02 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158206 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
1669 lines
98 KiB
C++
1669 lines
98 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <drawingml/fontworkhelpers.hxx>
|
|
|
|
#include <basegfx/utils/bgradient.hxx>
|
|
#include <basegfx/utils/gradienttools.hxx>
|
|
#include <comphelper/propertysequence.hxx>
|
|
#include <comphelper/propertyvalue.hxx>
|
|
#include <comphelper/sequence.hxx>
|
|
#include <comphelper/sequenceashashmap.hxx>
|
|
#include <docmodel/uno/UnoComplexColor.hxx>
|
|
#include <docmodel/uno/UnoGradientTools.hxx>
|
|
#include <drawingml/customshapeproperties.hxx>
|
|
#include <drawingml/presetgeometrynames.hxx>
|
|
#include <oox/drawingml/drawingmltypes.hxx>
|
|
#include <oox/helper/grabbagstack.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <svx/msdffdef.hxx>
|
|
#include <tools/color.hxx>
|
|
#include <tools/helpers.hxx>
|
|
|
|
#include <com/sun/star/awt/Gradient2.hpp>
|
|
#include <com/sun/star/beans/PropertyAttribute.hpp>
|
|
#include <com/sun/star/beans/PropertyValue.hpp>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
#include <com/sun/star/container/XEnumeration.hpp>
|
|
#include <com/sun/star/container/XEnumerationAccess.hpp>
|
|
#include <com/sun/star/drawing/DashStyle.hpp>
|
|
#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
|
|
#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
|
|
#include <com/sun/star/drawing/FillStyle.hpp>
|
|
#include <com/sun/star/drawing/LineCap.hpp>
|
|
#include <com/sun/star/drawing/LineDash.hpp>
|
|
#include <com/sun/star/drawing/LineJoint.hpp>
|
|
#include <com/sun/star/drawing/LineStyle.hpp>
|
|
#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
|
|
#include <com/sun/star/drawing/XShape.hpp>
|
|
#include <com/sun/star/text/XText.hpp>
|
|
#include <com/sun/star/text/XTextRange.hpp>
|
|
#include <com/sun/star/util/XComplexColor.hpp>
|
|
|
|
#include <array>
|
|
#include <map>
|
|
|
|
using namespace com::sun::star;
|
|
|
|
void FontworkHelpers::resetPropertyValueInVec(std::vector<beans::PropertyValue>& rPropVec,
|
|
const OUString& rName)
|
|
{
|
|
auto aIterator = std::find_if(
|
|
rPropVec.begin(), rPropVec.end(),
|
|
[rName](const beans::PropertyValue& rValue) { return rValue.Name == rName; });
|
|
|
|
if (aIterator != rPropVec.end())
|
|
rPropVec.erase(aIterator);
|
|
}
|
|
|
|
void FontworkHelpers::putCustomShapeIntoTextPathMode(
|
|
const css::uno::Reference<drawing::XShape>& xShape,
|
|
const oox::drawingml::CustomShapePropertiesPtr& pCustomShapePropertiesPtr,
|
|
const OUString& sMSPresetType, const bool bFromWordArt)
|
|
{
|
|
if (!xShape.is() || !pCustomShapePropertiesPtr || sMSPresetType == u"textNoShape")
|
|
return;
|
|
|
|
uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
|
|
if (!xDefaulter.is())
|
|
return;
|
|
|
|
uno::Reference<beans::XPropertySet> xSet(xShape, uno::UNO_QUERY);
|
|
if (!xSet.is())
|
|
return;
|
|
|
|
// 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.
|
|
const OUString sFontworkType = PresetGeometryTypeNames::GetFontworkType(sMSPresetType);
|
|
auto aAdjGdList = pCustomShapePropertiesPtr->getAdjustmentGuideList();
|
|
uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment(
|
|
!aAdjGdList.empty() ? aAdjGdList.size() : 1);
|
|
auto pAdjustment = aAdjustment.getArray();
|
|
int nIndex = 0;
|
|
for (const auto& aEntry : aAdjGdList)
|
|
{
|
|
double fValue = aEntry.maFormula.toDouble();
|
|
// then: polar-handle, else: XY-handle
|
|
// There exist only 8 polar-handles at all in presetTextWarp.
|
|
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
|
|
// sin(angle) are used.
|
|
fValue = NormAngle360(fValue / 60000.0);
|
|
}
|
|
else
|
|
{
|
|
// DrawingML writes adjustment guides as relative value with 100% = 100000,
|
|
// but WordArt definitions use values absolute in viewBox 0 0 21600 21600,
|
|
// 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 ((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 ((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;
|
|
}
|
|
}
|
|
|
|
pAdjustment[nIndex].Value <<= fValue;
|
|
pAdjustment[nIndex++].State = css::beans::PropertyState_DIRECT_VALUE;
|
|
}
|
|
|
|
// Set attributes in CustomShapeGeometry
|
|
xDefaulter->createCustomShapeDefaults(sFontworkType);
|
|
|
|
auto aGeomPropSeq
|
|
= xSet->getPropertyValue("CustomShapeGeometry").get<uno::Sequence<beans::PropertyValue>>();
|
|
auto aGeomPropVec
|
|
= comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(aGeomPropSeq);
|
|
|
|
// Reset old properties
|
|
static constexpr OUString sTextPath(u"TextPath"_ustr);
|
|
static constexpr OUString sAdjustmentValues(u"AdjustmentValues"_ustr);
|
|
static constexpr OUString sPresetTextWarp(u"PresetTextWarp"_ustr);
|
|
|
|
resetPropertyValueInVec(aGeomPropVec, u"CoordinateSize"_ustr);
|
|
resetPropertyValueInVec(aGeomPropVec, u"Equations"_ustr);
|
|
resetPropertyValueInVec(aGeomPropVec, u"Path"_ustr);
|
|
resetPropertyValueInVec(aGeomPropVec, sAdjustmentValues);
|
|
resetPropertyValueInVec(aGeomPropVec, u"ViewBox"_ustr);
|
|
resetPropertyValueInVec(aGeomPropVec, u"Handles"_ustr);
|
|
resetPropertyValueInVec(aGeomPropVec, sTextPath);
|
|
resetPropertyValueInVec(aGeomPropVec, sPresetTextWarp);
|
|
|
|
bool bScaleX(false);
|
|
if (!bFromWordArt
|
|
&& (sMSPresetType == u"textArchDown" || sMSPresetType == u"textArchUp"
|
|
|| sMSPresetType == u"textCircle" || sMSPresetType == u"textButton"))
|
|
{
|
|
bScaleX = true;
|
|
}
|
|
|
|
// Apply new properties
|
|
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
|
|
{ { sTextPath, uno::Any(true) },
|
|
{ u"TextPathMode"_ustr, uno::Any(drawing::EnhancedCustomShapeTextPathMode_PATH) },
|
|
{ u"ScaleX"_ustr, uno::Any(bScaleX) } }));
|
|
aGeomPropVec.push_back(comphelper::makePropertyValue(sTextPath, aPropertyValues));
|
|
|
|
aGeomPropVec.push_back(comphelper::makePropertyValue(sPresetTextWarp, sMSPresetType));
|
|
|
|
if (!aAdjGdList.empty())
|
|
{
|
|
aGeomPropVec.push_back(comphelper::makePropertyValue(sAdjustmentValues, aAdjustment));
|
|
}
|
|
|
|
xSet->setPropertyValue(u"CustomShapeGeometry"_ustr,
|
|
uno::Any(comphelper::containerToSequence(aGeomPropVec)));
|
|
}
|
|
|
|
OString FontworkHelpers::GetVMLFontworkShapetypeMarkup(const MSO_SPT eShapeType)
|
|
{
|
|
// The markup is taken from VML in DOCX documents. Using the generated 'vml-shape-types' file
|
|
// does not work.
|
|
|
|
static const std::map<MSO_SPT, OString> aTypeToMarkupMap{
|
|
{ mso_sptTextSimple,
|
|
"<v:shapetype id=\"_x0000_t24\" coordsize=\"21600,21600\" o:spt=\"24\" adj=\"10800\" "
|
|
"path=\"m@7,l@8,m@5,21600l@6,21600e\"><v:formulas><v:f eqn=\"sum #0 0 10800\"/><v:f "
|
|
"eqn=\"prod #0 2 1\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 0 0 @2\"/><v:f "
|
|
"eqn=\"sum 21600 0 @3\"/><v:f eqn=\"if @0 @3 0\"/><v:f eqn=\"if @0 21600 @1\"/><v:f "
|
|
"eqn=\"if @0 0 @2\"/><v:f eqn=\"if @0 @4 21600\"/><v:f eqn=\"mid @5 @6\"/><v:f eqn=\"mid "
|
|
"@8 @5\"/><v:f eqn=\"mid @7 @8\"/><v:f eqn=\"mid @6 @7\"/><v:f eqn=\"sum @6 0 "
|
|
"@5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@9,0;@10,10800;@11,21600;@12,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"#0,bottomRight\" xrange=\"6629,14971\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextOctagon,
|
|
"<v:shapetype id=\"_x0000_t25\" coordsize=\"21600,21600\" o:spt=\"25\" adj=\"4800\" "
|
|
"path=\"m0@0l7200,r7200,l21600@0m0@1l7200,21600r7200,l21600@1e\"><v:formulas><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"sum 21600 0 @0\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"3086,10800\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextHexagon,
|
|
"<v:shapetype id=\"_x0000_t26\" coordsize=\"21600,21600\" o:spt=\"26\" adj=\"10800\" "
|
|
"path=\"m0@0l10800,,21600@0m,21600r10800,l21600,21600e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @1 10800 0\"/><v:f eqn=\"sum 21600 0 "
|
|
"@1\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;5400,@1;10800,21600;16200,@1\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"0,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCurve,
|
|
"<v:shapetype id=\"_x0000_t27\" coordsize=\"21600,21600\" o:spt=\"27\" adj=\"3086\" "
|
|
"path=\"m,qy10800@0,21600,m0@1qy10800,21600,21600@1e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 "
|
|
"0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@0;0,@2;10800,21600;21600,@2\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"center,#0\" yrange=\"0,7200\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextWave,
|
|
"<v:shapetype id=\"_x0000_t28\" coordsize=\"21600,21600\" o:spt=\"28\" "
|
|
"adj=\"2809,10800\" "
|
|
"path=\"m@25@0c@26@3@27@1@28@0m@21@4c@22@5@23@6@24@4e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 9\"/><v:f eqn=\"sum 0 0 "
|
|
"@2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 #1\"/><v:f eqn=\"prod @8 2 "
|
|
"3\"/><v:f eqn=\"prod @8 4 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @11\"/><v:f eqn=\"prod #1 2 "
|
|
"3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@15\"/><v:f eqn=\"sum 21600 0 @16\"/><v:f eqn=\"sum 21600 0 @17\"/><v:f eqn=\"if @7 @14 "
|
|
"0\"/><v:f eqn=\"if @7 @13 @15\"/><v:f eqn=\"if @7 @12 @16\"/><v:f eqn=\"if @7 21600 "
|
|
"@17\"/><v:f eqn=\"if @7 0 @20\"/><v:f eqn=\"if @7 @9 @19\"/><v:f eqn=\"if @7 @10 "
|
|
"@18\"/><v:f eqn=\"if @7 @11 21600\"/><v:f eqn=\"sum @24 0 @21\"/><v:f eqn=\"sum @4 0 "
|
|
"@0\"/><v:f eqn=\"max @21 @25\"/><v:f eqn=\"min @24 @28\"/><v:f eqn=\"prod @0 2 "
|
|
"1\"/><v:f eqn=\"sum 21600 0 @33\"/><v:f eqn=\"mid @26 @27\"/><v:f eqn=\"mid @24 "
|
|
"@28\"/><v:f eqn=\"mid @22 @23\"/><v:f eqn=\"mid @21 @25\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@35,@0;@38,10800;@37,@4;@36,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,4459\"/><v:h "
|
|
"position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextRing,
|
|
"<v:shapetype id=\"_x0000_t29\" coordsize=\"21600,21600\" o:spt=\"29\" "
|
|
"adj=\"11796480,5400\" "
|
|
"path=\"al10800,10800,10800,10800@2@14al10800,10800@0@0@2@14e\"><v:formulas><v:f "
|
|
"eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 "
|
|
"180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 "
|
|
"90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 "
|
|
"90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 "
|
|
"@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 "
|
|
"@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 "
|
|
"2\"/><v:f eqn=\"sum @18 5400 0\"/><v:f eqn=\"cos @19 #0\"/><v:f eqn=\"sin @19 "
|
|
"#0\"/><v:f eqn=\"sum @20 10800 0\"/><v:f eqn=\"sum @21 10800 0\"/><v:f eqn=\"sum 10800 "
|
|
"0 @20\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if @9 @17 @25\"/><v:f eqn=\"if @9 0 "
|
|
"21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@27;@22,@23;10800,@26;@24,@23\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" "
|
|
"radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextOnCurve,
|
|
"<v:shapetype id=\"_x0000_t30\" coordsize=\"21600,21600\" o:spt=\"30\" adj=\"3086\" "
|
|
"path=\"m,qy10800@0,21600,m0@1qy10800,21600,21600@1e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 "
|
|
"0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@0;0,@2;10800,21600;21600,@2\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"center,#0\" yrange=\"0,7200\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextOnRing,
|
|
"<v:shapetype id=\"_x0000_t31\" coordsize=\"21600,21600\" o:spt=\"31\" adj=\"11796480\" "
|
|
"path=\"al10800,10800,10800,10800@2@14e\"><v:formulas><v:f eqn=\"val #1\"/><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 180\"/><v:f "
|
|
"eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 90 0\"/><v:f "
|
|
"eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 90\"/><v:f eqn=\"if "
|
|
"@9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 @10\"/><v:f "
|
|
"eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 @14\"/><v:f "
|
|
"eqn=\"val 10800\"/><v:f eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum "
|
|
"@17 10800 0\"/><v:f eqn=\"sum @18 10800 0\"/><v:f eqn=\"sum 10800 0 @17\"/><v:f "
|
|
"eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 @18\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@22;@19,@20;@21,@20\"/><v:textpath on=\"t\" "
|
|
"style=\"v-text-kern:t\" fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" "
|
|
"polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextPlainText,
|
|
"<v:shapetype id=\"_x0000_t136\" coordsize=\"21600,21600\" o:spt=\"136\" adj=\"10800\" "
|
|
"path=\"m@7,l@8,m@5,21600l@6,21600e\"><v:formulas><v:f eqn=\"sum #0 0 10800\"/><v:f "
|
|
"eqn=\"prod #0 2 1\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 0 0 @2\"/><v:f "
|
|
"eqn=\"sum 21600 0 @3\"/><v:f eqn=\"if @0 @3 0\"/><v:f eqn=\"if @0 21600 @1\"/><v:f "
|
|
"eqn=\"if @0 0 @2\"/><v:f eqn=\"if @0 @4 21600\"/><v:f eqn=\"mid @5 @6\"/><v:f eqn=\"mid "
|
|
"@8 @5\"/><v:f eqn=\"mid @7 @8\"/><v:f eqn=\"mid @6 @7\"/><v:f eqn=\"sum @6 0 "
|
|
"@5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@9,0;@10,10800;@11,21600;@12,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"#0,bottomRight\" xrange=\"6629,14971\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextStop,
|
|
"<v:shapetype id=\"_x0000_t137\" coordsize=\"21600,21600\" o:spt=\"137\" adj=\"4800\" "
|
|
"path=\"m0@0l7200,r7200,l21600@0m0@1l7200,21600r7200,l21600@1e\"><v:formulas><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"sum 21600 0 @0\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"3086,10800\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextTriangle,
|
|
"<v:shapetype id=\"_x0000_t138\" coordsize=\"21600,21600\" o:spt=\"138\" adj=\"10800\" "
|
|
"path=\"m0@0l10800,,21600@0m,21600r10800,l21600,21600e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @1 10800 0\"/><v:f eqn=\"sum 21600 0 "
|
|
"@1\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;5400,@1;10800,21600;16200,@1\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"0,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextTriangleInverted,
|
|
"<v:shapetype id=\"_x0000_t139\" coordsize=\"21600,21600\" o:spt=\"139\" adj=\"10800\" "
|
|
"path=\"m,l10800,,21600,m0@0l10800,21600,21600@0e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @1 10800 0\"/><v:f eqn=\"sum 21600 0 "
|
|
"@1\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;5400,@2;10800,21600;16200,@2\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"0,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextChevron,
|
|
"<v:shapetype id=\"_x0000_t140\" coordsize=\"21600,21600\" o:spt=\"140\" adj=\"5400\" "
|
|
"path=\"m0@0l10800,,21600@0m,21600l10800@1,21600,21600e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"sum 21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 "
|
|
"0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;0,@3;10800,@1;21600,@3\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextChevronInverted,
|
|
"<v:shapetype id=\"_x0000_t141\" coordsize=\"21600,21600\" o:spt=\"141\" adj=\"16200\" "
|
|
"path=\"m,l10800@1,21600,m0@0l10800,21600,21600@0e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"sum 21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 "
|
|
"0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@1;0,@2;10800,21600;21600,@2\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"10800,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextRingInside,
|
|
"<v:shapetype id=\"_x0000_t142\" coordsize=\"21600,21600\" o:spt=\"142\" adj=\"13500\" "
|
|
"path=\"m0@1qy10800,,21600@1,10800@0,0@1m0@2qy10800@3,21600@2,10800,21600,0@2e\"><v:"
|
|
"formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum height 0 "
|
|
"@1\"/><v:f eqn=\"sum height 0 #0\"/><v:f eqn=\"sum @2 0 @1\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;10800,@0;0,10800;10800,21600;10800,@3;21600,10800\" "
|
|
"o:connectangles=\"270,270,180,90,90,0\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"10800,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextRingOutside,
|
|
"<v:shapetype id=\"_x0000_t143\" coordsize=\"21600,21600\" o:spt=\"143\" adj=\"13500\" "
|
|
"path=\"m0@1qy10800@0,21600@1,10800,,0@1m0@2qy10800,21600,21600@2,10800@3,0@2e\"><v:"
|
|
"formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum height 0 "
|
|
"@1\"/><v:f eqn=\"sum height 0 #0\"/><v:f eqn=\"sum @2 0 @1\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;10800,@0;0,10800;10800,21600;10800,@3;21600,10800\" "
|
|
"o:connectangles=\"270,270,180,90,90,0\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"10800,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextArchUpCurve,
|
|
"<v:shapetype id=\"_x0000_t144\" coordsize=\"21600,21600\" o:spt=\"144\" "
|
|
"adj=\"11796480\" path=\"al10800,10800,10800,10800@2@14e\"><v:formulas><v:f eqn=\"val "
|
|
"#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 "
|
|
"180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 "
|
|
"90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 "
|
|
"90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 "
|
|
"@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 "
|
|
"@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 "
|
|
"#0\"/><v:f eqn=\"sum @17 10800 0\"/><v:f eqn=\"sum @18 10800 0\"/><v:f eqn=\"sum 10800 "
|
|
"0 @17\"/><v:f eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 @18\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@22;@19,@20;@21,@20\"/><v:textpath on=\"t\" "
|
|
"style=\"v-text-kern:t\" fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" "
|
|
"polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextArchDownCurve,
|
|
"<v:shapetype id=\"_x0000_t145\" coordsize=\"21600,21600\" o:spt=\"145\" "
|
|
"path=\"al10800,10800,10800,10800@3@15e\"><v:formulas><v:f eqn=\"val #1\"/><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 180\"/><v:f "
|
|
"eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 90 0\"/><v:f "
|
|
"eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 90\"/><v:f eqn=\"if "
|
|
"@9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 @10\"/><v:f "
|
|
"eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 @14\"/><v:f "
|
|
"eqn=\"val 10800\"/><v:f eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum "
|
|
"@17 10800 0\"/><v:f eqn=\"sum @18 10800 0\"/><v:f eqn=\"sum 10800 0 @17\"/><v:f "
|
|
"eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 @18\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@22;@19,@20;@21,@20\"/><v:textpath on=\"t\" "
|
|
"style=\"v-text-kern:t\" fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" "
|
|
"polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCircleCurve,
|
|
"<v:shapetype id=\"_x0000_t146\" coordsize=\"21600,21600\" o:spt=\"146\" "
|
|
"adj=\"-11730944\" path=\"al10800,10800,10800,10800@2@5e\"><v:formulas><v:f eqn=\"val "
|
|
"#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"prod #0 2 1\"/><v:f "
|
|
"eqn=\"sumangle @3 0 360\"/><v:f eqn=\"if @3 @4 @3\"/><v:f eqn=\"val 10800\"/><v:f "
|
|
"eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum @7 10800 0\"/><v:f "
|
|
"eqn=\"sum @8 10800 0\"/><v:f eqn=\"sum 10800 0 @8\"/><v:f eqn=\"if #0 0 "
|
|
"21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@12,10800;@9,@10;@9,@11\"/><v:textpath on=\"t\" style=\"v-text-kern:t\" "
|
|
"fitpath=\"t\"/><v:handles><v:h position=\"@6,#0\" "
|
|
"polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextButtonCurve,
|
|
"<v:shapetype id=\"_x0000_t147\" coordsize=\"21600,21600\" o:spt=\"147\" "
|
|
"adj=\"11796480\" "
|
|
"path=\"al10800,10800,10800,10800@2@14m,10800r21600,al10800,10800,10800,10800@1@15e\"><v:"
|
|
"formulas><v:f eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f "
|
|
"eqn=\"sumangle #0 0 180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 "
|
|
"1\"/><v:f eqn=\"sumangle #0 90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f "
|
|
"eqn=\"sumangle @8 0 90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 "
|
|
"360\"/><v:f eqn=\"if @10 @11 @10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 "
|
|
"@13 @12\"/><v:f eqn=\"sum 0 0 @14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"cos 10800 "
|
|
"#0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum @17 10800 0\"/><v:f eqn=\"sum @18 10800 "
|
|
"0\"/><v:f eqn=\"sum 10800 0 @17\"/><v:f eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 "
|
|
"@18\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;@19,@20;@21,@20;10800,10800;0,10800;21600,10800;10800,21600;@19,"
|
|
"@23;@21,@23\"/><v:textpath on=\"t\" style=\"v-text-kern:t\" "
|
|
"fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" "
|
|
"polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextArchUpPour,
|
|
"<v:shapetype id=\"_x0000_t148\" coordsize=\"21600,21600\" o:spt=\"148\" "
|
|
"adj=\"11796480,5400\" "
|
|
"path=\"al10800,10800,10800,10800@2@14al10800,10800@0@0@2@14e\"><v:formulas><v:f "
|
|
"eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 "
|
|
"180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 "
|
|
"90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 "
|
|
"90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 "
|
|
"@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 "
|
|
"@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 "
|
|
"2\"/><v:f eqn=\"sum @18 5400 0\"/><v:f eqn=\"cos @19 #0\"/><v:f eqn=\"sin @19 "
|
|
"#0\"/><v:f eqn=\"sum @20 10800 0\"/><v:f eqn=\"sum @21 10800 0\"/><v:f eqn=\"sum 10800 "
|
|
"0 @20\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if @9 @17 @25\"/><v:f eqn=\"if @9 0 "
|
|
"21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@27;@22,@23;10800,@26;@24,@23\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" "
|
|
"radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextArchDownPour,
|
|
"<v:shapetype id=\"_x0000_t149\" coordsize=\"21600,21600\" o:spt=\"149\" adj=\",5400\" "
|
|
"path=\"al10800,10800@0@0@3@15al10800,10800,10800,10800@3@15e\"><v:formulas><v:f "
|
|
"eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 "
|
|
"180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 "
|
|
"90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 "
|
|
"90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 "
|
|
"@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 "
|
|
"@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 "
|
|
"2\"/><v:f eqn=\"sum @18 5400 0\"/><v:f eqn=\"cos @19 #0\"/><v:f eqn=\"sin @19 "
|
|
"#0\"/><v:f eqn=\"sum @20 10800 0\"/><v:f eqn=\"sum @21 10800 0\"/><v:f eqn=\"sum 10800 "
|
|
"0 @20\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if @9 @17 @25\"/><v:f eqn=\"if @9 0 "
|
|
"21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@27;@22,@23;10800,@26;@24,@23\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" "
|
|
"radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCirclePour,
|
|
"<v:shapetype id=\"_x0000_t150\" coordsize=\"21600,21600\" o:spt=\"150\" "
|
|
"adj=\"-11730944,5400\" "
|
|
"path=\"al10800,10800,10800,10800@2@5al10800,10800@0@0@2@5e\"><v:formulas><v:f eqn=\"val "
|
|
"#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"prod #0 2 1\"/><v:f "
|
|
"eqn=\"sumangle @3 0 360\"/><v:f eqn=\"if @3 @4 @3\"/><v:f eqn=\"val 10800\"/><v:f "
|
|
"eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 2\"/><v:f eqn=\"sum @8 5400 0\"/><v:f "
|
|
"eqn=\"cos @9 #0\"/><v:f eqn=\"sin @9 #0\"/><v:f eqn=\"sum @10 10800 0\"/><v:f eqn=\"sum "
|
|
"@11 10800 0\"/><v:f eqn=\"sum 10800 0 @11\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if "
|
|
"#0 @7 @15\"/><v:f eqn=\"if #0 0 21600\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@17,10800;@12,@13;@16,10800;@12,@14\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" "
|
|
"radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextButtonPour,
|
|
"<v:shapetype id=\"_x0000_t151\" coordsize=\"21600,21600\" o:spt=\"151\" "
|
|
"adj=\"11796480,5400\" "
|
|
"path=\"al10800,10800,10800,10800@2@14al10800,10800@0@0@2@14m@25@17l@26@17m@25@18l@26@"
|
|
"18al10800,10800@0@0@1@15al10800,10800,10800,10800@1@15e\"><v:formulas><v:f eqn=\"val "
|
|
"#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 "
|
|
"180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 "
|
|
"90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 "
|
|
"90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 "
|
|
"@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 "
|
|
"@14\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"prod @16 1 2\"/><v:f eqn=\"sum 21600 0 "
|
|
"@17\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod @19 1 2\"/><v:f eqn=\"prod @20 @20 "
|
|
"1\"/><v:f eqn=\"prod #1 #1 1\"/><v:f eqn=\"sum @22 0 @21\"/><v:f eqn=\"sqrt @23\"/><v:f "
|
|
"eqn=\"sum 10800 0 @24\"/><v:f eqn=\"sum @24 10800 0\"/><v:f eqn=\"val 10800\"/><v:f "
|
|
"eqn=\"cos @17 #0\"/><v:f eqn=\"sin @17 #0\"/><v:f eqn=\"sum @28 10800 0\"/><v:f "
|
|
"eqn=\"sum @29 10800 0\"/><v:f eqn=\"sum 10800 0 @28\"/><v:f eqn=\"sum 10800 0 "
|
|
"@29\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;@30,@31;10800,@19;@32,@31;10800,@17;@25,10800;10800,@18;@26,"
|
|
"10800;10800,@16;@30,@33;10800,21600;@32,@33\"/><v:textpath on=\"t\" "
|
|
"fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" "
|
|
"radiusrange=\"4320,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCurveUp,
|
|
"<v:shapetype id=\"_x0000_t152\" coordsize=\"21600,21600\" o:spt=\"152\" adj=\"9931\" "
|
|
"path=\"m0@0c7200@2,14400@1,21600,m0@5c7200@6,14400@6,21600@5e\"><v:formulas><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"prod #0 3 4\"/><v:f eqn=\"prod #0 5 4\"/><v:f eqn=\"prod #0 "
|
|
"3 8\"/><v:f eqn=\"prod #0 1 8\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum @4 21600 "
|
|
"0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @5 1 2\"/><v:f eqn=\"sum @7 @8 0\"/><v:f "
|
|
"eqn=\"prod #0 7 8\"/><v:f eqn=\"prod @5 1 3\"/><v:f eqn=\"sum @1 @2 0\"/><v:f eqn=\"sum "
|
|
"@12 @0 0\"/><v:f eqn=\"prod @13 1 4\"/><v:f eqn=\"sum @11 14400 "
|
|
"@14\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@10;0,@9;10800,21600;21600,@8\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" "
|
|
"yrange=\"0,12169\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCurveDown,
|
|
"<v:shapetype id=\"_x0000_t153\" coordsize=\"21600,21600\" o:spt=\"153\" adj=\"9391\" "
|
|
"path=\"m,c7200@1,14400@2,21600@0m0@5c7200@6,14400@6,21600@5e\"><v:formulas><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"prod #0 3 4\"/><v:f eqn=\"prod #0 5 4\"/><v:f eqn=\"prod #0 "
|
|
"3 8\"/><v:f eqn=\"prod #0 1 8\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum @4 21600 "
|
|
"0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @5 1 2\"/><v:f eqn=\"sum @7 @8 0\"/><v:f "
|
|
"eqn=\"prod #0 7 8\"/><v:f eqn=\"prod @5 1 3\"/><v:f eqn=\"sum @1 @2 0\"/><v:f eqn=\"sum "
|
|
"@12 @0 0\"/><v:f eqn=\"prod @13 1 4\"/><v:f eqn=\"sum @11 14400 "
|
|
"@14\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@10;0,@8;10800,21600;21600,@9\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"bottomRight,#0\" "
|
|
"yrange=\"0,11368\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCascadeUp,
|
|
"<v:shapetype id=\"_x0000_t154\" coordsize=\"21600,21600\" o:spt=\"154\" adj=\"9600\" "
|
|
"path=\"m0@2l21600,m,21600l21600@0e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 #0\"/><v:f eqn=\"prod @1 1 4\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @2 1 "
|
|
"2\"/><v:f eqn=\"sum @3 10800 0\"/><v:f eqn=\"sum @4 10800 0\"/><v:f eqn=\"sum @0 21600 "
|
|
"@2\"/><v:f eqn=\"prod @7 1 2\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" o:connectlocs=\"10800,@4;0,@6;10800,@5;21600,@3\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"bottomRight,#0\" yrange=\"6171,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCascadeDown,
|
|
"<v:shapetype id=\"_x0000_t155\" coordsize=\"21600,21600\" o:spt=\"155\" adj=\"9600\" "
|
|
"path=\"m,l21600@2m0@0l21600,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 #0\"/><v:f eqn=\"prod @1 1 4\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @2 1 "
|
|
"2\"/><v:f eqn=\"sum @3 10800 0\"/><v:f eqn=\"sum @4 10800 0\"/><v:f eqn=\"sum @0 21600 "
|
|
"@2\"/><v:f eqn=\"prod @7 1 2\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" o:connectlocs=\"10800,@4;0,@3;10800,@5;21600,@6\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"6171,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextWave1,
|
|
"<v:shapetype id=\"_x0000_t156\" coordsize=\"21600,21600\" o:spt=\"156\" "
|
|
"adj=\"2809,10800\" "
|
|
"path=\"m@25@0c@26@3@27@1@28@0m@21@4c@22@5@23@6@24@4e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 9\"/><v:f eqn=\"sum 0 0 "
|
|
"@2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 #1\"/><v:f eqn=\"prod @8 2 "
|
|
"3\"/><v:f eqn=\"prod @8 4 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @11\"/><v:f eqn=\"prod #1 2 "
|
|
"3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@15\"/><v:f eqn=\"sum 21600 0 @16\"/><v:f eqn=\"sum 21600 0 @17\"/><v:f eqn=\"if @7 @14 "
|
|
"0\"/><v:f eqn=\"if @7 @13 @15\"/><v:f eqn=\"if @7 @12 @16\"/><v:f eqn=\"if @7 21600 "
|
|
"@17\"/><v:f eqn=\"if @7 0 @20\"/><v:f eqn=\"if @7 @9 @19\"/><v:f eqn=\"if @7 @10 "
|
|
"@18\"/><v:f eqn=\"if @7 @11 21600\"/><v:f eqn=\"sum @24 0 @21\"/><v:f eqn=\"sum @4 0 "
|
|
"@0\"/><v:f eqn=\"max @21 @25\"/><v:f eqn=\"min @24 @28\"/><v:f eqn=\"prod @0 2 "
|
|
"1\"/><v:f eqn=\"sum 21600 0 @33\"/><v:f eqn=\"mid @26 @27\"/><v:f eqn=\"mid @24 "
|
|
"@28\"/><v:f eqn=\"mid @22 @23\"/><v:f eqn=\"mid @21 @25\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@35,@0;@38,10800;@37,@4;@36,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,4459\"/><v:h "
|
|
"position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextWave2,
|
|
"<v:shapetype id=\"_x0000_t157\" coordsize=\"21600,21600\" o:spt=\"157\" "
|
|
"adj=\"2809,10800\" "
|
|
"path=\"m@25@0c@26@1@27@3@28@0m@21@4c@22@6@23@5@24@4e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 9\"/><v:f eqn=\"sum 0 0 "
|
|
"@2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 #1\"/><v:f eqn=\"prod @8 2 "
|
|
"3\"/><v:f eqn=\"prod @8 4 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @11\"/><v:f eqn=\"prod #1 2 "
|
|
"3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@15\"/><v:f eqn=\"sum 21600 0 @16\"/><v:f eqn=\"sum 21600 0 @17\"/><v:f eqn=\"if @7 @14 "
|
|
"0\"/><v:f eqn=\"if @7 @13 @15\"/><v:f eqn=\"if @7 @12 @16\"/><v:f eqn=\"if @7 21600 "
|
|
"@17\"/><v:f eqn=\"if @7 0 @20\"/><v:f eqn=\"if @7 @9 @19\"/><v:f eqn=\"if @7 @10 "
|
|
"@18\"/><v:f eqn=\"if @7 @11 21600\"/><v:f eqn=\"sum @24 0 @21\"/><v:f eqn=\"sum @4 0 "
|
|
"@0\"/><v:f eqn=\"max @21 @25\"/><v:f eqn=\"min @24 @28\"/><v:f eqn=\"prod @0 2 "
|
|
"1\"/><v:f eqn=\"sum 21600 0 @33\"/><v:f eqn=\"mid @26 @27\"/><v:f eqn=\"mid @24 "
|
|
"@28\"/><v:f eqn=\"mid @22 @23\"/><v:f eqn=\"mid @21 @25\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"@35,@0;@38,10800;@37,@4;@36,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,4459\"/><v:h "
|
|
"position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextWave3,
|
|
"<v:shapetype id=\"_x0000_t158\" coordsize=\"21600,21600\" o:spt=\"158\" "
|
|
"adj=\"1404,10800\" "
|
|
"path=\"m@37@0c@38@3@39@1@40@0@41@3@42@1@43@0m@30@4c@31@5@32@6@33@4@34@5@35@6@36@4e\"><v:"
|
|
"formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 "
|
|
"9\"/><v:f eqn=\"sum 0 0 @2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 "
|
|
"@1\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 "
|
|
"#1\"/><v:f eqn=\"prod @8 1 3\"/><v:f eqn=\"prod @8 2 3\"/><v:f eqn=\"prod @8 4 "
|
|
"3\"/><v:f eqn=\"prod @8 5 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @8\"/><v:f eqn=\"sum 21600 0 "
|
|
"@11\"/><v:f eqn=\"sum 21600 0 @12\"/><v:f eqn=\"sum 21600 0 @13\"/><v:f eqn=\"prod #1 1 "
|
|
"3\"/><v:f eqn=\"prod #1 2 3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 5 3\"/><v:f "
|
|
"eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 @20\"/><v:f eqn=\"sum 21600 0 @21\"/><v:f "
|
|
"eqn=\"sum 21600 0 @22\"/><v:f eqn=\"sum 21600 0 @23\"/><v:f eqn=\"sum 21600 0 "
|
|
"@24\"/><v:f eqn=\"if @7 @19 0\"/><v:f eqn=\"if @7 @18 @20\"/><v:f eqn=\"if @7 @17 "
|
|
"@21\"/><v:f eqn=\"if @7 @16 #1\"/><v:f eqn=\"if @7 @15 @22\"/><v:f eqn=\"if @7 @14 "
|
|
"@23\"/><v:f eqn=\"if @7 21600 @24\"/><v:f eqn=\"if @7 0 @29\"/><v:f eqn=\"if @7 @9 "
|
|
"@28\"/><v:f eqn=\"if @7 @10 @27\"/><v:f eqn=\"if @7 @8 @8\"/><v:f eqn=\"if @7 @11 "
|
|
"@26\"/><v:f eqn=\"if @7 @12 @25\"/><v:f eqn=\"if @7 @13 21600\"/><v:f eqn=\"sum @36 0 "
|
|
"@30\"/><v:f eqn=\"sum @4 0 @0\"/><v:f eqn=\"max @30 @37\"/><v:f eqn=\"min @36 "
|
|
"@43\"/><v:f eqn=\"prod @0 2 1\"/><v:f eqn=\"sum 21600 0 @48\"/><v:f eqn=\"mid @36 "
|
|
"@43\"/><v:f eqn=\"mid @30 @37\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" o:connectlocs=\"@40,@0;@51,10800;@33,@4;@50,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,2229\"/><v:h "
|
|
"position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextWave4,
|
|
"<v:shapetype id=\"_x0000_t159\" coordsize=\"21600,21600\" o:spt=\"159\" "
|
|
"adj=\"1404,10800\" "
|
|
"path=\"m@37@0c@38@1@39@3@40@0@41@1@42@3@43@0m@30@4c@31@6@32@5@33@4@34@6@35@5@36@4e\"><v:"
|
|
"formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 "
|
|
"9\"/><v:f eqn=\"sum 0 0 @2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 "
|
|
"@1\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 "
|
|
"#1\"/><v:f eqn=\"prod @8 1 3\"/><v:f eqn=\"prod @8 2 3\"/><v:f eqn=\"prod @8 4 "
|
|
"3\"/><v:f eqn=\"prod @8 5 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 "
|
|
"@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @8\"/><v:f eqn=\"sum 21600 0 "
|
|
"@11\"/><v:f eqn=\"sum 21600 0 @12\"/><v:f eqn=\"sum 21600 0 @13\"/><v:f eqn=\"prod #1 1 "
|
|
"3\"/><v:f eqn=\"prod #1 2 3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 5 3\"/><v:f "
|
|
"eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 @20\"/><v:f eqn=\"sum 21600 0 @21\"/><v:f "
|
|
"eqn=\"sum 21600 0 @22\"/><v:f eqn=\"sum 21600 0 @23\"/><v:f eqn=\"sum 21600 0 "
|
|
"@24\"/><v:f eqn=\"if @7 @19 0\"/><v:f eqn=\"if @7 @18 @20\"/><v:f eqn=\"if @7 @17 "
|
|
"@21\"/><v:f eqn=\"if @7 @16 #1\"/><v:f eqn=\"if @7 @15 @22\"/><v:f eqn=\"if @7 @14 "
|
|
"@23\"/><v:f eqn=\"if @7 21600 @24\"/><v:f eqn=\"if @7 0 @29\"/><v:f eqn=\"if @7 @9 "
|
|
"@28\"/><v:f eqn=\"if @7 @10 @27\"/><v:f eqn=\"if @7 @8 @8\"/><v:f eqn=\"if @7 @11 "
|
|
"@26\"/><v:f eqn=\"if @7 @12 @25\"/><v:f eqn=\"if @7 @13 21600\"/><v:f eqn=\"sum @36 0 "
|
|
"@30\"/><v:f eqn=\"sum @4 0 @0\"/><v:f eqn=\"max @30 @37\"/><v:f eqn=\"min @36 "
|
|
"@43\"/><v:f eqn=\"prod @0 2 1\"/><v:f eqn=\"sum 21600 0 @48\"/><v:f eqn=\"mid @36 "
|
|
"@43\"/><v:f eqn=\"mid @30 @37\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" o:connectlocs=\"@40,@0;@51,10800;@33,@4;@50,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,2229\"/><v:h "
|
|
"position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextInflate,
|
|
"<v:shapetype id=\"_x0000_t160\" coordsize=\"21600,21600\" o:spt=\"160\" adj=\"2945\" "
|
|
"path=\"m0@0c7200@2,14400@2,21600@0m0@3c7200@4,14400@4,21600@3e\"><v:formulas><v:f "
|
|
"eqn=\"val #0\"/><v:f eqn=\"prod #0 1 3\"/><v:f eqn=\"sum 0 0 @1\"/><v:f eqn=\"sum 21600 "
|
|
"0 #0\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"prod #0 2 3\"/><v:f eqn=\"sum 21600 0 "
|
|
"@5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"rect\"/><v:textpath "
|
|
"on=\"t\" fitshape=\"t\" xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" "
|
|
"yrange=\"0,4629\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextDeflate,
|
|
"<v:shapetype id=\"_x0000_t161\" coordsize=\"21600,21600\" o:spt=\"161\" adj=\"4050\" "
|
|
"path=\"m,c7200@0,14400@0,21600,m,21600c7200@1,14400@1,21600,21600e\"><v:formulas><v:f "
|
|
"eqn=\"prod #0 4 3\"/><v:f eqn=\"sum 21600 0 @0\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 #0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@2;0,10800;10800,@3;21600,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"0,8100\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextInflateBottom,
|
|
"<v:shapetype id=\"_x0000_t162\" coordsize=\"21600,21600\" o:spt=\"162\" adj=\"14706\" "
|
|
"path=\"m,l21600,m0@0c7200@2,14400@2,21600@0e\"><v:formulas><v:f eqn=\"val #0\"/><v:f "
|
|
"eqn=\"prod #0 1 3\"/><v:f eqn=\"sum 28800 0 @1\"/><v:f eqn=\"prod #0 1 2\"/><v:f "
|
|
"eqn=\"sum @1 7200 0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;0,@3;10800,21600;21600,@3\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" "
|
|
"yrange=\"11148,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextDeflateBottom,
|
|
"<v:shapetype id=\"_x0000_t163\" coordsize=\"21600,21600\" o:spt=\"163\" adj=\"11475\" "
|
|
"path=\"m,l21600,m,21600c7200@1,14400@1,21600,21600e\"><v:formulas><v:f eqn=\"prod #0 4 "
|
|
"3\"/><v:f eqn=\"sum @0 0 7200\"/><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 2 3\"/><v:f "
|
|
"eqn=\"sum @3 7200 0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;0,10800;10800,@2;21600,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"1350,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextInflateTop,
|
|
"<v:shapetype id=\"_x0000_t164\" coordsize=\"21600,21600\" o:spt=\"164\" adj=\"6894\" "
|
|
"path=\"m0@0c7200@2,14400@2,21600@0m,21600r21600,e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"prod #0 1 3\"/><v:f eqn=\"sum 0 0 @1\"/><v:f eqn=\"prod #0 1 2\"/><v:f "
|
|
"eqn=\"sum @3 10800 0\"/><v:f eqn=\"sum 21600 0 @1\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;0,@4;10800,21600;21600,@4\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" "
|
|
"yrange=\"0,10452\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextDeflateTop,
|
|
"<v:shapetype id=\"_x0000_t165\" coordsize=\"21600,21600\" o:spt=\"165\" adj=\"10125\" "
|
|
"path=\"m,c7200@0,14400@0,21600,m,21600r21600,e\"><v:formulas><v:f eqn=\"prod #0 4 "
|
|
"3\"/><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 2 3\"/><v:f eqn=\"sum 21600 0 "
|
|
"@2\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@1;0,10800;10800,21600;21600,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"0,20250\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextDeflateInflate,
|
|
"<v:shapetype id=\"_x0000_t166\" coordsize=\"21600,21600\" o:spt=\"166\" adj=\"6054\" "
|
|
"path=\"m,l21600,m,10125c7200@1,14400@1,21600,10125m,11475c7200@2,14400@2,21600,11475m,"
|
|
"21600r21600,e\"><v:formulas><v:f eqn=\"prod #0 4 3\"/><v:f eqn=\"sum @0 0 4275\"/><v:f "
|
|
"eqn=\"sum @0 0 2925\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"1308,20292\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextDeflateInflateDeflate,
|
|
"<v:shapetype id=\"_x0000_t167\" coordsize=\"21600,21600\" o:spt=\"167\" adj=\"6054\" "
|
|
"path=\"m,l21600,m,6609c7200@1,14400@1,21600,6609m,7491c7200@2,14400@2,21600,7491m,"
|
|
"14109c7200@4,14400@4,21600,14109m,14991c7200@3,14400@3,21600,14991m,21600r21600,e\"><v:"
|
|
"formulas><v:f eqn=\"prod #0 4 3\"/><v:f eqn=\"sum @0 0 2791\"/><v:f eqn=\"sum @0 0 "
|
|
"1909\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 @2\"/></v:formulas><v:path "
|
|
"textpathok=\"t\" o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\" "
|
|
"xscale=\"t\"/><v:handles><v:h position=\"center,#0\" "
|
|
"yrange=\"854,9525\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextFadeRight,
|
|
"<v:shapetype id=\"_x0000_t168\" coordsize=\"21600,21600\" o:spt=\"168\" adj=\"7200\" "
|
|
"path=\"m,l21600@0m,21600l21600@1e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 "
|
|
"21600 @0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@2;0,10800;10800,@3;21600,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"bottomRight,#0\" yrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextFadeLeft,
|
|
"<v:shapetype id=\"_x0000_t169\" coordsize=\"21600,21600\" o:spt=\"169\" adj=\"7200\" "
|
|
"path=\"m0@0l21600,m0@1l21600,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 "
|
|
"21600 @0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@2;0,10800;10800,@3;21600,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextFadeUp,
|
|
"<v:shapetype id=\"_x0000_t170\" coordsize=\"21600,21600\" o:spt=\"170\" adj=\"7200\" "
|
|
"path=\"m@0,l@1,m,21600r21600,e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum 21600 "
|
|
"0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 21600 "
|
|
"@0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;@2,10800;10800,21600;@3,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"#0,topLeft\" xrange=\"0,10792\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextFadeDown,
|
|
"<v:shapetype id=\"_x0000_t171\" coordsize=\"21600,21600\" o:spt=\"171\" adj=\"7200\" "
|
|
"path=\"m,l21600,m@0,21600l@1,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 "
|
|
"21600 @0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;@2,10800;10800,21600;@3,10800\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"#0,bottomRight\" xrange=\"0,10792\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextSlantUp,
|
|
"<v:shapetype id=\"_x0000_t172\" coordsize=\"21600,21600\" o:spt=\"172\" adj=\"12000\" "
|
|
"path=\"m0@0l21600,m,21600l21600@1e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 0\"/><v:f eqn=\"prod @1 "
|
|
"1 2\"/><v:f eqn=\"sum @4 10800 0\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" o:connectlocs=\"10800,@2;0,@3;10800,@5;21600,@4\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"0,15429\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextSlantDown,
|
|
"<v:shapetype id=\"_x0000_t173\" coordsize=\"21600,21600\" o:spt=\"173\" adj=\"9600\" "
|
|
"path=\"m,l21600@1m0@0l21600,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum "
|
|
"21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 0\"/><v:f eqn=\"prod @1 "
|
|
"1 2\"/><v:f eqn=\"sum @4 10800 0\"/></v:formulas><v:path textpathok=\"t\" "
|
|
"o:connecttype=\"custom\" o:connectlocs=\"10800,@4;0,@2;10800,@3;21600,@5\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"topLeft,#0\" yrange=\"6171,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCanUp,
|
|
"<v:shapetype id=\"_x0000_t174\" coordsize=\"21600,21600\" o:spt=\"174\" adj=\"18514\" "
|
|
"path=\"m0@1qy10800,,21600@1m,21600qy10800@0,21600,21600e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 "
|
|
"0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,0;0,@3;10800,@0;21600,@3\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"center,#0\" yrange=\"14400,21600\"/></v:handles><o:lock v:ext=\"edit\" "
|
|
"text=\"t\" shapetype=\"t\"/></v:shapetype>" },
|
|
{ mso_sptTextCanDown,
|
|
"<v:shapetype id=\"_x0000_t175\" coordsize=\"21600,21600\" o:spt=\"175\" adj=\"3086\" "
|
|
"path=\"m,qy10800@0,21600,m0@1qy10800,21600,21600@1e\"><v:formulas><v:f eqn=\"val "
|
|
"#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 "
|
|
"0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" "
|
|
"o:connectlocs=\"10800,@0;0,@2;10800,21600;21600,@2\" "
|
|
"o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h "
|
|
"position=\"center,#0\" yrange=\"0,7200\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" "
|
|
"shapetype=\"t\"/></v:shapetype>" }
|
|
};
|
|
|
|
auto i(aTypeToMarkupMap.find(eShapeType));
|
|
return i == aTypeToMarkupMap.end() ? OString() : i->second;
|
|
}
|
|
|
|
void FontworkHelpers::collectCharColorProps(const uno::Reference<text::XText>& rXText,
|
|
std::vector<beans::PropertyValue>& rCharPropVec)
|
|
{
|
|
if (!rXText.is())
|
|
return;
|
|
uno::Reference<text::XTextCursor> rXTextCursor = rXText->createTextCursor();
|
|
rXTextCursor->gotoStart(false);
|
|
rXTextCursor->gotoEnd(true);
|
|
uno::Reference<container::XEnumerationAccess> paraEnumAccess(rXText, uno::UNO_QUERY);
|
|
if (!paraEnumAccess.is())
|
|
return;
|
|
uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration());
|
|
while (paraEnum->hasMoreElements())
|
|
{
|
|
uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY);
|
|
uno::Reference<container::XEnumerationAccess> runEnumAccess(xParagraph, uno::UNO_QUERY);
|
|
if (!runEnumAccess.is())
|
|
continue;
|
|
uno::Reference<container::XEnumeration> runEnum = runEnumAccess->createEnumeration();
|
|
while (runEnum->hasMoreElements())
|
|
{
|
|
uno::Reference<text::XTextRange> xRun(runEnum->nextElement(), uno::UNO_QUERY);
|
|
if (xRun->getString().isEmpty())
|
|
continue;
|
|
uno::Reference<beans::XPropertySet> xRunPropSet(xRun, uno::UNO_QUERY);
|
|
if (!xRunPropSet.is())
|
|
continue;
|
|
auto xRunPropSetInfo = xRunPropSet->getPropertySetInfo();
|
|
if (!xRunPropSetInfo.is())
|
|
continue;
|
|
|
|
// We have found a non-empty run. Collect its simple color properties.
|
|
const std::array<OUString, 6> aNamesArray
|
|
= { u"CharColor"_ustr, u"CharLumMod"_ustr, u"CharLumOff"_ustr,
|
|
u"CharColorTheme"_ustr, u"CharComplexColor"_ustr, u"CharTransparence"_ustr };
|
|
for (const auto& propName : aNamesArray)
|
|
{
|
|
if (xRunPropSetInfo->hasPropertyByName(propName))
|
|
rCharPropVec.push_back(comphelper::makePropertyValue(
|
|
propName, xRunPropSet->getPropertyValue(propName)));
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void FontworkHelpers::applyPropsToRuns(const std::vector<beans::PropertyValue>& rTextPropVec,
|
|
uno::Reference<text::XText>& rXText)
|
|
{
|
|
if (!rXText.is())
|
|
return;
|
|
uno::Reference<text::XTextCursor> xTextCursor = rXText->createTextCursor();
|
|
xTextCursor->gotoStart(false);
|
|
xTextCursor->gotoEnd(true);
|
|
uno::Reference<container::XEnumerationAccess> paraEnumAccess(rXText, uno::UNO_QUERY);
|
|
if (!paraEnumAccess.is())
|
|
return;
|
|
uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration());
|
|
while (paraEnum->hasMoreElements())
|
|
{
|
|
uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY);
|
|
uno::Reference<container::XEnumerationAccess> runEnumAccess(xParagraph, uno::UNO_QUERY);
|
|
if (!runEnumAccess.is())
|
|
continue;
|
|
uno::Reference<container::XEnumeration> runEnum = runEnumAccess->createEnumeration();
|
|
while (runEnum->hasMoreElements())
|
|
{
|
|
uno::Reference<text::XTextRange> xRun(runEnum->nextElement(), uno::UNO_QUERY);
|
|
uno::Reference<beans::XPropertySet> xRunPropSet(xRun, uno::UNO_QUERY);
|
|
if (!xRunPropSet.is())
|
|
continue;
|
|
auto xRunPropSetInfo = xRunPropSet->getPropertySetInfo();
|
|
if (!xRunPropSetInfo.is())
|
|
continue;
|
|
|
|
for (const beans::PropertyValue& rProp : rTextPropVec)
|
|
{
|
|
if (xRunPropSetInfo->hasPropertyByName(rProp.Name)
|
|
&& !(xRunPropSetInfo->getPropertyByName(rProp.Name).Attributes
|
|
& beans::PropertyAttribute::READONLY)
|
|
&& rProp.Name != u"CharInteropGrabBag")
|
|
{
|
|
xRunPropSet->setPropertyValue(rProp.Name, rProp.Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
namespace
|
|
{
|
|
constexpr const std::array<std::u16string_view, 5> aCharPropNames{
|
|
u"CharColorLumMod", u"CharColorLumOff", u"CharColorTheme", u"CharComplexColor",
|
|
u"CharTransparence"
|
|
};
|
|
|
|
constexpr const std::array<std::u16string_view, 5> aShapePropNames{
|
|
u"FillColorLumMod", u"FillColorLumOff", u"FillColorTheme", u"FillComplexColor",
|
|
u"FillTransparence"
|
|
};
|
|
}
|
|
|
|
void FontworkHelpers::createCharFillPropsFromShape(
|
|
const uno::Reference<beans::XPropertySet>& rXPropSet,
|
|
std::vector<beans::PropertyValue>& rCharPropVec)
|
|
{
|
|
auto xPropSetInfo = rXPropSet->getPropertySetInfo();
|
|
if (!xPropSetInfo.is())
|
|
return;
|
|
// CharColor contains the color including all color transformations
|
|
// FillColor contains darken and lighten but not transparency
|
|
sal_Int32 nColorRGB = 0;
|
|
if (xPropSetInfo->hasPropertyByName(u"FillColor"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nColorRGB))
|
|
{
|
|
::Color aColor(ColorTransparency, nColorRGB);
|
|
sal_Int16 nTransPercent = 0;
|
|
if (xPropSetInfo->hasPropertyByName(u"FillTransparence"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillTransparence"_ustr) >>= nTransPercent))
|
|
{
|
|
sal_uInt8 nAlpha = 255 - sal_uInt8(std::lround(double(nTransPercent) * 2.55));
|
|
aColor.SetAlpha(nAlpha);
|
|
}
|
|
rCharPropVec.push_back(comphelper::makePropertyValue(u"CharColor"_ustr, sal_Int32(aColor)));
|
|
}
|
|
|
|
for (size_t i = 0; i < 5; i++)
|
|
{
|
|
OUString aPropertyName(aShapePropNames[i]);
|
|
if (xPropSetInfo->hasPropertyByName(aPropertyName))
|
|
rCharPropVec.push_back(comphelper::makePropertyValue(
|
|
OUString(aCharPropNames[i]), rXPropSet->getPropertyValue(aPropertyName)));
|
|
}
|
|
}
|
|
|
|
bool FontworkHelpers::createPrstDashFromLineDash(const drawing::LineDash& rLineDash,
|
|
const drawing::LineCap& rLineCap,
|
|
OUString& rsPrstDash)
|
|
{
|
|
bool bIsConverted = false;
|
|
|
|
bool bIsRelative(rLineDash.Style == drawing::DashStyle_RECTRELATIVE
|
|
|| rLineDash.Style == drawing::DashStyle_ROUNDRELATIVE);
|
|
if (bIsRelative && rLineDash.Dots == 1)
|
|
{ // The length were tweaked on import in case of prstDash. Revert it here.
|
|
sal_uInt32 nDotLen = rLineDash.DotLen;
|
|
sal_uInt32 nDashLen = rLineDash.DashLen;
|
|
sal_uInt32 nDistance = rLineDash.Distance;
|
|
if (rLineCap != drawing::LineCap_BUTT && nDistance >= 99)
|
|
{
|
|
nDistance -= 99;
|
|
nDotLen += 99;
|
|
if (nDashLen > 0)
|
|
nDashLen += 99;
|
|
}
|
|
|
|
// LO uses length 0 for 100%, if the attribute is missing in ODF.
|
|
// Other applications might write 100%. Make is unique for the conditions.
|
|
if (nDotLen == 0)
|
|
nDotLen = 100;
|
|
if (nDashLen == 0 && rLineDash.Dashes > 0)
|
|
nDashLen = 100;
|
|
|
|
bIsConverted = true;
|
|
if (nDotLen == 100 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
|
|
rsPrstDash = u"dot"_ustr;
|
|
else if (nDotLen == 400 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
|
|
rsPrstDash = u"dash"_ustr;
|
|
else if (nDotLen == 400 && rLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
|
|
rsPrstDash = u"dashDot"_ustr;
|
|
else if (nDotLen == 800 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
|
|
rsPrstDash = u"lgDash"_ustr;
|
|
else if (nDotLen == 800 && rLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
|
|
rsPrstDash = u"lgDashDot"_ustr;
|
|
else if (nDotLen == 800 && rLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300)
|
|
rsPrstDash = u"lgDashDotDot"_ustr;
|
|
else if (nDotLen == 100 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
|
|
rsPrstDash = u"sysDot"_ustr;
|
|
else if (nDotLen == 300 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
|
|
rsPrstDash = u"sysDash"_ustr;
|
|
else if (nDotLen == 300 && rLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100)
|
|
rsPrstDash = u"sysDashDot"_ustr;
|
|
else if (nDotLen == 300 && rLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100)
|
|
rsPrstDash = "sysDashDotDot";
|
|
else
|
|
bIsConverted = false;
|
|
}
|
|
return bIsConverted;
|
|
}
|
|
|
|
bool FontworkHelpers::getThemeColorFromShape(
|
|
OUString const& rPropertyName, const uno::Reference<beans::XPropertySet>& xPropertySet,
|
|
model::ComplexColor& rComplexColor)
|
|
{
|
|
auto xPropSetInfo = xPropertySet->getPropertySetInfo();
|
|
if (!xPropSetInfo.is())
|
|
return false;
|
|
uno::Reference<util::XComplexColor> xComplexColor;
|
|
if (xPropSetInfo->hasPropertyByName(rPropertyName)
|
|
&& (xPropertySet->getPropertyValue(rPropertyName) >>= xComplexColor) && xComplexColor.is())
|
|
{
|
|
rComplexColor = model::color::getFromXComplexColor(xComplexColor);
|
|
return rComplexColor.isValidThemeType();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
// Contains information about one gradient stop. Each gradient has at least 2 of these.
|
|
struct GradientStopColor
|
|
{
|
|
// RGBColor contains no transformations. In case TTColor has other type than
|
|
// ThemeColorType::Unknown, it has precedence. The color transformations in TTColor are used
|
|
// for RGBColor as well.
|
|
model::ComplexColor TTColor; // ThemeColorType and color transformations
|
|
::Color RGBColor;
|
|
};
|
|
}
|
|
|
|
// 'first' contains the position in the range 0 (=0%) to 100000 (=100%) in the gradient as needed for
|
|
// the 'pos' attribute in <w14:gs> element in oox, 'second' contains color and color transformations
|
|
// at this position. The map contains all information needed for a <w14:gsLst> element in oox.
|
|
typedef std::multimap<sal_Int32, GradientStopColor> ColorMapType;
|
|
|
|
namespace
|
|
{
|
|
constexpr const std::array<std::u16string_view, 12> W14ColorNames{
|
|
u"tx1", u"bg1", u"tx2", u"bg2", u"accent1", u"accent2",
|
|
u"accent3", u"accent4", u"accent5", u"accent6", u"hlink", u"folHlink"
|
|
};
|
|
|
|
constexpr const std::array<std::u16string_view, 12> WColorNames{
|
|
u"text1", u"background1", u"text2", u"background2", u"accent1", u"accent2",
|
|
u"accent3", u"accent4", u"accent5", u"accent6", u"hyperlink", u"followedHyperlink"
|
|
};
|
|
|
|
// Returns the string to be used in w14:schemeClr in case of w14:textOutline or w14:textFill
|
|
OUString lcl_getW14MarkupStringForThemeColor(const model::ComplexColor& rComplexColor)
|
|
{
|
|
const sal_uInt8 nClrNameIndex = std::clamp<sal_uInt8>(
|
|
sal_Int32(rComplexColor.getThemeColorType()), sal_Int32(model::ThemeColorType::Dark1),
|
|
sal_Int32(model::ThemeColorType::FollowedHyperlink));
|
|
return OUString(W14ColorNames[nClrNameIndex]);
|
|
}
|
|
|
|
// Returns the string to be used in w:themeColor. It is exported via CharThemeColor.
|
|
OUString lcl_getWMarkupStringForThemeColor(const model::ComplexColor& rComplexColor)
|
|
{
|
|
const sal_uInt8 nClrNameIndex = std::clamp<sal_uInt8>(
|
|
sal_Int32(rComplexColor.getThemeColorType()), sal_Int32(model::ThemeColorType::Dark1),
|
|
sal_Int32(model::ThemeColorType::FollowedHyperlink));
|
|
return OUString(WColorNames[nClrNameIndex]);
|
|
}
|
|
|
|
// Puts the value of the first occurrence of rType in rComplexColor into rValue and returns true.
|
|
// If such does not exist, rValue is unchanged and the method returns false.
|
|
bool lcl_getThemeColorTransformationValue(const model::ComplexColor& rComplexColor,
|
|
const model::TransformationType& rType, sal_Int16& rValue)
|
|
{
|
|
const std::vector<model::Transformation> aTransVec(rComplexColor.getTransformations());
|
|
auto bItemFound
|
|
= [rType](const model::Transformation& rTrans) { return rType == rTrans.meType; };
|
|
auto pIt = std::find_if(aTransVec.begin(), aTransVec.end(), bItemFound);
|
|
if (pIt == aTransVec.end())
|
|
return false;
|
|
rValue = (*pIt).mnValue;
|
|
return true;
|
|
}
|
|
|
|
// Adds the child elements 'lumMod' and 'lumOff' to 'schemeClr' maCurrentElement of pGrabStack,
|
|
// if such exist in rComplexColor. 'alpha' is contained in the maTransformations of rComplexColor
|
|
// in case of gradient fill.
|
|
void lcl_addColorTransformationToGrabBagStack(const model::ComplexColor& rComplexColor,
|
|
std::unique_ptr<oox::GrabBagStack>& pGrabBagStack)
|
|
{
|
|
if (pGrabBagStack == nullptr)
|
|
return;
|
|
for (auto const& rColorTransform : rComplexColor.getTransformations())
|
|
{
|
|
switch (rColorTransform.meType)
|
|
{
|
|
case model::TransformationType::LumMod:
|
|
pGrabBagStack->push("lumMod");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("val", rColorTransform.mnValue * 10);
|
|
pGrabBagStack->pop();
|
|
pGrabBagStack->pop();
|
|
break;
|
|
case model::TransformationType::LumOff:
|
|
pGrabBagStack->push("lumOff");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("val", rColorTransform.mnValue * 10);
|
|
pGrabBagStack->pop();
|
|
pGrabBagStack->pop();
|
|
break;
|
|
case model::TransformationType::Alpha:
|
|
pGrabBagStack->push("alpha");
|
|
pGrabBagStack->push("attributes");
|
|
// model::TransformationType::Alpha is designed to be used with a:alpha, which has
|
|
// opacity. But w14:alpha uses transparency. So convert it here.
|
|
pGrabBagStack->addInt32("val",
|
|
oox::drawingml::MAX_PERCENT - rColorTransform.mnValue * 10);
|
|
pGrabBagStack->pop();
|
|
pGrabBagStack->pop();
|
|
break;
|
|
default: // other child elements can be added later if needed for Fontwork
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void lcl_getGradientsFromShape(const uno::Reference<beans::XPropertySet>& rXPropSet,
|
|
const uno::Reference<beans::XPropertySetInfo>& rXPropSetInfo,
|
|
awt::Gradient2& rColorGradient, bool& rbHasColorGradient,
|
|
awt::Gradient2& rTransparenceGradient,
|
|
bool& rbHasTransparenceGradient)
|
|
{
|
|
OUString sColorGradientName;
|
|
rbHasColorGradient
|
|
= rXPropSetInfo->hasPropertyByName(u"FillGradientName"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillGradientName"_ustr) >>= sColorGradientName)
|
|
&& !sColorGradientName.isEmpty() && rXPropSetInfo->hasPropertyByName(u"FillGradient"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillGradient"_ustr) >>= rColorGradient);
|
|
|
|
OUString sTransparenceGradientName;
|
|
rbHasTransparenceGradient
|
|
= rXPropSetInfo->hasPropertyByName(u"FillTransparenceGradientName"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillTransparenceGradientName"_ustr)
|
|
>>= sTransparenceGradientName)
|
|
&& !sTransparenceGradientName.isEmpty()
|
|
&& rXPropSetInfo->hasPropertyByName(u"FillTransparenceGradient"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillTransparenceGradient"_ustr)
|
|
>>= rTransparenceGradient);
|
|
}
|
|
|
|
ColorMapType lcl_createColorMapFromShapeProps(
|
|
const uno::Reference<beans::XPropertySet>& rXPropSet,
|
|
const uno::Reference<beans::XPropertySetInfo>& rXPropSetInfo,
|
|
const awt::Gradient2& rColorGradient, const bool& rbHasColorGradient,
|
|
const awt::Gradient2& rTransparenceGradient, const bool& rbHasTransparenceGradient)
|
|
{
|
|
// LibreOffice can use color gradients and transparency gradients with different geometries.
|
|
// That is not possible in OOXML, so a fill might look different in Word. But a round-trip
|
|
// with gradients imported from Word, should work well.
|
|
|
|
// Word has transparency not as separate gradient but as color transformation in a color
|
|
// gradient. Thus we synchronize the gradients. Then they have same offsets and count.
|
|
basegfx::BColor aSingleColor;
|
|
basegfx::BGradient aColorBGradient;
|
|
basegfx::BColorStops aColorStops;
|
|
if (rbHasColorGradient)
|
|
{
|
|
aColorBGradient = model::gradient::getFromUnoGradient2(rColorGradient);
|
|
aColorBGradient.tryToApplyStartEndIntensity();
|
|
aColorBGradient.tryToApplyBorder();
|
|
aColorBGradient.tryToApplyAxial();
|
|
basegfx::utils::prepareColorStops(aColorBGradient, aColorStops, aSingleColor);
|
|
// All gradient styles but LINEAR and AXIAL (which is already converted to LINEAR) need the
|
|
// stops sequence reverse.
|
|
if (awt::GradientStyle_LINEAR != aColorBGradient.GetGradientStyle())
|
|
aColorStops.reverseColorStops();
|
|
}
|
|
else
|
|
{
|
|
sal_Int32 nFillColor(0);
|
|
if (rXPropSetInfo->hasPropertyByName("FillColor"))
|
|
rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
|
|
aSingleColor = ::Color(ColorTransparency, nFillColor).getBColor().clamp();
|
|
}
|
|
|
|
basegfx::BColor aSingleTrans;
|
|
basegfx::BGradient aTransBGradient;
|
|
basegfx::BColorStops aTransStops;
|
|
if (rbHasTransparenceGradient)
|
|
{
|
|
aTransBGradient = model::gradient::getFromUnoGradient2(rTransparenceGradient);
|
|
aTransBGradient.tryToApplyStartEndIntensity(); // usually 100%, but might be set by macro
|
|
aTransBGradient.tryToApplyBorder();
|
|
aTransBGradient.tryToApplyAxial();
|
|
basegfx::utils::prepareColorStops(aTransBGradient, aTransStops, aSingleTrans);
|
|
// All gradient styles but LINEAR and AXIAL (which is already converted to LINEAR) need the
|
|
// stops sequence reverse.
|
|
if (awt::GradientStyle_LINEAR != aTransBGradient.GetGradientStyle())
|
|
aTransStops.reverseColorStops();
|
|
}
|
|
else
|
|
{
|
|
sal_Int16 nAPITrans(0);
|
|
if (rXPropSetInfo->hasPropertyByName(u"FillTransparence"_ustr))
|
|
rXPropSet->getPropertyValue(u"FillTransparence"_ustr) >>= nAPITrans;
|
|
// API transparency is in range 0..100, BColor in range [0.0, 1.0].
|
|
aSingleTrans = basegfx::BColor(nAPITrans * 0.01).clamp();
|
|
}
|
|
|
|
basegfx::utils::synchronizeColorStops(aColorStops, aTransStops, aSingleColor, aSingleTrans);
|
|
|
|
ColorMapType aColorMap;
|
|
|
|
// If we have no color gradient, the fix fill color might be a theme color. In that case we use
|
|
// it instead of the color from the color stop.
|
|
GradientStopColor aFixColor;
|
|
bool bUseThemeColor(!rbHasColorGradient
|
|
&& FontworkHelpers::getThemeColorFromShape("FillComplexColor", rXPropSet,
|
|
aFixColor.TTColor));
|
|
|
|
for (auto itC = aColorStops.begin(), itT = aTransStops.begin();
|
|
itC != aColorStops.end() && itT != aTransStops.end(); ++itC, ++itT)
|
|
{
|
|
GradientStopColor aNextStopColor = aFixColor;
|
|
if (!bUseThemeColor)
|
|
{
|
|
aNextStopColor.TTColor = model::ComplexColor();
|
|
aNextStopColor.RGBColor = ::Color((*itC).getStopColor());
|
|
}
|
|
// model::TransformationType::Alpha is opacity in range 0..10000,
|
|
// BColor is transparency in range [0.0, 1.0]
|
|
sal_Int16 nAlpha = std::clamp<sal_Int16>(
|
|
10000 - std::lround((*itT).getStopColor().luminance() * 10000.0), 0, 10000);
|
|
if (nAlpha < 10000)
|
|
aNextStopColor.TTColor.addTransformation({ model::TransformationType::Alpha, nAlpha });
|
|
sal_Int32 nPosition
|
|
= static_cast<sal_Int32>(std::lround((*itC).getStopOffset() * 100000.0));
|
|
aColorMap.insert(std::pair{ nPosition, aNextStopColor });
|
|
}
|
|
|
|
// If a gradient has only two stops, MS Office renders it with a non-linear method which looks
|
|
// different than gradient in LibreOffice (see tdf#128795). For more than two stops rendering is
|
|
// the same as in LibreOffice, even if two stops are identical.
|
|
if (aColorMap.size() == 2)
|
|
{
|
|
auto it = aColorMap.begin();
|
|
aColorMap.insert(std::pair{ 0, (*it).second });
|
|
}
|
|
return aColorMap;
|
|
}
|
|
} // end namespace
|
|
|
|
void FontworkHelpers::createCharInteropGrabBagUpdatesFromShapeProps(
|
|
const uno::Reference<beans::XPropertySet>& rXPropSet,
|
|
std::vector<beans::PropertyValue>& rUpdatePropVec)
|
|
{
|
|
auto xPropSetInfo = rXPropSet->getPropertySetInfo();
|
|
if (!xPropSetInfo.is())
|
|
return;
|
|
|
|
// GrabBagStack is a special tool for handling the hierarchy in a GrabBag
|
|
std::unique_ptr<oox::GrabBagStack> pGrabBagStack;
|
|
|
|
// CharTextFillTextEffect
|
|
pGrabBagStack.reset(new oox::GrabBagStack("textFill"));
|
|
drawing::FillStyle eFillStyle = drawing::FillStyle_SOLID;
|
|
if (xPropSetInfo->hasPropertyByName(u"FillStyle"_ustr))
|
|
rXPropSet->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle;
|
|
|
|
// We might have a solid fill but a transparency gradient. That needs to be exported as gradFill
|
|
// too, because Word has transparency not separated but in the color stops in a color gradient.
|
|
// A gradient exists, if the GradientName is not empty.
|
|
OUString sTransparenceGradientName;
|
|
if (eFillStyle == drawing::FillStyle_SOLID
|
|
&& xPropSetInfo->hasPropertyByName(u"FillTransparenceGradientName"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"FillTransparenceGradientName"_ustr)
|
|
>>= sTransparenceGradientName)
|
|
&& !sTransparenceGradientName.isEmpty())
|
|
eFillStyle = drawing::FillStyle_GRADIENT;
|
|
|
|
switch (eFillStyle)
|
|
{
|
|
case drawing::FillStyle_NONE:
|
|
{
|
|
pGrabBagStack->appendElement("noFill", uno::Any());
|
|
break;
|
|
}
|
|
case drawing::FillStyle_GRADIENT:
|
|
{
|
|
awt::Gradient2 aColorGradient;
|
|
bool bHasColorGradient(false);
|
|
awt::Gradient2 aTransparenceGradient;
|
|
bool bHasTransparenceGradient(false);
|
|
lcl_getGradientsFromShape(rXPropSet, xPropSetInfo, aColorGradient, bHasColorGradient,
|
|
aTransparenceGradient, bHasTransparenceGradient);
|
|
// aColorMap contains the color stops suitable to generate gsLst
|
|
ColorMapType aColorMap = lcl_createColorMapFromShapeProps(
|
|
rXPropSet, xPropSetInfo, aColorGradient, bHasColorGradient, aTransparenceGradient,
|
|
bHasTransparenceGradient);
|
|
pGrabBagStack->push("gradFill");
|
|
pGrabBagStack->push("gsLst");
|
|
for (auto it = aColorMap.begin(); it != aColorMap.end(); ++it)
|
|
{
|
|
pGrabBagStack->push("gs");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("pos", (*it).first);
|
|
pGrabBagStack->pop();
|
|
if ((*it).second.TTColor.getThemeColorType() == model::ThemeColorType::Unknown)
|
|
{
|
|
pGrabBagStack->push("srgbClr");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addString("val", (*it).second.RGBColor.AsRGBHexString());
|
|
pGrabBagStack->pop(); // maCurrentElement:'srgbClr', maPropertyList:'attributes'
|
|
}
|
|
else
|
|
{
|
|
pGrabBagStack->push("schemeClr");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addString(
|
|
"val", lcl_getW14MarkupStringForThemeColor((*it).second.TTColor));
|
|
pGrabBagStack->pop();
|
|
// maCurrentElement:'schemeClr', maPropertyList:'attributes'
|
|
}
|
|
|
|
lcl_addColorTransformationToGrabBagStack((*it).second.TTColor, pGrabBagStack);
|
|
pGrabBagStack->pop();
|
|
// maCurrentElement:'gs', maPropertyList:'attributes', 'srgbClr' or 'schemeClr'
|
|
pGrabBagStack->pop(); // maCurrentElement:'gsLst', maPropertyList: at least two 'gs'
|
|
}
|
|
pGrabBagStack->pop(); // maCurrentElement:'gradFill', maPropertyList: gsLst
|
|
|
|
// Kind of gradient
|
|
awt::GradientStyle eGradientStyle = awt::GradientStyle_LINEAR;
|
|
if (bHasColorGradient)
|
|
eGradientStyle = aColorGradient.Style;
|
|
else if (bHasTransparenceGradient)
|
|
eGradientStyle = aTransparenceGradient.Style;
|
|
// write 'lin' or 'path'. LibreOffice has nothing which corresponds to 'shape'.
|
|
if (eGradientStyle == awt::GradientStyle_LINEAR
|
|
|| eGradientStyle == awt::GradientStyle_AXIAL)
|
|
{
|
|
// API angle is in 1/10th deg and describes counter-clockwise rotation of line of
|
|
// equal color. OOX angle is in 1/60000th deg and describes clockwise rotation of
|
|
// color transition direction.
|
|
sal_Int32 nAngleOOX = 0;
|
|
if (bHasColorGradient)
|
|
nAngleOOX = ((3600 - aColorGradient.Angle + 900) % 3600) * 6000;
|
|
else if (bHasTransparenceGradient)
|
|
nAngleOOX = ((3600 - aTransparenceGradient.Angle + 900) % 3600) * 6000;
|
|
pGrabBagStack->push("lin");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("ang", nAngleOOX);
|
|
// LibreOffice cannot scale a gradient to the shape size.
|
|
pGrabBagStack->addString("scaled", "0");
|
|
}
|
|
else
|
|
{
|
|
// Same rendering as in LibreOffice is not possible:
|
|
// (1) The gradient type 'path' in Word has no rotation.
|
|
// (2) To get the same size of gradient area, the element 'tileRect' is needed, but
|
|
// that is not available for <w14:textFill> element.
|
|
// So we can only set a reasonably suitable focus point.
|
|
pGrabBagStack->push("path");
|
|
pGrabBagStack->push("attributes");
|
|
if (eGradientStyle == awt::GradientStyle_RADIAL
|
|
|| eGradientStyle == awt::GradientStyle_ELLIPTICAL)
|
|
pGrabBagStack->addString("path", "circle");
|
|
else
|
|
pGrabBagStack->addString("path", "rect");
|
|
pGrabBagStack->pop();
|
|
pGrabBagStack->push("fillToRect");
|
|
pGrabBagStack->push("attributes");
|
|
sal_Int32 nLeftPercent
|
|
= bHasColorGradient ? aColorGradient.XOffset : aTransparenceGradient.XOffset;
|
|
sal_Int32 nTopPercent
|
|
= bHasColorGradient ? aColorGradient.YOffset : aTransparenceGradient.YOffset;
|
|
pGrabBagStack->addInt32("l", nLeftPercent * 1000);
|
|
pGrabBagStack->addInt32("t", nTopPercent * 1000);
|
|
pGrabBagStack->addInt32("r", (100 - nLeftPercent) * 1000);
|
|
pGrabBagStack->addInt32("b", (100 - nTopPercent) * 1000);
|
|
}
|
|
// all remaining pop() calls are in the final getRootProperty() method
|
|
break;
|
|
}
|
|
case drawing::FillStyle_SOLID:
|
|
{
|
|
pGrabBagStack->push("solidFill");
|
|
model::ComplexColor aComplexColor;
|
|
// It is either "schemeClr" or "srgbClr".
|
|
if (FontworkHelpers::getThemeColorFromShape("FillComplexColor", rXPropSet,
|
|
aComplexColor))
|
|
{
|
|
pGrabBagStack->push("schemeClr");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addString("val", lcl_getW14MarkupStringForThemeColor(aComplexColor));
|
|
pGrabBagStack->pop(); // maCurrentElement:'schemeClr', maPropertyList:'attributes'
|
|
lcl_addColorTransformationToGrabBagStack(aComplexColor, pGrabBagStack);
|
|
// maCurrentElement:'schemeClr', maPropertyList:'attributes', maybe 'lumMod' and
|
|
// maybe 'lumOff'
|
|
}
|
|
else
|
|
{
|
|
pGrabBagStack->push("srgbClr");
|
|
sal_Int32 nFillColor(0);
|
|
if (xPropSetInfo->hasPropertyByName(u"FillColor"_ustr))
|
|
rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
|
|
pGrabBagStack->push("attributes");
|
|
::Color aColor(ColorTransparency, nFillColor);
|
|
pGrabBagStack->addString("val", aColor.AsRGBHexString());
|
|
pGrabBagStack->pop();
|
|
// maCurrentElement:'srgbClr', maPropertyList:'attributes'
|
|
}
|
|
|
|
sal_Int16 nFillTransparence(0);
|
|
if (xPropSetInfo->hasPropertyByName(u"FillTransparence"_ustr))
|
|
rXPropSet->getPropertyValue(u"FillTransparence"_ustr) >>= nFillTransparence;
|
|
if (nFillTransparence != 0)
|
|
{
|
|
pGrabBagStack->push("alpha");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("val", nFillTransparence * 1000);
|
|
}
|
|
// all remaining pop() calls are in the final getRootProperty() method
|
|
break;
|
|
}
|
|
default: // BITMAP is VML only export and does not arrive here. HATCH has to be VML only
|
|
// export too, but is not yet implemented.
|
|
break;
|
|
}
|
|
// resolve the stack and put resulting PropertyValue into the update vector
|
|
beans::PropertyValue aCharTextFillTextEffect;
|
|
aCharTextFillTextEffect.Name = "CharTextFillTextEffect";
|
|
aCharTextFillTextEffect.Value <<= pGrabBagStack->getRootProperty();
|
|
rUpdatePropVec.push_back(aCharTextFillTextEffect);
|
|
|
|
// CharTextOutlineTextEffect
|
|
pGrabBagStack.reset(new oox::GrabBagStack("textOutline"));
|
|
|
|
// attributes
|
|
pGrabBagStack->push("attributes");
|
|
// line width
|
|
sal_Int32 nLineWidth(0);
|
|
if (xPropSetInfo->hasPropertyByName(u"LineWidth"_ustr))
|
|
rXPropSet->getPropertyValue(u"LineWidth"_ustr) >>= nLineWidth;
|
|
pGrabBagStack->addInt32("w", nLineWidth * 360);
|
|
// cap for dashes
|
|
drawing::LineCap eLineCap = drawing::LineCap_BUTT;
|
|
if (xPropSetInfo->hasPropertyByName(u"LineCap"_ustr))
|
|
rXPropSet->getPropertyValue(u"LineCap"_ustr) >>= eLineCap;
|
|
OUString sCap = u"flat"_ustr;
|
|
if (eLineCap == drawing::LineCap_ROUND)
|
|
sCap = u"rnd"_ustr;
|
|
else if (eLineCap == drawing::LineCap_SQUARE)
|
|
sCap = u"sq"_ustr;
|
|
pGrabBagStack->addString("cap", sCap);
|
|
// LO has no compound lines and always centers the lines
|
|
pGrabBagStack->addString("cmpd", u"sng"_ustr);
|
|
pGrabBagStack->addString("alng", u"ctr"_ustr);
|
|
pGrabBagStack->pop();
|
|
// maCurrentElement:'textOutline', maPropertyList:'attributes'
|
|
|
|
// style
|
|
drawing::LineStyle eLineStyle = drawing::LineStyle_NONE;
|
|
if (xPropSetInfo->hasPropertyByName(u"LineStyle"_ustr))
|
|
rXPropSet->getPropertyValue(u"LineStyle"_ustr) >>= eLineStyle;
|
|
// 'dashed' is not a separate style in Word. Word has a style 'gradFill', but that is not yet
|
|
// implemented in LO. So only 'noFill' and 'solidFill'.
|
|
if (eLineStyle == drawing::LineStyle_NONE)
|
|
{
|
|
pGrabBagStack->appendElement("noFill", uno::Any());
|
|
}
|
|
else
|
|
{
|
|
pGrabBagStack->push("solidFill");
|
|
// It is either "schemeClr" or "srgbClr".
|
|
model::ComplexColor aComplexColor;
|
|
if (FontworkHelpers::getThemeColorFromShape("LineComplexColor", rXPropSet, aComplexColor))
|
|
{
|
|
pGrabBagStack->push("schemeClr");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addString("val", lcl_getW14MarkupStringForThemeColor(aComplexColor));
|
|
pGrabBagStack->pop();
|
|
lcl_addColorTransformationToGrabBagStack(aComplexColor, pGrabBagStack);
|
|
// maCurrentElement:'schemeClr', maPropertylist:'attributes'
|
|
}
|
|
else // not a theme color
|
|
{
|
|
pGrabBagStack->push("srgbClr");
|
|
pGrabBagStack->push("attributes");
|
|
sal_Int32 nLineColor(0);
|
|
if (xPropSetInfo->hasPropertyByName(u"LineColor"_ustr))
|
|
rXPropSet->getPropertyValue(u"LineColor"_ustr) >>= nLineColor;
|
|
::Color aColor(ColorTransparency, nLineColor);
|
|
pGrabBagStack->addString("val", aColor.AsRGBHexString());
|
|
pGrabBagStack->pop();
|
|
// maCurrentElement:'srgbClr', maPropertylist:'attributes'
|
|
}
|
|
|
|
sal_Int16 nLineTransparence(0);
|
|
if (xPropSetInfo->hasPropertyByName(u"LineTransparence"_ustr))
|
|
rXPropSet->getPropertyValue(u"LineTransparence"_ustr) >>= nLineTransparence;
|
|
if (nLineTransparence != 0)
|
|
{
|
|
pGrabBagStack->push("alpha");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("val", nLineTransparence * 1000);
|
|
pGrabBagStack->pop(); // maCurrentElement: 'alpha'
|
|
pGrabBagStack->pop(); // maCurrentElement: 'srgbClr' or 'schemeClr'
|
|
}
|
|
pGrabBagStack->pop();
|
|
// maCurrentElement:'solidFill', maPropertyList:either 'srgbClr' or 'schemeClr
|
|
pGrabBagStack->pop();
|
|
}
|
|
// maCurrentElement:'textOutline', maPropertyList:'attributes' and either 'noFill' or 'solidFill'
|
|
|
|
// prstDash
|
|
if (eLineStyle == drawing::LineStyle_DASH)
|
|
{
|
|
pGrabBagStack->push("prstDash");
|
|
OUString sPrstDash = u"sysDot"_ustr;
|
|
drawing::LineDash aLineDash;
|
|
if (xPropSetInfo->hasPropertyByName(u"LineDash"_ustr)
|
|
&& (rXPropSet->getPropertyValue(u"LineDash"_ustr) >>= aLineDash))
|
|
{
|
|
// The outline of abc-transform in Word is not able to use custDash. But we know the line
|
|
// is dashed. We keep "sysDot" as fallback in case no prstDash is detected.
|
|
FontworkHelpers::createPrstDashFromLineDash(aLineDash, eLineCap, sPrstDash);
|
|
}
|
|
else
|
|
{
|
|
// ToDo: There may be a named dash style, but that is unlikely for Fontwork shapes. So
|
|
// I skip it for now and use the "sysDot" fallback.
|
|
}
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addString("val", sPrstDash);
|
|
pGrabBagStack->pop(); // maCurrentElement:'prstDash'
|
|
pGrabBagStack->pop(); // maCurrentElement:'textOutline'
|
|
}
|
|
// maCurrentElement:'textOutline', maPropertyList:'attributes', either 'noFill' or 'solidFill',
|
|
// and maybe 'prstDash'.
|
|
|
|
// LineJoint, can be 'round', 'bevel' or 'miter' in Word
|
|
drawing::LineJoint eLineJoint = drawing::LineJoint_NONE;
|
|
if (xPropSetInfo->hasPropertyByName(u"LineJoint"_ustr))
|
|
rXPropSet->getPropertyValue(u"LineJoint"_ustr) >>= eLineJoint;
|
|
if (eLineJoint == drawing::LineJoint_NONE || eLineJoint == drawing::LineJoint_BEVEL)
|
|
pGrabBagStack->appendElement("bevel", uno::Any());
|
|
else if (eLineJoint == drawing::LineJoint_ROUND)
|
|
pGrabBagStack->appendElement("round", uno::Any());
|
|
else // MITER or deprecated MIDDLE
|
|
{
|
|
pGrabBagStack->push("miter");
|
|
pGrabBagStack->push("attributes");
|
|
pGrabBagStack->addInt32("lim", 0); // As of Feb. 2023 LO cannot render other values.
|
|
pGrabBagStack->pop(); // maCurrentElement:'attributes'
|
|
pGrabBagStack->pop(); // maCurrentElement:'miter'
|
|
}
|
|
// maCurrentElement:'textOutline', maPropertyList:'attributes', either 'noFill' or
|
|
// 'solidFill', maybe 'prstDash', and either 'bevel', 'round' or 'miter'.
|
|
|
|
// resolve the stack and put resulting PropertyValue into the update vector
|
|
beans::PropertyValue aCharTextOutlineTextEffect;
|
|
aCharTextOutlineTextEffect.Name = "CharTextOutlineTextEffect";
|
|
aCharTextOutlineTextEffect.Value <<= pGrabBagStack->getRootProperty();
|
|
rUpdatePropVec.push_back(aCharTextOutlineTextEffect);
|
|
|
|
// CharThemeOriginalColor, CharThemeColor, and CharThemeColorShade or CharThemeColorTint will be
|
|
// used for <w:color> element. That is evaluated by applications, which do not understand w14
|
|
// namespace, or if w14:textFill is omitted.
|
|
model::ComplexColor aComplexColor;
|
|
if (FontworkHelpers::getThemeColorFromShape("FillComplexColor", rXPropSet, aComplexColor))
|
|
{
|
|
// CharThemeColor
|
|
beans::PropertyValue aCharThemeColor;
|
|
aCharThemeColor.Name = u"CharThemeColor"_ustr;
|
|
aCharThemeColor.Value <<= lcl_getWMarkupStringForThemeColor(aComplexColor);
|
|
rUpdatePropVec.push_back(aCharThemeColor);
|
|
|
|
// CharThemeColorShade or CharThemeColorTint
|
|
// MS Office uses themeTint and themeShade on the luminance in a HSL color space, see 2.1.72
|
|
// in [MS-OI29500]. That is different from OOXML specification.
|
|
// We made two assumption here: (1) If LumOff exists and is not zero, it is a 'tint'.
|
|
// (2) LumMod + LumOff == 10000;
|
|
sal_Int16 nLumMod;
|
|
if (lcl_getThemeColorTransformationValue(aComplexColor, model::TransformationType::LumMod,
|
|
nLumMod))
|
|
{
|
|
sal_Int16 nLumOff;
|
|
bool bIsTint = lcl_getThemeColorTransformationValue(
|
|
aComplexColor, model::TransformationType::LumOff, nLumOff)
|
|
&& nLumOff != 0;
|
|
sal_uInt8 nValue
|
|
= std::clamp<sal_uInt8>(lround(double(nLumMod) * 255.0 / 10000.0), 0, 255);
|
|
OUString sValue = OUString::number(nValue, 16);
|
|
|
|
beans::PropertyValue aCharThemeTintOrShade;
|
|
aCharThemeTintOrShade.Name = bIsTint ? u"CharThemeColorTint" : u"CharThemeColorShade";
|
|
aCharThemeTintOrShade.Value <<= sValue;
|
|
rUpdatePropVec.push_back(aCharThemeTintOrShade);
|
|
}
|
|
}
|
|
// ToDo: Are FillColorLumMod, FillColorLumOff and FillColorTheme possible without
|
|
// FillComplexColor? If yes, we need an 'else' part here.
|
|
|
|
// CharThemeOriginalColor.
|
|
beans::PropertyValue aCharThemeOriginalColor;
|
|
sal_Int32 nFillColor(0);
|
|
if (xPropSetInfo->hasPropertyByName(u"FillColor"_ustr))
|
|
rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor;
|
|
aCharThemeOriginalColor.Name = u"CharThemeOriginalColor"_ustr;
|
|
::Color aColor(ColorTransparency, nFillColor);
|
|
aCharThemeOriginalColor.Value <<= aColor.AsRGBHEXString();
|
|
rUpdatePropVec.push_back(aCharThemeOriginalColor);
|
|
}
|
|
|
|
void FontworkHelpers::applyUpdatesToCharInteropGrabBag(
|
|
const std::vector<beans::PropertyValue>& rUpdatePropVec, uno::Reference<text::XText>& rXText)
|
|
{
|
|
if (!rXText.is())
|
|
return;
|
|
uno::Reference<text::XTextCursor> rXTextCursor = rXText->createTextCursor();
|
|
rXTextCursor->gotoStart(false);
|
|
rXTextCursor->gotoEnd(true);
|
|
uno::Reference<container::XEnumerationAccess> paraEnumAccess(rXText, uno::UNO_QUERY);
|
|
if (!paraEnumAccess.is())
|
|
return;
|
|
uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration());
|
|
while (paraEnum->hasMoreElements())
|
|
{
|
|
uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY);
|
|
uno::Reference<container::XEnumerationAccess> runEnumAccess(xParagraph, uno::UNO_QUERY);
|
|
if (!runEnumAccess.is())
|
|
continue;
|
|
uno::Reference<container::XEnumeration> runEnum = runEnumAccess->createEnumeration();
|
|
while (runEnum->hasMoreElements())
|
|
{
|
|
uno::Reference<text::XTextRange> xRun(runEnum->nextElement(), uno::UNO_QUERY);
|
|
if (xRun->getString().isEmpty())
|
|
continue;
|
|
uno::Reference<beans::XPropertySet> xRunPropSet(xRun, uno::UNO_QUERY);
|
|
if (!xRunPropSet.is())
|
|
continue;
|
|
auto xRunPropSetInfo = xRunPropSet->getPropertySetInfo();
|
|
if (!xRunPropSetInfo.is())
|
|
continue;
|
|
|
|
// Now apply the updates to the CharInteropGrabBag of this run
|
|
uno::Sequence<beans::PropertyValue> aCharInteropGrabBagSeq;
|
|
if (xRunPropSetInfo->hasPropertyByName("CharInteropGrabBag"))
|
|
xRunPropSet->getPropertyValue("CharInteropGrabBag") >>= aCharInteropGrabBagSeq;
|
|
comphelper::SequenceAsHashMap aGrabBagMap(aCharInteropGrabBagSeq);
|
|
for (const auto& rProp : rUpdatePropVec)
|
|
{
|
|
aGrabBagMap[rProp.Name] = rProp.Value; // [] inserts if not exists
|
|
}
|
|
xRunPropSet->setPropertyValue("CharInteropGrabBag",
|
|
uno::Any(aGrabBagMap.getAsConstPropertyValueList()));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|