tdf#131098 docx export: write fill property of graphic
[LibreOffice.git] / lotuswordpro / source / filter / lwptools.cxx
blob16b1259ba2917d5b6ea48abba3e7fda34ed5a358
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 /*************************************************************************
57 * @file
58 * For LWP filter architecture prototype
59 ************************************************************************/
61 #include <lwptools.hxx>
62 #include <rtl/ustrbuf.hxx>
63 #include <o3tl/string_view.hxx>
64 #include <osl/process.h>
65 #include <osl/thread.h>
66 #include <osl/file.hxx>
67 #include <vcl/svapp.hxx>
68 #include <vcl/settings.hxx>
69 #include <unicode/datefmt.h>
70 #include <unicode/udat.h>
71 #include <i18nlangtag/languagetagicu.hxx>
73 #ifdef SAL_UNX
74 #define SEPARATOR '/'
75 #else
76 #define SEPARATOR '\\'
77 #endif
79 using namespace ::osl;
81 /**
82 * @descr read lwp unicode string from stream to OUString per aEncoding
84 void LwpTools::QuickReadUnicode(LwpObjectStream* pObjStrm,
85 OUString& str, sal_uInt16 strlen, rtl_TextEncoding aEncoding)
86 //strlen: length of bytes
88 OUStringBuffer strBuf(128);
90 if( !IsUnicodePacked(pObjStrm, strlen) )
92 sal_uInt16 len = 0;
93 char buf[1024];
95 while(strlen)
97 len = std::min(sal_uInt16(1023), strlen);
98 len = pObjStrm->QuickRead(buf, len);
99 buf[len] = '\0';
100 strBuf.append( OUString(buf, len, aEncoding) );
101 strlen -= len;
102 if(!len) break;
104 str = strBuf.makeStringAndClear();
106 else
108 char buf[1024];
109 sal_Unicode unibuf[1024];
110 sal_uInt8 readbyte;
111 sal_uInt16 readword;
113 bool flag = false; //switch if unicode part reached
114 sal_uInt16 sublen = 0;
116 sal_uInt16 readLen = 0;
117 while(readLen<strlen)
119 if(!flag) //Not unicode string
121 bool bFailure;
122 readbyte = pObjStrm->QuickReaduInt8(&bFailure);
123 if(bFailure) break;
124 readLen+=sizeof(readbyte);
126 if(readbyte == 0x00)
128 flag = true;
129 if(sublen>0) //add it to the strBuf
131 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
132 sublen = 0;
135 else
137 buf[sublen++] = readbyte;
139 if(sublen>=1023 || readLen==strlen) //add it to the strBuf
141 strBuf.append( OUString(buf, sublen, aEncoding) ); //try the aEncoding
142 sublen = 0;
145 else //unicode string
147 bool bFailure;
148 readword = pObjStrm->QuickReaduInt16(&bFailure);
149 if(bFailure) break;
150 readLen+=sizeof(readword);
152 if(readword == 0x0000)
154 flag = false;
155 if(sublen)
157 unibuf[sublen] = '\0';
158 strBuf.append( unibuf );
159 sublen = 0;
162 else
164 unibuf[sublen++] = readword;
166 if(sublen>=1023 || readLen==strlen)
168 unibuf[sublen] = '\0';
169 strBuf.append( unibuf );
170 sublen = 0;
174 str = strBuf.makeStringAndClear();
179 * @descr Judge if the data (len) in object stream is lwp unicode packed
181 bool LwpTools::IsUnicodePacked(LwpObjectStream* pObjStrm, sal_uInt16 len)
183 sal_uInt8 byte;
184 sal_uInt16 oldpos = pObjStrm->GetPos();
186 for (sal_uInt16 i = 0; i < len; i++)
188 byte = pObjStrm->QuickReaduInt8();
189 if (byte == 0x00)
191 pObjStrm->Seek(oldpos);
192 return true;
195 pObjStrm->Seek(oldpos);
196 return false;
199 bool LwpTools::isFileUrl(std::string_view fileName)
201 return o3tl::starts_with(fileName, "file://");
204 OUString LwpTools::convertToFileUrl(const OString &fileName)
206 if ( isFileUrl(fileName) )
208 return OStringToOUString(fileName, osl_getThreadTextEncoding());
211 OUString uUrlFileName;
212 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
213 if ( fileName.startsWith(".") || fileName.indexOf(SEPARATOR) < 0 )
215 OUString uWorkingDir;
216 OSL_VERIFY( osl_getProcessWorkingDir(&uWorkingDir.pData) == osl_Process_E_None );
217 OSL_VERIFY( FileBase::getAbsoluteFileURL(uWorkingDir, uFileName, uUrlFileName) == FileBase::E_None );
218 } else
220 OSL_VERIFY( FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName) == FileBase::E_None );
223 return uUrlFileName;
226 OUString LwpTools::DateTimeToOUString(const LtTm &dt)
228 OUString aResult = OUString::number(dt.tm_year) + "-" + OUString::number(dt.tm_mon) + "-" + OUString::number(dt.tm_mday) +
229 "T" + OUString::number(dt.tm_hour) + ":" + OUString::number(dt.tm_min) + ":" + OUString::number(dt.tm_sec);
231 return aResult;
235 * @descr get the system date format
237 std::unique_ptr<XFDateStyle> LwpTools::GetSystemDateStyle(bool bLongFormat)
239 icu::DateFormat::EStyle style;
240 if (bLongFormat)
241 style = icu::DateFormat::FULL;//system full date format
242 else
243 style = icu::DateFormat::SHORT;//system short date format
245 //1 get locale for system
246 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
247 //2 get icu format pattern by locale
248 icu::DateFormat* fmt = icu::DateFormat::createDateInstance(style,aLocale);
250 int32_t nLength = 0;
251 int32_t nLengthNeed;
252 UErrorCode status = U_ZERO_ERROR;
253 UChar* pattern = nullptr;
255 nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
256 if (status == U_BUFFER_OVERFLOW_ERROR)
258 status = U_ZERO_ERROR;
259 nLength = nLengthNeed +1;
260 pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
261 udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
263 if (pattern == nullptr)
264 return nullptr;
265 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
266 // as pattern letter,each represent an element in date/time and its repeat numbers represent
267 // different format: for example: M produces '1', MM produces '01', MMM produces 'Jan', MMMM produces 'January'
268 // letter other than these letters is regard as text in the format, for example ',' in 'Jan,2005'
269 // we parse pattern string letter by letter and get the time format.
270 UChar cSymbol;
271 UChar cTmp;
272 std::unique_ptr<XFDateStyle> pDateStyle(new XFDateStyle);
274 for (int32_t i=0;i<nLengthNeed;)
276 cSymbol = pattern[i];
277 int32_t j;
278 switch(cSymbol)
280 case 'G':
282 for (j=1;;j++)
284 cTmp = pattern[i+j];
285 if (cTmp != cSymbol)
287 i=i+j;
288 break;
291 pDateStyle->AddEra();
292 break;
294 case 'y':
296 for (j=1;;j++)
298 cTmp = pattern[i+j];
299 if (cTmp != cSymbol)
301 i=i+j;
302 break;
305 if (j <= 2)
306 pDateStyle->AddYear(false);
307 else
308 pDateStyle->AddYear();
309 break;
311 case 'M':
313 for (j=1;;j++)
315 cTmp = pattern[i+j];
316 if (cTmp != cSymbol)
318 i=i+j;
319 break;
322 if (j==1)
323 pDateStyle->AddMonth(false);
324 else if (j==2)
325 pDateStyle->AddMonth();
326 else if (j==3)
327 pDateStyle->AddMonth(false,true);
328 else
329 pDateStyle->AddMonth(true,true);
330 break;
332 case 'd':
334 for (j=1;;j++)
336 cTmp = pattern[i+j];
337 if (cTmp != cSymbol)
339 i=i+j;
340 break;
343 if (j==1)
344 pDateStyle->AddMonthDay(false);
345 else
346 pDateStyle->AddMonthDay();
347 break;
349 case 'h':
351 for (j=1;;j++)
353 cTmp = pattern[i+j];
354 if (cTmp != cSymbol)
356 i=i+j;
357 break;
360 if (j==1)
361 pDateStyle->AddHour(false);
362 else
363 pDateStyle->AddHour();
364 break;
366 case 'H':
368 for (j=1;;j++)
370 cTmp = pattern[i+j];
371 if (cTmp != cSymbol)
373 i=i+j;
374 break;
377 if (j==1)
378 pDateStyle->AddHour(false);
379 else
380 pDateStyle->AddHour();
381 break;
383 case 'm':
385 for (j=1;;j++)
387 cTmp = pattern[i+j];
388 if (cTmp != cSymbol)
390 i=i+j;
391 break;
394 if (j==1)
395 pDateStyle->AddMinute(false);
396 else
397 pDateStyle->AddMinute();
398 break;
400 case 's':
402 for (j=1;;j++)
404 cTmp = pattern[i+j];
405 if (cTmp != cSymbol)
407 i=i+j;
408 break;
411 if (j==1)
412 pDateStyle->AddSecond(false);
413 else
414 pDateStyle->AddSecond();
415 break;
417 case 'S':
419 for (j=1;;j++)
421 cTmp = pattern[i+j];
422 if (cTmp != cSymbol)
424 i=i+j;
425 break;
428 /*if (j==1)
429 pDateStyle->AddSecond(sal_False);
430 else
431 pDateStyle->AddSecond();*/
432 break;
434 case 'E':
436 for (j=1;;j++)
438 cTmp = pattern[i+j];
439 if (cTmp != cSymbol)
441 i=i+j;
442 break;
445 if (j<=2)
446 pDateStyle->AddWeekDay(false);
447 else
448 pDateStyle->AddWeekDay();
449 break;
451 case 'D':
453 for (j=1;;j++)
455 cTmp = pattern[i+j];
456 if (cTmp != cSymbol)
458 i=i+j;
459 break;
462 /*if (j==1)
463 pDateStyle->AddWeekDay(sal_False);
464 else
465 pDateStyle->AddWeekDay();*/
466 break;
468 case 'F':
470 for (j=1;;j++)
472 cTmp = pattern[i+j];
473 if (cTmp != cSymbol)
475 i=i+j;
476 break;
479 /*if (j==1)
480 pDateStyle->AddWeekDay(sal_False);
481 else
482 pDateStyle->AddWeekDay();*/
483 break;
485 case 'w':
487 for (j=1;;j++)
489 cTmp = pattern[i+j];
490 if (cTmp != cSymbol)
492 i=i+j;
493 break;
496 /*if (j==1)
497 pDateStyle->AddWeekDay(sal_False);
498 else
499 pDateStyle->AddWeekDay();*/
500 break;
502 case 'W':
504 for (j=1;;j++)
506 cTmp = pattern[i+j];
507 if (cTmp != cSymbol)
509 i=i+j;
510 break;
513 /*if (j==1)
514 pDateStyle->AddWeekDay(sal_False);
515 else
516 pDateStyle->AddWeekDay();*/
517 break;
519 case 'a':
521 for (j=1;;j++)
523 cTmp = pattern[i+j];
524 if (cTmp != cSymbol)
526 i=i+j;
527 break;
530 pDateStyle->AddAmPm();
531 break;
533 case 'k':
535 for (j=1;;j++)
537 cTmp = pattern[i+j];
538 if (cTmp != cSymbol)
540 i=i+j;
541 break;
544 break;
546 case 'K':
548 for (j=1;;j++)
550 cTmp = pattern[i+j];
551 if (cTmp != cSymbol)
553 i=i+j;
554 break;
557 if (j==1)
558 pDateStyle->AddHour(false);
559 else
560 pDateStyle->AddHour();
561 break;
563 case 'Z':
565 for (j=1;;j++)
567 cTmp = pattern[i+j];
568 if (cTmp != cSymbol)
570 i=i+j;
571 break;
574 break;
576 case '\''://'
578 for (j=1;;j++)
580 cTmp = pattern[i+j];
581 if (cTmp != cSymbol)
583 i=i+j;
584 break;
587 break;
589 case '"':
591 pDateStyle->AddText(u"'"_ustr);
592 break;
594 default:
596 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
598 return nullptr;
600 else//TEXT
602 //UChar buffer[1024];
603 sal_Unicode buffer[1024];
604 buffer[0] = cSymbol;
605 for (j=1;;j++)
607 cTmp = pattern[i+j];
608 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
609 cTmp=='\'' || cTmp=='"' )
611 i=i+j;
612 buffer[j]= '\0';
613 break;
615 else
616 buffer[j] = cTmp;
619 pDateStyle->AddText(OUString(buffer));//keep for all parsed
621 break;
625 // udat_close(fmt);
626 return pDateStyle;
629 * @descr get the system time format
631 std::unique_ptr<XFTimeStyle> LwpTools::GetSystemTimeStyle()
633 //1 get locale for system
634 icu::Locale aLocale( LanguageTagIcu::getIcuLocale( Application::GetSettings().GetLanguageTag()));
635 //2 get icu format pattern by locale
636 icu::DateFormat* fmt = icu::DateFormat::createTimeInstance(icu::DateFormat::DEFAULT,aLocale);
638 int32_t nLength = 0;
639 int32_t nLengthNeed;
640 UErrorCode status = U_ZERO_ERROR;
641 UChar* pattern = nullptr;
642 nLengthNeed = udat_toPattern(reinterpret_cast<void **>(fmt),false,nullptr,nLength,&status);
643 if (status == U_BUFFER_OVERFLOW_ERROR)
645 status = U_ZERO_ERROR;
646 nLength = nLengthNeed +1;
647 pattern = static_cast<UChar*>(malloc(sizeof(UChar)*nLength));
648 udat_toPattern(reinterpret_cast<void **>(fmt),false,pattern,nLength,&status);
651 if (pattern == nullptr)
652 return nullptr;
653 // 3 parse pattern string,per icu date/time format syntax, there are 20 letters reserved
654 // as pattern letter,each represent an element in date/time and its repeat numbers represent
655 // different format: for example: M produces '1',MM produces '01', MMM produces 'Jan', MMMM produces 'Januaray'
656 // letter other than these letters is regard as text in the format, for example ','in 'Jan,2005'
657 // we parse pattern string letter by letter and get the time format.
658 // for time format ,for there is not date info,we can only parse the letter representing time.
659 UChar cSymbol;
660 UChar cTmp;
661 std::unique_ptr<XFTimeStyle> pTimeStyle(new XFTimeStyle);
663 for (int32_t i=0;i<nLengthNeed;)
665 cSymbol = pattern[i];
666 int32_t j;
667 switch(cSymbol)
669 case 'h':
671 for (j=1;;j++)
673 cTmp = pattern[i+j];
674 if (cTmp != cSymbol)
676 i=i+j;
677 break;
680 if (j==1)
681 pTimeStyle->AddHour(false);
682 else
683 pTimeStyle->AddHour();
684 break;
686 case 'H':
688 for (j=1;;j++)
690 cTmp = pattern[i+j];
691 if (cTmp != cSymbol)
693 i=i+j;
694 break;
697 if (j==1)
698 pTimeStyle->AddHour(false);
699 else
700 pTimeStyle->AddHour();
701 break;
703 case 'm':
705 for (j=1;;j++)
707 cTmp = pattern[i+j];
708 if (cTmp != cSymbol)
710 i=i+j;
711 break;
714 if (j==1)
715 pTimeStyle->AddMinute(false);
716 else
717 pTimeStyle->AddMinute();
718 break;
720 case 's':
722 for (j=1;;j++)
724 cTmp = pattern[i+j];
725 if (cTmp != cSymbol)
727 i=i+j;
728 break;
731 if (j==1)
732 pTimeStyle->AddSecond(false);
733 else
734 pTimeStyle->AddSecond();
735 break;
737 case 'S':
739 for (j=1;;j++)
741 cTmp = pattern[i+j];
742 if (cTmp != cSymbol)
744 i=i+j;
745 break;
748 /*if (j==1)
749 pDateStyle->AddSecond(sal_False);
750 else
751 pDateStyle->AddSecond();*/
752 break;
754 case 'a':
756 for (j=1;;j++)
758 cTmp = pattern[i+j];
759 if (cTmp != cSymbol)
761 i=i+j;
762 break;
765 pTimeStyle->SetAmPm(true);
766 break;
768 case 'k':
770 for (j=1;;j++)
772 cTmp = pattern[i+j];
773 if (cTmp != cSymbol)
775 i=i+j;
776 break;
779 break;
781 case 'K':
783 for (j=1;;j++)
785 cTmp = pattern[i+j];
786 if (cTmp != cSymbol)
788 i=i+j;
789 break;
792 if (j==1)
793 pTimeStyle->AddHour(false);
794 else
795 pTimeStyle->AddHour();
796 break;
798 case '\''://'
800 for (j=1;;j++)
802 cTmp = pattern[i+j];
803 if (cTmp != cSymbol)
805 i=i+j;
806 break;
809 break;
811 case '"':
813 pTimeStyle->AddText(u"'"_ustr);
814 break;
816 default:
818 if ((cSymbol>='A' && cSymbol<='Z') || (cSymbol>='a' && cSymbol<='z') )
820 return nullptr;
822 else//TEXT
824 sal_Unicode buffer[1024];
825 buffer[0] = cSymbol;
826 //strBuffer.append(cSymbol);
827 for (j=1;;j++)
829 cTmp = pattern[i+j];
830 if ((cTmp>='A' && cTmp<='Z') || (cTmp>='a' && cTmp<='z') ||
831 cTmp=='\'' || cTmp=='"' )
833 i=i+j;
834 buffer[j]= '\0';
835 break;
837 else
838 buffer[j] = cTmp;
840 pTimeStyle->AddText(OUString(buffer));//keep for all parsed
842 break;
846 // udat_close(fmt);
847 return pTimeStyle;
850 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */