build fix
[LibreOffice.git] / filter / source / msfilter / util.cxx
blob24603aa4d704aa899b49cb098e7a7cf03d087909
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <com/sun/star/awt/Size.hpp>
11 #include <rtl/ustring.hxx>
12 #include <rtl/strbuf.hxx>
13 #include <unotools/fontcvt.hxx>
14 #include <unotools/fontdefs.hxx>
15 #include <vcl/svapp.hxx>
16 #include <vcl/salbtype.hxx>
17 #include <filter/msfilter/escherex.hxx>
18 #include <filter/msfilter/util.hxx>
19 #include <memory>
20 #include <unordered_map>
22 namespace msfilter {
23 namespace util {
25 rtl_TextEncoding getBestTextEncodingFromLocale(const css::lang::Locale &rLocale)
27 // Obviously not comprehensive, feel free to expand these, they're for ultimate fallbacks
28 // in last-ditch broken-file-format cases to guess the right 8bit encodings
29 const OUString &rLanguage = rLocale.Language;
30 if (rLanguage == "cs" || rLanguage == "hu" || rLanguage == "pl")
31 return RTL_TEXTENCODING_MS_1250;
32 if (rLanguage == "ru" || rLanguage == "uk")
33 return RTL_TEXTENCODING_MS_1251;
34 if (rLanguage == "el")
35 return RTL_TEXTENCODING_MS_1253;
36 if (rLanguage == "tr")
37 return RTL_TEXTENCODING_MS_1254;
38 if (rLanguage == "lt")
39 return RTL_TEXTENCODING_MS_1257;
40 if (rLanguage == "th")
41 return RTL_TEXTENCODING_MS_874;
42 if (rLanguage == "vi")
43 return RTL_TEXTENCODING_MS_1258;
44 return RTL_TEXTENCODING_MS_1252;
47 sal_uInt32 BGRToRGB(sal_uInt32 nColor)
49 sal_uInt8
50 r(static_cast<sal_uInt8>(nColor&0xFF)),
51 g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
52 b(static_cast<sal_uInt8>((nColor>>16)&0xFF)),
53 t(static_cast<sal_uInt8>((nColor>>24)&0xFF));
54 nColor = (t<<24) + (r<<16) + (g<<8) + b;
55 return nColor;
58 DateTime DTTM2DateTime( long lDTTM )
61 mint short :6 0000003F minutes (0-59)
62 hr short :5 000007C0 hours (0-23)
63 dom short :5 0000F800 days of month (1-31)
64 mon short :4 000F0000 months (1-12)
65 yr short :9 1FF00000 years (1900-2411)-1900
66 wdy short :3 E0000000 weekday(Sunday=0
67 Monday=1
68 ( wdy can be ignored ) Tuesday=2
69 Wednesday=3
70 Thursday=4
71 Friday=5
72 Saturday=6)
74 DateTime aDateTime(Date( 0 ), ::tools::Time( 0 ));
75 if( lDTTM )
77 sal_uInt16 lMin = (sal_uInt16)(lDTTM & 0x0000003F);
78 lDTTM >>= 6;
79 sal_uInt16 lHour= (sal_uInt16)(lDTTM & 0x0000001F);
80 lDTTM >>= 5;
81 sal_uInt16 lDay = (sal_uInt16)(lDTTM & 0x0000001F);
82 lDTTM >>= 5;
83 sal_uInt16 lMon = (sal_uInt16)(lDTTM & 0x0000000F);
84 lDTTM >>= 4;
85 sal_uInt16 lYear= (sal_uInt16)(lDTTM & 0x000001FF) + 1900;
86 aDateTime = DateTime(Date(lDay, lMon, lYear), tools::Time(lHour, lMin));
88 return aDateTime;
91 sal_Unicode bestFitOpenSymbolToMSFont(sal_Unicode cChar,
92 rtl_TextEncoding& rChrSet, OUString& rFontName)
94 std::unique_ptr<StarSymbolToMSMultiFont> pConvert(CreateStarSymbolToMSMultiFont());
95 OUString sFont = pConvert->ConvertChar(cChar);
96 pConvert.reset();
97 if (!sFont.isEmpty())
99 cChar = static_cast< sal_Unicode >(cChar | 0xF000);
100 rFontName = sFont;
101 rChrSet = RTL_TEXTENCODING_SYMBOL;
103 else if (cChar < 0xE000 || cChar > 0xF8FF)
106 Ok we can't fit into a known windows unicode font, but
107 we are not in the private area, so we are a
108 standardized symbol, so turn off the symbol bit and
109 let words own font substitution kick in
111 rChrSet = RTL_TEXTENCODING_UNICODE;
112 sal_Int32 nIndex = 0;
113 rFontName = ::GetNextFontToken(rFontName, nIndex);
115 else
118 Well we don't have an available substition, and we're
119 in our private area, so give up and show a standard
120 bullet symbol
122 rFontName = "Wingdings";
123 cChar = static_cast< sal_Unicode >(0x6C);
125 return cChar;
129 OString ConvertColor( const Color &rColor )
131 OString color( "auto" );
133 if ( rColor != COL_AUTO )
135 const char pHexDigits[] = "0123456789ABCDEF";
136 char pBuffer[] = "000000";
138 pBuffer[0] = pHexDigits[ ( rColor.GetRed() >> 4 ) & 0x0F ];
139 pBuffer[1] = pHexDigits[ rColor.GetRed() & 0x0F ];
140 pBuffer[2] = pHexDigits[ ( rColor.GetGreen() >> 4 ) & 0x0F ];
141 pBuffer[3] = pHexDigits[ rColor.GetGreen() & 0x0F ];
142 pBuffer[4] = pHexDigits[ ( rColor.GetBlue() >> 4 ) & 0x0F ];
143 pBuffer[5] = pHexDigits[ rColor.GetBlue() & 0x0F ];
145 color = OString( pBuffer );
147 return color;
150 #define IN2MM100( v ) static_cast< sal_Int32 >( (v) * 2540.0 + 0.5 )
151 #define MM2MM100( v ) static_cast< sal_Int32 >( (v) * 100.0 + 0.5 )
153 static const ApiPaperSize spPaperSizeTable[] =
155 { 0, 0 }, // 0 - (undefined)
156 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 1 - Letter paper
157 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 2 - Letter small paper
158 { IN2MM100( 11 ), IN2MM100( 17 ) }, // 3 - Tabloid paper
159 { IN2MM100( 17 ), IN2MM100( 11 ) }, // 4 - Ledger paper
160 { IN2MM100( 8.5 ), IN2MM100( 14 ) }, // 5 - Legal paper
161 { IN2MM100( 5.5 ), IN2MM100( 8.5 ) }, // 6 - Statement paper
162 { IN2MM100( 7.25 ), IN2MM100( 10.5 ) }, // 7 - Executive paper
163 { MM2MM100( 297 ), MM2MM100( 420 ) }, // 8 - A3 paper
164 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 9 - A4 paper
165 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 10 - A4 small paper
166 { MM2MM100( 148 ), MM2MM100( 210 ) }, // 11 - A5 paper
167 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 12 - B4 paper
168 { MM2MM100( 176 ), MM2MM100( 250 ) }, // 13 - B5 paper
169 { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 14 - Folio paper
170 { MM2MM100( 215 ), MM2MM100( 275 ) }, // 15 - Quarto paper
171 { IN2MM100( 10 ), IN2MM100( 14 ) }, // 16 - Standard paper
172 { IN2MM100( 11 ), IN2MM100( 17 ) }, // 17 - Standard paper
173 { IN2MM100( 8.5 ), IN2MM100( 11 ) }, // 18 - Note paper
174 { IN2MM100( 3.875 ), IN2MM100( 8.875 ) }, // 19 - #9 envelope
175 { IN2MM100( 4.125 ), IN2MM100( 9.5 ) }, // 20 - #10 envelope
176 { IN2MM100( 4.5 ), IN2MM100( 10.375 ) }, // 21 - #11 envelope
177 { IN2MM100( 4.75 ), IN2MM100( 11 ) }, // 22 - #12 envelope
178 { IN2MM100( 5 ), IN2MM100( 11.5 ) }, // 23 - #14 envelope
179 { IN2MM100( 17 ), IN2MM100( 22 ) }, // 24 - C paper
180 { IN2MM100( 22 ), IN2MM100( 34 ) }, // 25 - D paper
181 { IN2MM100( 34 ), IN2MM100( 44 ) }, // 26 - E paper
182 { MM2MM100( 110 ), MM2MM100( 220 ) }, // 27 - DL envelope
183 { MM2MM100( 162 ), MM2MM100( 229 ) }, // 28 - C5 envelope
184 { MM2MM100( 324 ), MM2MM100( 458 ) }, // 29 - C3 envelope
185 { MM2MM100( 229 ), MM2MM100( 324 ) }, // 30 - C4 envelope
186 { MM2MM100( 114 ), MM2MM100( 162 ) }, // 31 - C6 envelope
187 { MM2MM100( 114 ), MM2MM100( 229 ) }, // 32 - C65 envelope
188 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 33 - B4 envelope
189 { MM2MM100( 176 ), MM2MM100( 250 ) }, // 34 - B5 envelope
190 { MM2MM100( 176 ), MM2MM100( 125 ) }, // 35 - B6 envelope
191 { MM2MM100( 110 ), MM2MM100( 230 ) }, // 36 - Italy envelope
192 { IN2MM100( 3.875 ), IN2MM100( 7.5 ) }, // 37 - Monarch envelope
193 { IN2MM100( 3.625 ), IN2MM100( 6.5 ) }, // 38 - 6 3/4 envelope
194 { IN2MM100( 14.875 ), IN2MM100( 11 ) }, // 39 - US standard fanfold
195 { IN2MM100( 8.5 ), IN2MM100( 12 ) }, // 40 - German standard fanfold
196 { IN2MM100( 8.5 ), IN2MM100( 13 ) }, // 41 - German legal fanfold
197 { MM2MM100( 250 ), MM2MM100( 353 ) }, // 42 - ISO B4
198 { MM2MM100( 200 ), MM2MM100( 148 ) }, // 43 - Japanese double postcard
199 { IN2MM100( 9 ), IN2MM100( 11 ) }, // 44 - Standard paper
200 { IN2MM100( 10 ), IN2MM100( 11 ) }, // 45 - Standard paper
201 { IN2MM100( 15 ), IN2MM100( 11 ) }, // 46 - Standard paper
202 { MM2MM100( 220 ), MM2MM100( 220 ) }, // 47 - Invite envelope
203 { 0, 0 }, // 48 - (undefined)
204 { 0, 0 }, // 49 - (undefined)
205 { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 50 - Letter extra paper
206 { IN2MM100( 9.275 ), IN2MM100( 15 ) }, // 51 - Legal extra paper
207 { IN2MM100( 11.69 ), IN2MM100( 18 ) }, // 52 - Tabloid extra paper
208 { MM2MM100( 236 ), MM2MM100( 322 ) }, // 53 - A4 extra paper
209 { IN2MM100( 8.275 ), IN2MM100( 11 ) }, // 54 - Letter transverse paper
210 { MM2MM100( 210 ), MM2MM100( 297 ) }, // 55 - A4 transverse paper
211 { IN2MM100( 9.275 ), IN2MM100( 12 ) }, // 56 - Letter extra transverse paper
212 { MM2MM100( 227 ), MM2MM100( 356 ) }, // 57 - SuperA/SuperA/A4 paper
213 { MM2MM100( 305 ), MM2MM100( 487 ) }, // 58 - SuperB/SuperB/A3 paper
214 { IN2MM100( 8.5 ), IN2MM100( 12.69 ) }, // 59 - Letter plus paper
215 { MM2MM100( 210 ), MM2MM100( 330 ) }, // 60 - A4 plus paper
216 { MM2MM100( 148 ), MM2MM100( 210 ) }, // 61 - A5 transverse paper
217 { MM2MM100( 182 ), MM2MM100( 257 ) }, // 62 - JIS B5 transverse paper
218 { MM2MM100( 322 ), MM2MM100( 445 ) }, // 63 - A3 extra paper
219 { MM2MM100( 174 ), MM2MM100( 235 ) }, // 64 - A5 extra paper
220 { MM2MM100( 201 ), MM2MM100( 276 ) }, // 65 - ISO B5 extra paper
221 { MM2MM100( 420 ), MM2MM100( 594 ) }, // 66 - A2 paper
222 { MM2MM100( 297 ), MM2MM100( 420 ) }, // 67 - A3 transverse paper
223 { MM2MM100( 322 ), MM2MM100( 445 ) } // 68 - A3 extra transverse paper
226 sal_Int32 PaperSizeConv::getMSPaperSizeIndex( const css::awt::Size& rSize )
228 sal_Int32 nElems = SAL_N_ELEMENTS( spPaperSizeTable );
229 // Need to find the best match for current size
230 sal_Int32 nDeltaWidth = 0;
231 sal_Int32 nDeltaHeight = 0;
233 sal_Int32 nPaperSizeIndex = 0; // Undefined
234 const ApiPaperSize* pItem = spPaperSizeTable;
235 const ApiPaperSize* pEnd = spPaperSizeTable + nElems;
236 for ( ; pItem != pEnd; ++pItem )
238 sal_Int32 nCurDeltaHeight = std::abs( pItem->mnHeight - rSize.Height );
239 sal_Int32 nCurDeltaWidth = std::abs( pItem->mnWidth - rSize.Width );
240 if ( pItem == spPaperSizeTable ) // initialize delta with first item
242 nDeltaWidth = nCurDeltaWidth;
243 nDeltaHeight = nCurDeltaHeight;
245 else
247 if ( nCurDeltaWidth < nDeltaWidth && nCurDeltaHeight < nDeltaHeight )
249 nDeltaWidth = nCurDeltaWidth;
250 nDeltaHeight = nCurDeltaHeight;
251 nPaperSizeIndex = (pItem - spPaperSizeTable);
255 sal_Int32 nTol = 10; // hmm not sure is this the best way
256 if ( nDeltaWidth <= nTol && nDeltaHeight <= nTol )
257 return nPaperSizeIndex;
258 return 0;
261 const ApiPaperSize& PaperSizeConv::getApiSizeForMSPaperSizeIndex( sal_Int32 nMSOPaperIndex )
263 sal_Int32 nElems = SAL_N_ELEMENTS( spPaperSizeTable );
264 if ( nMSOPaperIndex < 0 || nMSOPaperIndex > nElems - 1 )
265 return spPaperSizeTable[ 0 ];
266 return spPaperSizeTable[ nMSOPaperIndex ];
269 OUString findQuotedText( const OUString& rCommand,
270 const sal_Char* cStartQuote, const sal_Unicode uEndQuote )
272 OUString sRet;
273 OUString sStartQuote( OUString::createFromAscii(cStartQuote) );
274 sal_Int32 nStartIndex = rCommand.indexOf( sStartQuote );
275 if( nStartIndex >= 0 )
277 sal_Int32 nStartLength = sStartQuote.getLength();
278 sal_Int32 nEndIndex = rCommand.indexOf( uEndQuote, nStartIndex + nStartLength);
279 if( nEndIndex > nStartIndex )
281 sRet = rCommand.copy( nStartIndex + nStartLength, nEndIndex - nStartIndex - nStartLength);
284 return sRet;
288 WW8ReadFieldParams::WW8ReadFieldParams( const OUString& _rData )
289 : aData( _rData )
290 , nFnd( 0 )
291 , nNext( 0 )
292 , nSavPtr( 0 )
296 First look for an opening bracket or a space or a question mark or a backslash, so that the field (i.e. INCLUDEPICTURE or EINFUEGENGRAFIK or...) gets read over
298 const sal_Int32 nLen = aData.getLength();
300 while ( nNext<nLen && aData[nNext]==' ' )
301 ++nNext;
303 while ( nNext<nLen )
305 const sal_Unicode c = aData[nNext];
306 if ( c==' ' || c=='"' || c=='\\' || c==132 || c==0x201c )
307 break;
308 ++nNext;
311 nFnd = nNext;
312 nSavPtr = nNext;
316 WW8ReadFieldParams::~WW8ReadFieldParams()
322 OUString WW8ReadFieldParams::GetResult() const
324 if (nFnd<0 && nSavPtr>nFnd)
325 return OUString();
326 else
328 return nSavPtr < nFnd ? aData.copy(nFnd) : aData.copy(nFnd, nSavPtr-nFnd);
333 bool WW8ReadFieldParams::GoToTokenParam()
335 const sal_Int32 nOld = nNext;
336 if( -2 == SkipToNextToken() )
337 return GetTokenSttPtr()>=0;
338 nNext = nOld;
339 return false;
342 // ret: -2: NOT a '\' parameter but normal text
343 sal_Int32 WW8ReadFieldParams::SkipToNextToken()
345 if ( nNext<0 || nNext>=aData.getLength() )
346 return -1;
348 nFnd = FindNextStringPiece(nNext);
349 if ( nFnd<0 )
350 return -1;
352 nSavPtr = nNext;
354 if (nFnd+1<aData.getLength() && aData[nFnd+1]!='\\' && aData[nFnd]=='\\')
356 const sal_Int32 nRet = aData[++nFnd];
357 nNext = ++nFnd; // and set after
358 return nRet;
361 if ( nSavPtr>0 && (aData[nSavPtr-1]=='"' || aData[nSavPtr-1]==0x201d ) )
363 --nSavPtr;
365 return -2;
368 // FindNextPara searches the next backslash parameter or the next string
369 // until the next blank or "\" or closing quatation mark
370 // or the end of the string of pStr.
372 // Output ppNext (if ppNext != 0) Suchbeginn fuer naechsten Parameter bzw. 0
374 // Return value: 0 if end of string reached,
375 // ansonsten Anfang des Paramters bzw. der Zeichenkette
377 sal_Int32 WW8ReadFieldParams::FindNextStringPiece(const sal_Int32 nStart)
379 const sal_Int32 nLen = aData.getLength();
380 sal_Int32 n = nStart<0 ? nFnd : nStart; // start
381 sal_Int32 n2; // end
383 nNext = -1; // if not found -> Default
385 while ( n<nLen && aData[n]==' ' )
386 ++n;
388 if ( n==nLen )
389 return -1;
391 if ( aData[n]==0x13 )
393 // Skip the nested field code since it's not supported
394 while ( n<nLen && aData[n]!=0x14 )
395 ++n;
396 if ( n==nLen )
397 return -1;
400 // quotation marks before paragraph?
401 if ( aData[n]=='"' || aData[n]==0x201c || aData[n]==132 || aData[n]==0x14 )
403 n++; // read over quatation marks
404 n2 = n; // search for the end from here on
405 while( (nLen > n2)
406 && (aData[n2] != '"')
407 && (aData[n2] != 0x201d)
408 && (aData[n2] != 147)
409 && (aData[n2] != 0x15) )
410 n2++; // search for the end of the paragraph
412 else // no quotation mark
414 n2 = n; // search for the end from here on
415 while ( n2<nLen && aData[n2]!=' ' ) // search for the end of the paragraph
417 if ( aData[n2]=='\\' )
419 if ( n2+1<nLen && aData[n2+1]=='\\' )
420 n2 += 2; // double backslash -> OK
421 else
423 if( n2 > n )
424 n2--;
425 break; // single backslash -> end
428 else
429 n2++; // no backslash -> OK
432 if( nLen > n2 )
434 if (aData[n2]!=' ') ++n2;
435 nNext = n2;
437 return n;
441 // read parameters "1-3" or 1-3 with both values between 1 and nMax
442 bool WW8ReadFieldParams::GetTokenSttFromTo(sal_Int32* pFrom, sal_Int32* pTo, sal_Int32 nMax)
444 sal_Int32 nStart = 0;
445 sal_Int32 nEnd = 0;
446 if ( GoToTokenParam() )
449 const OUString sParams( GetResult() );
451 sal_Int32 nIndex = 0;
452 const OUString sStart( sParams.getToken(0, '-', nIndex) );
453 if (nIndex>=0)
455 nStart = sStart.toInt32();
456 nEnd = sParams.copy(nIndex).toInt32();
459 if( pFrom ) *pFrom = nStart;
460 if( pTo ) *pTo = nEnd;
462 return nStart && nEnd && (nMax >= nStart) && (nMax >= nEnd);
465 EquationResult Read_SubF_Combined(WW8ReadFieldParams& rReadParam)
467 EquationResult aResult;
469 OUString sCombinedCharacters;
470 WW8ReadFieldParams aOriFldParam = rReadParam;
471 const sal_Int32 cGetChar = rReadParam.SkipToNextToken();
472 switch( cGetChar )
474 case 'a':
475 case 'A':
476 if ( !rReadParam.GetResult().startsWithIgnoreAsciiCase("d") )
478 break;
480 (void)rReadParam.SkipToNextToken();
481 SAL_FALLTHROUGH;
482 case -2:
484 if ( rReadParam.GetResult().startsWithIgnoreAsciiCase("(") )
486 for (int i=0;i<2;i++)
488 if ('s' == rReadParam.SkipToNextToken())
490 const sal_Int32 cChar = rReadParam.SkipToNextToken();
491 if (-2 != rReadParam.SkipToNextToken())
492 break;
493 const OUString sF = rReadParam.GetResult();
494 if ((('u' == cChar) && sF.startsWithIgnoreAsciiCase("p"))
495 || (('d' == cChar) && sF.startsWithIgnoreAsciiCase("o")))
497 if (-2 == rReadParam.SkipToNextToken())
499 OUString sPart = rReadParam.GetResult();
500 sal_Int32 nBegin = sPart.indexOf('(');
502 // Word disallows brackets in this field, which
503 // aids figuring out the case of an end of )) vs )
504 sal_Int32 nEnd = sPart.indexOf(')');
506 if (nBegin != -1 && nEnd != -1)
508 sCombinedCharacters +=
509 sPart.copy(nBegin+1,nEnd-nBegin-1);
515 if (!sCombinedCharacters.isEmpty())
517 aResult.sType = "CombinedCharacters";
518 aResult.sResult = sCombinedCharacters;
520 else
522 const OUString sPart = aOriFldParam.GetResult();
523 sal_Int32 nBegin = sPart.indexOf('(');
524 sal_Int32 nEnd = sPart.indexOf(',');
525 if ( nEnd == -1 )
527 nEnd = sPart.indexOf(')');
529 if ( nBegin != -1 && nEnd != -1 )
531 // skip certain leading characters
532 for (int i = nBegin;i < nEnd-1;i++)
534 const sal_Unicode cC = sPart[nBegin+1];
535 if ( cC < 32 )
537 nBegin++;
539 else
540 break;
542 sCombinedCharacters = sPart.copy( nBegin+1, nEnd-nBegin-1 );
543 if ( !sCombinedCharacters.isEmpty() )
545 aResult.sType = "Input";
546 aResult.sResult = sCombinedCharacters;
551 break;
553 default:
554 break;
556 return aResult;
559 EquationResult ParseCombinedChars(const OUString& rStr)
561 EquationResult aResult;
562 WW8ReadFieldParams aReadParam( rStr );
563 const sal_Int32 cChar = aReadParam.SkipToNextToken();
564 if ('o' == cChar || 'O' == cChar)
565 aResult = Read_SubF_Combined(aReadParam);
566 return aResult;
569 struct CustomShapeTypeTranslationTable
571 const char* sOOo;
572 const char* sMSO;
575 static const CustomShapeTypeTranslationTable pCustomShapeTypeTranslationTable[] =
577 // { "non-primitive", mso_sptMin },
578 { "frame", "frame" },
579 { "rectangle", "rect" },
580 { "round-rectangle", "roundRect" },
581 { "ellipse", "ellipse" },
582 { "diamond", "diamond" },
583 { "isosceles-triangle", "triangle" },
584 { "right-triangle", "rtTriangle" },
585 { "parallelogram", "parallelogram" },
586 { "trapezoid", "trapezoid" },
587 { "hexagon", "hexagon" },
588 { "octagon", "octagon" },
589 { "cross", "plus" },
590 { "star5", "star5" },
591 { "right-arrow", "rightArrow" },
592 // { "mso-spt14", mso_sptThickArrow },
593 { "pentagon-right", "homePlate" },
594 { "cube", "cube" },
595 // { "mso-spt17", mso_sptBalloon },
596 // { "mso-spt18", mso_sptSeal },
597 { "mso-spt19", "arc" },
598 { "mso-spt20", "line" },
599 { "mso-spt21", "plaque" },
600 { "can", "can" },
601 { "ring", "donut" },
602 { "mso-spt24", "textPlain" },
603 { "mso-spt25", "textStop" },
604 { "mso-spt26", "textTriangle" },
605 { "mso-spt27", "textCanDown" },
606 { "mso-spt28", "textWave1" },
607 { "mso-spt29", "textArchUpPour" },
608 { "mso-spt30", "textCanDown" },
609 { "mso-spt31", "textArchUp" },
610 { "mso-spt32", "straightConnector1" },
611 { "mso-spt33", "bentConnector2" },
612 { "mso-spt34", "bentConnector3" },
613 { "mso-spt35", "bentConnector4" },
614 { "mso-spt36", "bentConnector5" },
615 { "mso-spt37", "curvedConnector2" },
616 { "mso-spt38", "curvedConnector3" },
617 { "mso-spt39", "curvedConnector4" },
618 { "mso-spt40", "curvedConnector5" },
619 { "mso-spt41", "callout1" },
620 { "mso-spt42", "callout2" },
621 { "mso-spt43", "callout3" },
622 { "mso-spt44", "accentCallout1" },
623 { "mso-spt45", "accentCallout2" },
624 { "mso-spt46", "accentCallout3" },
625 { "line-callout-1", "borderCallout1" },
626 { "line-callout-2", "borderCallout2" },
627 { "line-callout-3", "borderCallout3" },
628 { "mso-spt49", "borderCallout3" },
629 { "mso-spt50", "accentBorderCallout1" },
630 { "mso-spt51", "accentBorderCallout2" },
631 { "mso-spt52", "accentBorderCallout3" },
632 { "mso-spt53", "ribbon" },
633 { "mso-spt54", "ribbon2" },
634 { "chevron", "chevron" },
635 { "pentagon", "pentagon" },
636 { "forbidden", "noSmoking" },
637 { "star8", "star8" },
638 { "mso-spt59", "star16" },
639 { "mso-spt60", "star32" },
640 { "rectangular-callout", "wedgeRectCallout" },
641 { "round-rectangular-callout", "wedgeRoundRectCallout" },
642 { "round-callout", "wedgeEllipseCallout" },
643 { "mso-spt64", "wave" },
644 { "paper", "foldedCorner" },
645 { "left-arrow", "leftArrow" },
646 { "down-arrow", "downArrow" },
647 { "up-arrow", "upArrow" },
648 { "left-right-arrow", "leftRightArrow" },
649 { "up-down-arrow", "upDownArrow" },
650 { "mso-spt71", "irregularSeal1" },
651 { "bang", "irregularSeal2" },
652 { "lightning", "lightningBolt" },
653 { "heart", "heart" },
654 { "quad-arrow", "quadArrow" },
655 { "left-arrow-callout", "leftArrowCallout" },
656 { "right-arrow-callout", "rightArrowCallout" },
657 { "up-arrow-callout", "upArrowCallout" },
658 { "down-arrow-callout", "downArrowCallout" },
659 { "left-right-arrow-callout", "leftRightArrowCallout" },
660 { "up-down-arrow-callout", "upDownArrowCallout" },
661 { "quad-arrow-callout", "quadArrowCallout" },
662 { "quad-bevel", "bevel" },
663 { "left-bracket", "leftBracket" },
664 { "right-bracket", "rightBracket" },
665 { "left-brace", "leftBrace" },
666 { "right-brace", "rightBrace" },
667 { "mso-spt89", "leftUpArrow" },
668 { "mso-spt90", "bentUpArrow" },
669 { "mso-spt91", "bentArrow" },
670 { "star24", "star24" },
671 { "striped-right-arrow", "stripedRightArrow" },
672 { "notched-right-arrow", "notchedRightArrow" },
673 { "block-arc", "blockArc" },
674 { "smiley", "smileyFace" },
675 { "vertical-scroll", "verticalScroll" },
676 { "horizontal-scroll", "horizontalScroll" },
677 { "circular-arrow", "circularArrow" },
678 { "mso-spt100", "pie" }, // looks like MSO_SPT is wrong here
679 { "mso-spt101", "uturnArrow" },
680 { "mso-spt102", "curvedRightArrow" },
681 { "mso-spt103", "curvedLeftArrow" },
682 { "mso-spt104", "curvedUpArrow" },
683 { "mso-spt105", "curvedDownArrow" },
684 { "cloud-callout", "cloudCallout" },
685 { "mso-spt107", "ellipseRibbon" },
686 { "mso-spt108", "ellipseRibbon2" },
687 { "flowchart-process", "flowChartProcess" },
688 { "flowchart-decision", "flowChartDecision" },
689 { "flowchart-data", "flowChartInputOutput" },
690 { "flowchart-predefined-process", "flowChartPredefinedProcess" },
691 { "flowchart-internal-storage", "flowChartInternalStorage" },
692 { "flowchart-document", "flowChartDocument" },
693 { "flowchart-multidocument", "flowChartMultidocument" },
694 { "flowchart-terminator", "flowChartTerminator" },
695 { "flowchart-preparation", "flowChartPreparation" },
696 { "flowchart-manual-input", "flowChartManualInput" },
697 { "flowchart-manual-operation", "flowChartManualOperation" },
698 { "flowchart-connector", "flowChartConnector" },
699 { "flowchart-card", "flowChartPunchedCard" },
700 { "flowchart-punched-tape", "flowChartPunchedTape" },
701 { "flowchart-summing-junction", "flowChartSummingJunction" },
702 { "flowchart-or", "flowChartOr" },
703 { "flowchart-collate", "flowChartCollate" },
704 { "flowchart-sort", "flowChartSort" },
705 { "flowchart-extract", "flowChartExtract" },
706 { "flowchart-merge", "flowChartMerge" },
707 { "mso-spt129", "flowChartOfflineStorage" },
708 { "flowchart-stored-data", "flowChartOnlineStorage" },
709 { "flowchart-sequential-access", "flowChartMagneticTape" },
710 { "flowchart-magnetic-disk", "flowChartMagneticDisk" },
711 { "flowchart-direct-access-storage", "flowChartMagneticDrum" },
712 { "flowchart-display", "flowChartDisplay" },
713 { "flowchart-delay", "flowChartDelay" },
714 // { "fontwork-plain-text", "textPlainText" },
715 // { "fontwork-stop", "textStop" },
716 // { "fontwork-triangle-up", "textTriangle" },
717 // { "fontwork-triangle-down", "textTriangleInverted" },
718 // { "fontwork-chevron-up", "textChevron" },
719 // { "fontwork-chevron-down", "textChevronInverted" },
720 // { "mso-spt142", "textRingInside" },
721 // { "mso-spt143", "textRingOutside" },
722 // { "fontwork-arch-up-curve", "textArchUpCurve" },
723 // { "fontwork-arch-down-curve", "textArchDownCurve" },
724 // { "fontwork-circle-curve", "textCircleCurve" },
725 // { "fontwork-open-circle-curve", "textButtonCurve" },
726 // { "fontwork-arch-up-pour", "textArchUpPour" },
727 // { "fontwork-arch-down-pour", "textArchDownPour" },
728 // { "fontwork-circle-pour", "textCirclePour" },
729 // { "fontwork-open-circle-pour", "textButtonPour" },
730 // { "fontwork-curve-up", "textCurveUp" },
731 // { "fontwork-curve-down", "textCurveDown" },
732 // { "fontwork-fade-up-and-right", "textCascadeUp" },
733 // { "fontwork-fade-up-and-left", "textCascadeDown" },
734 // { "fontwork-wave", "textWave1" },
735 // { "mso-spt157", "textWave2" },
736 // { "mso-spt158", "textWave3" },
737 // { "mso-spt159", "textWave4" },
738 // { "fontwork-inflate", "textInflate" },
739 // { "mso-spt161", "textDeflate" },
740 // { "mso-spt162", "textInflateBottom" },
741 // { "mso-spt163", "textDeflateBottom" },
742 // { "mso-spt164", "textInflateTop" },
743 // { "mso-spt165", "textDeflateTop" },
744 // { "mso-spt166", "textDeflateInflate" },
745 // { "mso-spt167", "textDeflateInflateDeflate" },
746 // { "fontwork-fade-right", "textFadeRight" },
747 // { "fontwork-fade-left", "textFadeLeft" },
748 // { "fontwork-fade-up", "textFadeUp" },
749 // { "fontwork-fade-down", "textFadeDown" },
750 // { "fontwork-slant-up", "textSlantUp" },
751 // { "fontwork-slant-down", "textSlantDown" },
752 // { "mso-spt174", "textCanUp" },
753 // { "mso-spt175", "textCanDown" },
754 { "flowchart-alternate-process", "flowChartAlternateProcess" },
755 { "flowchart-off-page-connector", "flowChartOffpageConnector" },
756 { "mso-spt178", "callout1" },
757 { "mso-spt179", "accentCallout1" },
758 { "mso-spt180", "borderCallout1" },
759 { "mso-spt182", "leftRightUpArrow" },
760 { "sun", "sun" },
761 { "moon", "moon" },
762 { "bracket-pair", "bracketPair" },
763 { "brace-pair", "bracePair" },
764 { "star4", "star4" },
765 { "mso-spt188", "doubleWave" },
766 { "mso-spt189", "actionButtonBlank" },
767 { "mso-spt190", "actionButtonHome" },
768 { "mso-spt191", "actionButtonHelp" },
769 { "mso-spt192", "actionButtonInformation" },
770 { "mso-spt193", "actionButtonForwardNext" },
771 { "mso-spt194", "actionButtonBackPrevious" },
772 { "mso-spt195", "actionButtonEnd" },
773 { "mso-spt196", "actionButtonBeginning" },
774 { "mso-spt197", "actionButtonReturn" },
775 { "mso-spt198", "actionButtonDocument" },
776 { "mso-spt199", "actionButtonSound" },
777 { "mso-spt200", "actionButtonMovie" },
778 // { "mso-spt201", "hostControl" },
779 { "mso-spt202", "rect" },
780 { "ooxml-actionButtonSound", "actionButtonSound" },
781 { "ooxml-borderCallout1", "borderCallout1" },
782 { "ooxml-plaqueTabs", "plaqueTabs" },
783 { "ooxml-curvedLeftArrow", "curvedLeftArrow" },
784 { "ooxml-octagon", "octagon" },
785 { "ooxml-leftRightRibbon", "leftRightRibbon" },
786 { "ooxml-actionButtonInformation", "actionButtonInformation" },
787 { "ooxml-bentConnector5", "bentConnector5" },
788 { "ooxml-circularArrow", "circularArrow" },
789 { "ooxml-downArrowCallout", "downArrowCallout" },
790 { "ooxml-mathMinus", "mathMinus" },
791 { "ooxml-gear9", "gear9" },
792 { "ooxml-round1Rect", "round1Rect" },
793 { "ooxml-sun", "sun" },
794 { "ooxml-plaque", "plaque" },
795 { "ooxml-chevron", "chevron" },
796 { "ooxml-flowChartPreparation", "flowChartPreparation" },
797 { "ooxml-diagStripe", "diagStripe" },
798 { "ooxml-pentagon", "pentagon" },
799 { "ooxml-funnel", "funnel" },
800 { "ooxml-chartStar", "chartStar" },
801 { "ooxml-accentBorderCallout1", "accentBorderCallout1" },
802 { "ooxml-notchedRightArrow", "notchedRightArrow" },
803 { "ooxml-rightBracket", "rightBracket" },
804 { "ooxml-flowChartOffpageConnector", "flowChartOffpageConnector" },
805 { "ooxml-leftRightArrow", "leftRightArrow" },
806 { "ooxml-decagon", "decagon" },
807 { "ooxml-actionButtonHelp", "actionButtonHelp" },
808 { "ooxml-star24", "star24" },
809 { "ooxml-mathDivide", "mathDivide" },
810 { "ooxml-curvedConnector4", "curvedConnector4" },
811 { "ooxml-flowChartOr", "flowChartOr" },
812 { "ooxml-borderCallout3", "borderCallout3" },
813 { "ooxml-upDownArrowCallout", "upDownArrowCallout" },
814 { "ooxml-flowChartDecision", "flowChartDecision" },
815 { "ooxml-leftRightArrowCallout", "leftRightArrowCallout" },
816 { "ooxml-flowChartManualOperation", "flowChartManualOperation" },
817 { "ooxml-snipRoundRect", "snipRoundRect" },
818 { "ooxml-mathPlus", "mathPlus" },
819 { "ooxml-actionButtonForwardNext", "actionButtonForwardNext" },
820 { "ooxml-can", "can" },
821 { "ooxml-foldedCorner", "foldedCorner" },
822 { "ooxml-star32", "star32" },
823 { "ooxml-flowChartInternalStorage", "flowChartInternalStorage" },
824 { "ooxml-upDownArrow", "upDownArrow" },
825 { "ooxml-irregularSeal2", "irregularSeal2" },
826 { "ooxml-mathEqual", "mathEqual" },
827 { "ooxml-star12", "star12" },
828 { "ooxml-uturnArrow", "uturnArrow" },
829 { "ooxml-squareTabs", "squareTabs" },
830 { "ooxml-leftRightUpArrow", "leftRightUpArrow" },
831 { "ooxml-homePlate", "homePlate" },
832 { "ooxml-dodecagon", "dodecagon" },
833 { "ooxml-leftArrowCallout", "leftArrowCallout" },
834 { "ooxml-chord", "chord" },
835 { "ooxml-quadArrowCallout", "quadArrowCallout" },
836 { "ooxml-actionButtonBeginning", "actionButtonBeginning" },
837 { "ooxml-ellipse", "ellipse" },
838 { "ooxml-actionButtonEnd", "actionButtonEnd" },
839 { "ooxml-arc", "arc" },
840 { "ooxml-star16", "star16" },
841 { "ooxml-parallelogram", "parallelogram" },
842 { "ooxml-bevel", "bevel" },
843 { "ooxml-roundRect", "roundRect" },
844 { "ooxml-accentCallout1", "accentCallout1" },
845 { "ooxml-flowChartSort", "flowChartSort" },
846 { "ooxml-star8", "star8" },
847 { "ooxml-flowChartAlternateProcess", "flowChartAlternateProcess" },
848 { "ooxml-moon", "moon" },
849 { "ooxml-star6", "star6" },
850 { "ooxml-round2SameRect", "round2SameRect" },
851 { "ooxml-nonIsoscelesTrapezoid", "nonIsoscelesTrapezoid" },
852 { "ooxml-diamond", "diamond" },
853 { "ooxml-ellipseRibbon", "ellipseRibbon" },
854 { "ooxml-callout2", "callout2" },
855 { "ooxml-pie", "pie" },
856 { "ooxml-star4", "star4" },
857 { "ooxml-flowChartPredefinedProcess", "flowChartPredefinedProcess" },
858 { "ooxml-flowChartPunchedTape", "flowChartPunchedTape" },
859 { "ooxml-curvedConnector2", "curvedConnector2" },
860 { "ooxml-bentConnector3", "bentConnector3" },
861 { "ooxml-cornerTabs", "cornerTabs" },
862 { "ooxml-hexagon", "hexagon" },
863 { "ooxml-flowChartConnector", "flowChartConnector" },
864 { "ooxml-flowChartMagneticDisk", "flowChartMagneticDisk" },
865 { "ooxml-heart", "heart" },
866 { "ooxml-ribbon2", "ribbon2" },
867 { "ooxml-bracePair", "bracePair" },
868 { "ooxml-flowChartExtract", "flowChartExtract" },
869 { "ooxml-actionButtonHome", "actionButtonHome" },
870 { "ooxml-accentBorderCallout3", "accentBorderCallout3" },
871 { "ooxml-flowChartOfflineStorage", "flowChartOfflineStorage" },
872 { "ooxml-irregularSeal1", "irregularSeal1" },
873 { "ooxml-quadArrow", "quadArrow" },
874 { "ooxml-leftBrace", "leftBrace" },
875 { "ooxml-leftBracket", "leftBracket" },
876 { "ooxml-blockArc", "blockArc" },
877 { "ooxml-curvedConnector3", "curvedConnector3" },
878 { "ooxml-wedgeRoundRectCallout", "wedgeRoundRectCallout" },
879 { "ooxml-actionButtonMovie", "actionButtonMovie" },
880 { "ooxml-flowChartOnlineStorage", "flowChartOnlineStorage" },
881 { "ooxml-gear6", "gear6" },
882 { "ooxml-halfFrame", "halfFrame" },
883 { "ooxml-snip2SameRect", "snip2SameRect" },
884 { "ooxml-triangle", "triangle" },
885 { "ooxml-teardrop", "teardrop" },
886 { "ooxml-flowChartDocument", "flowChartDocument" },
887 { "ooxml-rightArrowCallout", "rightArrowCallout" },
888 { "ooxml-rightBrace", "rightBrace" },
889 { "ooxml-chartPlus", "chartPlus" },
890 { "ooxml-flowChartManualInput", "flowChartManualInput" },
891 { "ooxml-flowChartMerge", "flowChartMerge" },
892 { "ooxml-line", "line" },
893 { "ooxml-downArrow", "downArrow" },
894 { "ooxml-upArrow", "upArrow" },
895 { "ooxml-curvedDownArrow", "curvedDownArrow" },
896 { "ooxml-actionButtonReturn", "actionButtonReturn" },
897 { "ooxml-flowChartInputOutput", "flowChartInputOutput" },
898 { "ooxml-bracketPair", "bracketPair" },
899 { "ooxml-smileyFace", "smileyFace" },
900 { "ooxml-actionButtonBlank", "actionButtonBlank" },
901 { "ooxml-wave", "wave" },
902 { "ooxml-swooshArrow", "swooshArrow" },
903 { "ooxml-flowChartSummingJunction", "flowChartSummingJunction" },
904 { "ooxml-lightningBolt", "lightningBolt" },
905 { "ooxml-flowChartDisplay", "flowChartDisplay" },
906 { "ooxml-actionButtonBackPrevious", "actionButtonBackPrevious" },
907 { "ooxml-frame", "frame" },
908 { "ooxml-rtTriangle", "rtTriangle" },
909 { "ooxml-flowChartMagneticTape", "flowChartMagneticTape" },
910 { "ooxml-curvedRightArrow", "curvedRightArrow" },
911 { "ooxml-leftUpArrow", "leftUpArrow" },
912 { "ooxml-wedgeEllipseCallout", "wedgeEllipseCallout" },
913 { "ooxml-doubleWave", "doubleWave" },
914 { "ooxml-bentArrow", "bentArrow" },
915 { "ooxml-star10", "star10" },
916 { "ooxml-leftArrow", "leftArrow" },
917 { "ooxml-curvedUpArrow", "curvedUpArrow" },
918 { "ooxml-snip1Rect", "snip1Rect" },
919 { "ooxml-ellipseRibbon2", "ellipseRibbon2" },
920 { "ooxml-plus", "plus" },
921 { "ooxml-accentCallout3", "accentCallout3" },
922 { "ooxml-leftCircularArrow", "leftCircularArrow" },
923 { "ooxml-rightArrow", "rightArrow" },
924 { "ooxml-flowChartPunchedCard", "flowChartPunchedCard" },
925 { "ooxml-snip2DiagRect", "snip2DiagRect" },
926 { "ooxml-verticalScroll", "verticalScroll" },
927 { "ooxml-star7", "star7" },
928 { "ooxml-chartX", "chartX" },
929 { "ooxml-cloud", "cloud" },
930 { "ooxml-cube", "cube" },
931 { "ooxml-round2DiagRect", "round2DiagRect" },
932 { "ooxml-flowChartMultidocument", "flowChartMultidocument" },
933 { "ooxml-actionButtonDocument", "actionButtonDocument" },
934 { "ooxml-flowChartTerminator", "flowChartTerminator" },
935 { "ooxml-flowChartDelay", "flowChartDelay" },
936 { "ooxml-curvedConnector5", "curvedConnector5" },
937 { "ooxml-horizontalScroll", "horizontalScroll" },
938 { "ooxml-bentConnector4", "bentConnector4" },
939 { "ooxml-leftRightCircularArrow", "leftRightCircularArrow" },
940 { "ooxml-wedgeRectCallout", "wedgeRectCallout" },
941 { "ooxml-accentCallout2", "accentCallout2" },
942 { "ooxml-flowChartMagneticDrum", "flowChartMagneticDrum" },
943 { "ooxml-corner", "corner" },
944 { "ooxml-borderCallout2", "borderCallout2" },
945 { "ooxml-donut", "donut" },
946 { "ooxml-flowChartCollate", "flowChartCollate" },
947 { "ooxml-mathNotEqual", "mathNotEqual" },
948 { "ooxml-bentConnector2", "bentConnector2" },
949 { "ooxml-mathMultiply", "mathMultiply" },
950 { "ooxml-heptagon", "heptagon" },
951 { "ooxml-rect", "rect" },
952 { "ooxml-accentBorderCallout2", "accentBorderCallout2" },
953 { "ooxml-pieWedge", "pieWedge" },
954 { "ooxml-upArrowCallout", "upArrowCallout" },
955 { "ooxml-flowChartProcess", "flowChartProcess" },
956 { "ooxml-star5", "star5" },
957 { "ooxml-lineInv", "lineInv" },
958 { "ooxml-straightConnector1", "straightConnector1" },
959 { "ooxml-stripedRightArrow", "stripedRightArrow" },
960 { "ooxml-callout3", "callout3" },
961 { "ooxml-bentUpArrow", "bentUpArrow" },
962 { "ooxml-noSmoking", "noSmoking" },
963 { "ooxml-trapezoid", "trapezoid" },
964 { "ooxml-cloudCallout", "cloudCallout" },
965 { "ooxml-callout1", "callout1" },
966 { "ooxml-ribbon", "ribbon" },
967 { "ooxml-rect", "rect" },
970 static struct {
971 const char* sDML;
972 MSO_SPT nVML;
973 } const pDMLToVMLTable[] = {
974 {"notPrimitive", mso_sptNotPrimitive},
975 {"rectangle", mso_sptRectangle},
976 {"roundRectangle", mso_sptRoundRectangle},
977 {"ellipse", mso_sptEllipse},
978 {"diamond", mso_sptDiamond},
979 {"triangle", mso_sptIsocelesTriangle},
980 {"rtTriangle", mso_sptRightTriangle},
981 {"parallelogram", mso_sptParallelogram},
982 {"trapezoid", mso_sptTrapezoid},
983 {"hexagon", mso_sptHexagon},
984 {"octagon", mso_sptOctagon},
985 {"plus", mso_sptPlus},
986 {"star5", mso_sptStar},
987 {"rightArrow", mso_sptArrow},
988 {"thickArrow", mso_sptThickArrow},
989 {"homePlate", mso_sptHomePlate},
990 {"cube", mso_sptCube},
991 {"wedgeRoundRectCallout", mso_sptBalloon},
992 {"star16", mso_sptSeal},
993 {"arc", mso_sptArc},
994 {"line", mso_sptLine},
995 {"plaque", mso_sptPlaque},
996 {"can", mso_sptCan},
997 {"donut", mso_sptDonut},
998 {"textPlain", mso_sptTextSimple},
999 {"textStop", mso_sptTextOctagon},
1000 {"textTriangle", mso_sptTextHexagon},
1001 {"textCanDown", mso_sptTextCurve},
1002 {"textWave1", mso_sptTextWave},
1003 {"textArchUpPour", mso_sptTextRing},
1004 {"textCanDown", mso_sptTextOnCurve},
1005 {"textArchUp", mso_sptTextOnRing},
1006 {"straightConnector1", mso_sptStraightConnector1},
1007 {"bentConnector2", mso_sptBentConnector2},
1008 {"bentConnector3", mso_sptBentConnector3},
1009 {"bentConnector4", mso_sptBentConnector4},
1010 {"bentConnector5", mso_sptBentConnector5},
1011 {"curvedConnector2", mso_sptCurvedConnector2},
1012 {"curvedConnector3", mso_sptCurvedConnector3},
1013 {"curvedConnector4", mso_sptCurvedConnector4},
1014 {"curvedConnector5", mso_sptCurvedConnector5},
1015 {"callout1", mso_sptCallout1},
1016 {"callout2", mso_sptCallout2},
1017 {"callout3", mso_sptCallout3},
1018 {"accentCallout1", mso_sptAccentCallout1},
1019 {"accentCallout2", mso_sptAccentCallout2},
1020 {"accentCallout3", mso_sptAccentCallout3},
1021 {"borderCallout1", mso_sptBorderCallout1},
1022 {"borderCallout2", mso_sptBorderCallout2},
1023 {"borderCallout3", mso_sptBorderCallout3},
1024 {"accentBorderCallout1", mso_sptAccentBorderCallout1},
1025 {"accentBorderCallout2", mso_sptAccentBorderCallout2},
1026 {"accentBorderCallout3", mso_sptAccentBorderCallout3},
1027 {"ribbon", mso_sptRibbon},
1028 {"ribbon2", mso_sptRibbon2},
1029 {"chevron", mso_sptChevron},
1030 {"pentagon", mso_sptPentagon},
1031 {"noSmoking", mso_sptNoSmoking},
1032 {"star8", mso_sptSeal8},
1033 {"star16", mso_sptSeal16},
1034 {"star32", mso_sptSeal32},
1035 {"wedgeRectCallout", mso_sptWedgeRectCallout},
1036 {"wedgeRoundRectCallout", mso_sptWedgeRRectCallout},
1037 {"wedgeEllipseCallout", mso_sptWedgeEllipseCallout},
1038 {"wave", mso_sptWave},
1039 {"foldedCorner", mso_sptFoldedCorner},
1040 {"leftArrow", mso_sptLeftArrow},
1041 {"downArrow", mso_sptDownArrow},
1042 {"upArrow", mso_sptUpArrow},
1043 {"leftRightArrow", mso_sptLeftRightArrow},
1044 {"upDownArrow", mso_sptUpDownArrow},
1045 {"irregularSeal1", mso_sptIrregularSeal1},
1046 {"irregularSeal2", mso_sptIrregularSeal2},
1047 {"lightningBolt", mso_sptLightningBolt},
1048 {"heart", mso_sptHeart},
1049 {"pictureFrame", mso_sptPictureFrame},
1050 {"quadArrow", mso_sptQuadArrow},
1051 {"leftArrowCallout", mso_sptLeftArrowCallout},
1052 {"rightArrowCallout", mso_sptRightArrowCallout},
1053 {"upArrowCallout", mso_sptUpArrowCallout},
1054 {"downArrowCallout", mso_sptDownArrowCallout},
1055 {"leftRightArrowCallout", mso_sptLeftRightArrowCallout},
1056 {"upDownArrowCallout", mso_sptUpDownArrowCallout},
1057 {"quadArrowCallout", mso_sptQuadArrowCallout},
1058 {"bevel", mso_sptBevel},
1059 {"leftBracket", mso_sptLeftBracket},
1060 {"rightBracket", mso_sptRightBracket},
1061 {"leftBrace", mso_sptLeftBrace},
1062 {"rightBrace", mso_sptRightBrace},
1063 {"leftUpArrow", mso_sptLeftUpArrow},
1064 {"bentUpArrow", mso_sptBentUpArrow},
1065 {"bentArrow", mso_sptBentArrow},
1066 {"star24", mso_sptSeal24},
1067 {"stripedRightArrow", mso_sptStripedRightArrow},
1068 {"notchedRightArrow", mso_sptNotchedRightArrow},
1069 {"blockArc", mso_sptBlockArc},
1070 {"smileyFace", mso_sptSmileyFace},
1071 {"verticalScroll", mso_sptVerticalScroll},
1072 {"horizontalScroll", mso_sptHorizontalScroll},
1073 {"circularArrow", mso_sptCircularArrow},
1074 {"notchedCircularArrow", mso_sptNotchedCircularArrow},
1075 {"uturnArrow", mso_sptUturnArrow},
1076 {"curvedRightArrow", mso_sptCurvedRightArrow},
1077 {"curvedLeftArrow", mso_sptCurvedLeftArrow},
1078 {"curvedUpArrow", mso_sptCurvedUpArrow},
1079 {"curvedDownArrow", mso_sptCurvedDownArrow},
1080 {"cloudCallout", mso_sptCloudCallout},
1081 {"ellipseRibbon", mso_sptEllipseRibbon},
1082 {"ellipseRibbon2", mso_sptEllipseRibbon2},
1083 {"flowChartProcess", mso_sptFlowChartProcess},
1084 {"flowChartDecision", mso_sptFlowChartDecision},
1085 {"flowChartInputOutput", mso_sptFlowChartInputOutput},
1086 {"flowChartPredefinedProcess", mso_sptFlowChartPredefinedProcess},
1087 {"flowChartInternalStorage", mso_sptFlowChartInternalStorage},
1088 {"flowChartDocument", mso_sptFlowChartDocument},
1089 {"flowChartMultidocument", mso_sptFlowChartMultidocument},
1090 {"flowChartTerminator", mso_sptFlowChartTerminator},
1091 {"flowChartPreparation", mso_sptFlowChartPreparation},
1092 {"flowChartManualInput", mso_sptFlowChartManualInput},
1093 {"flowChartManualOperation", mso_sptFlowChartManualOperation},
1094 {"flowChartConnector", mso_sptFlowChartConnector},
1095 {"flowChartPunchedCard", mso_sptFlowChartPunchedCard},
1096 {"flowChartPunchedTape", mso_sptFlowChartPunchedTape},
1097 {"flowChartSummingJunction", mso_sptFlowChartSummingJunction},
1098 {"flowChartOr", mso_sptFlowChartOr},
1099 {"flowChartCollate", mso_sptFlowChartCollate},
1100 {"flowChartSort", mso_sptFlowChartSort},
1101 {"flowChartExtract", mso_sptFlowChartExtract},
1102 {"flowChartMerge", mso_sptFlowChartMerge},
1103 {"flowChartOfflineStorage", mso_sptFlowChartOfflineStorage},
1104 {"flowChartOnlineStorage", mso_sptFlowChartOnlineStorage},
1105 {"flowChartMagneticTape", mso_sptFlowChartMagneticTape},
1106 {"flowChartMagneticDisk", mso_sptFlowChartMagneticDisk},
1107 {"flowChartMagneticDrum", mso_sptFlowChartMagneticDrum},
1108 {"flowChartDisplay", mso_sptFlowChartDisplay},
1109 {"flowChartDelay", mso_sptFlowChartDelay},
1110 {"textPlain", mso_sptTextPlainText},
1111 {"textStop", mso_sptTextStop},
1112 {"textTriangle", mso_sptTextTriangle},
1113 {"textTriangleInverted", mso_sptTextTriangleInverted},
1114 {"textChevron", mso_sptTextChevron},
1115 {"textChevronInverted", mso_sptTextChevronInverted},
1116 {"textRingInside", mso_sptTextRingInside},
1117 {"textRingOutside", mso_sptTextRingOutside},
1118 {"textArchUp", mso_sptTextArchUpCurve},
1119 {"textArchDown", mso_sptTextArchDownCurve},
1120 {"textCircle", mso_sptTextCircleCurve},
1121 {"textButton", mso_sptTextButtonCurve},
1122 {"textArchUpPour", mso_sptTextArchUpPour},
1123 {"textArchDownPour", mso_sptTextArchDownPour},
1124 {"textCirclePour", mso_sptTextCirclePour},
1125 {"textButtonPour", mso_sptTextButtonPour},
1126 {"textCurveUp", mso_sptTextCurveUp},
1127 {"textCurveDown", mso_sptTextCurveDown},
1128 {"textCascadeUp", mso_sptTextCascadeUp},
1129 {"textCascadeDown", mso_sptTextCascadeDown},
1130 {"textWave1", mso_sptTextWave1},
1131 {"textWave2", mso_sptTextWave2},
1132 {"textWave3", mso_sptTextWave3},
1133 {"textWave4", mso_sptTextWave4},
1134 {"textInflate", mso_sptTextInflate},
1135 {"textDeflate", mso_sptTextDeflate},
1136 {"textInflateBottom", mso_sptTextInflateBottom},
1137 {"textDeflateBottom", mso_sptTextDeflateBottom},
1138 {"textInflateTop", mso_sptTextInflateTop},
1139 {"textDeflateTop", mso_sptTextDeflateTop},
1140 {"textDeflateInflate", mso_sptTextDeflateInflate},
1141 {"textDeflateInflateDeflate", mso_sptTextDeflateInflateDeflate},
1142 {"textFadeRight", mso_sptTextFadeRight},
1143 {"textFadeLeft", mso_sptTextFadeLeft},
1144 {"textFadeUp", mso_sptTextFadeUp},
1145 {"textFadeDown", mso_sptTextFadeDown},
1146 {"textSlantUp", mso_sptTextSlantUp},
1147 {"textSlantDown", mso_sptTextSlantDown},
1148 {"textCanUp", mso_sptTextCanUp},
1149 {"textCanDown", mso_sptTextCanDown},
1150 {"flowChartAlternateProcess", mso_sptFlowChartAlternateProcess},
1151 {"flowChartOffpageConnector", mso_sptFlowChartOffpageConnector},
1152 {"callout1", mso_sptCallout90},
1153 {"accentCallout1", mso_sptAccentCallout90},
1154 {"borderCallout1", mso_sptBorderCallout90},
1155 {"accentBorderCallout1", mso_sptAccentBorderCallout90},
1156 {"leftRightUpArrow", mso_sptLeftRightUpArrow},
1157 {"sun", mso_sptSun},
1158 {"moon", mso_sptMoon},
1159 {"bracketPair", mso_sptBracketPair},
1160 {"bracePair", mso_sptBracePair},
1161 {"star4", mso_sptSeal4},
1162 {"doubleWave", mso_sptDoubleWave},
1163 {"actionButtonBlank", mso_sptActionButtonBlank},
1164 {"actionButtonHome", mso_sptActionButtonHome},
1165 {"actionButtonHelp", mso_sptActionButtonHelp},
1166 {"actionButtonInformation", mso_sptActionButtonInformation},
1167 {"actionButtonForwardNext", mso_sptActionButtonForwardNext},
1168 {"actionButtonBackPrevious", mso_sptActionButtonBackPrevious},
1169 {"actionButtonEnd", mso_sptActionButtonEnd},
1170 {"actionButtonBeginning", mso_sptActionButtonBeginning},
1171 {"actionButtonReturn", mso_sptActionButtonReturn},
1172 {"actionButtonDocument", mso_sptActionButtonDocument},
1173 {"actionButtonSound", mso_sptActionButtonSound},
1174 {"actionButtonMovie", mso_sptActionButtonMovie},
1175 {"hostControl", mso_sptHostControl},
1176 {"textBox", mso_sptTextBox},
1179 typedef std::unordered_map< const char*, const char*, rtl::CStringHash, rtl::CStringEqual> CustomShapeTypeTranslationHashMap;
1180 static CustomShapeTypeTranslationHashMap* pCustomShapeTypeTranslationHashMap = nullptr;
1182 const char* GetOOXMLPresetGeometry( const char* sShapeType )
1184 if( pCustomShapeTypeTranslationHashMap == nullptr )
1186 pCustomShapeTypeTranslationHashMap = new CustomShapeTypeTranslationHashMap ();
1187 for(const msfilter::util::CustomShapeTypeTranslationTable& i : pCustomShapeTypeTranslationTable)
1189 (*pCustomShapeTypeTranslationHashMap)[ i.sOOo ] = i.sMSO;
1192 CustomShapeTypeTranslationHashMap::iterator i(
1193 pCustomShapeTypeTranslationHashMap->find(sShapeType));
1194 return i == pCustomShapeTypeTranslationHashMap->end() ? "rect" : i->second;
1197 typedef std::unordered_map< const char*, MSO_SPT, rtl::CStringHash, rtl::CStringEqual> DMLToVMLTranslationHashMap;
1198 static DMLToVMLTranslationHashMap* pDMLToVMLMap;
1200 MSO_SPT GETVMLShapeType(const OString& aType)
1202 const char* pDML = GetOOXMLPresetGeometry(aType.getStr());
1204 if (!pDMLToVMLMap)
1206 pDMLToVMLMap = new DMLToVMLTranslationHashMap();
1207 for (auto& i : pDMLToVMLTable)
1208 (*pDMLToVMLMap)[i.sDML] = i.nVML;
1211 DMLToVMLTranslationHashMap::iterator i(pDMLToVMLMap->find(pDML));
1212 return i == pDMLToVMLMap->end() ? mso_sptNil : i->second;
1215 bool HasTextBoxContent(sal_uInt32 nShapeType)
1217 switch (nShapeType)
1219 case ESCHER_ShpInst_TextPlainText:
1220 case ESCHER_ShpInst_TextSlantUp:
1221 case ESCHER_ShpInst_TextDeflateInflateDeflate:
1222 return false;
1223 default:
1224 return true;
1228 namespace
1231 // Scheme means pattern of chromatic values.
1232 // [2,2,1] -> red and green are approximately equal and blue is the dominant color (e.g. blue)
1233 // [1,1,1] -> all chromatic values are approximately equal (e.g. white, gray, black)
1234 void CalculateScheme(const BitmapColor& rBitmapColor, std::vector<int> &vScheme, sal_uInt16 nVariance)
1236 vScheme.resize(3,1);
1237 if( rBitmapColor.GetRed() < rBitmapColor.GetGreen() + nVariance )
1238 ++vScheme[0];
1239 if( rBitmapColor.GetRed() < rBitmapColor.GetBlue() + nVariance )
1240 ++vScheme[0];
1241 if( rBitmapColor.GetGreen() < rBitmapColor.GetRed() + nVariance )
1242 ++vScheme[1];
1243 if( rBitmapColor.GetGreen() < rBitmapColor.GetBlue() + nVariance )
1244 ++vScheme[1];
1245 if( rBitmapColor.GetBlue() < rBitmapColor.GetRed() + nVariance )
1246 ++vScheme[2];
1247 if( rBitmapColor.GetBlue() < rBitmapColor.GetGreen() + nVariance )
1248 ++vScheme[2];
1251 bool HasSimilarScheme(const BitmapColor& rBitmapColor1, const BitmapColor& rBitmapColor2, sal_uInt16 nVariance)
1253 std::vector<int> vScheme1, vScheme2;
1254 CalculateScheme(rBitmapColor1, vScheme1, nVariance);
1255 CalculateScheme(rBitmapColor2, vScheme2, nVariance);
1256 for( int i = 0; i < 3; ++i )
1258 if( vScheme1[i] != vScheme2[i] )
1259 return false;
1261 return true;
1264 // Find the best match in the color palette using scheme of the input color
1265 sal_uInt16 GetBestIndex(const BitmapPalette& rPalette, const BitmapColor& rBitmapColor)
1267 sal_uInt16 nReturn = 0;
1268 sal_uInt16 nLastErr = SAL_MAX_UINT16;
1269 bool bFound = false;
1271 // Prefer those colors which have similar scheme as the input
1272 // Allow bigger and bigger variance of the schemes until we find
1273 // a color in the palette with similar scheme.
1274 for( sal_uInt16 nVariance = 0; nVariance <= 255; ++nVariance )
1276 for( sal_uInt16 i = 0; i < rPalette.GetEntryCount(); ++i )
1278 if( HasSimilarScheme(rBitmapColor, rPalette[i], nVariance) )
1280 const sal_uInt16 nActErr = rBitmapColor.GetColorError( rPalette[i] );
1281 if( nActErr < nLastErr )
1283 nLastErr = nActErr;
1284 nReturn = i;
1285 bFound = true;
1289 if( bFound )
1290 return nReturn;
1292 return nReturn;
1296 sal_uInt8 TransColToIco( const Color& rCol )
1298 sal_uInt8 nCol = 0; // ->Auto
1299 switch( rCol.GetColor() )
1301 case COL_BLACK: nCol = 1; break;
1302 case COL_BLUE: nCol = 9; break;
1303 case COL_GREEN: nCol = 11; break;
1304 case COL_CYAN: nCol = 10; break;
1305 case COL_RED: nCol = 13; break;
1306 case COL_MAGENTA: nCol = 12; break;
1307 case COL_BROWN: nCol = 14; break;
1308 case COL_GRAY: nCol = 15; break;
1309 case COL_LIGHTGRAY: nCol = 16; break;
1310 case COL_LIGHTBLUE: nCol = 2; break;
1311 case COL_LIGHTGREEN: nCol = 4; break;
1312 case COL_LIGHTCYAN: nCol = 3; break;
1313 case COL_LIGHTRED: nCol = 6; break;
1314 case COL_LIGHTMAGENTA: nCol = 5; break;
1315 case COL_YELLOW: nCol = 7; break;
1316 case COL_WHITE: nCol = 8; break;
1317 case COL_AUTO: nCol = 0; break;
1319 default:
1320 static const ColorData aColArr[ 16 ] = {
1321 COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
1322 COL_LIGHTMAGENTA,COL_LIGHTRED, COL_YELLOW, COL_WHITE,
1323 COL_BLUE, COL_CYAN, COL_GREEN, COL_MAGENTA,
1324 COL_RED, COL_BROWN, COL_GRAY, COL_LIGHTGRAY
1326 BitmapPalette aBmpPal(16);
1327 for( sal_uInt16 i = 0; i < 16; ++i )
1328 aBmpPal[i] = Color( aColArr[ i ] );
1330 nCol = static_cast< sal_uInt8 >(GetBestIndex(aBmpPal, rCol) + 1);
1331 break;
1333 return nCol;
1339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */