1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "resources.hxx"
25 #include "WW8DocumentImpl.hxx"
26 
27 namespace writerfilter {
28 namespace doctok
29 {
30 
31 class ShapeTypeToString
32 {
33     typedef boost::shared_ptr<ShapeTypeToString> Pointer_t;
34 
35     static Pointer_t pInstance;
36 
37     typedef map<sal_uInt32, string> Map_t;
38     Map_t mMap;
39 
40 protected:
41     ShapeTypeToString();
42 
43 public:
Instance()44     static Pointer_t Instance()
45     {
46         if( !bool(pInstance))
47             pInstance = Pointer_t(new ShapeTypeToString());
48 
49         return pInstance;
50     }
51 
operator ()(sal_uInt32 nShapeType)52     string operator()(sal_uInt32 nShapeType)
53     {
54         return mMap[nShapeType];
55     }
56 };
57 
58 ShapeTypeToString::Pointer_t ShapeTypeToString::pInstance;
59 
ShapeTypeToString()60 ShapeTypeToString::ShapeTypeToString()
61 {
62     mMap[0]="NotPrimitive";
63     mMap[1]="Rectangle";
64     mMap[2]="RoundRectangle";
65     mMap[3]="Ellipse";
66     mMap[4]="Diamond";
67     mMap[5]="IsocelesTriangle";
68     mMap[6]="RightTriangle";
69     mMap[7]="Parallelogram";
70     mMap[8]="Trapezoid";
71     mMap[9]="Hexagon";
72     mMap[10]="Octagon";
73     mMap[11]="Plus";
74     mMap[12]="Star";
75     mMap[13]="Arrow";
76     mMap[14]="ThickArrow";
77     mMap[15]="HomePlate";
78     mMap[16]="Cube";
79     mMap[17]="Balloon";
80     mMap[18]="Seal";
81     mMap[19]="Arc";
82     mMap[20]="Line";
83     mMap[21]="Plaque";
84     mMap[22]="Can";
85     mMap[23]="Donut";
86     mMap[24]="TextSimple";
87     mMap[25]="TextOctagon";
88     mMap[26]="TextHexagon";
89     mMap[27]="TextCurve";
90     mMap[28]="TextWave";
91     mMap[29]="TextRing";
92     mMap[30]="TextOnCurve";
93     mMap[31]="TextOnRing";
94     mMap[32]="StraightConnector1";
95     mMap[33]="BentConnector2";
96     mMap[34]="BentConnector3";
97     mMap[35]="BentConnector4";
98     mMap[36]="BentConnector5";
99     mMap[37]="CurvedConnector2";
100     mMap[38]="CurvedConnector3";
101     mMap[39]="CurvedConnector4";
102     mMap[40]="CurvedConnector5";
103     mMap[41]="Callout1";
104     mMap[42]="Callout2";
105     mMap[43]="Callout3";
106     mMap[44]="AccentCallout1";
107     mMap[45]="AccentCallout2";
108     mMap[46]="AccentCallout3";
109     mMap[47]="BorderCallout1";
110     mMap[48]="BorderCallout2";
111     mMap[49]="BorderCallout3";
112     mMap[50]="AccentBorderCallout1";
113     mMap[51]="AccentBorderCallout2";
114     mMap[52]="AccentBorderCallout3";
115     mMap[53]="Ribbon";
116     mMap[54]="Ribbon2";
117     mMap[55]="Chevron";
118     mMap[56]="Pentagon";
119     mMap[57]="NoSmoking";
120     mMap[58]="Seal8";
121     mMap[59]="Seal16";
122     mMap[60]="Seal32";
123     mMap[61]="WedgeRectCallout";
124     mMap[62]="WedgeRRectCallout";
125     mMap[63]="WedgeEllipseCallout";
126     mMap[64]="Wave";
127     mMap[65]="FoldedCorner";
128     mMap[66]="LeftArrow";
129     mMap[67]="DownArrow";
130     mMap[68]="UpArrow";
131     mMap[69]="LeftRightArrow";
132     mMap[70]="UpDownArrow";
133     mMap[71]="IrregularSeal1";
134     mMap[72]="IrregularSeal2";
135     mMap[73]="LightningBolt";
136     mMap[74]="Heart";
137     mMap[75]="PictureFrame";
138     mMap[76]="QuadArrow";
139     mMap[77]="LeftArrowCallout";
140     mMap[78]="RightArrowCallout";
141     mMap[79]="UpArrowCallout";
142     mMap[80]="DownArrowCallout";
143     mMap[81]="LeftRightArrowCallout";
144     mMap[82]="UpDownArrowCallout";
145     mMap[83]="QuadArrowCallout";
146     mMap[84]="Bevel";
147     mMap[85]="LeftBracket";
148     mMap[86]="RightBracket";
149     mMap[87]="LeftBrace";
150     mMap[88]="RightBrace";
151     mMap[89]="LeftUpArrow";
152     mMap[90]="BentUpArrow";
153     mMap[91]="BentArrow";
154     mMap[92]="Seal24";
155     mMap[93]="StripedRightArrow";
156     mMap[94]="NotchedRightArrow";
157     mMap[95]="BlockArc";
158     mMap[96]="SmileyFace";
159     mMap[97]="VerticalScroll";
160     mMap[98]="HorizontalScroll";
161     mMap[99]="CircularArrow";
162     mMap[100]="NotchedCircularArrow";
163     mMap[101]="UturnArrow";
164     mMap[102]="CurvedRightArrow";
165     mMap[103]="CurvedLeftArrow";
166     mMap[104]="CurvedUpArrow";
167     mMap[105]="CurvedDownArrow";
168     mMap[106]="CloudCallout";
169     mMap[107]="EllipseRibbon";
170     mMap[108]="EllipseRibbon2";
171     mMap[109]="FlowChartProcess";
172     mMap[110]="FlowChartDecision";
173     mMap[111]="FlowChartInputOutput";
174     mMap[112]="FlowChartPredefinedProcess";
175     mMap[113]="FlowChartInternalStorage";
176     mMap[114]="FlowChartDocument";
177     mMap[115]="FlowChartMultidocument";
178     mMap[116]="FlowChartTerminator";
179     mMap[117]="FlowChartPreparation";
180     mMap[118]="FlowChartManualInput";
181     mMap[119]="FlowChartManualOperation";
182     mMap[120]="FlowChartConnector";
183     mMap[121]="FlowChartPunchedCard";
184     mMap[122]="FlowChartPunchedTape";
185     mMap[123]="FlowChartSummingJunction";
186     mMap[124]="FlowChartOr";
187     mMap[125]="FlowChartCollate";
188     mMap[126]="FlowChartSort";
189     mMap[127]="FlowChartExtract";
190     mMap[128]="FlowChartMerge";
191     mMap[129]="FlowChartOfflineStorage";
192     mMap[130]="FlowChartOnlineStorage";
193     mMap[131]="FlowChartMagneticTape";
194     mMap[132]="FlowChartMagneticDisk";
195     mMap[133]="FlowChartMagneticDrum";
196     mMap[134]="FlowChartDisplay";
197     mMap[135]="FlowChartDelay";
198     mMap[136]="TextPlainText";
199     mMap[137]="TextStop";
200     mMap[138]="TextTriangle";
201     mMap[139]="TextTriangleInverted";
202     mMap[140]="TextChevron";
203     mMap[141]="TextChevronInverted";
204     mMap[142]="TextRingInside";
205     mMap[143]="TextRingOutside";
206     mMap[144]="TextArchUpCurve";
207     mMap[145]="TextArchDownCurve";
208     mMap[146]="TextCircleCurve";
209     mMap[147]="TextButtonCurve";
210     mMap[148]="TextArchUpPour";
211     mMap[149]="TextArchDownPour";
212     mMap[150]="TextCirclePour";
213     mMap[151]="TextButtonPour";
214     mMap[152]="TextCurveUp";
215     mMap[153]="TextCurveDown";
216     mMap[154]="TextCascadeUp";
217     mMap[155]="TextCascadeDown";
218     mMap[156]="TextWave1";
219     mMap[157]="TextWave2";
220     mMap[158]="TextWave3";
221     mMap[159]="TextWave4";
222     mMap[160]="TextInflate";
223     mMap[161]="TextDeflate";
224     mMap[162]="TextInflateBottom";
225     mMap[163]="TextDeflateBottom";
226     mMap[164]="TextInflateTop";
227     mMap[165]="TextDeflateTop";
228     mMap[166]="TextDeflateInflate";
229     mMap[167]="TextDeflateInflateDeflate";
230     mMap[168]="TextFadeRight";
231     mMap[169]="TextFadeLeft";
232     mMap[170]="TextFadeUp";
233     mMap[171]="TextFadeDown";
234     mMap[172]="TextSlantUp";
235     mMap[173]="TextSlantDown";
236     mMap[174]="TextCanUp";
237     mMap[175]="TextCanDown";
238     mMap[176]="FlowChartAlternateProcess";
239     mMap[177]="FlowChartOffpageConnector";
240     mMap[178]="Callout90";
241     mMap[179]="AccentCallout90";
242     mMap[180]="BorderCallout90";
243     mMap[181]="AccentBorderCallout90";
244     mMap[182]="LeftRightUpArrow";
245     mMap[183]="Sun";
246     mMap[184]="Moon";
247     mMap[185]="BracketPair";
248     mMap[186]="BracePair";
249     mMap[187]="Seal4";
250     mMap[188]="DoubleWave";
251     mMap[189]="ActionButtonBlank";
252     mMap[190]="ActionButtonHome";
253     mMap[191]="ActionButtonHelp";
254     mMap[192]="ActionButtonInformation";
255     mMap[193]="ActionButtonForwardNext";
256     mMap[194]="ActionButtonBackPrevious";
257     mMap[195]="ActionButtonEnd";
258     mMap[196]="ActionButtonBeginning";
259     mMap[197]="ActionButtonReturn";
260     mMap[198]="ActionButtonDocument";
261     mMap[199]="ActionButtonSound";
262     mMap[200]="ActionButtonMovie";
263     mMap[201]="HostControl";
264     mMap[202]="TextBox";
265 }
266 
267 // DffOPT
268 
get_property_count()269 sal_uInt32 DffOPT::get_property_count()
270 {
271     return getInstance();
272 }
273 
274 writerfilter::Reference<Properties>::Pointer_t
get_property(sal_uInt32 nPos)275 DffOPT::get_property(sal_uInt32 nPos)
276 {
277     WW8FOPTE * pTmp = new WW8FOPTE(this, 0x8 + nPos * WW8FOPTE::getSize());
278     pTmp->setIndex(nPos);
279 
280     return writerfilter::Reference<Properties>::Pointer_t(pTmp);
281 }
282 
get_extraoffset_count()283 sal_uInt32 DffOPT::get_extraoffset_count()
284 {
285     return get_property_count();
286 }
287 
get_extraoffset(sal_uInt32 pos)288 sal_uInt32 DffOPT::get_extraoffset(sal_uInt32 pos)
289 {
290     sal_uInt32 nResult;
291     sal_uInt32 nCount = get_property_count();
292 
293     if (pos < nCount)
294     {
295         nResult = 0x8 + nCount * WW8FOPTE::getSize();
296 
297         for (sal_uInt32 n = 0; n < pos; ++n)
298         {
299             WW8FOPTE aFOPTE(this, 0x8 + n * WW8FOPTE::getSize());
300 
301             if (aFOPTE.get_fComplex())
302             {
303                 sal_uInt32 nValue = aFOPTE.get_op();
304                 nResult += nValue;
305             }
306         }
307     }
308     else
309         nResult = getCount();
310 
311     return nResult;
312 }
313 
314 //DffDGG
315 
get_fidcl_count()316 sal_uInt32 DffDGG::get_fidcl_count()
317 {
318     return (getCount() - 0x18) / WW8FIDCL::getSize();
319 }
320 
321 writerfilter::Reference<Properties>::Pointer_t
get_fidcl(sal_uInt32 pos)322 DffDGG::get_fidcl(sal_uInt32 pos)
323 {
324     return writerfilter::Reference<Properties>::Pointer_t
325         (new WW8FIDCL(this, 0x18 + pos * WW8FIDCL::getSize()));
326 }
327 
328 
329 // DffBSE
330 
get_blipname()331 rtl::OUString DffBSE::get_blipname()
332 {
333     rtl::OUString sResult;
334     WW8FBSE aFBSE(this, 0x8);
335 
336     if (aFBSE.get_cbName() > 0)
337         sResult = getString(0x24, aFBSE.get_cbName());
338 
339     return sResult;
340 }
341 
342 writerfilter::Reference<Properties>::Pointer_t
get_blip()343 DffBSE::get_blip()
344 {
345     writerfilter::Reference<Properties>::Pointer_t pResult;
346 
347     WW8FBSE aFBSE(this, 8);
348     sal_uInt32 nOffset = 8 + WW8FBSE::getSize() + aFBSE.get_cbName();
349 
350     if (nOffset + 8 < getCount())
351     {
352         WW8StructBase aTmp(this, nOffset, 0x8);
353 
354         sal_uInt32 nCount = getCount() - 8;
355 
356         if (aTmp.getU32(0x4) - 8 < nCount)
357             nCount = aTmp.getU32(0x4) - 8;
358 
359         if (nCount)
360         {
361             DffRecord * pRecord = createDffRecord(this, nOffset);
362 
363             pResult = writerfilter::Reference<Properties>::Pointer_t(pRecord);
364         }
365     }
366     else
367     {
368         nOffset = sal::static_int_cast<sal_Int32>(aFBSE.get_foDelay());
369         if (! (nOffset & 1 << 31) && nOffset > 0 && getDocument() != NULL)
370         {
371             WW8StructBase aStructBase(*getDocument()->getDocStream(),
372                                       nOffset, 0x8);
373 
374             DffRecord * pRecord =
375                 createDffRecord(*getDocument()->getDocStream(),
376                                 aFBSE.get_foDelay());
377 
378             pResult = writerfilter::Reference<Properties>::Pointer_t(pRecord);
379         }
380     }
381 
382     return pResult;
383 }
384 
385 #if 0
386 WW8BinaryObjReference::Pointer_t DffBSE::get_binary()
387 {
388     WW8BinaryObjReference::Pointer_t pResult;
389 
390     if (getCount() > 0x45)
391         pResult = WW8BinaryObjReference::Pointer_t
392             (new WW8BinaryObjReference(this, 0x45,
393                                        getCount() - 0x45));
394     else
395     {
396         WW8FBSE aFBSE(this, 0x8);
397 
398         sal_Int32 nOffset = sal::static_int_cast<sal_Int32>(aFBSE.get_foDelay());
399         if (nOffset > 0 && getDocument() != NULL)
400         {
401             WW8StructBase aStructBase(*getDocument()->getDocStream(),
402                                       nOffset, 0x8);
403 
404             sal_uInt32 nCount = aStructBase.getU32(0x4) - 0x11;
405 
406             pResult = WW8BinaryObjReference::Pointer_t
407                 (new WW8BinaryObjReference(*getDocument()->getDocStream(),
408                                            aFBSE.get_foDelay() + 0x19, nCount));
409         }
410     }
411 
412     return pResult;
413 }
414 #endif
415 
416 // WW8FOPTE
resolveNoAuto(Properties & rHandler)417 void WW8FOPTE::resolveNoAuto(Properties & rHandler)
418 {
419     sal_uInt16 nId = get_pid() + 1;
420     sal_uInt32 nOp = get_op();
421     sal_uInt32 nMask = 2;
422 
423     while (isBooleanDffOpt(nId))
424     {
425         WW8Value::Pointer_t pVal = createValue(getDffOptName(nId));
426         rHandler.attribute(NS_rtf::LN_shpname, *pVal);
427 
428         pVal = createValue((nOp & nMask) != 0);
429         rHandler.attribute(NS_rtf::LN_shpvalue, *pVal);
430 
431         --nId;
432         nMask = nMask << 1;
433     }
434 }
435 
436 // DffFSP
437 
get_shptypename()438 rtl::OUString DffFSP::get_shptypename()
439 {
440     string aName = (*ShapeTypeToString::Instance())(get_shptype());
441 
442     return rtl::OUString::createFromAscii(aName.c_str());
443 }
444 
445 // DffSpContainer
446 
447 writerfilter::Reference<Properties>::Pointer_t
get_blip()448 DffSpContainer::get_blip()
449 {
450     writerfilter::Reference<Properties>::Pointer_t pResult;
451 
452     if (getShapeType() == 75)
453     {
454         sal_uInt32 nBid = getShapeBid();
455 
456         if (getDocument() != NULL && nBid > 0)
457             pResult = getDocument()->getBlip(nBid);
458     }
459 
460     return pResult;
461 }
462 
463 writerfilter::Reference<Stream>::Pointer_t
get_shptxt()464 DffSpContainer::get_shptxt()
465 {
466     writerfilter::Reference<Stream>::Pointer_t pResult;
467 
468     if (getShapeType() == 202)
469     {
470         sal_uInt32 nShpId = getShapeId();
471 
472         if (getDocument() != NULL)
473             pResult = getDocument()->getTextboxText(nShpId);
474     }
475 
476     return pResult;
477 }
478 
479 // DffUDefProp
480 
resolveNoAuto(Properties & rHandler)481 void DffUDefProp::resolveNoAuto(Properties & rHandler)
482 {
483     sal_uInt32 nOffset = 0x8;
484     sal_uInt32 nCount = getCount();
485 
486     while (nOffset + 6 <= nCount)
487     {
488         sal_uInt16 nPid = getU16(nOffset);
489         sal_uInt32 nValue = getU32(nOffset + 2);
490 
491         sal_uInt32 nAttrid = 0;
492         switch (nPid)
493         {
494         case 0x38f: nAttrid = NS_rtf::LN_XAlign; break;
495         case 0x390: nAttrid = NS_rtf::LN_XRelTo; break;
496         case 0x391: nAttrid = NS_rtf::LN_YAlign; break;
497         case 0x392: nAttrid = NS_rtf::LN_YRelTo; break;
498         case 0x3bf: nAttrid = NS_rtf::LN_LayoutInTableCell; break;
499         case 0x53f: nAttrid = NS_rtf::LN_Inline; break;
500         default:
501             break;
502         }
503 
504         if (nAttrid != 0)
505         {
506             WW8Value::Pointer_t pVal = createValue(nValue);
507             rHandler.attribute(nAttrid, *pVal);
508         }
509 
510         nOffset += 6;
511     }
512 }
513 
514 }}
515