/src/libreoffice/oox/source/drawingml/fontworkhelpers.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <drawingml/fontworkhelpers.hxx> |
21 | | |
22 | | #include <basegfx/utils/bgradient.hxx> |
23 | | #include <basegfx/utils/gradienttools.hxx> |
24 | | #include <comphelper/propertysequence.hxx> |
25 | | #include <comphelper/propertyvalue.hxx> |
26 | | #include <comphelper/sequence.hxx> |
27 | | #include <comphelper/sequenceashashmap.hxx> |
28 | | #include <docmodel/uno/UnoComplexColor.hxx> |
29 | | #include <docmodel/uno/UnoGradientTools.hxx> |
30 | | #include <drawingml/customshapeproperties.hxx> |
31 | | #include <drawingml/presetgeometrynames.hxx> |
32 | | #include <oox/drawingml/drawingmltypes.hxx> |
33 | | #include <oox/helper/grabbagstack.hxx> |
34 | | #include <sal/log.hxx> |
35 | | #include <svx/msdffdef.hxx> |
36 | | #include <tools/color.hxx> |
37 | | #include <tools/helpers.hxx> |
38 | | |
39 | | #include <com/sun/star/awt/Gradient2.hpp> |
40 | | #include <com/sun/star/beans/PropertyAttribute.hpp> |
41 | | #include <com/sun/star/beans/PropertyValue.hpp> |
42 | | #include <com/sun/star/beans/XPropertySet.hpp> |
43 | | #include <com/sun/star/container/XEnumeration.hpp> |
44 | | #include <com/sun/star/container/XEnumerationAccess.hpp> |
45 | | #include <com/sun/star/drawing/DashStyle.hpp> |
46 | | #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> |
47 | | #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp> |
48 | | #include <com/sun/star/drawing/FillStyle.hpp> |
49 | | #include <com/sun/star/drawing/LineCap.hpp> |
50 | | #include <com/sun/star/drawing/LineDash.hpp> |
51 | | #include <com/sun/star/drawing/LineJoint.hpp> |
52 | | #include <com/sun/star/drawing/LineStyle.hpp> |
53 | | #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp> |
54 | | #include <com/sun/star/drawing/XShape.hpp> |
55 | | #include <com/sun/star/text/XText.hpp> |
56 | | #include <com/sun/star/text/XTextRange.hpp> |
57 | | #include <com/sun/star/util/XComplexColor.hpp> |
58 | | |
59 | | #include <array> |
60 | | #include <map> |
61 | | |
62 | | using namespace com::sun::star; |
63 | | |
64 | | void FontworkHelpers::resetPropertyValueInVec(std::vector<beans::PropertyValue>& rPropVec, |
65 | | const OUString& rName) |
66 | 0 | { |
67 | 0 | auto aIterator = std::find_if( |
68 | 0 | rPropVec.begin(), rPropVec.end(), |
69 | 0 | [rName](const beans::PropertyValue& rValue) { return rValue.Name == rName; }); |
70 | |
|
71 | 0 | if (aIterator != rPropVec.end()) |
72 | 0 | rPropVec.erase(aIterator); |
73 | 0 | } |
74 | | |
75 | | void FontworkHelpers::putCustomShapeIntoTextPathMode( |
76 | | const css::uno::Reference<drawing::XShape>& xShape, |
77 | | const oox::drawingml::CustomShapePropertiesPtr& pCustomShapePropertiesPtr, |
78 | | const OUString& sMSPresetType, const bool bFromWordArt) |
79 | 0 | { |
80 | 0 | if (!xShape.is() || !pCustomShapePropertiesPtr || sMSPresetType == u"textNoShape") |
81 | 0 | return; |
82 | | |
83 | 0 | uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY); |
84 | 0 | if (!xDefaulter.is()) |
85 | 0 | return; |
86 | | |
87 | 0 | uno::Reference<beans::XPropertySet> xSet(xShape, uno::UNO_QUERY); |
88 | 0 | if (!xSet.is()) |
89 | 0 | return; |
90 | | |
91 | | // The DrawingML shapes from the presetTextWarpDefinitions are mapped to the definitions |
92 | | // in svx/../EnhancedCustomShapeGeometry.cxx, which are used for WordArt shapes from |
93 | | // binary MS Office. Therefore all adjustment values need to be adapted. |
94 | 0 | const OUString sFontworkType = PresetGeometryTypeNames::GetFontworkType(sMSPresetType); |
95 | 0 | auto aAdjGdList = pCustomShapePropertiesPtr->getAdjustmentGuideList(); |
96 | 0 | uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment( |
97 | 0 | !aAdjGdList.empty() ? aAdjGdList.size() : 1); |
98 | 0 | auto pAdjustment = aAdjustment.getArray(); |
99 | 0 | int nIndex = 0; |
100 | 0 | for (const auto& aEntry : aAdjGdList) |
101 | 0 | { |
102 | 0 | double fValue = aEntry.maFormula.toDouble(); |
103 | | // then: polar-handle, else: XY-handle |
104 | | // There exist only 8 polar-handles at all in presetTextWarp. |
105 | 0 | if ((sFontworkType == "fontwork-arch-down-curve") |
106 | 0 | || (sFontworkType == "fontwork-arch-down-pour" && aEntry.maName == "adj1") |
107 | 0 | || (sFontworkType == "fontwork-arch-up-curve") |
108 | 0 | || (sFontworkType == "fontwork-arch-up-pour" && aEntry.maName == "adj1") |
109 | 0 | || (sFontworkType == "fontwork-open-circle-curve") |
110 | 0 | || (sFontworkType == "fontwork-open-circle-pour" && aEntry.maName == "adj1") |
111 | 0 | || (sFontworkType == "fontwork-circle-curve") |
112 | 0 | || (sFontworkType == "fontwork-circle-pour" && aEntry.maName == "adj1")) |
113 | 0 | { |
114 | | // DrawingML has 1/60000 degree unit, but WordArt simple degree. Range [0..360[ |
115 | | // or range ]-180..180] doesn't matter, because only cos(angle) and |
116 | | // sin(angle) are used. |
117 | 0 | fValue = NormAngle360(fValue / 60000.0); |
118 | 0 | } |
119 | 0 | else |
120 | 0 | { |
121 | | // DrawingML writes adjustment guides as relative value with 100% = 100000, |
122 | | // but WordArt definitions use values absolute in viewBox 0 0 21600 21600, |
123 | | // so scale with 21600/100000 = 0.216, with two exceptions: |
124 | | // X-handles of waves describe increase/decrease relative to horizontal center. |
125 | | // The gdRefR of pour-shapes is not relative to viewBox but to radius. |
126 | 0 | if ((sFontworkType == "mso-spt158" && aEntry.maName == "adj2") // textDoubleWave1 |
127 | 0 | || (sFontworkType == "fontwork-wave" && aEntry.maName == "adj2") // textWave1 |
128 | 0 | || (sFontworkType == "mso-spt157" && aEntry.maName == "adj2") // textWave2 |
129 | 0 | || (sFontworkType == "mso-spt159" && aEntry.maName == "adj2")) // textWave4 |
130 | 0 | { |
131 | 0 | fValue = (fValue + 50000.0) * 0.216; |
132 | 0 | } |
133 | 0 | else if ((sFontworkType == "fontwork-arch-down-pour" && aEntry.maName == "adj2") |
134 | 0 | || (sFontworkType == "fontwork-arch-up-pour" && aEntry.maName == "adj2") |
135 | 0 | || (sFontworkType == "fontwork-open-circle-pour" && aEntry.maName == "adj2") |
136 | 0 | || (sFontworkType == "fontwork-circle-pour" && aEntry.maName == "adj2")) |
137 | 0 | { |
138 | 0 | fValue *= 0.108; |
139 | 0 | } |
140 | 0 | else |
141 | 0 | { |
142 | 0 | fValue *= 0.216; |
143 | 0 | } |
144 | 0 | } |
145 | |
|
146 | 0 | pAdjustment[nIndex].Value <<= fValue; |
147 | 0 | pAdjustment[nIndex++].State = css::beans::PropertyState_DIRECT_VALUE; |
148 | 0 | } |
149 | | |
150 | | // Set attributes in CustomShapeGeometry |
151 | 0 | xDefaulter->createCustomShapeDefaults(sFontworkType); |
152 | |
|
153 | 0 | auto aGeomPropSeq = xSet->getPropertyValue(u"CustomShapeGeometry"_ustr) |
154 | 0 | .get<uno::Sequence<beans::PropertyValue>>(); |
155 | 0 | auto aGeomPropVec |
156 | 0 | = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(aGeomPropSeq); |
157 | | |
158 | | // Reset old properties |
159 | 0 | static constexpr OUString sTextPath(u"TextPath"_ustr); |
160 | 0 | static constexpr OUString sAdjustmentValues(u"AdjustmentValues"_ustr); |
161 | 0 | static constexpr OUString sPresetTextWarp(u"PresetTextWarp"_ustr); |
162 | |
|
163 | 0 | resetPropertyValueInVec(aGeomPropVec, u"CoordinateSize"_ustr); |
164 | 0 | resetPropertyValueInVec(aGeomPropVec, u"Equations"_ustr); |
165 | 0 | resetPropertyValueInVec(aGeomPropVec, u"Path"_ustr); |
166 | 0 | resetPropertyValueInVec(aGeomPropVec, sAdjustmentValues); |
167 | 0 | resetPropertyValueInVec(aGeomPropVec, u"ViewBox"_ustr); |
168 | 0 | resetPropertyValueInVec(aGeomPropVec, u"Handles"_ustr); |
169 | 0 | resetPropertyValueInVec(aGeomPropVec, sTextPath); |
170 | 0 | resetPropertyValueInVec(aGeomPropVec, sPresetTextWarp); |
171 | |
|
172 | 0 | bool bScaleX(false); |
173 | 0 | if (!bFromWordArt |
174 | 0 | && (sMSPresetType == u"textArchDown" || sMSPresetType == u"textArchUp" |
175 | 0 | || sMSPresetType == u"textCircle" || sMSPresetType == u"textButton")) |
176 | 0 | { |
177 | 0 | bScaleX = true; |
178 | 0 | } |
179 | | |
180 | | // Apply new properties |
181 | 0 | uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence( |
182 | 0 | { { sTextPath, uno::Any(true) }, |
183 | 0 | { u"TextPathMode"_ustr, uno::Any(drawing::EnhancedCustomShapeTextPathMode_PATH) }, |
184 | 0 | { u"ScaleX"_ustr, uno::Any(bScaleX) } })); |
185 | 0 | aGeomPropVec.push_back(comphelper::makePropertyValue(sTextPath, aPropertyValues)); |
186 | |
|
187 | 0 | aGeomPropVec.push_back(comphelper::makePropertyValue(sPresetTextWarp, sMSPresetType)); |
188 | |
|
189 | 0 | if (!aAdjGdList.empty()) |
190 | 0 | { |
191 | 0 | aGeomPropVec.push_back(comphelper::makePropertyValue(sAdjustmentValues, aAdjustment)); |
192 | 0 | } |
193 | |
|
194 | 0 | xSet->setPropertyValue(u"CustomShapeGeometry"_ustr, |
195 | 0 | uno::Any(comphelper::containerToSequence(aGeomPropVec))); |
196 | 0 | } |
197 | | |
198 | | OString FontworkHelpers::GetVMLFontworkShapetypeMarkup(const MSO_SPT eShapeType) |
199 | 0 | { |
200 | | // The markup is taken from VML in DOCX documents. Using the generated 'vml-shape-types' file |
201 | | // does not work. |
202 | |
|
203 | 0 | static const std::map<MSO_SPT, OString> aTypeToMarkupMap{ |
204 | 0 | { mso_sptTextSimple, |
205 | 0 | "<v:shapetype id=\"_x0000_t24\" coordsize=\"21600,21600\" o:spt=\"24\" adj=\"10800\" " |
206 | 0 | "path=\"m@7,l@8,m@5,21600l@6,21600e\"><v:formulas><v:f eqn=\"sum #0 0 10800\"/><v:f " |
207 | 0 | "eqn=\"prod #0 2 1\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 0 0 @2\"/><v:f " |
208 | 0 | "eqn=\"sum 21600 0 @3\"/><v:f eqn=\"if @0 @3 0\"/><v:f eqn=\"if @0 21600 @1\"/><v:f " |
209 | 0 | "eqn=\"if @0 0 @2\"/><v:f eqn=\"if @0 @4 21600\"/><v:f eqn=\"mid @5 @6\"/><v:f eqn=\"mid " |
210 | 0 | "@8 @5\"/><v:f eqn=\"mid @7 @8\"/><v:f eqn=\"mid @6 @7\"/><v:f eqn=\"sum @6 0 " |
211 | 0 | "@5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
212 | 0 | "o:connectlocs=\"@9,0;@10,10800;@11,21600;@12,10800\" " |
213 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
214 | 0 | "position=\"#0,bottomRight\" xrange=\"6629,14971\"/></v:handles><o:lock v:ext=\"edit\" " |
215 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
216 | 0 | { mso_sptTextOctagon, |
217 | 0 | "<v:shapetype id=\"_x0000_t25\" coordsize=\"21600,21600\" o:spt=\"25\" adj=\"4800\" " |
218 | 0 | "path=\"m0@0l7200,r7200,l21600@0m0@1l7200,21600r7200,l21600@1e\"><v:formulas><v:f " |
219 | 0 | "eqn=\"val #0\"/><v:f eqn=\"sum 21600 0 @0\"/></v:formulas><v:path textpathok=\"t\" " |
220 | 0 | "o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
221 | 0 | "position=\"topLeft,#0\" yrange=\"3086,10800\"/></v:handles><o:lock v:ext=\"edit\" " |
222 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
223 | 0 | { mso_sptTextHexagon, |
224 | 0 | "<v:shapetype id=\"_x0000_t26\" coordsize=\"21600,21600\" o:spt=\"26\" adj=\"10800\" " |
225 | 0 | "path=\"m0@0l10800,,21600@0m,21600r10800,l21600,21600e\"><v:formulas><v:f eqn=\"val " |
226 | 0 | "#0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @1 10800 0\"/><v:f eqn=\"sum 21600 0 " |
227 | 0 | "@1\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
228 | 0 | "o:connectlocs=\"10800,0;5400,@1;10800,21600;16200,@1\" " |
229 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
230 | 0 | "position=\"topLeft,#0\" yrange=\"0,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
231 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
232 | 0 | { mso_sptTextCurve, |
233 | 0 | "<v:shapetype id=\"_x0000_t27\" coordsize=\"21600,21600\" o:spt=\"27\" adj=\"3086\" " |
234 | 0 | "path=\"m,qy10800@0,21600,m0@1qy10800,21600,21600@1e\"><v:formulas><v:f eqn=\"val " |
235 | 0 | "#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 " |
236 | 0 | "0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
237 | 0 | "o:connectlocs=\"10800,@0;0,@2;10800,21600;21600,@2\" " |
238 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
239 | 0 | "position=\"center,#0\" yrange=\"0,7200\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
240 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
241 | 0 | { mso_sptTextWave, |
242 | 0 | "<v:shapetype id=\"_x0000_t28\" coordsize=\"21600,21600\" o:spt=\"28\" " |
243 | 0 | "adj=\"2809,10800\" " |
244 | 0 | "path=\"m@25@0c@26@3@27@1@28@0m@21@4c@22@5@23@6@24@4e\"><v:formulas><v:f eqn=\"val " |
245 | 0 | "#0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 9\"/><v:f eqn=\"sum 0 0 " |
246 | 0 | "@2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 " |
247 | 0 | "@3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 #1\"/><v:f eqn=\"prod @8 2 " |
248 | 0 | "3\"/><v:f eqn=\"prod @8 4 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 " |
249 | 0 | "@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @11\"/><v:f eqn=\"prod #1 2 " |
250 | 0 | "3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 " |
251 | 0 | "@15\"/><v:f eqn=\"sum 21600 0 @16\"/><v:f eqn=\"sum 21600 0 @17\"/><v:f eqn=\"if @7 @14 " |
252 | 0 | "0\"/><v:f eqn=\"if @7 @13 @15\"/><v:f eqn=\"if @7 @12 @16\"/><v:f eqn=\"if @7 21600 " |
253 | 0 | "@17\"/><v:f eqn=\"if @7 0 @20\"/><v:f eqn=\"if @7 @9 @19\"/><v:f eqn=\"if @7 @10 " |
254 | 0 | "@18\"/><v:f eqn=\"if @7 @11 21600\"/><v:f eqn=\"sum @24 0 @21\"/><v:f eqn=\"sum @4 0 " |
255 | 0 | "@0\"/><v:f eqn=\"max @21 @25\"/><v:f eqn=\"min @24 @28\"/><v:f eqn=\"prod @0 2 " |
256 | 0 | "1\"/><v:f eqn=\"sum 21600 0 @33\"/><v:f eqn=\"mid @26 @27\"/><v:f eqn=\"mid @24 " |
257 | 0 | "@28\"/><v:f eqn=\"mid @22 @23\"/><v:f eqn=\"mid @21 @25\"/></v:formulas><v:path " |
258 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
259 | 0 | "o:connectlocs=\"@35,@0;@38,10800;@37,@4;@36,10800\" " |
260 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
261 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,4459\"/><v:h " |
262 | 0 | "position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" " |
263 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
264 | 0 | { mso_sptTextRing, |
265 | 0 | "<v:shapetype id=\"_x0000_t29\" coordsize=\"21600,21600\" o:spt=\"29\" " |
266 | 0 | "adj=\"11796480,5400\" " |
267 | 0 | "path=\"al10800,10800,10800,10800@2@14al10800,10800@0@0@2@14e\"><v:formulas><v:f " |
268 | 0 | "eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 " |
269 | 0 | "180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 " |
270 | 0 | "90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 " |
271 | 0 | "90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 " |
272 | 0 | "@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 " |
273 | 0 | "@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 " |
274 | 0 | "2\"/><v:f eqn=\"sum @18 5400 0\"/><v:f eqn=\"cos @19 #0\"/><v:f eqn=\"sin @19 " |
275 | 0 | "#0\"/><v:f eqn=\"sum @20 10800 0\"/><v:f eqn=\"sum @21 10800 0\"/><v:f eqn=\"sum 10800 " |
276 | 0 | "0 @20\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if @9 @17 @25\"/><v:f eqn=\"if @9 0 " |
277 | 0 | "21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
278 | 0 | "o:connectlocs=\"10800,@27;@22,@23;10800,@26;@24,@23\"/><v:textpath on=\"t\" " |
279 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" " |
280 | 0 | "radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
281 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
282 | 0 | { mso_sptTextOnCurve, |
283 | 0 | "<v:shapetype id=\"_x0000_t30\" coordsize=\"21600,21600\" o:spt=\"30\" adj=\"3086\" " |
284 | 0 | "path=\"m,qy10800@0,21600,m0@1qy10800,21600,21600@1e\"><v:formulas><v:f eqn=\"val " |
285 | 0 | "#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 " |
286 | 0 | "0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
287 | 0 | "o:connectlocs=\"10800,@0;0,@2;10800,21600;21600,@2\" " |
288 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
289 | 0 | "position=\"center,#0\" yrange=\"0,7200\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
290 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
291 | 0 | { mso_sptTextOnRing, |
292 | 0 | "<v:shapetype id=\"_x0000_t31\" coordsize=\"21600,21600\" o:spt=\"31\" adj=\"11796480\" " |
293 | 0 | "path=\"al10800,10800,10800,10800@2@14e\"><v:formulas><v:f eqn=\"val #1\"/><v:f " |
294 | 0 | "eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 180\"/><v:f " |
295 | 0 | "eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 90 0\"/><v:f " |
296 | 0 | "eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 90\"/><v:f eqn=\"if " |
297 | 0 | "@9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 @10\"/><v:f " |
298 | 0 | "eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 @14\"/><v:f " |
299 | 0 | "eqn=\"val 10800\"/><v:f eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum " |
300 | 0 | "@17 10800 0\"/><v:f eqn=\"sum @18 10800 0\"/><v:f eqn=\"sum 10800 0 @17\"/><v:f " |
301 | 0 | "eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 @18\"/></v:formulas><v:path " |
302 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
303 | 0 | "o:connectlocs=\"10800,@22;@19,@20;@21,@20\"/><v:textpath on=\"t\" " |
304 | 0 | "style=\"v-text-kern:t\" fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" " |
305 | 0 | "polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
306 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
307 | 0 | { mso_sptTextPlainText, |
308 | 0 | "<v:shapetype id=\"_x0000_t136\" coordsize=\"21600,21600\" o:spt=\"136\" adj=\"10800\" " |
309 | 0 | "path=\"m@7,l@8,m@5,21600l@6,21600e\"><v:formulas><v:f eqn=\"sum #0 0 10800\"/><v:f " |
310 | 0 | "eqn=\"prod #0 2 1\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 0 0 @2\"/><v:f " |
311 | 0 | "eqn=\"sum 21600 0 @3\"/><v:f eqn=\"if @0 @3 0\"/><v:f eqn=\"if @0 21600 @1\"/><v:f " |
312 | 0 | "eqn=\"if @0 0 @2\"/><v:f eqn=\"if @0 @4 21600\"/><v:f eqn=\"mid @5 @6\"/><v:f eqn=\"mid " |
313 | 0 | "@8 @5\"/><v:f eqn=\"mid @7 @8\"/><v:f eqn=\"mid @6 @7\"/><v:f eqn=\"sum @6 0 " |
314 | 0 | "@5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
315 | 0 | "o:connectlocs=\"@9,0;@10,10800;@11,21600;@12,10800\" " |
316 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
317 | 0 | "position=\"#0,bottomRight\" xrange=\"6629,14971\"/></v:handles><o:lock v:ext=\"edit\" " |
318 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
319 | 0 | { mso_sptTextStop, |
320 | 0 | "<v:shapetype id=\"_x0000_t137\" coordsize=\"21600,21600\" o:spt=\"137\" adj=\"4800\" " |
321 | 0 | "path=\"m0@0l7200,r7200,l21600@0m0@1l7200,21600r7200,l21600@1e\"><v:formulas><v:f " |
322 | 0 | "eqn=\"val #0\"/><v:f eqn=\"sum 21600 0 @0\"/></v:formulas><v:path textpathok=\"t\" " |
323 | 0 | "o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
324 | 0 | "position=\"topLeft,#0\" yrange=\"3086,10800\"/></v:handles><o:lock v:ext=\"edit\" " |
325 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
326 | 0 | { mso_sptTextTriangle, |
327 | 0 | "<v:shapetype id=\"_x0000_t138\" coordsize=\"21600,21600\" o:spt=\"138\" adj=\"10800\" " |
328 | 0 | "path=\"m0@0l10800,,21600@0m,21600r10800,l21600,21600e\"><v:formulas><v:f eqn=\"val " |
329 | 0 | "#0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @1 10800 0\"/><v:f eqn=\"sum 21600 0 " |
330 | 0 | "@1\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
331 | 0 | "o:connectlocs=\"10800,0;5400,@1;10800,21600;16200,@1\" " |
332 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
333 | 0 | "position=\"topLeft,#0\" yrange=\"0,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
334 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
335 | 0 | { mso_sptTextTriangleInverted, |
336 | 0 | "<v:shapetype id=\"_x0000_t139\" coordsize=\"21600,21600\" o:spt=\"139\" adj=\"10800\" " |
337 | 0 | "path=\"m,l10800,,21600,m0@0l10800,21600,21600@0e\"><v:formulas><v:f eqn=\"val " |
338 | 0 | "#0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @1 10800 0\"/><v:f eqn=\"sum 21600 0 " |
339 | 0 | "@1\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
340 | 0 | "o:connectlocs=\"10800,0;5400,@2;10800,21600;16200,@2\" " |
341 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
342 | 0 | "position=\"topLeft,#0\" yrange=\"0,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
343 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
344 | 0 | { mso_sptTextChevron, |
345 | 0 | "<v:shapetype id=\"_x0000_t140\" coordsize=\"21600,21600\" o:spt=\"140\" adj=\"5400\" " |
346 | 0 | "path=\"m0@0l10800,,21600@0m,21600l10800@1,21600,21600e\"><v:formulas><v:f eqn=\"val " |
347 | 0 | "#0\"/><v:f eqn=\"sum 21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 " |
348 | 0 | "0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
349 | 0 | "o:connectlocs=\"10800,0;0,@3;10800,@1;21600,@3\" " |
350 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
351 | 0 | "position=\"topLeft,#0\" yrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" " |
352 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
353 | 0 | { mso_sptTextChevronInverted, |
354 | 0 | "<v:shapetype id=\"_x0000_t141\" coordsize=\"21600,21600\" o:spt=\"141\" adj=\"16200\" " |
355 | 0 | "path=\"m,l10800@1,21600,m0@0l10800,21600,21600@0e\"><v:formulas><v:f eqn=\"val " |
356 | 0 | "#0\"/><v:f eqn=\"sum 21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 " |
357 | 0 | "0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
358 | 0 | "o:connectlocs=\"10800,@1;0,@2;10800,21600;21600,@2\" " |
359 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
360 | 0 | "position=\"topLeft,#0\" yrange=\"10800,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
361 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
362 | 0 | { mso_sptTextRingInside, |
363 | 0 | "<v:shapetype id=\"_x0000_t142\" coordsize=\"21600,21600\" o:spt=\"142\" adj=\"13500\" " |
364 | 0 | "path=\"m0@1qy10800,,21600@1,10800@0,0@1m0@2qy10800@3,21600@2,10800,21600,0@2e\"><v:" |
365 | 0 | "formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum height 0 " |
366 | 0 | "@1\"/><v:f eqn=\"sum height 0 #0\"/><v:f eqn=\"sum @2 0 @1\"/></v:formulas><v:path " |
367 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
368 | 0 | "o:connectlocs=\"10800,0;10800,@0;0,10800;10800,21600;10800,@3;21600,10800\" " |
369 | 0 | "o:connectangles=\"270,270,180,90,90,0\"/><v:textpath on=\"t\" " |
370 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"center,#0\" " |
371 | 0 | "yrange=\"10800,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
372 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
373 | 0 | { mso_sptTextRingOutside, |
374 | 0 | "<v:shapetype id=\"_x0000_t143\" coordsize=\"21600,21600\" o:spt=\"143\" adj=\"13500\" " |
375 | 0 | "path=\"m0@1qy10800@0,21600@1,10800,,0@1m0@2qy10800,21600,21600@2,10800@3,0@2e\"><v:" |
376 | 0 | "formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum height 0 " |
377 | 0 | "@1\"/><v:f eqn=\"sum height 0 #0\"/><v:f eqn=\"sum @2 0 @1\"/></v:formulas><v:path " |
378 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
379 | 0 | "o:connectlocs=\"10800,0;10800,@0;0,10800;10800,21600;10800,@3;21600,10800\" " |
380 | 0 | "o:connectangles=\"270,270,180,90,90,0\"/><v:textpath on=\"t\" " |
381 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"center,#0\" " |
382 | 0 | "yrange=\"10800,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
383 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
384 | 0 | { mso_sptTextArchUpCurve, |
385 | 0 | "<v:shapetype id=\"_x0000_t144\" coordsize=\"21600,21600\" o:spt=\"144\" " |
386 | 0 | "adj=\"11796480\" path=\"al10800,10800,10800,10800@2@14e\"><v:formulas><v:f eqn=\"val " |
387 | 0 | "#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 " |
388 | 0 | "180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 " |
389 | 0 | "90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 " |
390 | 0 | "90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 " |
391 | 0 | "@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 " |
392 | 0 | "@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 " |
393 | 0 | "#0\"/><v:f eqn=\"sum @17 10800 0\"/><v:f eqn=\"sum @18 10800 0\"/><v:f eqn=\"sum 10800 " |
394 | 0 | "0 @17\"/><v:f eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 @18\"/></v:formulas><v:path " |
395 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
396 | 0 | "o:connectlocs=\"10800,@22;@19,@20;@21,@20\"/><v:textpath on=\"t\" " |
397 | 0 | "style=\"v-text-kern:t\" fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" " |
398 | 0 | "polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
399 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
400 | 0 | { mso_sptTextArchDownCurve, |
401 | 0 | "<v:shapetype id=\"_x0000_t145\" coordsize=\"21600,21600\" o:spt=\"145\" " |
402 | 0 | "path=\"al10800,10800,10800,10800@3@15e\"><v:formulas><v:f eqn=\"val #1\"/><v:f " |
403 | 0 | "eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 180\"/><v:f " |
404 | 0 | "eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 90 0\"/><v:f " |
405 | 0 | "eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 90\"/><v:f eqn=\"if " |
406 | 0 | "@9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 @10\"/><v:f " |
407 | 0 | "eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 @14\"/><v:f " |
408 | 0 | "eqn=\"val 10800\"/><v:f eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum " |
409 | 0 | "@17 10800 0\"/><v:f eqn=\"sum @18 10800 0\"/><v:f eqn=\"sum 10800 0 @17\"/><v:f " |
410 | 0 | "eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 @18\"/></v:formulas><v:path " |
411 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
412 | 0 | "o:connectlocs=\"10800,@22;@19,@20;@21,@20\"/><v:textpath on=\"t\" " |
413 | 0 | "style=\"v-text-kern:t\" fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" " |
414 | 0 | "polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
415 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
416 | 0 | { mso_sptTextCircleCurve, |
417 | 0 | "<v:shapetype id=\"_x0000_t146\" coordsize=\"21600,21600\" o:spt=\"146\" " |
418 | 0 | "adj=\"-11730944\" path=\"al10800,10800,10800,10800@2@5e\"><v:formulas><v:f eqn=\"val " |
419 | 0 | "#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"prod #0 2 1\"/><v:f " |
420 | 0 | "eqn=\"sumangle @3 0 360\"/><v:f eqn=\"if @3 @4 @3\"/><v:f eqn=\"val 10800\"/><v:f " |
421 | 0 | "eqn=\"cos 10800 #0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum @7 10800 0\"/><v:f " |
422 | 0 | "eqn=\"sum @8 10800 0\"/><v:f eqn=\"sum 10800 0 @8\"/><v:f eqn=\"if #0 0 " |
423 | 0 | "21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
424 | 0 | "o:connectlocs=\"@12,10800;@9,@10;@9,@11\"/><v:textpath on=\"t\" style=\"v-text-kern:t\" " |
425 | 0 | "fitpath=\"t\"/><v:handles><v:h position=\"@6,#0\" " |
426 | 0 | "polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
427 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
428 | 0 | { mso_sptTextButtonCurve, |
429 | 0 | "<v:shapetype id=\"_x0000_t147\" coordsize=\"21600,21600\" o:spt=\"147\" " |
430 | 0 | "adj=\"11796480\" " |
431 | 0 | "path=\"al10800,10800,10800,10800@2@14m,10800r21600,al10800,10800,10800,10800@1@15e\"><v:" |
432 | 0 | "formulas><v:f eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f " |
433 | 0 | "eqn=\"sumangle #0 0 180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 " |
434 | 0 | "1\"/><v:f eqn=\"sumangle #0 90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f " |
435 | 0 | "eqn=\"sumangle @8 0 90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 " |
436 | 0 | "360\"/><v:f eqn=\"if @10 @11 @10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 " |
437 | 0 | "@13 @12\"/><v:f eqn=\"sum 0 0 @14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"cos 10800 " |
438 | 0 | "#0\"/><v:f eqn=\"sin 10800 #0\"/><v:f eqn=\"sum @17 10800 0\"/><v:f eqn=\"sum @18 10800 " |
439 | 0 | "0\"/><v:f eqn=\"sum 10800 0 @17\"/><v:f eqn=\"if @9 0 21600\"/><v:f eqn=\"sum 10800 0 " |
440 | 0 | "@18\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
441 | 0 | "o:connectlocs=\"10800,0;@19,@20;@21,@20;10800,10800;0,10800;21600,10800;10800,21600;@19," |
442 | 0 | "@23;@21,@23\"/><v:textpath on=\"t\" style=\"v-text-kern:t\" " |
443 | 0 | "fitpath=\"t\"/><v:handles><v:h position=\"@16,#0\" " |
444 | 0 | "polar=\"10800,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
445 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
446 | 0 | { mso_sptTextArchUpPour, |
447 | 0 | "<v:shapetype id=\"_x0000_t148\" coordsize=\"21600,21600\" o:spt=\"148\" " |
448 | 0 | "adj=\"11796480,5400\" " |
449 | 0 | "path=\"al10800,10800,10800,10800@2@14al10800,10800@0@0@2@14e\"><v:formulas><v:f " |
450 | 0 | "eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 " |
451 | 0 | "180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 " |
452 | 0 | "90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 " |
453 | 0 | "90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 " |
454 | 0 | "@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 " |
455 | 0 | "@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 " |
456 | 0 | "2\"/><v:f eqn=\"sum @18 5400 0\"/><v:f eqn=\"cos @19 #0\"/><v:f eqn=\"sin @19 " |
457 | 0 | "#0\"/><v:f eqn=\"sum @20 10800 0\"/><v:f eqn=\"sum @21 10800 0\"/><v:f eqn=\"sum 10800 " |
458 | 0 | "0 @20\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if @9 @17 @25\"/><v:f eqn=\"if @9 0 " |
459 | 0 | "21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
460 | 0 | "o:connectlocs=\"10800,@27;@22,@23;10800,@26;@24,@23\"/><v:textpath on=\"t\" " |
461 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" " |
462 | 0 | "radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
463 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
464 | 0 | { mso_sptTextArchDownPour, |
465 | 0 | "<v:shapetype id=\"_x0000_t149\" coordsize=\"21600,21600\" o:spt=\"149\" adj=\",5400\" " |
466 | 0 | "path=\"al10800,10800@0@0@3@15al10800,10800,10800,10800@3@15e\"><v:formulas><v:f " |
467 | 0 | "eqn=\"val #1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 " |
468 | 0 | "180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 " |
469 | 0 | "90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 " |
470 | 0 | "90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 " |
471 | 0 | "@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 " |
472 | 0 | "@14\"/><v:f eqn=\"val 10800\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 " |
473 | 0 | "2\"/><v:f eqn=\"sum @18 5400 0\"/><v:f eqn=\"cos @19 #0\"/><v:f eqn=\"sin @19 " |
474 | 0 | "#0\"/><v:f eqn=\"sum @20 10800 0\"/><v:f eqn=\"sum @21 10800 0\"/><v:f eqn=\"sum 10800 " |
475 | 0 | "0 @20\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if @9 @17 @25\"/><v:f eqn=\"if @9 0 " |
476 | 0 | "21600\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
477 | 0 | "o:connectlocs=\"10800,@27;@22,@23;10800,@26;@24,@23\"/><v:textpath on=\"t\" " |
478 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" " |
479 | 0 | "radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
480 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
481 | 0 | { mso_sptTextCirclePour, |
482 | 0 | "<v:shapetype id=\"_x0000_t150\" coordsize=\"21600,21600\" o:spt=\"150\" " |
483 | 0 | "adj=\"-11730944,5400\" " |
484 | 0 | "path=\"al10800,10800,10800,10800@2@5al10800,10800@0@0@2@5e\"><v:formulas><v:f eqn=\"val " |
485 | 0 | "#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"prod #0 2 1\"/><v:f " |
486 | 0 | "eqn=\"sumangle @3 0 360\"/><v:f eqn=\"if @3 @4 @3\"/><v:f eqn=\"val 10800\"/><v:f " |
487 | 0 | "eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod #1 1 2\"/><v:f eqn=\"sum @8 5400 0\"/><v:f " |
488 | 0 | "eqn=\"cos @9 #0\"/><v:f eqn=\"sin @9 #0\"/><v:f eqn=\"sum @10 10800 0\"/><v:f eqn=\"sum " |
489 | 0 | "@11 10800 0\"/><v:f eqn=\"sum 10800 0 @11\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"if " |
490 | 0 | "#0 @7 @15\"/><v:f eqn=\"if #0 0 21600\"/></v:formulas><v:path textpathok=\"t\" " |
491 | 0 | "o:connecttype=\"custom\" " |
492 | 0 | "o:connectlocs=\"@17,10800;@12,@13;@16,10800;@12,@14\"/><v:textpath on=\"t\" " |
493 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" " |
494 | 0 | "radiusrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
495 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
496 | 0 | { mso_sptTextButtonPour, |
497 | 0 | "<v:shapetype id=\"_x0000_t151\" coordsize=\"21600,21600\" o:spt=\"151\" " |
498 | 0 | "adj=\"11796480,5400\" " |
499 | 0 | "path=\"al10800,10800,10800,10800@2@14al10800,10800@0@0@2@14m@25@17l@26@17m@25@18l@26@" |
500 | 0 | "18al10800,10800@0@0@1@15al10800,10800,10800,10800@1@15e\"><v:formulas><v:f eqn=\"val " |
501 | 0 | "#1\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum 0 0 #0\"/><v:f eqn=\"sumangle #0 0 " |
502 | 0 | "180\"/><v:f eqn=\"sumangle #0 0 90\"/><v:f eqn=\"prod @4 2 1\"/><v:f eqn=\"sumangle #0 " |
503 | 0 | "90 0\"/><v:f eqn=\"prod @6 2 1\"/><v:f eqn=\"abs #0\"/><v:f eqn=\"sumangle @8 0 " |
504 | 0 | "90\"/><v:f eqn=\"if @9 @7 @5\"/><v:f eqn=\"sumangle @10 0 360\"/><v:f eqn=\"if @10 @11 " |
505 | 0 | "@10\"/><v:f eqn=\"sumangle @12 0 360\"/><v:f eqn=\"if @12 @13 @12\"/><v:f eqn=\"sum 0 0 " |
506 | 0 | "@14\"/><v:f eqn=\"sum #1 10800 0\"/><v:f eqn=\"prod @16 1 2\"/><v:f eqn=\"sum 21600 0 " |
507 | 0 | "@17\"/><v:f eqn=\"sum 10800 0 #1\"/><v:f eqn=\"prod @19 1 2\"/><v:f eqn=\"prod @20 @20 " |
508 | 0 | "1\"/><v:f eqn=\"prod #1 #1 1\"/><v:f eqn=\"sum @22 0 @21\"/><v:f eqn=\"sqrt @23\"/><v:f " |
509 | 0 | "eqn=\"sum 10800 0 @24\"/><v:f eqn=\"sum @24 10800 0\"/><v:f eqn=\"val 10800\"/><v:f " |
510 | 0 | "eqn=\"cos @17 #0\"/><v:f eqn=\"sin @17 #0\"/><v:f eqn=\"sum @28 10800 0\"/><v:f " |
511 | 0 | "eqn=\"sum @29 10800 0\"/><v:f eqn=\"sum 10800 0 @28\"/><v:f eqn=\"sum 10800 0 " |
512 | 0 | "@29\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
513 | 0 | "o:connectlocs=\"10800,0;@30,@31;10800,@19;@32,@31;10800,@17;@25,10800;10800,@18;@26," |
514 | 0 | "10800;10800,@16;@30,@33;10800,21600;@32,@33\"/><v:textpath on=\"t\" " |
515 | 0 | "fitshape=\"t\"/><v:handles><v:h position=\"#1,#0\" polar=\"10800,10800\" " |
516 | 0 | "radiusrange=\"4320,10800\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
517 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
518 | 0 | { mso_sptTextCurveUp, |
519 | 0 | "<v:shapetype id=\"_x0000_t152\" coordsize=\"21600,21600\" o:spt=\"152\" adj=\"9931\" " |
520 | 0 | "path=\"m0@0c7200@2,14400@1,21600,m0@5c7200@6,14400@6,21600@5e\"><v:formulas><v:f " |
521 | 0 | "eqn=\"val #0\"/><v:f eqn=\"prod #0 3 4\"/><v:f eqn=\"prod #0 5 4\"/><v:f eqn=\"prod #0 " |
522 | 0 | "3 8\"/><v:f eqn=\"prod #0 1 8\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum @4 21600 " |
523 | 0 | "0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @5 1 2\"/><v:f eqn=\"sum @7 @8 0\"/><v:f " |
524 | 0 | "eqn=\"prod #0 7 8\"/><v:f eqn=\"prod @5 1 3\"/><v:f eqn=\"sum @1 @2 0\"/><v:f eqn=\"sum " |
525 | 0 | "@12 @0 0\"/><v:f eqn=\"prod @13 1 4\"/><v:f eqn=\"sum @11 14400 " |
526 | 0 | "@14\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
527 | 0 | "o:connectlocs=\"10800,@10;0,@9;10800,21600;21600,@8\" " |
528 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
529 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" " |
530 | 0 | "yrange=\"0,12169\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
531 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
532 | 0 | { mso_sptTextCurveDown, |
533 | 0 | "<v:shapetype id=\"_x0000_t153\" coordsize=\"21600,21600\" o:spt=\"153\" adj=\"9391\" " |
534 | 0 | "path=\"m,c7200@1,14400@2,21600@0m0@5c7200@6,14400@6,21600@5e\"><v:formulas><v:f " |
535 | 0 | "eqn=\"val #0\"/><v:f eqn=\"prod #0 3 4\"/><v:f eqn=\"prod #0 5 4\"/><v:f eqn=\"prod #0 " |
536 | 0 | "3 8\"/><v:f eqn=\"prod #0 1 8\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum @4 21600 " |
537 | 0 | "0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @5 1 2\"/><v:f eqn=\"sum @7 @8 0\"/><v:f " |
538 | 0 | "eqn=\"prod #0 7 8\"/><v:f eqn=\"prod @5 1 3\"/><v:f eqn=\"sum @1 @2 0\"/><v:f eqn=\"sum " |
539 | 0 | "@12 @0 0\"/><v:f eqn=\"prod @13 1 4\"/><v:f eqn=\"sum @11 14400 " |
540 | 0 | "@14\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
541 | 0 | "o:connectlocs=\"10800,@10;0,@8;10800,21600;21600,@9\" " |
542 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
543 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"bottomRight,#0\" " |
544 | 0 | "yrange=\"0,11368\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
545 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
546 | 0 | { mso_sptTextCascadeUp, |
547 | 0 | "<v:shapetype id=\"_x0000_t154\" coordsize=\"21600,21600\" o:spt=\"154\" adj=\"9600\" " |
548 | 0 | "path=\"m0@2l21600,m,21600l21600@0e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
549 | 0 | "21600 0 #0\"/><v:f eqn=\"prod @1 1 4\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @2 1 " |
550 | 0 | "2\"/><v:f eqn=\"sum @3 10800 0\"/><v:f eqn=\"sum @4 10800 0\"/><v:f eqn=\"sum @0 21600 " |
551 | 0 | "@2\"/><v:f eqn=\"prod @7 1 2\"/></v:formulas><v:path textpathok=\"t\" " |
552 | 0 | "o:connecttype=\"custom\" o:connectlocs=\"10800,@4;0,@6;10800,@5;21600,@3\" " |
553 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
554 | 0 | "position=\"bottomRight,#0\" yrange=\"6171,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
555 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
556 | 0 | { mso_sptTextCascadeDown, |
557 | 0 | "<v:shapetype id=\"_x0000_t155\" coordsize=\"21600,21600\" o:spt=\"155\" adj=\"9600\" " |
558 | 0 | "path=\"m,l21600@2m0@0l21600,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
559 | 0 | "21600 0 #0\"/><v:f eqn=\"prod @1 1 4\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"prod @2 1 " |
560 | 0 | "2\"/><v:f eqn=\"sum @3 10800 0\"/><v:f eqn=\"sum @4 10800 0\"/><v:f eqn=\"sum @0 21600 " |
561 | 0 | "@2\"/><v:f eqn=\"prod @7 1 2\"/></v:formulas><v:path textpathok=\"t\" " |
562 | 0 | "o:connecttype=\"custom\" o:connectlocs=\"10800,@4;0,@3;10800,@5;21600,@6\" " |
563 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
564 | 0 | "position=\"topLeft,#0\" yrange=\"6171,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
565 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
566 | 0 | { mso_sptTextWave1, |
567 | 0 | "<v:shapetype id=\"_x0000_t156\" coordsize=\"21600,21600\" o:spt=\"156\" " |
568 | 0 | "adj=\"2809,10800\" " |
569 | 0 | "path=\"m@25@0c@26@3@27@1@28@0m@21@4c@22@5@23@6@24@4e\"><v:formulas><v:f eqn=\"val " |
570 | 0 | "#0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 9\"/><v:f eqn=\"sum 0 0 " |
571 | 0 | "@2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 " |
572 | 0 | "@3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 #1\"/><v:f eqn=\"prod @8 2 " |
573 | 0 | "3\"/><v:f eqn=\"prod @8 4 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 " |
574 | 0 | "@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @11\"/><v:f eqn=\"prod #1 2 " |
575 | 0 | "3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 " |
576 | 0 | "@15\"/><v:f eqn=\"sum 21600 0 @16\"/><v:f eqn=\"sum 21600 0 @17\"/><v:f eqn=\"if @7 @14 " |
577 | 0 | "0\"/><v:f eqn=\"if @7 @13 @15\"/><v:f eqn=\"if @7 @12 @16\"/><v:f eqn=\"if @7 21600 " |
578 | 0 | "@17\"/><v:f eqn=\"if @7 0 @20\"/><v:f eqn=\"if @7 @9 @19\"/><v:f eqn=\"if @7 @10 " |
579 | 0 | "@18\"/><v:f eqn=\"if @7 @11 21600\"/><v:f eqn=\"sum @24 0 @21\"/><v:f eqn=\"sum @4 0 " |
580 | 0 | "@0\"/><v:f eqn=\"max @21 @25\"/><v:f eqn=\"min @24 @28\"/><v:f eqn=\"prod @0 2 " |
581 | 0 | "1\"/><v:f eqn=\"sum 21600 0 @33\"/><v:f eqn=\"mid @26 @27\"/><v:f eqn=\"mid @24 " |
582 | 0 | "@28\"/><v:f eqn=\"mid @22 @23\"/><v:f eqn=\"mid @21 @25\"/></v:formulas><v:path " |
583 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
584 | 0 | "o:connectlocs=\"@35,@0;@38,10800;@37,@4;@36,10800\" " |
585 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
586 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,4459\"/><v:h " |
587 | 0 | "position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" " |
588 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
589 | 0 | { mso_sptTextWave2, |
590 | 0 | "<v:shapetype id=\"_x0000_t157\" coordsize=\"21600,21600\" o:spt=\"157\" " |
591 | 0 | "adj=\"2809,10800\" " |
592 | 0 | "path=\"m@25@0c@26@1@27@3@28@0m@21@4c@22@6@23@5@24@4e\"><v:formulas><v:f eqn=\"val " |
593 | 0 | "#0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 9\"/><v:f eqn=\"sum 0 0 " |
594 | 0 | "@2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 " |
595 | 0 | "@3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 #1\"/><v:f eqn=\"prod @8 2 " |
596 | 0 | "3\"/><v:f eqn=\"prod @8 4 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 " |
597 | 0 | "@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @11\"/><v:f eqn=\"prod #1 2 " |
598 | 0 | "3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 " |
599 | 0 | "@15\"/><v:f eqn=\"sum 21600 0 @16\"/><v:f eqn=\"sum 21600 0 @17\"/><v:f eqn=\"if @7 @14 " |
600 | 0 | "0\"/><v:f eqn=\"if @7 @13 @15\"/><v:f eqn=\"if @7 @12 @16\"/><v:f eqn=\"if @7 21600 " |
601 | 0 | "@17\"/><v:f eqn=\"if @7 0 @20\"/><v:f eqn=\"if @7 @9 @19\"/><v:f eqn=\"if @7 @10 " |
602 | 0 | "@18\"/><v:f eqn=\"if @7 @11 21600\"/><v:f eqn=\"sum @24 0 @21\"/><v:f eqn=\"sum @4 0 " |
603 | 0 | "@0\"/><v:f eqn=\"max @21 @25\"/><v:f eqn=\"min @24 @28\"/><v:f eqn=\"prod @0 2 " |
604 | 0 | "1\"/><v:f eqn=\"sum 21600 0 @33\"/><v:f eqn=\"mid @26 @27\"/><v:f eqn=\"mid @24 " |
605 | 0 | "@28\"/><v:f eqn=\"mid @22 @23\"/><v:f eqn=\"mid @21 @25\"/></v:formulas><v:path " |
606 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
607 | 0 | "o:connectlocs=\"@35,@0;@38,10800;@37,@4;@36,10800\" " |
608 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
609 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,4459\"/><v:h " |
610 | 0 | "position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" " |
611 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
612 | 0 | { mso_sptTextWave3, |
613 | 0 | "<v:shapetype id=\"_x0000_t158\" coordsize=\"21600,21600\" o:spt=\"158\" " |
614 | 0 | "adj=\"1404,10800\" " |
615 | 0 | "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:" |
616 | 0 | "formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 " |
617 | 0 | "9\"/><v:f eqn=\"sum 0 0 @2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 " |
618 | 0 | "@1\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 " |
619 | 0 | "#1\"/><v:f eqn=\"prod @8 1 3\"/><v:f eqn=\"prod @8 2 3\"/><v:f eqn=\"prod @8 4 " |
620 | 0 | "3\"/><v:f eqn=\"prod @8 5 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 " |
621 | 0 | "@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @8\"/><v:f eqn=\"sum 21600 0 " |
622 | 0 | "@11\"/><v:f eqn=\"sum 21600 0 @12\"/><v:f eqn=\"sum 21600 0 @13\"/><v:f eqn=\"prod #1 1 " |
623 | 0 | "3\"/><v:f eqn=\"prod #1 2 3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 5 3\"/><v:f " |
624 | 0 | "eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 @20\"/><v:f eqn=\"sum 21600 0 @21\"/><v:f " |
625 | 0 | "eqn=\"sum 21600 0 @22\"/><v:f eqn=\"sum 21600 0 @23\"/><v:f eqn=\"sum 21600 0 " |
626 | 0 | "@24\"/><v:f eqn=\"if @7 @19 0\"/><v:f eqn=\"if @7 @18 @20\"/><v:f eqn=\"if @7 @17 " |
627 | 0 | "@21\"/><v:f eqn=\"if @7 @16 #1\"/><v:f eqn=\"if @7 @15 @22\"/><v:f eqn=\"if @7 @14 " |
628 | 0 | "@23\"/><v:f eqn=\"if @7 21600 @24\"/><v:f eqn=\"if @7 0 @29\"/><v:f eqn=\"if @7 @9 " |
629 | 0 | "@28\"/><v:f eqn=\"if @7 @10 @27\"/><v:f eqn=\"if @7 @8 @8\"/><v:f eqn=\"if @7 @11 " |
630 | 0 | "@26\"/><v:f eqn=\"if @7 @12 @25\"/><v:f eqn=\"if @7 @13 21600\"/><v:f eqn=\"sum @36 0 " |
631 | 0 | "@30\"/><v:f eqn=\"sum @4 0 @0\"/><v:f eqn=\"max @30 @37\"/><v:f eqn=\"min @36 " |
632 | 0 | "@43\"/><v:f eqn=\"prod @0 2 1\"/><v:f eqn=\"sum 21600 0 @48\"/><v:f eqn=\"mid @36 " |
633 | 0 | "@43\"/><v:f eqn=\"mid @30 @37\"/></v:formulas><v:path textpathok=\"t\" " |
634 | 0 | "o:connecttype=\"custom\" o:connectlocs=\"@40,@0;@51,10800;@33,@4;@50,10800\" " |
635 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
636 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,2229\"/><v:h " |
637 | 0 | "position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" " |
638 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
639 | 0 | { mso_sptTextWave4, |
640 | 0 | "<v:shapetype id=\"_x0000_t159\" coordsize=\"21600,21600\" o:spt=\"159\" " |
641 | 0 | "adj=\"1404,10800\" " |
642 | 0 | "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:" |
643 | 0 | "formulas><v:f eqn=\"val #0\"/><v:f eqn=\"prod @0 41 9\"/><v:f eqn=\"prod @0 23 " |
644 | 0 | "9\"/><v:f eqn=\"sum 0 0 @2\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"sum 21600 0 " |
645 | 0 | "@1\"/><v:f eqn=\"sum 21600 0 @3\"/><v:f eqn=\"sum #1 0 10800\"/><v:f eqn=\"sum 21600 0 " |
646 | 0 | "#1\"/><v:f eqn=\"prod @8 1 3\"/><v:f eqn=\"prod @8 2 3\"/><v:f eqn=\"prod @8 4 " |
647 | 0 | "3\"/><v:f eqn=\"prod @8 5 3\"/><v:f eqn=\"prod @8 2 1\"/><v:f eqn=\"sum 21600 0 " |
648 | 0 | "@9\"/><v:f eqn=\"sum 21600 0 @10\"/><v:f eqn=\"sum 21600 0 @8\"/><v:f eqn=\"sum 21600 0 " |
649 | 0 | "@11\"/><v:f eqn=\"sum 21600 0 @12\"/><v:f eqn=\"sum 21600 0 @13\"/><v:f eqn=\"prod #1 1 " |
650 | 0 | "3\"/><v:f eqn=\"prod #1 2 3\"/><v:f eqn=\"prod #1 4 3\"/><v:f eqn=\"prod #1 5 3\"/><v:f " |
651 | 0 | "eqn=\"prod #1 2 1\"/><v:f eqn=\"sum 21600 0 @20\"/><v:f eqn=\"sum 21600 0 @21\"/><v:f " |
652 | 0 | "eqn=\"sum 21600 0 @22\"/><v:f eqn=\"sum 21600 0 @23\"/><v:f eqn=\"sum 21600 0 " |
653 | 0 | "@24\"/><v:f eqn=\"if @7 @19 0\"/><v:f eqn=\"if @7 @18 @20\"/><v:f eqn=\"if @7 @17 " |
654 | 0 | "@21\"/><v:f eqn=\"if @7 @16 #1\"/><v:f eqn=\"if @7 @15 @22\"/><v:f eqn=\"if @7 @14 " |
655 | 0 | "@23\"/><v:f eqn=\"if @7 21600 @24\"/><v:f eqn=\"if @7 0 @29\"/><v:f eqn=\"if @7 @9 " |
656 | 0 | "@28\"/><v:f eqn=\"if @7 @10 @27\"/><v:f eqn=\"if @7 @8 @8\"/><v:f eqn=\"if @7 @11 " |
657 | 0 | "@26\"/><v:f eqn=\"if @7 @12 @25\"/><v:f eqn=\"if @7 @13 21600\"/><v:f eqn=\"sum @36 0 " |
658 | 0 | "@30\"/><v:f eqn=\"sum @4 0 @0\"/><v:f eqn=\"max @30 @37\"/><v:f eqn=\"min @36 " |
659 | 0 | "@43\"/><v:f eqn=\"prod @0 2 1\"/><v:f eqn=\"sum 21600 0 @48\"/><v:f eqn=\"mid @36 " |
660 | 0 | "@43\"/><v:f eqn=\"mid @30 @37\"/></v:formulas><v:path textpathok=\"t\" " |
661 | 0 | "o:connecttype=\"custom\" o:connectlocs=\"@40,@0;@51,10800;@33,@4;@50,10800\" " |
662 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
663 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" yrange=\"0,2229\"/><v:h " |
664 | 0 | "position=\"#1,bottomRight\" xrange=\"8640,12960\"/></v:handles><o:lock v:ext=\"edit\" " |
665 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
666 | 0 | { mso_sptTextInflate, |
667 | 0 | "<v:shapetype id=\"_x0000_t160\" coordsize=\"21600,21600\" o:spt=\"160\" adj=\"2945\" " |
668 | 0 | "path=\"m0@0c7200@2,14400@2,21600@0m0@3c7200@4,14400@4,21600@3e\"><v:formulas><v:f " |
669 | 0 | "eqn=\"val #0\"/><v:f eqn=\"prod #0 1 3\"/><v:f eqn=\"sum 0 0 @1\"/><v:f eqn=\"sum 21600 " |
670 | 0 | "0 #0\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"prod #0 2 3\"/><v:f eqn=\"sum 21600 0 " |
671 | 0 | "@5\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"rect\"/><v:textpath " |
672 | 0 | "on=\"t\" fitshape=\"t\" xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" " |
673 | 0 | "yrange=\"0,4629\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
674 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
675 | 0 | { mso_sptTextDeflate, |
676 | 0 | "<v:shapetype id=\"_x0000_t161\" coordsize=\"21600,21600\" o:spt=\"161\" adj=\"4050\" " |
677 | 0 | "path=\"m,c7200@0,14400@0,21600,m,21600c7200@1,14400@1,21600,21600e\"><v:formulas><v:f " |
678 | 0 | "eqn=\"prod #0 4 3\"/><v:f eqn=\"sum 21600 0 @0\"/><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
679 | 0 | "21600 0 #0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
680 | 0 | "o:connectlocs=\"10800,@2;0,10800;10800,@3;21600,10800\" " |
681 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
682 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"center,#0\" " |
683 | 0 | "yrange=\"0,8100\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
684 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
685 | 0 | { mso_sptTextInflateBottom, |
686 | 0 | "<v:shapetype id=\"_x0000_t162\" coordsize=\"21600,21600\" o:spt=\"162\" adj=\"14706\" " |
687 | 0 | "path=\"m,l21600,m0@0c7200@2,14400@2,21600@0e\"><v:formulas><v:f eqn=\"val #0\"/><v:f " |
688 | 0 | "eqn=\"prod #0 1 3\"/><v:f eqn=\"sum 28800 0 @1\"/><v:f eqn=\"prod #0 1 2\"/><v:f " |
689 | 0 | "eqn=\"sum @1 7200 0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
690 | 0 | "o:connectlocs=\"10800,0;0,@3;10800,21600;21600,@3\" " |
691 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
692 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" " |
693 | 0 | "yrange=\"11148,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
694 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
695 | 0 | { mso_sptTextDeflateBottom, |
696 | 0 | "<v:shapetype id=\"_x0000_t163\" coordsize=\"21600,21600\" o:spt=\"163\" adj=\"11475\" " |
697 | 0 | "path=\"m,l21600,m,21600c7200@1,14400@1,21600,21600e\"><v:formulas><v:f eqn=\"prod #0 4 " |
698 | 0 | "3\"/><v:f eqn=\"sum @0 0 7200\"/><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 2 3\"/><v:f " |
699 | 0 | "eqn=\"sum @3 7200 0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
700 | 0 | "o:connectlocs=\"10800,0;0,10800;10800,@2;21600,10800\" " |
701 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
702 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"center,#0\" " |
703 | 0 | "yrange=\"1350,21600\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
704 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
705 | 0 | { mso_sptTextInflateTop, |
706 | 0 | "<v:shapetype id=\"_x0000_t164\" coordsize=\"21600,21600\" o:spt=\"164\" adj=\"6894\" " |
707 | 0 | "path=\"m0@0c7200@2,14400@2,21600@0m,21600r21600,e\"><v:formulas><v:f eqn=\"val " |
708 | 0 | "#0\"/><v:f eqn=\"prod #0 1 3\"/><v:f eqn=\"sum 0 0 @1\"/><v:f eqn=\"prod #0 1 2\"/><v:f " |
709 | 0 | "eqn=\"sum @3 10800 0\"/><v:f eqn=\"sum 21600 0 @1\"/></v:formulas><v:path " |
710 | 0 | "textpathok=\"t\" o:connecttype=\"custom\" " |
711 | 0 | "o:connectlocs=\"10800,0;0,@4;10800,21600;21600,@4\" " |
712 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
713 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"topLeft,#0\" " |
714 | 0 | "yrange=\"0,10452\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
715 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
716 | 0 | { mso_sptTextDeflateTop, |
717 | 0 | "<v:shapetype id=\"_x0000_t165\" coordsize=\"21600,21600\" o:spt=\"165\" adj=\"10125\" " |
718 | 0 | "path=\"m,c7200@0,14400@0,21600,m,21600r21600,e\"><v:formulas><v:f eqn=\"prod #0 4 " |
719 | 0 | "3\"/><v:f eqn=\"val #0\"/><v:f eqn=\"prod #0 2 3\"/><v:f eqn=\"sum 21600 0 " |
720 | 0 | "@2\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
721 | 0 | "o:connectlocs=\"10800,@1;0,10800;10800,21600;21600,10800\" " |
722 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\" " |
723 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"center,#0\" " |
724 | 0 | "yrange=\"0,20250\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
725 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
726 | 0 | { mso_sptTextDeflateInflate, |
727 | 0 | "<v:shapetype id=\"_x0000_t166\" coordsize=\"21600,21600\" o:spt=\"166\" adj=\"6054\" " |
728 | 0 | "path=\"m,l21600,m,10125c7200@1,14400@1,21600,10125m,11475c7200@2,14400@2,21600,11475m," |
729 | 0 | "21600r21600,e\"><v:formulas><v:f eqn=\"prod #0 4 3\"/><v:f eqn=\"sum @0 0 4275\"/><v:f " |
730 | 0 | "eqn=\"sum @0 0 2925\"/></v:formulas><v:path textpathok=\"t\" " |
731 | 0 | "o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\" " |
732 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"center,#0\" " |
733 | 0 | "yrange=\"1308,20292\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
734 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
735 | 0 | { mso_sptTextDeflateInflateDeflate, |
736 | 0 | "<v:shapetype id=\"_x0000_t167\" coordsize=\"21600,21600\" o:spt=\"167\" adj=\"6054\" " |
737 | 0 | "path=\"m,l21600,m,6609c7200@1,14400@1,21600,6609m,7491c7200@2,14400@2,21600,7491m," |
738 | 0 | "14109c7200@4,14400@4,21600,14109m,14991c7200@3,14400@3,21600,14991m,21600r21600,e\"><v:" |
739 | 0 | "formulas><v:f eqn=\"prod #0 4 3\"/><v:f eqn=\"sum @0 0 2791\"/><v:f eqn=\"sum @0 0 " |
740 | 0 | "1909\"/><v:f eqn=\"sum 21600 0 @1\"/><v:f eqn=\"sum 21600 0 @2\"/></v:formulas><v:path " |
741 | 0 | "textpathok=\"t\" o:connecttype=\"rect\"/><v:textpath on=\"t\" fitshape=\"t\" " |
742 | 0 | "xscale=\"t\"/><v:handles><v:h position=\"center,#0\" " |
743 | 0 | "yrange=\"854,9525\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
744 | 0 | "shapetype=\"t\"/></v:shapetype>" }, |
745 | 0 | { mso_sptTextFadeRight, |
746 | 0 | "<v:shapetype id=\"_x0000_t168\" coordsize=\"21600,21600\" o:spt=\"168\" adj=\"7200\" " |
747 | 0 | "path=\"m,l21600@0m,21600l21600@1e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
748 | 0 | "21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 " |
749 | 0 | "21600 @0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
750 | 0 | "o:connectlocs=\"10800,@2;0,10800;10800,@3;21600,10800\" " |
751 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
752 | 0 | "position=\"bottomRight,#0\" yrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" " |
753 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
754 | 0 | { mso_sptTextFadeLeft, |
755 | 0 | "<v:shapetype id=\"_x0000_t169\" coordsize=\"21600,21600\" o:spt=\"169\" adj=\"7200\" " |
756 | 0 | "path=\"m0@0l21600,m0@1l21600,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
757 | 0 | "21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 " |
758 | 0 | "21600 @0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
759 | 0 | "o:connectlocs=\"10800,@2;0,10800;10800,@3;21600,10800\" " |
760 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
761 | 0 | "position=\"topLeft,#0\" yrange=\"0,10800\"/></v:handles><o:lock v:ext=\"edit\" " |
762 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
763 | 0 | { mso_sptTextFadeUp, |
764 | 0 | "<v:shapetype id=\"_x0000_t170\" coordsize=\"21600,21600\" o:spt=\"170\" adj=\"7200\" " |
765 | 0 | "path=\"m@0,l@1,m,21600r21600,e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum 21600 " |
766 | 0 | "0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 21600 " |
767 | 0 | "@0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
768 | 0 | "o:connectlocs=\"10800,0;@2,10800;10800,21600;@3,10800\" " |
769 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
770 | 0 | "position=\"#0,topLeft\" xrange=\"0,10792\"/></v:handles><o:lock v:ext=\"edit\" " |
771 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
772 | 0 | { mso_sptTextFadeDown, |
773 | 0 | "<v:shapetype id=\"_x0000_t171\" coordsize=\"21600,21600\" o:spt=\"171\" adj=\"7200\" " |
774 | 0 | "path=\"m,l21600,m@0,21600l@1,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
775 | 0 | "21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum 21600 0 @2\"/><v:f eqn=\"sum @1 " |
776 | 0 | "21600 @0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
777 | 0 | "o:connectlocs=\"10800,0;@2,10800;10800,21600;@3,10800\" " |
778 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
779 | 0 | "position=\"#0,bottomRight\" xrange=\"0,10792\"/></v:handles><o:lock v:ext=\"edit\" " |
780 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
781 | 0 | { mso_sptTextSlantUp, |
782 | 0 | "<v:shapetype id=\"_x0000_t172\" coordsize=\"21600,21600\" o:spt=\"172\" adj=\"12000\" " |
783 | 0 | "path=\"m0@0l21600,m,21600l21600@1e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
784 | 0 | "21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 0\"/><v:f eqn=\"prod @1 " |
785 | 0 | "1 2\"/><v:f eqn=\"sum @4 10800 0\"/></v:formulas><v:path textpathok=\"t\" " |
786 | 0 | "o:connecttype=\"custom\" o:connectlocs=\"10800,@2;0,@3;10800,@5;21600,@4\" " |
787 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
788 | 0 | "position=\"topLeft,#0\" yrange=\"0,15429\"/></v:handles><o:lock v:ext=\"edit\" " |
789 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
790 | 0 | { mso_sptTextSlantDown, |
791 | 0 | "<v:shapetype id=\"_x0000_t173\" coordsize=\"21600,21600\" o:spt=\"173\" adj=\"9600\" " |
792 | 0 | "path=\"m,l21600@1m0@0l21600,21600e\"><v:formulas><v:f eqn=\"val #0\"/><v:f eqn=\"sum " |
793 | 0 | "21600 0 @0\"/><v:f eqn=\"prod #0 1 2\"/><v:f eqn=\"sum @2 10800 0\"/><v:f eqn=\"prod @1 " |
794 | 0 | "1 2\"/><v:f eqn=\"sum @4 10800 0\"/></v:formulas><v:path textpathok=\"t\" " |
795 | 0 | "o:connecttype=\"custom\" o:connectlocs=\"10800,@4;0,@2;10800,@3;21600,@5\" " |
796 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
797 | 0 | "position=\"topLeft,#0\" yrange=\"6171,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
798 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
799 | 0 | { mso_sptTextCanUp, |
800 | 0 | "<v:shapetype id=\"_x0000_t174\" coordsize=\"21600,21600\" o:spt=\"174\" adj=\"18514\" " |
801 | 0 | "path=\"m0@1qy10800,,21600@1m,21600qy10800@0,21600,21600e\"><v:formulas><v:f eqn=\"val " |
802 | 0 | "#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 " |
803 | 0 | "0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
804 | 0 | "o:connectlocs=\"10800,0;0,@3;10800,@0;21600,@3\" " |
805 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
806 | 0 | "position=\"center,#0\" yrange=\"14400,21600\"/></v:handles><o:lock v:ext=\"edit\" " |
807 | 0 | "text=\"t\" shapetype=\"t\"/></v:shapetype>" }, |
808 | 0 | { mso_sptTextCanDown, |
809 | 0 | "<v:shapetype id=\"_x0000_t175\" coordsize=\"21600,21600\" o:spt=\"175\" adj=\"3086\" " |
810 | 0 | "path=\"m,qy10800@0,21600,m0@1qy10800,21600,21600@1e\"><v:formulas><v:f eqn=\"val " |
811 | 0 | "#0\"/><v:f eqn=\"sum 21600 0 #0\"/><v:f eqn=\"prod @1 1 2\"/><v:f eqn=\"sum @2 10800 " |
812 | 0 | "0\"/></v:formulas><v:path textpathok=\"t\" o:connecttype=\"custom\" " |
813 | 0 | "o:connectlocs=\"10800,@0;0,@2;10800,21600;21600,@2\" " |
814 | 0 | "o:connectangles=\"270,180,90,0\"/><v:textpath on=\"t\" fitshape=\"t\"/><v:handles><v:h " |
815 | 0 | "position=\"center,#0\" yrange=\"0,7200\"/></v:handles><o:lock v:ext=\"edit\" text=\"t\" " |
816 | 0 | "shapetype=\"t\"/></v:shapetype>" } |
817 | 0 | }; |
818 | |
|
819 | 0 | auto i(aTypeToMarkupMap.find(eShapeType)); |
820 | 0 | return i == aTypeToMarkupMap.end() ? OString() : i->second; |
821 | 0 | } |
822 | | |
823 | | void FontworkHelpers::collectCharColorProps(const uno::Reference<text::XText>& rXText, |
824 | | std::vector<beans::PropertyValue>& rCharPropVec) |
825 | 0 | { |
826 | 0 | if (!rXText.is()) |
827 | 0 | return; |
828 | 0 | uno::Reference<text::XTextCursor> rXTextCursor = rXText->createTextCursor(); |
829 | 0 | rXTextCursor->gotoStart(false); |
830 | 0 | rXTextCursor->gotoEnd(true); |
831 | 0 | uno::Reference<container::XEnumerationAccess> paraEnumAccess(rXText, uno::UNO_QUERY); |
832 | 0 | if (!paraEnumAccess.is()) |
833 | 0 | return; |
834 | 0 | uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration()); |
835 | 0 | while (paraEnum->hasMoreElements()) |
836 | 0 | { |
837 | 0 | uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY); |
838 | 0 | uno::Reference<container::XEnumerationAccess> runEnumAccess(xParagraph, uno::UNO_QUERY); |
839 | 0 | if (!runEnumAccess.is()) |
840 | 0 | continue; |
841 | 0 | uno::Reference<container::XEnumeration> runEnum = runEnumAccess->createEnumeration(); |
842 | 0 | while (runEnum->hasMoreElements()) |
843 | 0 | { |
844 | 0 | uno::Reference<text::XTextRange> xRun(runEnum->nextElement(), uno::UNO_QUERY); |
845 | 0 | if (xRun->getString().isEmpty()) |
846 | 0 | continue; |
847 | 0 | uno::Reference<beans::XPropertySet> xRunPropSet(xRun, uno::UNO_QUERY); |
848 | 0 | if (!xRunPropSet.is()) |
849 | 0 | continue; |
850 | 0 | auto xRunPropSetInfo = xRunPropSet->getPropertySetInfo(); |
851 | 0 | if (!xRunPropSetInfo.is()) |
852 | 0 | continue; |
853 | | |
854 | | // We have found a non-empty run. Collect its simple color properties. |
855 | 0 | static constexpr auto aNamesArray = std::to_array<std::u16string_view>( |
856 | 0 | { u"CharColor", u"CharLumMod", u"CharLumOff", u"CharColorTheme", |
857 | 0 | u"CharComplexColor", u"CharTransparence" }); |
858 | 0 | for (const auto& sName : aNamesArray) |
859 | 0 | { |
860 | 0 | OUString aPropertyName(sName); |
861 | 0 | if (xRunPropSetInfo->hasPropertyByName(aPropertyName)) |
862 | 0 | rCharPropVec.push_back(comphelper::makePropertyValue( |
863 | 0 | aPropertyName, xRunPropSet->getPropertyValue(aPropertyName))); |
864 | 0 | } |
865 | 0 | return; |
866 | 0 | } |
867 | 0 | } |
868 | 0 | } |
869 | | |
870 | | void FontworkHelpers::applyPropsToRuns(const std::vector<beans::PropertyValue>& rTextPropVec, |
871 | | const uno::Reference<text::XText>& rXText) |
872 | 0 | { |
873 | 0 | if (!rXText.is()) |
874 | 0 | return; |
875 | 0 | uno::Reference<text::XTextCursor> xTextCursor = rXText->createTextCursor(); |
876 | 0 | xTextCursor->gotoStart(false); |
877 | 0 | xTextCursor->gotoEnd(true); |
878 | 0 | uno::Reference<container::XEnumerationAccess> paraEnumAccess(rXText, uno::UNO_QUERY); |
879 | 0 | if (!paraEnumAccess.is()) |
880 | 0 | return; |
881 | 0 | uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration()); |
882 | 0 | while (paraEnum->hasMoreElements()) |
883 | 0 | { |
884 | 0 | uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY); |
885 | 0 | uno::Reference<container::XEnumerationAccess> runEnumAccess(xParagraph, uno::UNO_QUERY); |
886 | 0 | if (!runEnumAccess.is()) |
887 | 0 | continue; |
888 | 0 | uno::Reference<container::XEnumeration> runEnum = runEnumAccess->createEnumeration(); |
889 | 0 | while (runEnum->hasMoreElements()) |
890 | 0 | { |
891 | 0 | uno::Reference<text::XTextRange> xRun(runEnum->nextElement(), uno::UNO_QUERY); |
892 | 0 | uno::Reference<beans::XPropertySet> xRunPropSet(xRun, uno::UNO_QUERY); |
893 | 0 | if (!xRunPropSet.is()) |
894 | 0 | continue; |
895 | 0 | auto xRunPropSetInfo = xRunPropSet->getPropertySetInfo(); |
896 | 0 | if (!xRunPropSetInfo.is()) |
897 | 0 | continue; |
898 | | |
899 | 0 | for (const beans::PropertyValue& rProp : rTextPropVec) |
900 | 0 | { |
901 | 0 | if (xRunPropSetInfo->hasPropertyByName(rProp.Name) |
902 | 0 | && !(xRunPropSetInfo->getPropertyByName(rProp.Name).Attributes |
903 | 0 | & beans::PropertyAttribute::READONLY) |
904 | 0 | && rProp.Name != u"CharInteropGrabBag") |
905 | 0 | { |
906 | 0 | xRunPropSet->setPropertyValue(rProp.Name, rProp.Value); |
907 | 0 | } |
908 | 0 | } |
909 | 0 | } |
910 | 0 | } |
911 | 0 | } |
912 | | namespace |
913 | | { |
914 | | constexpr auto aCharPropNames = std::to_array<std::u16string_view>( |
915 | | { u"CharColorLumMod", u"CharColorLumOff", u"CharColorTheme", u"CharComplexColor", |
916 | | u"CharTransparence" }); |
917 | | |
918 | | constexpr auto aShapePropNames = std::to_array<std::u16string_view>( |
919 | | { u"FillColorLumMod", u"FillColorLumOff", u"FillColorTheme", u"FillComplexColor", |
920 | | u"FillTransparence" }); |
921 | | } |
922 | | |
923 | | void FontworkHelpers::createCharFillPropsFromShape( |
924 | | const uno::Reference<beans::XPropertySet>& rXPropSet, |
925 | | std::vector<beans::PropertyValue>& rCharPropVec) |
926 | 0 | { |
927 | 0 | auto xPropSetInfo = rXPropSet->getPropertySetInfo(); |
928 | 0 | if (!xPropSetInfo.is()) |
929 | 0 | return; |
930 | | // CharColor contains the color including all color transformations |
931 | | // FillColor contains darken and lighten but not transparency |
932 | 0 | sal_Int32 nColorRGB = 0; |
933 | 0 | if (xPropSetInfo->hasPropertyByName(u"FillColor"_ustr) |
934 | 0 | && (rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nColorRGB)) |
935 | 0 | { |
936 | 0 | ::Color aColor(ColorTransparency, nColorRGB); |
937 | 0 | sal_Int16 nTransPercent = 0; |
938 | 0 | if (xPropSetInfo->hasPropertyByName(u"FillTransparence"_ustr) |
939 | 0 | && (rXPropSet->getPropertyValue(u"FillTransparence"_ustr) >>= nTransPercent)) |
940 | 0 | { |
941 | 0 | sal_uInt8 nAlpha = 255 - sal_uInt8(std::round(double(nTransPercent) * 2.55)); |
942 | 0 | aColor.SetAlpha(nAlpha); |
943 | 0 | } |
944 | 0 | rCharPropVec.push_back(comphelper::makePropertyValue(u"CharColor"_ustr, sal_Int32(aColor))); |
945 | 0 | } |
946 | |
|
947 | 0 | for (size_t i = 0; i < 5; i++) |
948 | 0 | { |
949 | 0 | OUString aPropertyName(aShapePropNames[i]); |
950 | 0 | if (xPropSetInfo->hasPropertyByName(aPropertyName)) |
951 | 0 | rCharPropVec.push_back(comphelper::makePropertyValue( |
952 | 0 | OUString(aCharPropNames[i]), rXPropSet->getPropertyValue(aPropertyName))); |
953 | 0 | } |
954 | 0 | } |
955 | | |
956 | | bool FontworkHelpers::createPrstDashFromLineDash(const drawing::LineDash& rLineDash, |
957 | | const drawing::LineCap& rLineCap, |
958 | | OUString& rsPrstDash) |
959 | 0 | { |
960 | 0 | bool bIsConverted = false; |
961 | |
|
962 | 0 | bool bIsRelative(rLineDash.Style == drawing::DashStyle_RECTRELATIVE |
963 | 0 | || rLineDash.Style == drawing::DashStyle_ROUNDRELATIVE); |
964 | 0 | if (bIsRelative && rLineDash.Dots == 1) |
965 | 0 | { // The length were tweaked on import in case of prstDash. Revert it here. |
966 | 0 | sal_uInt32 nDotLen = rLineDash.DotLen; |
967 | 0 | sal_uInt32 nDashLen = rLineDash.DashLen; |
968 | 0 | sal_uInt32 nDistance = rLineDash.Distance; |
969 | 0 | if (rLineCap != drawing::LineCap_BUTT && nDistance >= 99) |
970 | 0 | { |
971 | 0 | nDistance -= 99; |
972 | 0 | nDotLen += 99; |
973 | 0 | if (nDashLen > 0) |
974 | 0 | nDashLen += 99; |
975 | 0 | } |
976 | | |
977 | | // LO uses length 0 for 100%, if the attribute is missing in ODF. |
978 | | // Other applications might write 100%. Make is unique for the conditions. |
979 | 0 | if (nDotLen == 0) |
980 | 0 | nDotLen = 100; |
981 | 0 | if (nDashLen == 0 && rLineDash.Dashes > 0) |
982 | 0 | nDashLen = 100; |
983 | |
|
984 | 0 | bIsConverted = true; |
985 | 0 | if (nDotLen == 100 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300) |
986 | 0 | rsPrstDash = u"dot"_ustr; |
987 | 0 | else if (nDotLen == 400 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300) |
988 | 0 | rsPrstDash = u"dash"_ustr; |
989 | 0 | else if (nDotLen == 400 && rLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300) |
990 | 0 | rsPrstDash = u"dashDot"_ustr; |
991 | 0 | else if (nDotLen == 800 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300) |
992 | 0 | rsPrstDash = u"lgDash"_ustr; |
993 | 0 | else if (nDotLen == 800 && rLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300) |
994 | 0 | rsPrstDash = u"lgDashDot"_ustr; |
995 | 0 | else if (nDotLen == 800 && rLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300) |
996 | 0 | rsPrstDash = u"lgDashDotDot"_ustr; |
997 | 0 | else if (nDotLen == 100 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100) |
998 | 0 | rsPrstDash = u"sysDot"_ustr; |
999 | 0 | else if (nDotLen == 300 && rLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100) |
1000 | 0 | rsPrstDash = u"sysDash"_ustr; |
1001 | 0 | else if (nDotLen == 300 && rLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100) |
1002 | 0 | rsPrstDash = u"sysDashDot"_ustr; |
1003 | 0 | else if (nDotLen == 300 && rLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100) |
1004 | 0 | rsPrstDash = "sysDashDotDot"; |
1005 | 0 | else |
1006 | 0 | bIsConverted = false; |
1007 | 0 | } |
1008 | 0 | return bIsConverted; |
1009 | 0 | } |
1010 | | |
1011 | | bool FontworkHelpers::getThemeColorFromShape( |
1012 | | OUString const& rPropertyName, const uno::Reference<beans::XPropertySet>& xPropertySet, |
1013 | | model::ComplexColor& rComplexColor) |
1014 | 0 | { |
1015 | 0 | auto xPropSetInfo = xPropertySet->getPropertySetInfo(); |
1016 | 0 | if (!xPropSetInfo.is()) |
1017 | 0 | return false; |
1018 | 0 | uno::Reference<util::XComplexColor> xComplexColor; |
1019 | 0 | if (xPropSetInfo->hasPropertyByName(rPropertyName) |
1020 | 0 | && (xPropertySet->getPropertyValue(rPropertyName) >>= xComplexColor) && xComplexColor.is()) |
1021 | 0 | { |
1022 | 0 | rComplexColor = model::color::getFromXComplexColor(xComplexColor); |
1023 | 0 | return rComplexColor.isValidThemeType(); |
1024 | 0 | } |
1025 | 0 | return false; |
1026 | 0 | } |
1027 | | |
1028 | | namespace |
1029 | | { |
1030 | | // Contains information about one gradient stop. Each gradient has at least 2 of these. |
1031 | | struct GradientStopColor |
1032 | | { |
1033 | | // RGBColor contains no transformations. In case TTColor has other type than |
1034 | | // ThemeColorType::Unknown, it has precedence. The color transformations in TTColor are used |
1035 | | // for RGBColor as well. |
1036 | | model::ComplexColor TTColor; // ThemeColorType and color transformations |
1037 | | ::Color RGBColor; |
1038 | | }; |
1039 | | } |
1040 | | |
1041 | | // 'first' contains the position in the range 0 (=0%) to 100000 (=100%) in the gradient as needed for |
1042 | | // the 'pos' attribute in <w14:gs> element in oox, 'second' contains color and color transformations |
1043 | | // at this position. The map contains all information needed for a <w14:gsLst> element in oox. |
1044 | | typedef std::multimap<sal_Int32, GradientStopColor> ColorMapType; |
1045 | | |
1046 | | namespace |
1047 | | { |
1048 | | constexpr auto W14ColorNames = std::to_array<std::u16string_view>( |
1049 | | { u"tx1", u"bg1", u"tx2", u"bg2", u"accent1", u"accent2", u"accent3", u"accent4", u"accent5", |
1050 | | u"accent6", u"hlink", u"folHlink" }); |
1051 | | |
1052 | | constexpr auto WColorNames = std::to_array<std::u16string_view>( |
1053 | | { u"text1", u"background1", u"text2", u"background2", u"accent1", u"accent2", u"accent3", |
1054 | | u"accent4", u"accent5", u"accent6", u"hyperlink", u"followedHyperlink" }); |
1055 | | |
1056 | | // Returns the string to be used in w14:schemeClr in case of w14:textOutline or w14:textFill |
1057 | | OUString lcl_getW14MarkupStringForThemeColor(const model::ComplexColor& rComplexColor) |
1058 | 0 | { |
1059 | 0 | const sal_uInt8 nClrNameIndex = std::clamp<sal_uInt8>( |
1060 | 0 | sal_Int32(rComplexColor.getThemeColorType()), sal_Int32(model::ThemeColorType::Dark1), |
1061 | 0 | sal_Int32(model::ThemeColorType::FollowedHyperlink)); |
1062 | 0 | return OUString(W14ColorNames[nClrNameIndex]); |
1063 | 0 | } |
1064 | | |
1065 | | // Returns the string to be used in w:themeColor. It is exported via CharThemeColor. |
1066 | | OUString lcl_getWMarkupStringForThemeColor(const model::ComplexColor& rComplexColor) |
1067 | 0 | { |
1068 | 0 | const sal_uInt8 nClrNameIndex = std::clamp<sal_uInt8>( |
1069 | 0 | sal_Int32(rComplexColor.getThemeColorType()), sal_Int32(model::ThemeColorType::Dark1), |
1070 | 0 | sal_Int32(model::ThemeColorType::FollowedHyperlink)); |
1071 | 0 | return OUString(WColorNames[nClrNameIndex]); |
1072 | 0 | } |
1073 | | |
1074 | | // Puts the value of the first occurrence of rType in rComplexColor into rValue and returns true. |
1075 | | // If such does not exist, rValue is unchanged and the method returns false. |
1076 | | bool lcl_getThemeColorTransformationValue(const model::ComplexColor& rComplexColor, |
1077 | | const model::TransformationType& rType, sal_Int16& rValue) |
1078 | 0 | { |
1079 | 0 | const std::vector<model::Transformation>& aTransVec(rComplexColor.getTransformations()); |
1080 | 0 | auto bItemFound |
1081 | 0 | = [rType](const model::Transformation& rTrans) { return rType == rTrans.meType; }; |
1082 | 0 | auto pIt = std::find_if(aTransVec.begin(), aTransVec.end(), bItemFound); |
1083 | 0 | if (pIt == aTransVec.end()) |
1084 | 0 | return false; |
1085 | 0 | rValue = (*pIt).mnValue; |
1086 | 0 | return true; |
1087 | 0 | } |
1088 | | |
1089 | | // Adds the child elements 'lumMod' and 'lumOff' to 'schemeClr' maCurrentElement of pGrabStack, |
1090 | | // if such exist in rComplexColor. 'alpha' is contained in the maTransformations of rComplexColor |
1091 | | // in case of gradient fill. |
1092 | | void lcl_addColorTransformationToGrabBagStack( |
1093 | | const model::ComplexColor& rComplexColor, |
1094 | | const std::unique_ptr<oox::GrabBagStack>& pGrabBagStack) |
1095 | 0 | { |
1096 | 0 | if (pGrabBagStack == nullptr) |
1097 | 0 | return; |
1098 | 0 | for (auto const& rColorTransform : rComplexColor.getTransformations()) |
1099 | 0 | { |
1100 | 0 | switch (rColorTransform.meType) |
1101 | 0 | { |
1102 | 0 | case model::TransformationType::LumMod: |
1103 | 0 | pGrabBagStack->push(u"lumMod"_ustr); |
1104 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1105 | 0 | pGrabBagStack->addInt32(u"val"_ustr, rColorTransform.mnValue * 10); |
1106 | 0 | pGrabBagStack->pop(); |
1107 | 0 | pGrabBagStack->pop(); |
1108 | 0 | break; |
1109 | 0 | case model::TransformationType::LumOff: |
1110 | 0 | pGrabBagStack->push(u"lumOff"_ustr); |
1111 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1112 | 0 | pGrabBagStack->addInt32(u"val"_ustr, rColorTransform.mnValue * 10); |
1113 | 0 | pGrabBagStack->pop(); |
1114 | 0 | pGrabBagStack->pop(); |
1115 | 0 | break; |
1116 | 0 | case model::TransformationType::Alpha: |
1117 | 0 | pGrabBagStack->push(u"alpha"_ustr); |
1118 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1119 | | // model::TransformationType::Alpha is designed to be used with a:alpha, which has |
1120 | | // opacity. But w14:alpha uses transparency. So convert it here. |
1121 | 0 | pGrabBagStack->addInt32(u"val"_ustr, |
1122 | 0 | oox::drawingml::MAX_PERCENT - rColorTransform.mnValue * 10); |
1123 | 0 | pGrabBagStack->pop(); |
1124 | 0 | pGrabBagStack->pop(); |
1125 | 0 | break; |
1126 | 0 | default: // other child elements can be added later if needed for Fontwork |
1127 | 0 | break; |
1128 | 0 | } |
1129 | 0 | } |
1130 | 0 | } |
1131 | | |
1132 | | void lcl_getGradientsFromShape(const uno::Reference<beans::XPropertySet>& rXPropSet, |
1133 | | const uno::Reference<beans::XPropertySetInfo>& rXPropSetInfo, |
1134 | | awt::Gradient2& rColorGradient, bool& rbHasColorGradient, |
1135 | | awt::Gradient2& rTransparenceGradient, |
1136 | | bool& rbHasTransparenceGradient) |
1137 | 0 | { |
1138 | 0 | OUString sColorGradientName; |
1139 | 0 | rbHasColorGradient |
1140 | 0 | = rXPropSetInfo->hasPropertyByName(u"FillGradientName"_ustr) |
1141 | 0 | && (rXPropSet->getPropertyValue(u"FillGradientName"_ustr) >>= sColorGradientName) |
1142 | 0 | && !sColorGradientName.isEmpty() && rXPropSetInfo->hasPropertyByName(u"FillGradient"_ustr) |
1143 | 0 | && (rXPropSet->getPropertyValue(u"FillGradient"_ustr) >>= rColorGradient); |
1144 | |
|
1145 | 0 | OUString sTransparenceGradientName; |
1146 | 0 | rbHasTransparenceGradient |
1147 | 0 | = rXPropSetInfo->hasPropertyByName(u"FillTransparenceGradientName"_ustr) |
1148 | 0 | && (rXPropSet->getPropertyValue(u"FillTransparenceGradientName"_ustr) |
1149 | 0 | >>= sTransparenceGradientName) |
1150 | 0 | && !sTransparenceGradientName.isEmpty() |
1151 | 0 | && rXPropSetInfo->hasPropertyByName(u"FillTransparenceGradient"_ustr) |
1152 | 0 | && (rXPropSet->getPropertyValue(u"FillTransparenceGradient"_ustr) |
1153 | 0 | >>= rTransparenceGradient); |
1154 | 0 | } |
1155 | | |
1156 | | ColorMapType lcl_createColorMapFromShapeProps( |
1157 | | const uno::Reference<beans::XPropertySet>& rXPropSet, |
1158 | | const uno::Reference<beans::XPropertySetInfo>& rXPropSetInfo, |
1159 | | const awt::Gradient2& rColorGradient, const bool& rbHasColorGradient, |
1160 | | const awt::Gradient2& rTransparenceGradient, const bool& rbHasTransparenceGradient) |
1161 | 0 | { |
1162 | | // LibreOffice can use color gradients and transparency gradients with different geometries. |
1163 | | // That is not possible in OOXML, so a fill might look different in Word. But a round-trip |
1164 | | // with gradients imported from Word, should work well. |
1165 | | |
1166 | | // Word has transparency not as separate gradient but as color transformation in a color |
1167 | | // gradient. Thus we synchronize the gradients. Then they have same offsets and count. |
1168 | 0 | basegfx::BColor aSingleColor; |
1169 | 0 | basegfx::BGradient aColorBGradient; |
1170 | 0 | basegfx::BColorStops aColorStops; |
1171 | 0 | if (rbHasColorGradient) |
1172 | 0 | { |
1173 | 0 | aColorBGradient = model::gradient::getFromUnoGradient2(rColorGradient); |
1174 | 0 | aColorBGradient.tryToApplyStartEndIntensity(); |
1175 | 0 | aColorBGradient.tryToApplyBorder(); |
1176 | 0 | aColorBGradient.tryToApplyAxial(); |
1177 | 0 | basegfx::utils::prepareColorStops(aColorBGradient, aColorStops, aSingleColor); |
1178 | | // All gradient styles but LINEAR and AXIAL (which is already converted to LINEAR) need the |
1179 | | // stops sequence reverse. |
1180 | 0 | if (awt::GradientStyle_LINEAR != aColorBGradient.GetGradientStyle()) |
1181 | 0 | aColorStops.reverseColorStops(); |
1182 | 0 | } |
1183 | 0 | else |
1184 | 0 | { |
1185 | 0 | sal_Int32 nFillColor(0); |
1186 | 0 | if (rXPropSetInfo->hasPropertyByName(u"FillColor"_ustr)) |
1187 | 0 | rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor; |
1188 | 0 | aSingleColor = ::Color(ColorTransparency, nFillColor).getBColor().clamp(); |
1189 | 0 | } |
1190 | |
|
1191 | 0 | basegfx::BColor aSingleTrans; |
1192 | 0 | basegfx::BGradient aTransBGradient; |
1193 | 0 | basegfx::BColorStops aTransStops; |
1194 | 0 | if (rbHasTransparenceGradient) |
1195 | 0 | { |
1196 | 0 | aTransBGradient = model::gradient::getFromUnoGradient2(rTransparenceGradient); |
1197 | 0 | aTransBGradient.tryToApplyStartEndIntensity(); // usually 100%, but might be set by macro |
1198 | 0 | aTransBGradient.tryToApplyBorder(); |
1199 | 0 | aTransBGradient.tryToApplyAxial(); |
1200 | 0 | basegfx::utils::prepareColorStops(aTransBGradient, aTransStops, aSingleTrans); |
1201 | | // All gradient styles but LINEAR and AXIAL (which is already converted to LINEAR) need the |
1202 | | // stops sequence reverse. |
1203 | 0 | if (awt::GradientStyle_LINEAR != aTransBGradient.GetGradientStyle()) |
1204 | 0 | aTransStops.reverseColorStops(); |
1205 | 0 | } |
1206 | 0 | else |
1207 | 0 | { |
1208 | 0 | sal_Int16 nAPITrans(0); |
1209 | 0 | if (rXPropSetInfo->hasPropertyByName(u"FillTransparence"_ustr)) |
1210 | 0 | rXPropSet->getPropertyValue(u"FillTransparence"_ustr) >>= nAPITrans; |
1211 | | // API transparency is in range 0..100, BColor in range [0.0, 1.0]. |
1212 | 0 | aSingleTrans = basegfx::BColor(nAPITrans * 0.01).clamp(); |
1213 | 0 | } |
1214 | |
|
1215 | 0 | basegfx::utils::synchronizeColorStops(aColorStops, aTransStops, aSingleColor, aSingleTrans); |
1216 | |
|
1217 | 0 | ColorMapType aColorMap; |
1218 | | |
1219 | | // If we have no color gradient, the fix fill color might be a theme color. In that case we use |
1220 | | // it instead of the color from the color stop. |
1221 | 0 | GradientStopColor aFixColor; |
1222 | 0 | bool bUseThemeColor(!rbHasColorGradient |
1223 | 0 | && FontworkHelpers::getThemeColorFromShape(u"FillComplexColor"_ustr, |
1224 | 0 | rXPropSet, aFixColor.TTColor)); |
1225 | |
|
1226 | 0 | for (auto itC = aColorStops.begin(), itT = aTransStops.begin(); |
1227 | 0 | itC != aColorStops.end() && itT != aTransStops.end(); ++itC, ++itT) |
1228 | 0 | { |
1229 | 0 | GradientStopColor aNextStopColor = aFixColor; |
1230 | 0 | if (!bUseThemeColor) |
1231 | 0 | { |
1232 | 0 | aNextStopColor.TTColor = model::ComplexColor(); |
1233 | 0 | aNextStopColor.RGBColor = ::Color((*itC).getStopColor()); |
1234 | 0 | } |
1235 | | // model::TransformationType::Alpha is opacity in range 0..10000, |
1236 | | // BColor is transparency in range [0.0, 1.0] |
1237 | 0 | sal_Int16 nAlpha = std::clamp<sal_Int16>( |
1238 | 0 | 10000 - std::lround((*itT).getStopColor().luminance() * 10000.0), 0, 10000); |
1239 | 0 | if (nAlpha < 10000) |
1240 | 0 | aNextStopColor.TTColor.addTransformation({ model::TransformationType::Alpha, nAlpha }); |
1241 | 0 | sal_Int32 nPosition |
1242 | 0 | = static_cast<sal_Int32>(std::lround((*itC).getStopOffset() * 100000.0)); |
1243 | 0 | aColorMap.insert(std::pair{ nPosition, aNextStopColor }); |
1244 | 0 | } |
1245 | | |
1246 | | // If a gradient has only two stops, MS Office renders it with a non-linear method which looks |
1247 | | // different than gradient in LibreOffice (see tdf#128795). For more than two stops rendering is |
1248 | | // the same as in LibreOffice, even if two stops are identical. |
1249 | 0 | if (aColorMap.size() == 2) |
1250 | 0 | { |
1251 | 0 | auto it = aColorMap.begin(); |
1252 | 0 | aColorMap.insert(std::pair{ 0, (*it).second }); |
1253 | 0 | } |
1254 | 0 | return aColorMap; |
1255 | 0 | } |
1256 | | } // end namespace |
1257 | | |
1258 | | void FontworkHelpers::createCharInteropGrabBagUpdatesFromShapeProps( |
1259 | | const uno::Reference<beans::XPropertySet>& rXPropSet, |
1260 | | std::vector<beans::PropertyValue>& rUpdatePropVec) |
1261 | 0 | { |
1262 | 0 | auto xPropSetInfo = rXPropSet->getPropertySetInfo(); |
1263 | 0 | if (!xPropSetInfo.is()) |
1264 | 0 | return; |
1265 | | |
1266 | | // GrabBagStack is a special tool for handling the hierarchy in a GrabBag |
1267 | 0 | std::unique_ptr<oox::GrabBagStack> pGrabBagStack; |
1268 | | |
1269 | | // CharTextFillTextEffect |
1270 | 0 | pGrabBagStack.reset(new oox::GrabBagStack(u"textFill"_ustr)); |
1271 | 0 | drawing::FillStyle eFillStyle = drawing::FillStyle_SOLID; |
1272 | 0 | if (xPropSetInfo->hasPropertyByName(u"FillStyle"_ustr)) |
1273 | 0 | rXPropSet->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle; |
1274 | | |
1275 | | // We might have a solid fill but a transparency gradient. That needs to be exported as gradFill |
1276 | | // too, because Word has transparency not separated but in the color stops in a color gradient. |
1277 | | // A gradient exists, if the GradientName is not empty. |
1278 | 0 | OUString sTransparenceGradientName; |
1279 | 0 | if (eFillStyle == drawing::FillStyle_SOLID |
1280 | 0 | && xPropSetInfo->hasPropertyByName(u"FillTransparenceGradientName"_ustr) |
1281 | 0 | && (rXPropSet->getPropertyValue(u"FillTransparenceGradientName"_ustr) |
1282 | 0 | >>= sTransparenceGradientName) |
1283 | 0 | && !sTransparenceGradientName.isEmpty()) |
1284 | 0 | eFillStyle = drawing::FillStyle_GRADIENT; |
1285 | |
|
1286 | 0 | switch (eFillStyle) |
1287 | 0 | { |
1288 | 0 | case drawing::FillStyle_NONE: |
1289 | 0 | { |
1290 | 0 | pGrabBagStack->appendElement(u"noFill"_ustr, uno::Any()); |
1291 | 0 | break; |
1292 | 0 | } |
1293 | 0 | case drawing::FillStyle_GRADIENT: |
1294 | 0 | { |
1295 | 0 | awt::Gradient2 aColorGradient; |
1296 | 0 | bool bHasColorGradient(false); |
1297 | 0 | awt::Gradient2 aTransparenceGradient; |
1298 | 0 | bool bHasTransparenceGradient(false); |
1299 | 0 | lcl_getGradientsFromShape(rXPropSet, xPropSetInfo, aColorGradient, bHasColorGradient, |
1300 | 0 | aTransparenceGradient, bHasTransparenceGradient); |
1301 | | // aColorMap contains the color stops suitable to generate gsLst |
1302 | 0 | ColorMapType aColorMap = lcl_createColorMapFromShapeProps( |
1303 | 0 | rXPropSet, xPropSetInfo, aColorGradient, bHasColorGradient, aTransparenceGradient, |
1304 | 0 | bHasTransparenceGradient); |
1305 | 0 | pGrabBagStack->push(u"gradFill"_ustr); |
1306 | 0 | pGrabBagStack->push(u"gsLst"_ustr); |
1307 | 0 | for (const auto & [ nPos, rColors ] : aColorMap) |
1308 | 0 | { |
1309 | 0 | pGrabBagStack->push(u"gs"_ustr); |
1310 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1311 | 0 | pGrabBagStack->addInt32(u"pos"_ustr, nPos); |
1312 | 0 | pGrabBagStack->pop(); |
1313 | 0 | if (rColors.TTColor.getThemeColorType() == model::ThemeColorType::Unknown) |
1314 | 0 | { |
1315 | 0 | pGrabBagStack->push(u"srgbClr"_ustr); |
1316 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1317 | 0 | pGrabBagStack->addString(u"val"_ustr, rColors.RGBColor.AsRGBHexString()); |
1318 | 0 | pGrabBagStack->pop(); // maCurrentElement:'srgbClr', maPropertyList:'attributes' |
1319 | 0 | } |
1320 | 0 | else |
1321 | 0 | { |
1322 | 0 | pGrabBagStack->push(u"schemeClr"_ustr); |
1323 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1324 | 0 | pGrabBagStack->addString(u"val"_ustr, |
1325 | 0 | lcl_getW14MarkupStringForThemeColor(rColors.TTColor)); |
1326 | 0 | pGrabBagStack->pop(); |
1327 | | // maCurrentElement:'schemeClr', maPropertyList:'attributes' |
1328 | 0 | } |
1329 | |
|
1330 | 0 | lcl_addColorTransformationToGrabBagStack(rColors.TTColor, pGrabBagStack); |
1331 | 0 | pGrabBagStack->pop(); |
1332 | | // maCurrentElement:'gs', maPropertyList:'attributes', 'srgbClr' or 'schemeClr' |
1333 | 0 | pGrabBagStack->pop(); // maCurrentElement:'gsLst', maPropertyList: at least two 'gs' |
1334 | 0 | } |
1335 | 0 | pGrabBagStack->pop(); // maCurrentElement:'gradFill', maPropertyList: gsLst |
1336 | | |
1337 | | // Kind of gradient |
1338 | 0 | awt::GradientStyle eGradientStyle = awt::GradientStyle_LINEAR; |
1339 | 0 | if (bHasColorGradient) |
1340 | 0 | eGradientStyle = aColorGradient.Style; |
1341 | 0 | else if (bHasTransparenceGradient) |
1342 | 0 | eGradientStyle = aTransparenceGradient.Style; |
1343 | | // write 'lin' or 'path'. LibreOffice has nothing which corresponds to 'shape'. |
1344 | 0 | if (eGradientStyle == awt::GradientStyle_LINEAR |
1345 | 0 | || eGradientStyle == awt::GradientStyle_AXIAL) |
1346 | 0 | { |
1347 | | // API angle is in 1/10th deg and describes counter-clockwise rotation of line of |
1348 | | // equal color. OOX angle is in 1/60000th deg and describes clockwise rotation of |
1349 | | // color transition direction. |
1350 | 0 | sal_Int32 nAngleOOX = 0; |
1351 | 0 | if (bHasColorGradient) |
1352 | 0 | nAngleOOX = ((3600 - aColorGradient.Angle + 900) % 3600) * 6000; |
1353 | 0 | else if (bHasTransparenceGradient) |
1354 | 0 | nAngleOOX = ((3600 - aTransparenceGradient.Angle + 900) % 3600) * 6000; |
1355 | 0 | pGrabBagStack->push(u"lin"_ustr); |
1356 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1357 | 0 | pGrabBagStack->addInt32(u"ang"_ustr, nAngleOOX); |
1358 | | // LibreOffice cannot scale a gradient to the shape size. |
1359 | 0 | pGrabBagStack->addString(u"scaled"_ustr, u"0"_ustr); |
1360 | 0 | } |
1361 | 0 | else |
1362 | 0 | { |
1363 | | // Same rendering as in LibreOffice is not possible: |
1364 | | // (1) The gradient type 'path' in Word has no rotation. |
1365 | | // (2) To get the same size of gradient area, the element 'tileRect' is needed, but |
1366 | | // that is not available for <w14:textFill> element. |
1367 | | // So we can only set a reasonably suitable focus point. |
1368 | 0 | pGrabBagStack->push(u"path"_ustr); |
1369 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1370 | 0 | if (eGradientStyle == awt::GradientStyle_RADIAL |
1371 | 0 | || eGradientStyle == awt::GradientStyle_ELLIPTICAL) |
1372 | 0 | pGrabBagStack->addString(u"path"_ustr, u"circle"_ustr); |
1373 | 0 | else |
1374 | 0 | pGrabBagStack->addString(u"path"_ustr, u"rect"_ustr); |
1375 | 0 | pGrabBagStack->pop(); |
1376 | 0 | pGrabBagStack->push(u"fillToRect"_ustr); |
1377 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1378 | 0 | sal_Int32 nLeftPercent |
1379 | 0 | = bHasColorGradient ? aColorGradient.XOffset : aTransparenceGradient.XOffset; |
1380 | 0 | sal_Int32 nTopPercent |
1381 | 0 | = bHasColorGradient ? aColorGradient.YOffset : aTransparenceGradient.YOffset; |
1382 | 0 | pGrabBagStack->addInt32(u"l"_ustr, nLeftPercent * 1000); |
1383 | 0 | pGrabBagStack->addInt32(u"t"_ustr, nTopPercent * 1000); |
1384 | 0 | pGrabBagStack->addInt32(u"r"_ustr, (100 - nLeftPercent) * 1000); |
1385 | 0 | pGrabBagStack->addInt32(u"b"_ustr, (100 - nTopPercent) * 1000); |
1386 | 0 | } |
1387 | | // all remaining pop() calls are in the final getRootProperty() method |
1388 | 0 | break; |
1389 | 0 | } |
1390 | 0 | case drawing::FillStyle_SOLID: |
1391 | 0 | { |
1392 | 0 | pGrabBagStack->push(u"solidFill"_ustr); |
1393 | 0 | model::ComplexColor aComplexColor; |
1394 | | // It is either "schemeClr" or "srgbClr". |
1395 | 0 | if (FontworkHelpers::getThemeColorFromShape(u"FillComplexColor"_ustr, rXPropSet, |
1396 | 0 | aComplexColor)) |
1397 | 0 | { |
1398 | 0 | pGrabBagStack->push(u"schemeClr"_ustr); |
1399 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1400 | 0 | pGrabBagStack->addString(u"val"_ustr, |
1401 | 0 | lcl_getW14MarkupStringForThemeColor(aComplexColor)); |
1402 | 0 | pGrabBagStack->pop(); // maCurrentElement:'schemeClr', maPropertyList:'attributes' |
1403 | 0 | lcl_addColorTransformationToGrabBagStack(aComplexColor, pGrabBagStack); |
1404 | | // maCurrentElement:'schemeClr', maPropertyList:'attributes', maybe 'lumMod' and |
1405 | | // maybe 'lumOff' |
1406 | 0 | } |
1407 | 0 | else |
1408 | 0 | { |
1409 | 0 | pGrabBagStack->push(u"srgbClr"_ustr); |
1410 | 0 | sal_Int32 nFillColor(0); |
1411 | 0 | if (xPropSetInfo->hasPropertyByName(u"FillColor"_ustr)) |
1412 | 0 | rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor; |
1413 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1414 | 0 | ::Color aColor(ColorTransparency, nFillColor); |
1415 | 0 | pGrabBagStack->addString(u"val"_ustr, aColor.AsRGBHexString()); |
1416 | 0 | pGrabBagStack->pop(); |
1417 | | // maCurrentElement:'srgbClr', maPropertyList:'attributes' |
1418 | 0 | } |
1419 | |
|
1420 | 0 | sal_Int16 nFillTransparence(0); |
1421 | 0 | if (xPropSetInfo->hasPropertyByName(u"FillTransparence"_ustr)) |
1422 | 0 | rXPropSet->getPropertyValue(u"FillTransparence"_ustr) >>= nFillTransparence; |
1423 | 0 | if (nFillTransparence != 0) |
1424 | 0 | { |
1425 | 0 | pGrabBagStack->push(u"alpha"_ustr); |
1426 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1427 | 0 | pGrabBagStack->addInt32(u"val"_ustr, nFillTransparence * 1000); |
1428 | 0 | } |
1429 | | // all remaining pop() calls are in the final getRootProperty() method |
1430 | 0 | break; |
1431 | 0 | } |
1432 | 0 | default: // BITMAP is VML only export and does not arrive here. HATCH has to be VML only |
1433 | | // export too, but is not yet implemented. |
1434 | 0 | break; |
1435 | 0 | } |
1436 | | // resolve the stack and put resulting PropertyValue into the update vector |
1437 | 0 | beans::PropertyValue aCharTextFillTextEffect; |
1438 | 0 | aCharTextFillTextEffect.Name = "CharTextFillTextEffect"; |
1439 | 0 | aCharTextFillTextEffect.Value <<= pGrabBagStack->getRootProperty(); |
1440 | 0 | rUpdatePropVec.push_back(aCharTextFillTextEffect); |
1441 | | |
1442 | | // CharTextOutlineTextEffect |
1443 | 0 | pGrabBagStack.reset(new oox::GrabBagStack(u"textOutline"_ustr)); |
1444 | | |
1445 | | // attributes |
1446 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1447 | | // line width |
1448 | 0 | sal_Int32 nLineWidth(0); |
1449 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineWidth"_ustr)) |
1450 | 0 | rXPropSet->getPropertyValue(u"LineWidth"_ustr) >>= nLineWidth; |
1451 | 0 | pGrabBagStack->addInt32(u"w"_ustr, nLineWidth * 360); |
1452 | | // cap for dashes |
1453 | 0 | drawing::LineCap eLineCap = drawing::LineCap_BUTT; |
1454 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineCap"_ustr)) |
1455 | 0 | rXPropSet->getPropertyValue(u"LineCap"_ustr) >>= eLineCap; |
1456 | 0 | OUString sCap = u"flat"_ustr; |
1457 | 0 | if (eLineCap == drawing::LineCap_ROUND) |
1458 | 0 | sCap = u"rnd"_ustr; |
1459 | 0 | else if (eLineCap == drawing::LineCap_SQUARE) |
1460 | 0 | sCap = u"sq"_ustr; |
1461 | 0 | pGrabBagStack->addString(u"cap"_ustr, sCap); |
1462 | | // LO has no compound lines and always centers the lines |
1463 | 0 | pGrabBagStack->addString(u"cmpd"_ustr, u"sng"_ustr); |
1464 | 0 | pGrabBagStack->addString(u"alng"_ustr, u"ctr"_ustr); |
1465 | 0 | pGrabBagStack->pop(); |
1466 | | // maCurrentElement:'textOutline', maPropertyList:'attributes' |
1467 | | |
1468 | | // style |
1469 | 0 | drawing::LineStyle eLineStyle = drawing::LineStyle_NONE; |
1470 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineStyle"_ustr)) |
1471 | 0 | rXPropSet->getPropertyValue(u"LineStyle"_ustr) >>= eLineStyle; |
1472 | | // 'dashed' is not a separate style in Word. Word has a style 'gradFill', but that is not yet |
1473 | | // implemented in LO. So only 'noFill' and 'solidFill'. |
1474 | 0 | if (eLineStyle == drawing::LineStyle_NONE) |
1475 | 0 | { |
1476 | 0 | pGrabBagStack->appendElement(u"noFill"_ustr, uno::Any()); |
1477 | 0 | } |
1478 | 0 | else |
1479 | 0 | { |
1480 | 0 | pGrabBagStack->push(u"solidFill"_ustr); |
1481 | | // It is either "schemeClr" or "srgbClr". |
1482 | 0 | model::ComplexColor aComplexColor; |
1483 | 0 | if (FontworkHelpers::getThemeColorFromShape(u"LineComplexColor"_ustr, rXPropSet, |
1484 | 0 | aComplexColor)) |
1485 | 0 | { |
1486 | 0 | pGrabBagStack->push(u"schemeClr"_ustr); |
1487 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1488 | 0 | pGrabBagStack->addString(u"val"_ustr, |
1489 | 0 | lcl_getW14MarkupStringForThemeColor(aComplexColor)); |
1490 | 0 | pGrabBagStack->pop(); |
1491 | 0 | lcl_addColorTransformationToGrabBagStack(aComplexColor, pGrabBagStack); |
1492 | | // maCurrentElement:'schemeClr', maPropertylist:'attributes' |
1493 | 0 | } |
1494 | 0 | else // not a theme color |
1495 | 0 | { |
1496 | 0 | pGrabBagStack->push(u"srgbClr"_ustr); |
1497 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1498 | 0 | sal_Int32 nLineColor(0); |
1499 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineColor"_ustr)) |
1500 | 0 | rXPropSet->getPropertyValue(u"LineColor"_ustr) >>= nLineColor; |
1501 | 0 | ::Color aColor(ColorTransparency, nLineColor); |
1502 | 0 | pGrabBagStack->addString(u"val"_ustr, aColor.AsRGBHexString()); |
1503 | 0 | pGrabBagStack->pop(); |
1504 | | // maCurrentElement:'srgbClr', maPropertylist:'attributes' |
1505 | 0 | } |
1506 | |
|
1507 | 0 | sal_Int16 nLineTransparence(0); |
1508 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineTransparence"_ustr)) |
1509 | 0 | rXPropSet->getPropertyValue(u"LineTransparence"_ustr) >>= nLineTransparence; |
1510 | 0 | if (nLineTransparence != 0) |
1511 | 0 | { |
1512 | 0 | pGrabBagStack->push(u"alpha"_ustr); |
1513 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1514 | 0 | pGrabBagStack->addInt32(u"val"_ustr, nLineTransparence * 1000); |
1515 | 0 | pGrabBagStack->pop(); // maCurrentElement: 'alpha' |
1516 | 0 | pGrabBagStack->pop(); // maCurrentElement: 'srgbClr' or 'schemeClr' |
1517 | 0 | } |
1518 | 0 | pGrabBagStack->pop(); |
1519 | | // maCurrentElement:'solidFill', maPropertyList:either 'srgbClr' or 'schemeClr |
1520 | 0 | pGrabBagStack->pop(); |
1521 | 0 | } |
1522 | | // maCurrentElement:'textOutline', maPropertyList:'attributes' and either 'noFill' or 'solidFill' |
1523 | | |
1524 | | // prstDash |
1525 | 0 | if (eLineStyle == drawing::LineStyle_DASH) |
1526 | 0 | { |
1527 | 0 | pGrabBagStack->push(u"prstDash"_ustr); |
1528 | 0 | OUString sPrstDash = u"sysDot"_ustr; |
1529 | 0 | drawing::LineDash aLineDash; |
1530 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineDash"_ustr) |
1531 | 0 | && (rXPropSet->getPropertyValue(u"LineDash"_ustr) >>= aLineDash)) |
1532 | 0 | { |
1533 | | // The outline of abc-transform in Word is not able to use custDash. But we know the line |
1534 | | // is dashed. We keep "sysDot" as fallback in case no prstDash is detected. |
1535 | 0 | FontworkHelpers::createPrstDashFromLineDash(aLineDash, eLineCap, sPrstDash); |
1536 | 0 | } |
1537 | 0 | else |
1538 | 0 | { |
1539 | | // ToDo: There may be a named dash style, but that is unlikely for Fontwork shapes. So |
1540 | | // I skip it for now and use the "sysDot" fallback. |
1541 | 0 | } |
1542 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1543 | 0 | pGrabBagStack->addString(u"val"_ustr, sPrstDash); |
1544 | 0 | pGrabBagStack->pop(); // maCurrentElement:'prstDash' |
1545 | 0 | pGrabBagStack->pop(); // maCurrentElement:'textOutline' |
1546 | 0 | } |
1547 | | // maCurrentElement:'textOutline', maPropertyList:'attributes', either 'noFill' or 'solidFill', |
1548 | | // and maybe 'prstDash'. |
1549 | | |
1550 | | // LineJoint, can be 'round', 'bevel' or 'miter' in Word |
1551 | 0 | drawing::LineJoint eLineJoint = drawing::LineJoint_NONE; |
1552 | 0 | if (xPropSetInfo->hasPropertyByName(u"LineJoint"_ustr)) |
1553 | 0 | rXPropSet->getPropertyValue(u"LineJoint"_ustr) >>= eLineJoint; |
1554 | 0 | if (eLineJoint == drawing::LineJoint_NONE || eLineJoint == drawing::LineJoint_BEVEL) |
1555 | 0 | pGrabBagStack->appendElement(u"bevel"_ustr, uno::Any()); |
1556 | 0 | else if (eLineJoint == drawing::LineJoint_ROUND) |
1557 | 0 | pGrabBagStack->appendElement(u"round"_ustr, uno::Any()); |
1558 | 0 | else // MITER or deprecated MIDDLE |
1559 | 0 | { |
1560 | 0 | pGrabBagStack->push(u"miter"_ustr); |
1561 | 0 | pGrabBagStack->push(u"attributes"_ustr); |
1562 | 0 | pGrabBagStack->addInt32(u"lim"_ustr, 0); // As of Feb. 2023 LO cannot render other values. |
1563 | 0 | pGrabBagStack->pop(); // maCurrentElement:'attributes' |
1564 | 0 | pGrabBagStack->pop(); // maCurrentElement:'miter' |
1565 | 0 | } |
1566 | | // maCurrentElement:'textOutline', maPropertyList:'attributes', either 'noFill' or |
1567 | | // 'solidFill', maybe 'prstDash', and either 'bevel', 'round' or 'miter'. |
1568 | | |
1569 | | // resolve the stack and put resulting PropertyValue into the update vector |
1570 | 0 | beans::PropertyValue aCharTextOutlineTextEffect; |
1571 | 0 | aCharTextOutlineTextEffect.Name = "CharTextOutlineTextEffect"; |
1572 | 0 | aCharTextOutlineTextEffect.Value <<= pGrabBagStack->getRootProperty(); |
1573 | 0 | rUpdatePropVec.push_back(aCharTextOutlineTextEffect); |
1574 | | |
1575 | | // CharThemeOriginalColor, CharThemeColor, and CharThemeColorShade or CharThemeColorTint will be |
1576 | | // used for <w:color> element. That is evaluated by applications, which do not understand w14 |
1577 | | // namespace, or if w14:textFill is omitted. |
1578 | 0 | model::ComplexColor aComplexColor; |
1579 | 0 | if (FontworkHelpers::getThemeColorFromShape(u"FillComplexColor"_ustr, rXPropSet, aComplexColor)) |
1580 | 0 | { |
1581 | | // CharThemeColor |
1582 | 0 | beans::PropertyValue aCharThemeColor; |
1583 | 0 | aCharThemeColor.Name = u"CharThemeColor"_ustr; |
1584 | 0 | aCharThemeColor.Value <<= lcl_getWMarkupStringForThemeColor(aComplexColor); |
1585 | 0 | rUpdatePropVec.push_back(aCharThemeColor); |
1586 | | |
1587 | | // CharThemeColorShade or CharThemeColorTint |
1588 | | // MS Office uses themeTint and themeShade on the luminance in a HSL color space, see 2.1.72 |
1589 | | // in [MS-OI29500]. That is different from OOXML specification. |
1590 | | // We made two assumption here: (1) If LumOff exists and is not zero, it is a 'tint'. |
1591 | | // (2) LumMod + LumOff == 10000; |
1592 | 0 | sal_Int16 nLumMod; |
1593 | 0 | if (lcl_getThemeColorTransformationValue(aComplexColor, model::TransformationType::LumMod, |
1594 | 0 | nLumMod)) |
1595 | 0 | { |
1596 | 0 | sal_Int16 nLumOff; |
1597 | 0 | bool bIsTint = lcl_getThemeColorTransformationValue( |
1598 | 0 | aComplexColor, model::TransformationType::LumOff, nLumOff) |
1599 | 0 | && nLumOff != 0; |
1600 | 0 | sal_uInt8 nValue |
1601 | 0 | = std::clamp<sal_uInt8>(lround(double(nLumMod) * 255.0 / 10000.0), 0, 255); |
1602 | 0 | OUString sValue = OUString::number(nValue, 16); |
1603 | |
|
1604 | 0 | beans::PropertyValue aCharThemeTintOrShade; |
1605 | 0 | aCharThemeTintOrShade.Name = bIsTint ? u"CharThemeColorTint" : u"CharThemeColorShade"; |
1606 | 0 | aCharThemeTintOrShade.Value <<= sValue; |
1607 | 0 | rUpdatePropVec.push_back(aCharThemeTintOrShade); |
1608 | 0 | } |
1609 | 0 | } |
1610 | | // ToDo: Are FillColorLumMod, FillColorLumOff and FillColorTheme possible without |
1611 | | // FillComplexColor? If yes, we need an 'else' part here. |
1612 | | |
1613 | | // CharThemeOriginalColor. |
1614 | 0 | beans::PropertyValue aCharThemeOriginalColor; |
1615 | 0 | sal_Int32 nFillColor(0); |
1616 | 0 | if (xPropSetInfo->hasPropertyByName(u"FillColor"_ustr)) |
1617 | 0 | rXPropSet->getPropertyValue(u"FillColor"_ustr) >>= nFillColor; |
1618 | 0 | aCharThemeOriginalColor.Name = u"CharThemeOriginalColor"_ustr; |
1619 | 0 | ::Color aColor(ColorTransparency, nFillColor); |
1620 | 0 | aCharThemeOriginalColor.Value <<= aColor.AsRGBHEXString(); |
1621 | 0 | rUpdatePropVec.push_back(aCharThemeOriginalColor); |
1622 | 0 | } |
1623 | | |
1624 | | void FontworkHelpers::applyUpdatesToCharInteropGrabBag( |
1625 | | const std::vector<beans::PropertyValue>& rUpdatePropVec, |
1626 | | const uno::Reference<text::XText>& rXText) |
1627 | 0 | { |
1628 | 0 | if (!rXText.is()) |
1629 | 0 | return; |
1630 | 0 | uno::Reference<text::XTextCursor> rXTextCursor = rXText->createTextCursor(); |
1631 | 0 | rXTextCursor->gotoStart(false); |
1632 | 0 | rXTextCursor->gotoEnd(true); |
1633 | 0 | uno::Reference<container::XEnumerationAccess> paraEnumAccess(rXText, uno::UNO_QUERY); |
1634 | 0 | if (!paraEnumAccess.is()) |
1635 | 0 | return; |
1636 | 0 | uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration()); |
1637 | 0 | while (paraEnum->hasMoreElements()) |
1638 | 0 | { |
1639 | 0 | uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY); |
1640 | 0 | uno::Reference<container::XEnumerationAccess> runEnumAccess(xParagraph, uno::UNO_QUERY); |
1641 | 0 | if (!runEnumAccess.is()) |
1642 | 0 | continue; |
1643 | 0 | uno::Reference<container::XEnumeration> runEnum = runEnumAccess->createEnumeration(); |
1644 | 0 | while (runEnum->hasMoreElements()) |
1645 | 0 | { |
1646 | 0 | uno::Reference<text::XTextRange> xRun(runEnum->nextElement(), uno::UNO_QUERY); |
1647 | 0 | if (xRun->getString().isEmpty()) |
1648 | 0 | continue; |
1649 | 0 | uno::Reference<beans::XPropertySet> xRunPropSet(xRun, uno::UNO_QUERY); |
1650 | 0 | if (!xRunPropSet.is()) |
1651 | 0 | continue; |
1652 | 0 | auto xRunPropSetInfo = xRunPropSet->getPropertySetInfo(); |
1653 | 0 | if (!xRunPropSetInfo.is()) |
1654 | 0 | continue; |
1655 | | |
1656 | | // Now apply the updates to the CharInteropGrabBag of this run |
1657 | 0 | uno::Sequence<beans::PropertyValue> aCharInteropGrabBagSeq; |
1658 | 0 | if (xRunPropSetInfo->hasPropertyByName(u"CharInteropGrabBag"_ustr)) |
1659 | 0 | xRunPropSet->getPropertyValue(u"CharInteropGrabBag"_ustr) |
1660 | 0 | >>= aCharInteropGrabBagSeq; |
1661 | 0 | comphelper::SequenceAsHashMap aGrabBagMap(aCharInteropGrabBagSeq); |
1662 | 0 | for (const auto& rProp : rUpdatePropVec) |
1663 | 0 | { |
1664 | 0 | aGrabBagMap[rProp.Name] = rProp.Value; // [] inserts if not exists |
1665 | 0 | } |
1666 | 0 | xRunPropSet->setPropertyValue(u"CharInteropGrabBag"_ustr, |
1667 | 0 | uno::Any(aGrabBagMap.getAsConstPropertyValueList())); |
1668 | 0 | } |
1669 | 0 | } |
1670 | 0 | } |
1671 | | |
1672 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |