LibreOffice Module writerfilter (master) 1
ConversionHelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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#include "ConversionHelper.hxx"
20#include <com/sun/star/table/BorderLine2.hpp>
21#include <com/sun/star/lang/Locale.hpp>
22#include <com/sun/star/text/HoriOrientation.hpp>
23#include <com/sun/star/style/NumberingType.hpp>
25#include <ooxml/resourceids.hxx>
26#include <rtl/ustrbuf.hxx>
27#include <tools/color.hxx>
28#include <tools/mapunit.hxx>
30#include <o3tl/string_view.hxx>
31
32using namespace com::sun::star;
33
35
37static sal_Int32 lcl_convertBorderStyleFromToken(sal_Int32 nOOXMLType)
38{
39 switch (nOOXMLType)
40 {
41 case NS_ooxml::LN_Value_ST_Border_nil: return 255;
42 case NS_ooxml::LN_Value_ST_Border_none: return 0;
43 case NS_ooxml::LN_Value_ST_Border_single: return 1;
44 case NS_ooxml::LN_Value_ST_Border_thick: return 2;
45 case NS_ooxml::LN_Value_ST_Border_double: return 3;
46 case NS_ooxml::LN_Value_ST_Border_dotted: return 6;
47 case NS_ooxml::LN_Value_ST_Border_dashed: return 7;
48 case NS_ooxml::LN_Value_ST_Border_dotDash: return 8;
49 case NS_ooxml::LN_Value_ST_Border_dotDotDash: return 9;
50 case NS_ooxml::LN_Value_ST_Border_triple: return 10;
51 case NS_ooxml::LN_Value_ST_Border_thinThickSmallGap: return 11;
52 case NS_ooxml::LN_Value_ST_Border_thickThinSmallGap: return 12;
53 case NS_ooxml::LN_Value_ST_Border_thinThickThinSmallGap: return 13;
54 case NS_ooxml::LN_Value_ST_Border_thinThickMediumGap: return 14;
55 case NS_ooxml::LN_Value_ST_Border_thickThinMediumGap: return 15;
56 case NS_ooxml::LN_Value_ST_Border_thinThickThinMediumGap: return 16;
57 case NS_ooxml::LN_Value_ST_Border_thinThickLargeGap: return 17;
58 case NS_ooxml::LN_Value_ST_Border_thickThinLargeGap: return 18;
59 case NS_ooxml::LN_Value_ST_Border_thinThickThinLargeGap: return 19;
60 case NS_ooxml::LN_Value_ST_Border_wave: return 20;
61 case NS_ooxml::LN_Value_ST_Border_doubleWave: return 21;
62 case NS_ooxml::LN_Value_ST_Border_dashSmallGap: return 22;
63 case NS_ooxml::LN_Value_ST_Border_dashDotStroked: return 23;
64 case NS_ooxml::LN_Value_ST_Border_threeDEmboss: return 24;
65 case NS_ooxml::LN_Value_ST_Border_threeDEngrave: return 25;
66 case NS_ooxml::LN_Value_ST_Border_outset: return 26;
67 case NS_ooxml::LN_Value_ST_Border_inset: return 27;
68 case NS_ooxml::LN_Value_ST_Border_apples: return 64;
69 case NS_ooxml::LN_Value_ST_Border_archedScallops: return 65;
70 case NS_ooxml::LN_Value_ST_Border_babyPacifier: return 66;
71 case NS_ooxml::LN_Value_ST_Border_babyRattle: return 67;
72 case NS_ooxml::LN_Value_ST_Border_balloons3Colors: return 68;
73 case NS_ooxml::LN_Value_ST_Border_balloonsHotAir: return 69;
74 case NS_ooxml::LN_Value_ST_Border_basicBlackDashes: return 70;
75 case NS_ooxml::LN_Value_ST_Border_basicBlackDots: return 71;
76 case NS_ooxml::LN_Value_ST_Border_basicBlackSquares: return 72;
77 case NS_ooxml::LN_Value_ST_Border_basicThinLines: return 73;
78 case NS_ooxml::LN_Value_ST_Border_basicWhiteDashes: return 74;
79 case NS_ooxml::LN_Value_ST_Border_basicWhiteDots: return 75;
80 case NS_ooxml::LN_Value_ST_Border_basicWhiteSquares: return 76;
81 case NS_ooxml::LN_Value_ST_Border_basicWideInline: return 77;
82 case NS_ooxml::LN_Value_ST_Border_basicWideMidline: return 78;
83 case NS_ooxml::LN_Value_ST_Border_basicWideOutline: return 79;
84 case NS_ooxml::LN_Value_ST_Border_bats: return 80;
85 case NS_ooxml::LN_Value_ST_Border_birds: return 81;
86 case NS_ooxml::LN_Value_ST_Border_birdsFlight: return 82;
87 case NS_ooxml::LN_Value_ST_Border_cabins: return 83;
88 case NS_ooxml::LN_Value_ST_Border_cakeSlice: return 84;
89 case NS_ooxml::LN_Value_ST_Border_candyCorn: return 85;
90 case NS_ooxml::LN_Value_ST_Border_celticKnotwork: return 86;
91 case NS_ooxml::LN_Value_ST_Border_certificateBanner: return 87;
92 case NS_ooxml::LN_Value_ST_Border_chainLink: return 88;
93 case NS_ooxml::LN_Value_ST_Border_champagneBottle: return 89;
94 case NS_ooxml::LN_Value_ST_Border_checkedBarBlack: return 90;
95 case NS_ooxml::LN_Value_ST_Border_checkedBarColor: return 91;
96 case NS_ooxml::LN_Value_ST_Border_checkered: return 92;
97 case NS_ooxml::LN_Value_ST_Border_christmasTree: return 93;
98 case NS_ooxml::LN_Value_ST_Border_circlesLines: return 94;
99 case NS_ooxml::LN_Value_ST_Border_circlesRectangles: return 95;
100 case NS_ooxml::LN_Value_ST_Border_classicalWave: return 96;
101 case NS_ooxml::LN_Value_ST_Border_clocks: return 97;
102 case NS_ooxml::LN_Value_ST_Border_compass: return 98;
103 case NS_ooxml::LN_Value_ST_Border_confetti: return 99;
104 case NS_ooxml::LN_Value_ST_Border_confettiGrays: return 100;
105 case NS_ooxml::LN_Value_ST_Border_confettiOutline: return 101;
106 case NS_ooxml::LN_Value_ST_Border_confettiStreamers: return 102;
107 case NS_ooxml::LN_Value_ST_Border_confettiWhite: return 103;
108 case NS_ooxml::LN_Value_ST_Border_cornerTriangles: return 104;
109 case NS_ooxml::LN_Value_ST_Border_couponCutoutDashes: return 105;
110 case NS_ooxml::LN_Value_ST_Border_couponCutoutDots: return 106;
111 case NS_ooxml::LN_Value_ST_Border_crazyMaze: return 107;
112 case NS_ooxml::LN_Value_ST_Border_creaturesButterfly: return 108;
113 case NS_ooxml::LN_Value_ST_Border_creaturesFish: return 109;
114 case NS_ooxml::LN_Value_ST_Border_creaturesInsects: return 110;
115 case NS_ooxml::LN_Value_ST_Border_creaturesLadyBug: return 111;
116 case NS_ooxml::LN_Value_ST_Border_crossStitch: return 112;
117 case NS_ooxml::LN_Value_ST_Border_cup: return 113;
118 case NS_ooxml::LN_Value_ST_Border_decoArch: return 114;
119 case NS_ooxml::LN_Value_ST_Border_decoArchColor: return 115;
120 case NS_ooxml::LN_Value_ST_Border_decoBlocks: return 116;
121 case NS_ooxml::LN_Value_ST_Border_diamondsGray: return 117;
122 case NS_ooxml::LN_Value_ST_Border_doubleD: return 118;
123 case NS_ooxml::LN_Value_ST_Border_doubleDiamonds: return 119;
124 case NS_ooxml::LN_Value_ST_Border_earth1: return 120;
125 case NS_ooxml::LN_Value_ST_Border_earth2: return 121;
126 case NS_ooxml::LN_Value_ST_Border_eclipsingSquares1: return 122;
127 case NS_ooxml::LN_Value_ST_Border_eclipsingSquares2: return 123;
128 case NS_ooxml::LN_Value_ST_Border_eggsBlack: return 124;
129 case NS_ooxml::LN_Value_ST_Border_fans: return 125;
130 case NS_ooxml::LN_Value_ST_Border_film: return 126;
131 case NS_ooxml::LN_Value_ST_Border_firecrackers: return 127;
132 case NS_ooxml::LN_Value_ST_Border_flowersBlockPrint: return 128;
133 case NS_ooxml::LN_Value_ST_Border_flowersDaisies: return 129;
134 case NS_ooxml::LN_Value_ST_Border_flowersModern1: return 130;
135 case NS_ooxml::LN_Value_ST_Border_flowersModern2: return 131;
136 case NS_ooxml::LN_Value_ST_Border_flowersPansy: return 132;
137 case NS_ooxml::LN_Value_ST_Border_flowersRedRose: return 133;
138 case NS_ooxml::LN_Value_ST_Border_flowersRoses: return 134;
139 case NS_ooxml::LN_Value_ST_Border_flowersTeacup: return 135;
140 case NS_ooxml::LN_Value_ST_Border_flowersTiny: return 136;
141 case NS_ooxml::LN_Value_ST_Border_gems: return 137;
142 case NS_ooxml::LN_Value_ST_Border_gingerbreadMan: return 138;
143 case NS_ooxml::LN_Value_ST_Border_gradient: return 139;
144 case NS_ooxml::LN_Value_ST_Border_handmade1: return 140;
145 case NS_ooxml::LN_Value_ST_Border_handmade2: return 141;
146 case NS_ooxml::LN_Value_ST_Border_heartBalloon: return 142;
147 case NS_ooxml::LN_Value_ST_Border_heartGray: return 143;
148 case NS_ooxml::LN_Value_ST_Border_hearts: return 144;
149 case NS_ooxml::LN_Value_ST_Border_heebieJeebies: return 145;
150 case NS_ooxml::LN_Value_ST_Border_holly: return 146;
151 case NS_ooxml::LN_Value_ST_Border_houseFunky: return 147;
152 case NS_ooxml::LN_Value_ST_Border_hypnotic: return 148;
153 case NS_ooxml::LN_Value_ST_Border_iceCreamCones: return 149;
154 case NS_ooxml::LN_Value_ST_Border_lightBulb: return 150;
155 case NS_ooxml::LN_Value_ST_Border_lightning1: return 151;
156 case NS_ooxml::LN_Value_ST_Border_lightning2: return 152;
157 case NS_ooxml::LN_Value_ST_Border_mapPins: return 153;
158 case NS_ooxml::LN_Value_ST_Border_mapleLeaf: return 154;
159 case NS_ooxml::LN_Value_ST_Border_mapleMuffins: return 155;
160 case NS_ooxml::LN_Value_ST_Border_marquee: return 156;
161 case NS_ooxml::LN_Value_ST_Border_marqueeToothed: return 157;
162 case NS_ooxml::LN_Value_ST_Border_moons: return 158;
163 case NS_ooxml::LN_Value_ST_Border_mosaic: return 159;
164 case NS_ooxml::LN_Value_ST_Border_musicNotes: return 160;
165 case NS_ooxml::LN_Value_ST_Border_northwest: return 161;
166 case NS_ooxml::LN_Value_ST_Border_ovals: return 162;
167 case NS_ooxml::LN_Value_ST_Border_packages: return 163;
168 case NS_ooxml::LN_Value_ST_Border_palmsBlack: return 164;
169 case NS_ooxml::LN_Value_ST_Border_palmsColor: return 165;
170 case NS_ooxml::LN_Value_ST_Border_paperClips: return 166;
171 case NS_ooxml::LN_Value_ST_Border_papyrus: return 167;
172 case NS_ooxml::LN_Value_ST_Border_partyFavor: return 168;
173 case NS_ooxml::LN_Value_ST_Border_partyGlass: return 169;
174 case NS_ooxml::LN_Value_ST_Border_pencils: return 170;
175 case NS_ooxml::LN_Value_ST_Border_people: return 171;
176 case NS_ooxml::LN_Value_ST_Border_peopleWaving: return 172;
177 case NS_ooxml::LN_Value_ST_Border_peopleHats: return 173;
178 case NS_ooxml::LN_Value_ST_Border_poinsettias: return 174;
179 case NS_ooxml::LN_Value_ST_Border_postageStamp: return 175;
180 case NS_ooxml::LN_Value_ST_Border_pumpkin1: return 176;
181 case NS_ooxml::LN_Value_ST_Border_pushPinNote2: return 177;
182 case NS_ooxml::LN_Value_ST_Border_pushPinNote1: return 178;
183 case NS_ooxml::LN_Value_ST_Border_pyramids: return 179;
184 case NS_ooxml::LN_Value_ST_Border_pyramidsAbove: return 180;
185 case NS_ooxml::LN_Value_ST_Border_quadrants: return 181;
186 case NS_ooxml::LN_Value_ST_Border_rings: return 182;
187 case NS_ooxml::LN_Value_ST_Border_safari: return 183;
188 case NS_ooxml::LN_Value_ST_Border_sawtooth: return 184;
189 case NS_ooxml::LN_Value_ST_Border_sawtoothGray: return 185;
190 case NS_ooxml::LN_Value_ST_Border_scaredCat: return 186;
191 case NS_ooxml::LN_Value_ST_Border_seattle: return 187;
192 case NS_ooxml::LN_Value_ST_Border_shadowedSquares: return 188;
193 case NS_ooxml::LN_Value_ST_Border_sharksTeeth: return 189;
194 case NS_ooxml::LN_Value_ST_Border_shorebirdTracks: return 190;
195 case NS_ooxml::LN_Value_ST_Border_skyrocket: return 191;
196 case NS_ooxml::LN_Value_ST_Border_snowflakeFancy: return 192;
197 case NS_ooxml::LN_Value_ST_Border_snowflakes: return 193;
198 case NS_ooxml::LN_Value_ST_Border_sombrero: return 194;
199 case NS_ooxml::LN_Value_ST_Border_southwest: return 195;
200 case NS_ooxml::LN_Value_ST_Border_stars: return 196;
201 case NS_ooxml::LN_Value_ST_Border_starsTop: return 197;
202 case NS_ooxml::LN_Value_ST_Border_stars3d: return 198;
203 case NS_ooxml::LN_Value_ST_Border_starsBlack: return 199;
204 case NS_ooxml::LN_Value_ST_Border_starsShadowed: return 200;
205 case NS_ooxml::LN_Value_ST_Border_sun: return 201;
206 case NS_ooxml::LN_Value_ST_Border_swirligig: return 202;
207 case NS_ooxml::LN_Value_ST_Border_tornPaper: return 203;
208 case NS_ooxml::LN_Value_ST_Border_tornPaperBlack: return 204;
209 case NS_ooxml::LN_Value_ST_Border_trees: return 205;
210 case NS_ooxml::LN_Value_ST_Border_triangleParty: return 206;
211 case NS_ooxml::LN_Value_ST_Border_triangles: return 207;
212 case NS_ooxml::LN_Value_ST_Border_tribal1: return 208;
213 case NS_ooxml::LN_Value_ST_Border_tribal2: return 209;
214 case NS_ooxml::LN_Value_ST_Border_tribal3: return 210;
215 case NS_ooxml::LN_Value_ST_Border_tribal4: return 211;
216 case NS_ooxml::LN_Value_ST_Border_tribal5: return 212;
217 case NS_ooxml::LN_Value_ST_Border_tribal6: return 213;
218 case NS_ooxml::LN_Value_ST_Border_twistedLines1: return 214;
219 case NS_ooxml::LN_Value_ST_Border_twistedLines2: return 215;
220 case NS_ooxml::LN_Value_ST_Border_vine: return 216;
221 case NS_ooxml::LN_Value_ST_Border_waveline: return 217;
222 case NS_ooxml::LN_Value_ST_Border_weavingAngles: return 218;
223 case NS_ooxml::LN_Value_ST_Border_weavingBraid: return 219;
224 case NS_ooxml::LN_Value_ST_Border_weavingRibbon: return 220;
225 case NS_ooxml::LN_Value_ST_Border_weavingStrips: return 221;
226 case NS_ooxml::LN_Value_ST_Border_whiteFlowers: return 222;
227 case NS_ooxml::LN_Value_ST_Border_woodwork: return 223;
228 case NS_ooxml::LN_Value_ST_Border_xIllusions: return 224;
229 case NS_ooxml::LN_Value_ST_Border_zanyTriangles: return 225;
230 case NS_ooxml::LN_Value_ST_Border_zigZag: return 226;
231 case NS_ooxml::LN_Value_ST_Border_zigZagStitch: return 227;
232 default: break;
233 }
234 return 0;
235}
236
237void MakeBorderLine( sal_Int32 nLineThickness, sal_Int32 nLineToken,
238 sal_Int32 nLineColor,
239 table::BorderLine2& rToFill, bool bIsOOXML )
240{
241 static const Color aBorderDefColor[] =
242 {
243 // The first item means automatic color (COL_AUTO), but we
244 // do not use it anyway (see the next statement) .-)
245 // See also GetLineIndex in sw/source/filter/ww8/ww8par6.cxx
250 };
251 if(!bIsOOXML && sal::static_int_cast<sal_uInt32>(nLineColor) < SAL_N_ELEMENTS(aBorderDefColor))
252 nLineColor = sal_Int32(aBorderDefColor[nLineColor]);
253 //no auto color for borders
254 if (nLineColor == sal_Int32(COL_AUTO))
255 nLineColor = sal_Int32(COL_BLACK);
256
257 sal_Int32 nLineType = lcl_convertBorderStyleFromToken(nLineToken);
258
259 // Map to our border types, we should use of one equal line
260 // thickness, or one of smaller thickness. If too small we
261 // can make the deficit up in additional white space or
262 // object size
263 SvxBorderLineStyle const nLineStyle(
264 ::editeng::ConvertBorderStyleFromWord(nLineType));
265 rToFill.LineStyle = static_cast<sal_Int16>(nLineStyle);
266 double const fConverted( (SvxBorderLineStyle::NONE == nLineStyle) ? 0.0 :
267 ::editeng::ConvertBorderWidthFromWord(nLineStyle, nLineThickness,
268 nLineType));
269 rToFill.LineWidth = convertTwipToMM100(fConverted);
270 rToFill.Color = nLineColor;
271}
272
273namespace {
274void lcl_SwapQuotesInField(OUString &rFmt)
275{
276 //Swap unescaped " and ' with ' and "
277 sal_Int32 nLen = rFmt.getLength();
278 OUStringBuffer aBuffer( rFmt );
279 const sal_Unicode* pFmt = rFmt.getStr();
280 for (sal_Int32 nI = 0; nI < nLen; ++nI)
281 {
282 if ((pFmt[nI] == '\"') && (!nI || pFmt[nI-1] != '\\'))
283 aBuffer[nI] = '\'';
284 else if ((pFmt[nI] == '\'') && (!nI || pFmt[nI-1] != '\\'))
285 aBuffer[nI] = '\"';
286 }
287 rFmt = aBuffer.makeStringAndClear();
288}
289bool lcl_IsNotAM(std::u16string_view rFmt, sal_Int32 nPos)
290{
291 return (
292 (nPos == static_cast<sal_Int32>(rFmt.size()) - 1) ||
293 (
294 (rFmt[nPos+1] != 'M') &&
295 (rFmt[nPos+1] != 'm')
296 )
297 );
298}
299bool IsPreviousAM(std::u16string_view rParams, sal_Int32 nPos)
300{
301 return nPos >= 2 && o3tl::matchIgnoreAsciiCase(rParams, u"am", nPos - 2);
302}
303bool IsNextPM(std::u16string_view rParams, sal_Int32 nPos)
304{
305 return o3tl::make_unsigned(nPos + 2) < rParams.size() && o3tl::matchIgnoreAsciiCase(rParams, u"pm", nPos + 1);
306}
307}
308
309// See also sw::ms::MSDateTimeFormatToSwFormat
311 const OUString& rFormat, lang::Locale& rLocale, bool bHijri)
312{
313 OUString sFormat(rFormat);
314 lcl_SwapQuotesInField(sFormat);
315
316 //#102782#, #102815#, #108341# & #111944# have to work at the same time :-)
317 bool bForceJapanese(false);
318 bool bForceNatNum(false);
319 const sal_Int32 nLen = sFormat.getLength();
320 sal_Int32 nI = 0;
321 sal_Int32 nAddedChars = 0;
322// const sal_Unicode* pFormat = sFormat.getStr();
323 OUStringBuffer aNewFormat( sFormat );
324 while (nI < nLen)
325 {
326 if (sFormat[nI] == '\\')
327 ++nI;
328 else if (sFormat[nI] == '\"')
329 {
330 ++nI;
331 //While not at the end and not at an unescaped end quote
332 while ((nI < nLen) && ((sFormat[nI] != '\"') && (sFormat[nI-1] != '\\')))
333 ++nI;
334 }
335 else //normal unquoted section
336 {
337 sal_Unicode nChar = sFormat[nI];
338 if (nChar == 'O')
339 {
340 aNewFormat[nI + nAddedChars] = 'M';
341 bForceNatNum = true;
342 }
343 else if (nChar == 'o')
344 {
345 aNewFormat[nI + nAddedChars] = 'm';
346 bForceNatNum = true;
347 }
348 else if ((nChar == 'A') && lcl_IsNotAM(sFormat, nI))
349 {
350 aNewFormat[nI + nAddedChars] = 'D';
351 bForceNatNum = true;
352 }
353 else if ((nChar == 'g') || (nChar == 'G'))
354 bForceJapanese = true;
355 else if ((nChar == 'a') && lcl_IsNotAM(sFormat, nI))
356 bForceJapanese = true;
357 else if (nChar == 'E')
358 {
359 if ((nI != nLen-1) && (sFormat[nI+1] == 'E'))
360 {
361 //todo: this cannot be the right way to replace a part of the string!
362 aNewFormat[nI + nAddedChars] = 'Y';
363 aNewFormat[nI + nAddedChars + 1] = 'Y';
364 aNewFormat.insert(nI + nAddedChars + 2, "YY");
365 nAddedChars += 2;
366 ++nI;
367 }
368 bForceJapanese = true;
369 }
370 else if (nChar == 'e')
371 {
372 if ((nI != nLen-1) && (sFormat[nI+1] == 'e'))
373 {
374 //todo: this cannot be the right way to replace a part of the string!
375 aNewFormat[nI + nAddedChars] = 'y';
376 aNewFormat[nI + nAddedChars + 1] = 'y';
377 aNewFormat.insert(nI + nAddedChars + 2, "yy");
378 nAddedChars += 2;
379 ++nI;
380 }
381 bForceJapanese = true;
382 }
383 else if (nChar == '/' && !(IsPreviousAM(sFormat, nI) && IsNextPM(sFormat, nI)))
384 {
385 // MM We have to escape '/' in case it's used as a char
386 //todo: this cannot be the right way to replace a part of the string!
387 aNewFormat[nI + nAddedChars] = '\\';
388 aNewFormat.insert(nI + nAddedChars + 1, "/");
389 ++nAddedChars;
390 ++nI;
391 }
392 }
393 ++nI;
394 }
395
396 if (bForceNatNum)
397 bForceJapanese = true;
398
399 if (bForceJapanese)
400 {
401 rLocale.Language = "ja";
402 rLocale.Country = "JP";
403 }
404
405 if (bForceNatNum)
406 {
407 aNewFormat.insert( 0, "[NatNum1][$-411]");
408 }
409
410 if (bHijri)
411 {
412 aNewFormat.insert( 0, "[~hijri]");
413 }
414 return aNewFormat.makeStringAndClear();
415
416}
417
418sal_Int32 convertTwipToMM100(sal_Int32 _t)
419{
420 // It appears that MSO handles large twip values specially, probably legacy 16bit handling,
421 // anything that's bigger than 32767 appears to be simply ignored.
422 if( _t >= 0x8000 )
423 return 0;
424 return ::convertTwipToMm100( _t );
425}
426
427sal_Int32 convertTwipToMM100WithoutLimit(sal_Int32 _t)
428{
429 return ::convertTwipToMm100(_t);
430}
431
432double convertTwipToMM100Double(sal_Int32 _t)
433{
434 // It appears that MSO handles large twip values specially, probably legacy 16bit handling,
435 // anything that's bigger than 32767 appears to be simply ignored.
436 if( _t >= 0x8000 )
437 return 0.0;
438 return o3tl::convert<double>(_t, o3tl::Length::twip, o3tl::Length::mm100);
439}
440
441sal_uInt32 convertTwipToMM100Unsigned(sal_Int32 _t)
442{
443 if( _t < 0 )
444 return 0;
445 return convertTwipToMM100( _t );
446}
447
448text::RubyAdjust convertRubyAlign( sal_Int32 nIntValue )
449{
450 text::RubyAdjust rubyAdjust = text::RubyAdjust_LEFT;
451 switch( nIntValue )
452 {
453 case NS_ooxml::LN_Value_ST_RubyAlign_center:
454 case NS_ooxml::LN_Value_ST_RubyAlign_rightVertical:
455 rubyAdjust = text::RubyAdjust_CENTER;
456 break;
457 case NS_ooxml::LN_Value_ST_RubyAlign_distributeLetter:
458 rubyAdjust = text::RubyAdjust_BLOCK;
459 break;
460 case NS_ooxml::LN_Value_ST_RubyAlign_distributeSpace:
461 rubyAdjust = text::RubyAdjust_INDENT_BLOCK;
462 break;
463 case NS_ooxml::LN_Value_ST_RubyAlign_left:
464 rubyAdjust = text::RubyAdjust_LEFT;
465 break;
466 case NS_ooxml::LN_Value_ST_RubyAlign_right:
467 rubyAdjust = text::RubyAdjust_RIGHT;
468 break;
469 }
470 return rubyAdjust;
471}
472
473sal_Int16 convertTableJustification( sal_Int32 nIntValue )
474{
475 sal_Int16 nOrient = text::HoriOrientation::LEFT_AND_WIDTH;
476 switch( nIntValue )
477 {
478 case NS_ooxml::LN_Value_ST_Jc_center:
479 nOrient = text::HoriOrientation::CENTER;
480 break;
481 case NS_ooxml::LN_Value_ST_Jc_right:
482 case NS_ooxml::LN_Value_ST_Jc_end:
483 nOrient = text::HoriOrientation::RIGHT;
484 break;
485 case NS_ooxml::LN_Value_ST_Jc_left:
486 case NS_ooxml::LN_Value_ST_Jc_start:
487 //no break
488 default:;
489
490 }
491 return nOrient;
492}
493
494// Return the suggested default if the given format has no known conversion
495sal_Int16 ConvertNumberingType(const sal_Int32 nFmt, const sal_Int16 nDefault)
496{
497 sal_Int16 nRet;
498 switch(nFmt)
499 {
500 case NS_ooxml::LN_Value_ST_NumberFormat_decimal:
501 nRet = style::NumberingType::ARABIC;
502 break;
503 case NS_ooxml::LN_Value_ST_NumberFormat_upperRoman:
504 nRet = style::NumberingType::ROMAN_UPPER;
505 break;
506 case NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman:
507 nRet = style::NumberingType::ROMAN_LOWER;
508 break;
509 case NS_ooxml::LN_Value_ST_NumberFormat_ordinal:
510 nRet = style::NumberingType::TEXT_NUMBER;
511 break;
512 case NS_ooxml::LN_Value_ST_NumberFormat_bullet:
513 nRet = style::NumberingType::CHAR_SPECIAL;
514 break;
515 case NS_ooxml::LN_Value_ST_NumberFormat_none:
516 nRet = style::NumberingType::NUMBER_NONE;
517 break;
518 case NS_ooxml::LN_Value_ST_NumberFormat_upperLetter:
519 nRet = style::NumberingType::CHARS_UPPER_LETTER_N;
520 break;
521 case NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter:
522 nRet = style::NumberingType::CHARS_LOWER_LETTER_N;
523 break;
524 case NS_ooxml::LN_Value_ST_NumberFormat_iroha:
525 nRet = style::NumberingType::IROHA_HALFWIDTH_JA;
526 break;
527 case NS_ooxml::LN_Value_ST_NumberFormat_irohaFullWidth:
528 nRet = style::NumberingType::IROHA_FULLWIDTH_JA;
529 break;
530 case NS_ooxml::LN_Value_ST_NumberFormat_aiueo:
531 nRet = style::NumberingType::AIU_HALFWIDTH_JA;
532 break;
533 case NS_ooxml::LN_Value_ST_NumberFormat_aiueoFullWidth:
534 nRet = style::NumberingType::AIU_FULLWIDTH_JA;
535 break;
536 case NS_ooxml::LN_Value_ST_NumberFormat_hebrew2:
537 nRet = style::NumberingType::CHARS_HEBREW;
538 break;
539 case NS_ooxml::LN_Value_ST_NumberFormat_thaiLetters:
540 nRet = style::NumberingType::CHARS_THAI;
541 break;
542 case NS_ooxml::LN_Value_ST_NumberFormat_russianLower:
543 nRet = style::NumberingType::CHARS_CYRILLIC_LOWER_LETTER_RU;
544 break;
545 case NS_ooxml::LN_Value_ST_NumberFormat_russianUpper:
546 nRet = style::NumberingType::CHARS_CYRILLIC_UPPER_LETTER_RU;
547 break;
548 case NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircleChinese:
549 case NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedCircle:
550 case NS_ooxml::LN_Value_ST_NumberFormat_ideographEnclosedCircle:
551 nRet = style::NumberingType::CIRCLE_NUMBER;
552 break;
553 case NS_ooxml::LN_Value_ST_NumberFormat_ideographTraditional:
554 nRet = style::NumberingType::TIAN_GAN_ZH;
555 break;
556 case NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiac:
557 nRet = style::NumberingType::DI_ZI_ZH;
558 break;
559 case NS_ooxml::LN_Value_ST_NumberFormat_ganada:
560 nRet = style::NumberingType::HANGUL_SYLLABLE_KO;
561 break;
562 case NS_ooxml::LN_Value_ST_NumberFormat_chosung:
563 nRet = style::NumberingType::HANGUL_JAMO_KO;
564 break;
565 case NS_ooxml::LN_Value_ST_NumberFormat_koreanLegal:
566 nRet = style::NumberingType::NUMBER_LEGAL_KO;
567 break;
568 case NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital:
569 nRet = style::NumberingType::NUMBER_DIGITAL_KO;
570 break;
571 case NS_ooxml::LN_Value_ST_NumberFormat_koreanCounting:
572 nRet = style::NumberingType::NUMBER_HANGUL_KO;
573 break;
574 case NS_ooxml::LN_Value_ST_NumberFormat_koreanDigital2:
575 nRet = style::NumberingType::NUMBER_DIGITAL2_KO;
576 break;
577 case NS_ooxml::LN_Value_ST_NumberFormat_ideographLegalTraditional:
578 nRet = style::NumberingType::NUMBER_UPPER_ZH_TW;
579 break;
580 case NS_ooxml::LN_Value_ST_NumberFormat_arabicAlpha:
581 nRet = style::NumberingType::CHARS_ARABIC;
582 break;
583 case NS_ooxml::LN_Value_ST_NumberFormat_arabicAbjad:
584 nRet = style::NumberingType::CHARS_ARABIC_ABJAD;
585 break;
586 case NS_ooxml::LN_Value_ST_NumberFormat_hindiVowels:
587 nRet = style::NumberingType::CHARS_NEPALI;
588 break;
589 case NS_ooxml::LN_Value_ST_NumberFormat_japaneseLegal:
590 nRet = style::NumberingType::NUMBER_TRADITIONAL_JA;
591 break;
592 case NS_ooxml::LN_Value_ST_NumberFormat_chineseCounting:
593 case NS_ooxml::LN_Value_ST_NumberFormat_japaneseCounting:
594 case NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCounting:
595 case NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseCountingThousand:
596 case NS_ooxml::LN_Value_ST_NumberFormat_ideographDigital:
597 case NS_ooxml::LN_Value_ST_NumberFormat_chineseCountingThousand:
598 nRet = style::NumberingType::NUMBER_LOWER_ZH;
599 break;
600 case NS_ooxml::LN_Value_ST_NumberFormat_chineseLegalSimplified:
601 nRet = style::NumberingType::NUMBER_UPPER_ZH;
602 break;
603 case NS_ooxml::LN_Value_ST_NumberFormat_hebrew1:
604 //91726
605 nRet = style::NumberingType::NUMBER_HEBREW;
606 break;
607 case NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth:
608 case NS_ooxml::LN_Value_ST_NumberFormat_decimalFullWidth2:
609 nRet = style::NumberingType::FULLWIDTH_ARABIC;
610 break;
611 case NS_ooxml::LN_Value_ST_NumberFormat_cardinalText:
612 nRet = style::NumberingType::TEXT_CARDINAL;
613 break;
614 case NS_ooxml::LN_Value_ST_NumberFormat_ordinalText:
615 nRet = style::NumberingType::TEXT_ORDINAL;
616 break;
617 case NS_ooxml::LN_Value_ST_NumberFormat_chicago:
618 nRet = style::NumberingType::SYMBOL_CHICAGO;
619 break;
620 case NS_ooxml::LN_Value_ST_NumberFormat_decimalZero:
621 nRet = style::NumberingType::ARABIC_ZERO;
622 break;
623 default: nRet = nDefault;
624 }
625/* TODO: Lots of additional values are available - some are supported in the I18 framework
626 NS_ooxml::LN_Value_ST_NumberFormat_hex = 91685;
627 NS_ooxml::LN_Value_ST_NumberFormat_decimalHalfWidth = 91692;
628 NS_ooxml::LN_Value_ST_NumberFormat_japaneseDigitalTenThousand = 91694;
629 NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedFullstop = 91703;
630 NS_ooxml::LN_Value_ST_NumberFormat_decimalEnclosedParen = 91704;
631 NS_ooxml::LN_Value_ST_NumberFormat_ideographZodiacTraditional = 91709;
632 NS_ooxml::LN_Value_ST_NumberFormat_taiwaneseDigital = 91713;
633 NS_ooxml::LN_Value_ST_NumberFormat_vietnameseCounting = 91721;
634 NS_ooxml::LN_Value_ST_NumberFormat_numberInDash = 91725;
635 NS_ooxml::LN_Value_ST_NumberFormat_hindiConsonants = 91731;
636 NS_ooxml::LN_Value_ST_NumberFormat_hindiNumbers = 91732;
637 NS_ooxml::LN_Value_ST_NumberFormat_hindiCounting = 91733;
638 NS_ooxml::LN_Value_ST_NumberFormat_thaiNumbers = 91735;
639 NS_ooxml::LN_Value_ST_NumberFormat_thaiCounting = 91736;*/
640 return nRet;
641}
642
643sal_Int16 ConvertCustomNumberFormat(std::u16string_view rFormat)
644{
645 sal_Int16 nRet = -1;
646
647 if (rFormat == u"001, 002, 003, ...")
648 {
649 nRet = style::NumberingType::ARABIC_ZERO3;
650 }
651 else if (rFormat == u"0001, 0002, 0003, ...")
652 {
653 nRet = style::NumberingType::ARABIC_ZERO4;
654 }
655 else if (rFormat == u"00001, 00002, 00003, ...")
656 {
657 nRet = style::NumberingType::ARABIC_ZERO5;
658 }
659
660 return nRet;
661}
662
663util::DateTime ConvertDateStringToDateTime( std::u16string_view rDateTime )
664{
665 util::DateTime aDateTime;
666 //xsd::DateTime in the format [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] example: 2008-01-21T10:42:00Z
667 //OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const
668 sal_Int32 nIndex = 0;
669 std::u16string_view sDate = o3tl::getToken(rDateTime, 0, 'T', nIndex );
670 // HACK: this is broken according to the spec, but MSOffice always treats the time as local,
671 // and writes it as Z (=UTC+0)
672 std::u16string_view sTime = o3tl::getToken(rDateTime, 0, 'Z', nIndex );
673 nIndex = 0;
674 aDateTime.Year = sal_uInt16( o3tl::toInt32(o3tl::getToken(sDate, 0, '-', nIndex )) );
675 aDateTime.Month = sal_uInt16( o3tl::toInt32(o3tl::getToken(sDate, 0, '-', nIndex )) );
676 if (nIndex != -1)
677 aDateTime.Day = sal_uInt16( o3tl::toInt32(sDate.substr( nIndex )) );
678
679 nIndex = 0;
680 aDateTime.Hours = sal_uInt16( o3tl::toInt32(o3tl::getToken(sTime, 0, ':', nIndex )) );
681 aDateTime.Minutes = sal_uInt16( o3tl::toInt32(o3tl::getToken(sTime, 0, ':', nIndex )) );
682 if (nIndex != -1)
683 aDateTime.Seconds = sal_uInt16( o3tl::toInt32(sTime.substr( nIndex )) );
684
685 return aDateTime;
686}
687
688
689} //namespace writerfilter
690
691/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxBorderLineStyle
constexpr ::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
constexpr ::Color COL_GRAY(0x80, 0x80, 0x80)
constexpr ::Color COL_GREEN(0x00, 0x80, 0x00)
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTCYAN(0x00, 0xFF, 0xFF)
constexpr ::Color COL_MAGENTA(0x80, 0x00, 0x80)
constexpr ::Color COL_LIGHTMAGENTA(0xFF, 0x00, 0xFF)
constexpr ::Color COL_BROWN(0x80, 0x80, 0x00)
constexpr ::Color COL_YELLOW(0xFF, 0xFF, 0x00)
constexpr ::Color COL_RED(0x80, 0x00, 0x00)
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
constexpr ::Color COL_LIGHTBLUE(0x00, 0x00, 0xFF)
constexpr ::Color COL_CYAN(0x00, 0x80, 0x80)
constexpr ::Color COL_LIGHTGREEN(0x00, 0xFF, 0x00)
constexpr ::Color COL_BLUE(0x00, 0x00, 0x80)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
float u
sal_Int32 nIndex
sal_uInt16 nPos
#define SAL_N_ELEMENTS(arr)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
bool matchIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2, sal_Int32 fromIndex=0)
bool IsPreviousAM(std::u16string_view rParams, sal_Int32 nPos)
bool IsNextPM(std::u16string_view rParams, sal_Int32 nPos)
static sal_Int32 lcl_convertBorderStyleFromToken(sal_Int32 nOOXMLType)
Convert OOXML border style to WW8 that editeng can handle.
OUString ConvertMSFormatStringToSO(const OUString &rFormat, lang::Locale &rLocale, bool bHijri)
void MakeBorderLine(sal_Int32 nLineThickness, sal_Int32 nLineToken, sal_Int32 nLineColor, table::BorderLine2 &rToFill, bool bIsOOXML)
sal_uInt32 convertTwipToMM100Unsigned(sal_Int32 _t)
sal_Int32 convertTwipToMM100WithoutLimit(sal_Int32 _t)
sal_Int16 convertTableJustification(sal_Int32 nIntValue)
text::RubyAdjust convertRubyAlign(sal_Int32 nIntValue)
sal_Int16 ConvertNumberingType(const sal_Int32 nFmt, const sal_Int16 nDefault)
util::DateTime ConvertDateStringToDateTime(std::u16string_view rDateTime)
sal_Int16 ConvertCustomNumberFormat(std::u16string_view rFormat)
sal_uInt16 sal_Unicode
std::unique_ptr< char[]> aBuffer