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 
20 
21 #include <svl/zformat.hxx>
22 #include <svl/macitem.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/settings.hxx>
25 #include <svl/zforlist.hxx>
26 
27 #include <svtools/HtmlWriter.hxx>
28 #include <svtools/htmlout.hxx>
29 #include <svtools/htmlkywd.hxx>
30 #include <vcl/imap.hxx>
31 #include <vcl/imaprect.hxx>
32 #include <vcl/imapcirc.hxx>
33 #include <vcl/imappoly.hxx>
34 #include <svl/urihelper.hxx>
35 #include <rtl/character.hxx>
36 #include <tools/debug.hxx>
37 
38 #include <sstream>
39 
40 #define TXTCONV_BUFFER_SIZE 20
41 
HTMLOutContext(rtl_TextEncoding eDestEnc)42 HTMLOutContext::HTMLOutContext( rtl_TextEncoding eDestEnc )
43 {
44     m_eDestEnc = RTL_TEXTENCODING_DONTKNOW == eDestEnc
45                     ? osl_getThreadTextEncoding()
46                     : eDestEnc;
47 
48     m_hConv = rtl_createUnicodeToTextConverter( eDestEnc );
49     DBG_ASSERT( m_hConv,
50         "HTMLOutContext::HTMLOutContext: no converter for source encoding" );
51     m_hContext = m_hConv ? rtl_createUnicodeToTextContext( m_hConv )
52                      : reinterpret_cast<rtl_TextToUnicodeContext>(1);
53 }
54 
~HTMLOutContext()55 HTMLOutContext::~HTMLOutContext()
56 {
57     rtl_destroyUnicodeToTextContext( m_hConv, m_hContext );
58     rtl_destroyUnicodeToTextConverter( m_hConv );
59 }
60 
lcl_svhtml_GetEntityForChar(sal_uInt32 c,rtl_TextEncoding eDestEnc)61 static const char *lcl_svhtml_GetEntityForChar( sal_uInt32 c,
62                                              rtl_TextEncoding eDestEnc )
63 {
64     const char* pStr = nullptr;
65 
66     // Note: We currently handle special cases for ISO-8859-2 here simply because
67     // the code was already submitted.  But we should also handle other code pages
68     // as well as the code becomes available.
69 
70     if( eDestEnc == RTL_TEXTENCODING_ISO_8859_2 || eDestEnc == RTL_TEXTENCODING_MS_1250 )
71     {
72         // Don't handle the following characters for Easter European (ISO-8859-2).
73         switch ( c )
74         {
75         case 164: // curren
76         case 184: // ccedil
77         case 193: // Aacute
78         case 194: // Acirc
79         case 196: // Auml
80         case 199: // Ccedil
81         case 201: // Eacute
82         case 203: // Euml
83         case 205: // Iacute
84         case 206: // Icirc
85         case 211: // Oacute
86         case 212: // Ocirc
87         case 214: // Ouml
88         case 215: // times
89         case 218: // Uacute
90         case 220: // Uuml
91         case 221: // Yacute
92         case 225: // aacute
93         case 226: // acirc
94         case 228: // auml
95         case 233: // eacute
96         case 235: // euml
97         case 237: // iacute
98         case 238: // icirc
99         case 243: // oacute
100         case 244: // ocirc
101         case 246: // ouml
102         case 247: // divide
103         case 250: // uacute
104         case 252: // uuml
105         case 253: // yacute
106         case 352: // Scaron
107         case 353: // scaron
108             return pStr;
109         }
110     }
111 
112     // TODO: handle more special cases for other code pages.
113 
114     switch( c )
115     {
116 //      case '\x0a':   return HTMLOutFuncs::Out_Tag( rStream, OOO_STRING_SVTOOLS_HTML_linebreak );
117 
118     case '<':       pStr = OOO_STRING_SVTOOLS_HTML_C_lt;        break;
119     case '>':       pStr = OOO_STRING_SVTOOLS_HTML_C_gt;        break;
120     case '&':       pStr = OOO_STRING_SVTOOLS_HTML_C_amp;       break;
121     case '"':       pStr = OOO_STRING_SVTOOLS_HTML_C_quot;  break;
122 
123     case 161:       pStr = OOO_STRING_SVTOOLS_HTML_S_iexcl; break;
124     case 162:       pStr = OOO_STRING_SVTOOLS_HTML_S_cent;  break;
125     case 163:       pStr = OOO_STRING_SVTOOLS_HTML_S_pound; break;
126     case 164:       pStr = OOO_STRING_SVTOOLS_HTML_S_curren;    break;
127     case 165:       pStr = OOO_STRING_SVTOOLS_HTML_S_yen;       break;
128     case 166:       pStr = OOO_STRING_SVTOOLS_HTML_S_brvbar;    break;
129     case 167:       pStr = OOO_STRING_SVTOOLS_HTML_S_sect;  break;
130     case 168:       pStr = OOO_STRING_SVTOOLS_HTML_S_uml;       break;
131     case 169:       pStr = OOO_STRING_SVTOOLS_HTML_S_copy;  break;
132     case 170:       pStr = OOO_STRING_SVTOOLS_HTML_S_ordf;  break;
133     case 171:       pStr = OOO_STRING_SVTOOLS_HTML_S_laquo; break;
134     case 172:       pStr = OOO_STRING_SVTOOLS_HTML_S_not;       break;
135     case 174:       pStr = OOO_STRING_SVTOOLS_HTML_S_reg;       break;
136     case 175:       pStr = OOO_STRING_SVTOOLS_HTML_S_macr;  break;
137     case 176:       pStr = OOO_STRING_SVTOOLS_HTML_S_deg;       break;
138     case 177:       pStr = OOO_STRING_SVTOOLS_HTML_S_plusmn;    break;
139     case 178:       pStr = OOO_STRING_SVTOOLS_HTML_S_sup2;  break;
140     case 179:       pStr = OOO_STRING_SVTOOLS_HTML_S_sup3;  break;
141     case 180:       pStr = OOO_STRING_SVTOOLS_HTML_S_acute; break;
142     case 181:       pStr = OOO_STRING_SVTOOLS_HTML_S_micro; break;
143     case 182:       pStr = OOO_STRING_SVTOOLS_HTML_S_para;  break;
144     case 183:       pStr = OOO_STRING_SVTOOLS_HTML_S_middot;    break;
145     case 184:       pStr = OOO_STRING_SVTOOLS_HTML_S_cedil; break;
146     case 185:       pStr = OOO_STRING_SVTOOLS_HTML_S_sup1;  break;
147     case 186:       pStr = OOO_STRING_SVTOOLS_HTML_S_ordm;  break;
148     case 187:       pStr = OOO_STRING_SVTOOLS_HTML_S_raquo; break;
149     case 188:       pStr = OOO_STRING_SVTOOLS_HTML_S_frac14;    break;
150     case 189:       pStr = OOO_STRING_SVTOOLS_HTML_S_frac12;    break;
151     case 190:       pStr = OOO_STRING_SVTOOLS_HTML_S_frac34;    break;
152     case 191:       pStr = OOO_STRING_SVTOOLS_HTML_S_iquest;    break;
153 
154     case 192:       pStr = OOO_STRING_SVTOOLS_HTML_C_Agrave;    break;
155     case 193:       pStr = OOO_STRING_SVTOOLS_HTML_C_Aacute;    break;
156     case 194:       pStr = OOO_STRING_SVTOOLS_HTML_C_Acirc; break;
157     case 195:       pStr = OOO_STRING_SVTOOLS_HTML_C_Atilde;    break;
158     case 196:       pStr = OOO_STRING_SVTOOLS_HTML_C_Auml;  break;
159     case 197:       pStr = OOO_STRING_SVTOOLS_HTML_C_Aring; break;
160     case 198:       pStr = OOO_STRING_SVTOOLS_HTML_C_AElig; break;
161     case 199:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ccedil;    break;
162     case 200:       pStr = OOO_STRING_SVTOOLS_HTML_C_Egrave;    break;
163     case 201:       pStr = OOO_STRING_SVTOOLS_HTML_C_Eacute;    break;
164     case 202:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ecirc; break;
165     case 203:       pStr = OOO_STRING_SVTOOLS_HTML_C_Euml;  break;
166     case 204:       pStr = OOO_STRING_SVTOOLS_HTML_C_Igrave;    break;
167     case 205:       pStr = OOO_STRING_SVTOOLS_HTML_C_Iacute;    break;
168     case 206:       pStr = OOO_STRING_SVTOOLS_HTML_C_Icirc; break;
169     case 207:       pStr = OOO_STRING_SVTOOLS_HTML_C_Iuml;  break;
170     case 208:       pStr = OOO_STRING_SVTOOLS_HTML_C_ETH;       break;
171     case 209:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ntilde;    break;
172     case 210:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ograve;    break;
173     case 211:       pStr = OOO_STRING_SVTOOLS_HTML_C_Oacute;    break;
174     case 212:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ocirc; break;
175     case 213:       pStr = OOO_STRING_SVTOOLS_HTML_C_Otilde;    break;
176     case 214:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ouml;  break;
177     case 215:       pStr = OOO_STRING_SVTOOLS_HTML_S_times; break;
178     case 216:       pStr = OOO_STRING_SVTOOLS_HTML_C_Oslash;    break;
179     case 217:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ugrave;    break;
180     case 218:       pStr = OOO_STRING_SVTOOLS_HTML_C_Uacute;    break;
181     case 219:       pStr = OOO_STRING_SVTOOLS_HTML_C_Ucirc; break;
182     case 220:       pStr = OOO_STRING_SVTOOLS_HTML_C_Uuml;  break;
183     case 221:       pStr = OOO_STRING_SVTOOLS_HTML_C_Yacute;    break;
184 
185     case 222:       pStr = OOO_STRING_SVTOOLS_HTML_C_THORN; break;
186     case 223:       pStr = OOO_STRING_SVTOOLS_HTML_C_szlig; break;
187 
188     case 224:       pStr = OOO_STRING_SVTOOLS_HTML_S_agrave;    break;
189     case 225:       pStr = OOO_STRING_SVTOOLS_HTML_S_aacute;    break;
190     case 226:       pStr = OOO_STRING_SVTOOLS_HTML_S_acirc; break;
191     case 227:       pStr = OOO_STRING_SVTOOLS_HTML_S_atilde;    break;
192     case 228:       pStr = OOO_STRING_SVTOOLS_HTML_S_auml;  break;
193     case 229:       pStr = OOO_STRING_SVTOOLS_HTML_S_aring; break;
194     case 230:       pStr = OOO_STRING_SVTOOLS_HTML_S_aelig; break;
195     case 231:       pStr = OOO_STRING_SVTOOLS_HTML_S_ccedil;    break;
196     case 232:       pStr = OOO_STRING_SVTOOLS_HTML_S_egrave;    break;
197     case 233:       pStr = OOO_STRING_SVTOOLS_HTML_S_eacute;    break;
198     case 234:       pStr = OOO_STRING_SVTOOLS_HTML_S_ecirc; break;
199     case 235:       pStr = OOO_STRING_SVTOOLS_HTML_S_euml;  break;
200     case 236:       pStr = OOO_STRING_SVTOOLS_HTML_S_igrave;    break;
201     case 237:       pStr = OOO_STRING_SVTOOLS_HTML_S_iacute;    break;
202     case 238:       pStr = OOO_STRING_SVTOOLS_HTML_S_icirc; break;
203     case 239:       pStr = OOO_STRING_SVTOOLS_HTML_S_iuml;  break;
204     case 240:       pStr = OOO_STRING_SVTOOLS_HTML_S_eth;       break;
205     case 241:       pStr = OOO_STRING_SVTOOLS_HTML_S_ntilde;    break;
206     case 242:       pStr = OOO_STRING_SVTOOLS_HTML_S_ograve;    break;
207     case 243:       pStr = OOO_STRING_SVTOOLS_HTML_S_oacute;    break;
208     case 244:       pStr = OOO_STRING_SVTOOLS_HTML_S_ocirc; break;
209     case 245:       pStr = OOO_STRING_SVTOOLS_HTML_S_otilde;    break;
210     case 246:       pStr = OOO_STRING_SVTOOLS_HTML_S_ouml;  break;
211     case 247:       pStr = OOO_STRING_SVTOOLS_HTML_S_divide;    break;
212     case 248:       pStr = OOO_STRING_SVTOOLS_HTML_S_oslash;    break;
213     case 249:       pStr = OOO_STRING_SVTOOLS_HTML_S_ugrave;    break;
214     case 250:       pStr = OOO_STRING_SVTOOLS_HTML_S_uacute;    break;
215     case 251:       pStr = OOO_STRING_SVTOOLS_HTML_S_ucirc; break;
216     case 252:       pStr = OOO_STRING_SVTOOLS_HTML_S_uuml;  break;
217     case 253:       pStr = OOO_STRING_SVTOOLS_HTML_S_yacute;    break;
218     case 254:       pStr = OOO_STRING_SVTOOLS_HTML_S_thorn; break;
219     case 255:       pStr = OOO_STRING_SVTOOLS_HTML_S_yuml;  break;
220 
221     case 338:       pStr = OOO_STRING_SVTOOLS_HTML_S_OElig; break;
222     case 339:       pStr = OOO_STRING_SVTOOLS_HTML_S_oelig; break;
223     case 352:       pStr = OOO_STRING_SVTOOLS_HTML_S_Scaron;    break;
224     case 353:       pStr = OOO_STRING_SVTOOLS_HTML_S_scaron;    break;
225     case 376:       pStr = OOO_STRING_SVTOOLS_HTML_S_Yuml;  break;
226     case 402:       pStr = OOO_STRING_SVTOOLS_HTML_S_fnof;  break;
227     case 710:       pStr = OOO_STRING_SVTOOLS_HTML_S_circ;  break;
228     case 732:       pStr = OOO_STRING_SVTOOLS_HTML_S_tilde; break;
229 
230     // Greek chars are handled later,
231     // since they should *not* be transformed to entities
232     // when generating Greek text (== using Greek encoding)
233 
234     case 8194:      pStr = OOO_STRING_SVTOOLS_HTML_S_ensp;  break;
235     case 8195:      pStr = OOO_STRING_SVTOOLS_HTML_S_emsp;  break;
236     case 8201:      pStr = OOO_STRING_SVTOOLS_HTML_S_thinsp;    break;
237     case 8204:      pStr = OOO_STRING_SVTOOLS_HTML_S_zwnj;  break;
238     case 8205:      pStr = OOO_STRING_SVTOOLS_HTML_S_zwj;       break;
239     case 8206:      pStr = OOO_STRING_SVTOOLS_HTML_S_lrm;       break;
240     case 8207:      pStr = OOO_STRING_SVTOOLS_HTML_S_rlm;       break;
241     case 8211:      pStr = OOO_STRING_SVTOOLS_HTML_S_ndash; break;
242     case 8212:      pStr = OOO_STRING_SVTOOLS_HTML_S_mdash; break;
243     case 8216:      pStr = OOO_STRING_SVTOOLS_HTML_S_lsquo; break;
244     case 8217:      pStr = OOO_STRING_SVTOOLS_HTML_S_rsquo; break;
245     case 8218:      pStr = OOO_STRING_SVTOOLS_HTML_S_sbquo; break;
246     case 8220:      pStr = OOO_STRING_SVTOOLS_HTML_S_ldquo; break;
247     case 8221:      pStr = OOO_STRING_SVTOOLS_HTML_S_rdquo; break;
248     case 8222:      pStr = OOO_STRING_SVTOOLS_HTML_S_bdquo; break;
249     case 8224:      pStr = OOO_STRING_SVTOOLS_HTML_S_dagger;    break;
250     case 8225:      pStr = OOO_STRING_SVTOOLS_HTML_S_Dagger;    break;
251     case 8226:      pStr = OOO_STRING_SVTOOLS_HTML_S_bull;  break;
252     case 8230:      pStr = OOO_STRING_SVTOOLS_HTML_S_hellip;    break;
253     case 8240:      pStr = OOO_STRING_SVTOOLS_HTML_S_permil;    break;
254     case 8242:      pStr = OOO_STRING_SVTOOLS_HTML_S_prime; break;
255     case 8243:      pStr = OOO_STRING_SVTOOLS_HTML_S_Prime; break;
256     case 8249:      pStr = OOO_STRING_SVTOOLS_HTML_S_lsaquo;    break;
257     case 8250:      pStr = OOO_STRING_SVTOOLS_HTML_S_rsaquo;    break;
258     case 8254:      pStr = OOO_STRING_SVTOOLS_HTML_S_oline; break;
259     case 8260:      pStr = OOO_STRING_SVTOOLS_HTML_S_frasl; break;
260     case 8364:      pStr = OOO_STRING_SVTOOLS_HTML_S_euro;  break;
261     case 8465:      pStr = OOO_STRING_SVTOOLS_HTML_S_image; break;
262     case 8472:      pStr = OOO_STRING_SVTOOLS_HTML_S_weierp;    break;
263     case 8476:      pStr = OOO_STRING_SVTOOLS_HTML_S_real;  break;
264     case 8482:      pStr = OOO_STRING_SVTOOLS_HTML_S_trade; break;
265     case 8501:      pStr = OOO_STRING_SVTOOLS_HTML_S_alefsym;   break;
266     case 8592:      pStr = OOO_STRING_SVTOOLS_HTML_S_larr;  break;
267     case 8593:      pStr = OOO_STRING_SVTOOLS_HTML_S_uarr;  break;
268     case 8594:      pStr = OOO_STRING_SVTOOLS_HTML_S_rarr;  break;
269     case 8595:      pStr = OOO_STRING_SVTOOLS_HTML_S_darr;  break;
270     case 8596:      pStr = OOO_STRING_SVTOOLS_HTML_S_harr;  break;
271     case 8629:      pStr = OOO_STRING_SVTOOLS_HTML_S_crarr; break;
272     case 8656:      pStr = OOO_STRING_SVTOOLS_HTML_S_lArr;  break;
273     case 8657:      pStr = OOO_STRING_SVTOOLS_HTML_S_uArr;  break;
274     case 8658:      pStr = OOO_STRING_SVTOOLS_HTML_S_rArr;  break;
275     case 8659:      pStr = OOO_STRING_SVTOOLS_HTML_S_dArr;  break;
276     case 8660:      pStr = OOO_STRING_SVTOOLS_HTML_S_hArr;  break;
277     case 8704:      pStr = OOO_STRING_SVTOOLS_HTML_S_forall;    break;
278     case 8706:      pStr = OOO_STRING_SVTOOLS_HTML_S_part;  break;
279     case 8707:      pStr = OOO_STRING_SVTOOLS_HTML_S_exist; break;
280     case 8709:      pStr = OOO_STRING_SVTOOLS_HTML_S_empty; break;
281     case 8711:      pStr = OOO_STRING_SVTOOLS_HTML_S_nabla; break;
282     case 8712:      pStr = OOO_STRING_SVTOOLS_HTML_S_isin;  break;
283     case 8713:      pStr = OOO_STRING_SVTOOLS_HTML_S_notin; break;
284     case 8715:      pStr = OOO_STRING_SVTOOLS_HTML_S_ni;        break;
285     case 8719:      pStr = OOO_STRING_SVTOOLS_HTML_S_prod;  break;
286     case 8721:      pStr = OOO_STRING_SVTOOLS_HTML_S_sum;       break;
287     case 8722:      pStr = OOO_STRING_SVTOOLS_HTML_S_minus; break;
288     case 8727:      pStr = OOO_STRING_SVTOOLS_HTML_S_lowast;    break;
289     case 8730:      pStr = OOO_STRING_SVTOOLS_HTML_S_radic; break;
290     case 8733:      pStr = OOO_STRING_SVTOOLS_HTML_S_prop;  break;
291     case 8734:      pStr = OOO_STRING_SVTOOLS_HTML_S_infin; break;
292     case 8736:      pStr = OOO_STRING_SVTOOLS_HTML_S_ang;       break;
293     case 8743:      pStr = OOO_STRING_SVTOOLS_HTML_S_and;       break;
294     case 8744:      pStr = OOO_STRING_SVTOOLS_HTML_S_or;        break;
295     case 8745:      pStr = OOO_STRING_SVTOOLS_HTML_S_cap;       break;
296     case 8746:      pStr = OOO_STRING_SVTOOLS_HTML_S_cup;       break;
297     case 8747:      pStr = OOO_STRING_SVTOOLS_HTML_S_int;       break;
298     case 8756:      pStr = OOO_STRING_SVTOOLS_HTML_S_there4;    break;
299     case 8764:      pStr = OOO_STRING_SVTOOLS_HTML_S_sim;       break;
300     case 8773:      pStr = OOO_STRING_SVTOOLS_HTML_S_cong;  break;
301     case 8776:      pStr = OOO_STRING_SVTOOLS_HTML_S_asymp; break;
302     case 8800:      pStr = OOO_STRING_SVTOOLS_HTML_S_ne;        break;
303     case 8801:      pStr = OOO_STRING_SVTOOLS_HTML_S_equiv; break;
304     case 8804:      pStr = OOO_STRING_SVTOOLS_HTML_S_le;        break;
305     case 8805:      pStr = OOO_STRING_SVTOOLS_HTML_S_ge;        break;
306     case 8834:      pStr = OOO_STRING_SVTOOLS_HTML_S_sub;       break;
307     case 8835:      pStr = OOO_STRING_SVTOOLS_HTML_S_sup;       break;
308     case 8836:      pStr = OOO_STRING_SVTOOLS_HTML_S_nsub;  break;
309     case 8838:      pStr = OOO_STRING_SVTOOLS_HTML_S_sube;  break;
310     case 8839:      pStr = OOO_STRING_SVTOOLS_HTML_S_supe;  break;
311     case 8853:      pStr = OOO_STRING_SVTOOLS_HTML_S_oplus; break;
312     case 8855:      pStr = OOO_STRING_SVTOOLS_HTML_S_otimes;    break;
313     case 8869:      pStr = OOO_STRING_SVTOOLS_HTML_S_perp;  break;
314     case 8901:      pStr = OOO_STRING_SVTOOLS_HTML_S_sdot;  break;
315     case 8968:      pStr = OOO_STRING_SVTOOLS_HTML_S_lceil; break;
316     case 8969:      pStr = OOO_STRING_SVTOOLS_HTML_S_rceil; break;
317     case 8970:      pStr = OOO_STRING_SVTOOLS_HTML_S_lfloor;    break;
318     case 8971:      pStr = OOO_STRING_SVTOOLS_HTML_S_rfloor;    break;
319     case 9001:      pStr = OOO_STRING_SVTOOLS_HTML_S_lang;  break;
320     case 9002:      pStr = OOO_STRING_SVTOOLS_HTML_S_rang;  break;
321     case 9674:      pStr = OOO_STRING_SVTOOLS_HTML_S_loz;       break;
322     case 9824:      pStr = OOO_STRING_SVTOOLS_HTML_S_spades;    break;
323     case 9827:      pStr = OOO_STRING_SVTOOLS_HTML_S_clubs; break;
324     case 9829:      pStr = OOO_STRING_SVTOOLS_HTML_S_hearts;    break;
325     case 9830:      pStr = OOO_STRING_SVTOOLS_HTML_S_diams; break;
326     }
327 
328     // Greek chars: if we do not produce a Greek encoding,
329     // transform them into entities
330     if( !pStr &&
331         ( eDestEnc != RTL_TEXTENCODING_ISO_8859_7 ) &&
332         ( eDestEnc != RTL_TEXTENCODING_MS_1253 ) )
333     {
334         switch( c )
335         {
336         case 913:       pStr = OOO_STRING_SVTOOLS_HTML_S_Alpha; break;
337         case 914:       pStr = OOO_STRING_SVTOOLS_HTML_S_Beta;  break;
338         case 915:       pStr = OOO_STRING_SVTOOLS_HTML_S_Gamma; break;
339         case 916:       pStr = OOO_STRING_SVTOOLS_HTML_S_Delta; break;
340         case 917:       pStr = OOO_STRING_SVTOOLS_HTML_S_Epsilon;   break;
341         case 918:       pStr = OOO_STRING_SVTOOLS_HTML_S_Zeta;  break;
342         case 919:       pStr = OOO_STRING_SVTOOLS_HTML_S_Eta;       break;
343         case 920:       pStr = OOO_STRING_SVTOOLS_HTML_S_Theta; break;
344         case 921:       pStr = OOO_STRING_SVTOOLS_HTML_S_Iota;  break;
345         case 922:       pStr = OOO_STRING_SVTOOLS_HTML_S_Kappa; break;
346         case 923:       pStr = OOO_STRING_SVTOOLS_HTML_S_Lambda;    break;
347         case 924:       pStr = OOO_STRING_SVTOOLS_HTML_S_Mu;        break;
348         case 925:       pStr = OOO_STRING_SVTOOLS_HTML_S_Nu;        break;
349         case 926:       pStr = OOO_STRING_SVTOOLS_HTML_S_Xi;        break;
350         case 927:       pStr = OOO_STRING_SVTOOLS_HTML_S_Omicron;   break;
351         case 928:       pStr = OOO_STRING_SVTOOLS_HTML_S_Pi;        break;
352         case 929:       pStr = OOO_STRING_SVTOOLS_HTML_S_Rho;       break;
353         case 931:       pStr = OOO_STRING_SVTOOLS_HTML_S_Sigma; break;
354         case 932:       pStr = OOO_STRING_SVTOOLS_HTML_S_Tau;       break;
355         case 933:       pStr = OOO_STRING_SVTOOLS_HTML_S_Upsilon;   break;
356         case 934:       pStr = OOO_STRING_SVTOOLS_HTML_S_Phi;       break;
357         case 935:       pStr = OOO_STRING_SVTOOLS_HTML_S_Chi;       break;
358         case 936:       pStr = OOO_STRING_SVTOOLS_HTML_S_Psi;       break;
359         case 937:       pStr = OOO_STRING_SVTOOLS_HTML_S_Omega; break;
360         case 945:       pStr = OOO_STRING_SVTOOLS_HTML_S_alpha; break;
361         case 946:       pStr = OOO_STRING_SVTOOLS_HTML_S_beta;  break;
362         case 947:       pStr = OOO_STRING_SVTOOLS_HTML_S_gamma; break;
363         case 948:       pStr = OOO_STRING_SVTOOLS_HTML_S_delta; break;
364         case 949:       pStr = OOO_STRING_SVTOOLS_HTML_S_epsilon;   break;
365         case 950:       pStr = OOO_STRING_SVTOOLS_HTML_S_zeta;  break;
366         case 951:       pStr = OOO_STRING_SVTOOLS_HTML_S_eta;       break;
367         case 952:       pStr = OOO_STRING_SVTOOLS_HTML_S_theta; break;
368         case 953:       pStr = OOO_STRING_SVTOOLS_HTML_S_iota;  break;
369         case 954:       pStr = OOO_STRING_SVTOOLS_HTML_S_kappa; break;
370         case 955:       pStr = OOO_STRING_SVTOOLS_HTML_S_lambda;    break;
371         case 956:       pStr = OOO_STRING_SVTOOLS_HTML_S_mu;        break;
372         case 957:       pStr = OOO_STRING_SVTOOLS_HTML_S_nu;        break;
373         case 958:       pStr = OOO_STRING_SVTOOLS_HTML_S_xi;        break;
374         case 959:       pStr = OOO_STRING_SVTOOLS_HTML_S_omicron;   break;
375         case 960:       pStr = OOO_STRING_SVTOOLS_HTML_S_pi;        break;
376         case 961:       pStr = OOO_STRING_SVTOOLS_HTML_S_rho;       break;
377         case 962:       pStr = OOO_STRING_SVTOOLS_HTML_S_sigmaf;    break;
378         case 963:       pStr = OOO_STRING_SVTOOLS_HTML_S_sigma; break;
379         case 964:       pStr = OOO_STRING_SVTOOLS_HTML_S_tau;       break;
380         case 965:       pStr = OOO_STRING_SVTOOLS_HTML_S_upsilon;   break;
381         case 966:       pStr = OOO_STRING_SVTOOLS_HTML_S_phi;       break;
382         case 967:       pStr = OOO_STRING_SVTOOLS_HTML_S_chi;       break;
383         case 968:       pStr = OOO_STRING_SVTOOLS_HTML_S_psi;       break;
384         case 969:       pStr = OOO_STRING_SVTOOLS_HTML_S_omega; break;
385         case 977:       pStr = OOO_STRING_SVTOOLS_HTML_S_thetasym;break;
386         case 978:       pStr = OOO_STRING_SVTOOLS_HTML_S_upsih; break;
387         case 982:       pStr = OOO_STRING_SVTOOLS_HTML_S_piv;       break;
388         }
389     }
390 
391     return pStr;
392 }
393 
lcl_FlushContext(HTMLOutContext & rContext,char * pBuffer,sal_uInt32 nFlags)394 static sal_Size lcl_FlushContext(HTMLOutContext& rContext, char* pBuffer, sal_uInt32 nFlags)
395 {
396     sal_uInt32 nInfo = 0;
397     sal_Size nSrcChars;
398     sal_Size nLen = rtl_convertUnicodeToText(rContext.m_hConv, rContext.m_hContext, nullptr, 0,
399                                              pBuffer, TXTCONV_BUFFER_SIZE, nFlags|RTL_UNICODETOTEXT_FLAGS_FLUSH,
400                                              &nInfo, &nSrcChars);
401     DBG_ASSERT((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR|RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) == 0, "HTMLOut: error while flushing");
402     return nLen;
403 }
404 
lcl_ConvertCharToHTML(sal_uInt32 c,HTMLOutContext & rContext,OUString * pNonConvertableChars)405 static OString lcl_ConvertCharToHTML( sal_uInt32 c,
406                             HTMLOutContext& rContext,
407                             OUString *pNonConvertableChars )
408 {
409     assert(rtl::isUnicodeCodePoint(c));
410 
411     OStringBuffer aDest;
412     DBG_ASSERT( RTL_TEXTENCODING_DONTKNOW != rContext.m_eDestEnc,
413                     "wrong destination encoding" );
414     const char *pStr = nullptr;
415     switch( c )
416     {
417     case 0xA0:      // is a hard blank
418         pStr = OOO_STRING_SVTOOLS_HTML_S_nbsp;
419         break;
420     case 0x2011:    // is a hard hyphen
421         pStr = "#8209";
422         break;
423     case 0xAD:      // is a soft hyphen
424         pStr = OOO_STRING_SVTOOLS_HTML_S_shy;
425         break;
426     default:
427         // There may be an entity for the character.
428         // The new HTML4 entities above 255 are not used for UTF-8,
429         // because Netscape 4 does support UTF-8 but does not support
430         // these entities.
431         if( c < 128 || RTL_TEXTENCODING_UTF8 != rContext.m_eDestEnc )
432             pStr = lcl_svhtml_GetEntityForChar( c, rContext.m_eDestEnc );
433         break;
434     }
435 
436     char cBuffer[TXTCONV_BUFFER_SIZE];
437     const sal_uInt32 nFlags = RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE|
438                               RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE|
439                               RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|
440                               RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
441     if( pStr )
442     {
443         sal_Size nLen = lcl_FlushContext(rContext, cBuffer, nFlags);
444         char *pBuffer = cBuffer;
445         while( nLen-- )
446             aDest.append(*pBuffer++);
447         aDest.append('&').append(pStr).append(';');
448     }
449     else
450     {
451         sal_uInt32 nInfo = 0;
452         sal_Size nSrcChars;
453 
454         sal_Unicode utf16[2];
455         auto n = rtl::splitSurrogates(c, utf16);
456         sal_Size nLen = rtl_convertUnicodeToText(rContext.m_hConv,
457                                                  rContext.m_hContext, utf16, n,
458                                                  cBuffer, TXTCONV_BUFFER_SIZE,
459                                                  nFlags, &nInfo, &nSrcChars);
460         if( nLen > 0 && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR|RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) == 0 )
461         {
462             char *pBuffer = cBuffer;
463             while( nLen-- )
464                 aDest.append(*pBuffer++);
465         }
466         else
467         {
468             // If the character could not be converted to the destination
469             // character set, the UNICODE character is exported as character
470             // entity.
471             // coverity[callee_ptr_arith] - its ok
472             nLen = lcl_FlushContext(rContext, cBuffer, nFlags);
473             char *pBuffer = cBuffer;
474             while( nLen-- )
475                 aDest.append(*pBuffer++);
476 
477             aDest.append('&').append('#').append(static_cast<sal_Int32>(c))
478                     // Unicode code points guaranteed to fit into sal_Int32
479                  .append(';');
480             if( pNonConvertableChars )
481             {
482                 OUString cs(&c, 1);
483                 if( -1 == pNonConvertableChars->indexOf( cs ) )
484                     (*pNonConvertableChars) += cs;
485             }
486         }
487     }
488     return aDest.makeStringAndClear();
489 }
490 
lcl_FlushToAscii(HTMLOutContext & rContext)491 static OString lcl_FlushToAscii( HTMLOutContext& rContext )
492 {
493     OStringBuffer aDest;
494 
495     char cBuffer[TXTCONV_BUFFER_SIZE];
496     const sal_uInt32 nFlags = RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE|
497                               RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE|
498                               RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|
499                               RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR;
500     sal_Size nLen = lcl_FlushContext(rContext, cBuffer, nFlags);
501     char *pBuffer = cBuffer;
502     while( nLen-- )
503         aDest.append(*pBuffer++);
504     return aDest.makeStringAndClear();
505 }
506 
ConvertStringToHTML(const OUString & rSrc,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)507 OString HTMLOutFuncs::ConvertStringToHTML( const OUString& rSrc,
508     rtl_TextEncoding eDestEnc, OUString *pNonConvertableChars )
509 {
510     HTMLOutContext aContext( eDestEnc );
511     OStringBuffer aDest;
512     for( sal_Int32 i=0, nLen = rSrc.getLength(); i < nLen; )
513         aDest.append(lcl_ConvertCharToHTML(
514             rSrc.iterateCodePoints(&i), aContext, pNonConvertableChars));
515     aDest.append(lcl_FlushToAscii(aContext));
516     return aDest.makeStringAndClear();
517 }
518 
Out_AsciiTag(SvStream & rStream,std::string_view rStr,bool bOn)519 SvStream& HTMLOutFuncs::Out_AsciiTag( SvStream& rStream, std::string_view rStr,
520                                       bool bOn )
521 {
522     if(bOn)
523         rStream.WriteCharPtr("<");
524     else
525         rStream.WriteCharPtr("</");
526 
527     rStream.WriteOString(rStr).WriteChar('>');
528 
529     return rStream;
530 }
531 
Out_Char(SvStream & rStream,sal_uInt32 c,HTMLOutContext & rContext,OUString * pNonConvertableChars)532 SvStream& HTMLOutFuncs::Out_Char( SvStream& rStream, sal_uInt32 c,
533                                   HTMLOutContext& rContext,
534                                   OUString *pNonConvertableChars )
535 {
536     OString sOut = lcl_ConvertCharToHTML( c, rContext, pNonConvertableChars );
537     rStream.WriteOString( sOut );
538     return rStream;
539 }
540 
Out_String(SvStream & rStream,const OUString & rOUStr,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)541 SvStream& HTMLOutFuncs::Out_String( SvStream& rStream, const OUString& rOUStr,
542                                     rtl_TextEncoding eDestEnc,
543                                     OUString *pNonConvertableChars )
544 {
545     HTMLOutContext aContext( eDestEnc );
546     sal_Int32 nLen = rOUStr.getLength();
547     for( sal_Int32 n = 0; n < nLen; )
548         HTMLOutFuncs::Out_Char( rStream, rOUStr.iterateCodePoints(&n),
549                                 aContext, pNonConvertableChars );
550     HTMLOutFuncs::FlushToAscii( rStream, aContext );
551     return rStream;
552 }
553 
FlushToAscii(SvStream & rStream,HTMLOutContext & rContext)554 SvStream& HTMLOutFuncs::FlushToAscii( SvStream& rStream,
555                                        HTMLOutContext& rContext )
556 {
557     OString sOut = lcl_FlushToAscii( rContext );
558 
559     if (!sOut.isEmpty())
560         rStream.WriteOString( sOut );
561 
562     return rStream;
563 }
564 
Out_Hex(SvStream & rStream,sal_uInt32 nHex,sal_uInt8 nLen)565 SvStream& HTMLOutFuncs::Out_Hex( SvStream& rStream, sal_uInt32 nHex, sal_uInt8 nLen )
566 {                                                  // out into a stream
567     char aNToABuf[] = "0000000000000000";
568 
569     DBG_ASSERT( nLen < sizeof(aNToABuf), "too many places" );
570     if( nLen>=sizeof(aNToABuf) )
571         nLen = (sizeof(aNToABuf)-1);
572 
573     // set pointer to end of buffer
574     char *pStr = aNToABuf + (sizeof(aNToABuf)-1);
575     for( sal_uInt8 n = 0; n < nLen; ++n )
576     {
577         *(--pStr) = static_cast<char>(nHex & 0xf ) + 48;
578         if( *pStr > '9' )
579             *pStr += 39;
580         nHex >>= 4;
581     }
582     return rStream.WriteCharPtr( pStr );
583 }
584 
585 
Out_Color(SvStream & rStream,const Color & rColor,bool bXHTML)586 SvStream& HTMLOutFuncs::Out_Color( SvStream& rStream, const Color& rColor, bool bXHTML )
587 {
588     rStream.WriteCharPtr( "\"" );
589     if (bXHTML)
590         rStream.WriteCharPtr( "color: " );
591     rStream.WriteCharPtr( "#" );
592     if( rColor == COL_AUTO )
593     {
594         rStream.WriteCharPtr( "000000" );
595     }
596     else
597     {
598         Out_Hex( rStream, rColor.GetRed(), 2 );
599         Out_Hex( rStream, rColor.GetGreen(), 2 );
600         Out_Hex( rStream, rColor.GetBlue(), 2 );
601     }
602     rStream.WriteChar( '\"' );
603 
604     return rStream;
605 }
606 
Out_ImageMap(SvStream & rStream,const OUString & rBaseURL,const ImageMap & rIMap,const OUString & rName,const HTMLOutEvent * pEventTable,bool bOutStarBasic,const char * pDelim,const char * pIndentArea,const char * pIndentMap,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)607 SvStream& HTMLOutFuncs::Out_ImageMap( SvStream& rStream,
608                                       const OUString& rBaseURL,
609                                       const ImageMap& rIMap,
610                                       const OUString& rName,
611                                       const HTMLOutEvent *pEventTable,
612                                       bool bOutStarBasic,
613                                       const char *pDelim,
614                                       const char *pIndentArea,
615                                       const char *pIndentMap,
616                                       rtl_TextEncoding eDestEnc,
617                                       OUString *pNonConvertableChars    )
618 {
619     if( RTL_TEXTENCODING_DONTKNOW == eDestEnc )
620         eDestEnc = osl_getThreadTextEncoding();
621 
622     const OUString& rOutName = !rName.isEmpty() ? rName : rIMap.GetName();
623     DBG_ASSERT( !rOutName.isEmpty(), "No ImageMap-Name" );
624     if( rOutName.isEmpty() )
625         return rStream;
626 
627     OStringBuffer sOut;
628     sOut.append(OString::Concat("<") +
629             OOO_STRING_SVTOOLS_HTML_map
630             " "
631             OOO_STRING_SVTOOLS_HTML_O_name
632             "=\"");
633     rStream.WriteOString( sOut.makeStringAndClear() );
634     Out_String( rStream, rOutName, eDestEnc, pNonConvertableChars );
635     rStream.WriteCharPtr( "\">" );
636 
637     for( size_t i=0; i<rIMap.GetIMapObjectCount(); i++ )
638     {
639         const IMapObject* pObj = rIMap.GetIMapObject( i );
640         DBG_ASSERT( pObj, "Where is the ImageMap-Object?" );
641 
642         if( pObj )
643         {
644             const char *pShape = nullptr;
645             OString aCoords;
646             switch( pObj->GetType() )
647             {
648             case IMapObjectType::Rectangle:
649                 {
650                     const IMapRectangleObject* pRectObj =
651                         static_cast<const IMapRectangleObject *>(pObj);
652                     pShape = OOO_STRING_SVTOOLS_HTML_SH_rect;
653                     tools::Rectangle aRect( pRectObj->GetRectangle() );
654 
655                     aCoords = OStringBuffer()
656                         .append(static_cast<sal_Int32>(aRect.Left()))
657                         .append(',')
658                         .append(static_cast<sal_Int32>(aRect.Top()))
659                         .append(',')
660                         .append(static_cast<sal_Int32>(aRect.Right()))
661                         .append(',')
662                         .append(static_cast<sal_Int32>(aRect.Bottom()))
663                         .makeStringAndClear();
664                 }
665                 break;
666             case IMapObjectType::Circle:
667                 {
668                     const IMapCircleObject* pCirc =
669                         static_cast<const IMapCircleObject *>(pObj);
670                     pShape= OOO_STRING_SVTOOLS_HTML_SH_circ;
671                     Point aCenter( pCirc->GetCenter() );
672                     tools::Long nOff = pCirc->GetRadius();
673 
674                     aCoords = OStringBuffer()
675                         .append(static_cast<sal_Int32>(aCenter.X()))
676                         .append(',')
677                         .append(static_cast<sal_Int32>(aCenter.Y()))
678                         .append(',')
679                         .append(static_cast<sal_Int32>(nOff))
680                         .makeStringAndClear();
681                 }
682                 break;
683             case IMapObjectType::Polygon:
684                 {
685                     const IMapPolygonObject* pPolyObj =
686                         static_cast<const IMapPolygonObject *>(pObj);
687                     pShape= OOO_STRING_SVTOOLS_HTML_SH_poly;
688                     tools::Polygon aPoly( pPolyObj->GetPolygon() );
689                     sal_uInt16 nCount = aPoly.GetSize();
690                     OStringBuffer aTmpBuf;
691                     if( nCount>0 )
692                     {
693                         const Point& rPoint = aPoly[0];
694                         aTmpBuf.append(static_cast<sal_Int32>(rPoint.X()))
695                             .append(',')
696                             .append(static_cast<sal_Int32>(rPoint.Y()));
697                     }
698                     for( sal_uInt16 j=1; j<nCount; j++ )
699                     {
700                         const Point& rPoint = aPoly[j];
701                         aTmpBuf.append(',')
702                             .append(static_cast<sal_Int32>(rPoint.X()))
703                             .append(',')
704                             .append(static_cast<sal_Int32>(rPoint.Y()));
705                     }
706                     aCoords = aTmpBuf.makeStringAndClear();
707                 }
708                 break;
709             default:
710                 DBG_ASSERT( pShape, "unknown IMapObject" );
711                 break;
712             }
713 
714             if( pShape )
715             {
716                 if( pDelim )
717                     rStream.WriteCharPtr( pDelim );
718                 if( pIndentArea )
719                     rStream.WriteCharPtr( pIndentArea );
720 
721                 sOut.append(OString::Concat("<") + OOO_STRING_SVTOOLS_HTML_area
722                         " " OOO_STRING_SVTOOLS_HTML_O_shape
723                         "=" + pShape + " "
724                         OOO_STRING_SVTOOLS_HTML_O_coords "=\"" +
725                         aCoords + "\" ");
726                 rStream.WriteOString( sOut.makeStringAndClear() );
727 
728                 OUString aURL( pObj->GetURL() );
729                 if( !aURL.isEmpty() && pObj->IsActive() )
730                 {
731                     aURL = URIHelper::simpleNormalizedMakeRelative(
732                         rBaseURL, aURL );
733                     sOut.append(OOO_STRING_SVTOOLS_HTML_O_href "=\"");
734                     rStream.WriteOString( sOut.makeStringAndClear() );
735                     Out_String( rStream, aURL, eDestEnc, pNonConvertableChars ).WriteChar( '\"' );
736                 }
737                 else
738                     rStream.WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_nohref );
739 
740                 const OUString& rObjName = pObj->GetName();
741                 if( !rObjName.isEmpty() )
742                 {
743                     sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_name "=\"");
744                     rStream.WriteOString( sOut.makeStringAndClear() );
745                     Out_String( rStream, rObjName, eDestEnc, pNonConvertableChars ).WriteChar( '\"' );
746                 }
747 
748                 const OUString& rTarget = pObj->GetTarget();
749                 if( !rTarget.isEmpty() && pObj->IsActive() )
750                 {
751                     sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_target "=\"");
752                     rStream.WriteOString( sOut.makeStringAndClear() );
753                     Out_String( rStream, rTarget, eDestEnc, pNonConvertableChars ).WriteChar( '\"' );
754                 }
755 
756                 OUString rDesc( pObj->GetAltText() );
757                 if( rDesc.isEmpty() )
758                     rDesc = pObj->GetDesc();
759 
760                 if( !rDesc.isEmpty() )
761                 {
762                     sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_alt "=\"");
763                     rStream.WriteOString( sOut.makeStringAndClear() );
764                     Out_String( rStream, rDesc, eDestEnc, pNonConvertableChars ).WriteChar( '\"' );
765                 }
766 
767                 const SvxMacroTableDtor& rMacroTab = pObj->GetMacroTable();
768                 if( pEventTable && !rMacroTab.empty() )
769                     Out_Events( rStream, rMacroTab, pEventTable,
770                                 bOutStarBasic, eDestEnc, pNonConvertableChars );
771 
772                 rStream.WriteChar( '>' );
773             }
774         }
775 
776     }
777 
778     if( pDelim )
779         rStream.WriteCharPtr( pDelim );
780     if( pIndentMap )
781         rStream.WriteCharPtr( pIndentMap );
782     Out_AsciiTag( rStream, OOO_STRING_SVTOOLS_HTML_map, false );
783 
784     return rStream;
785 }
786 
OutScript(SvStream & rStrm,const OUString & rBaseURL,std::u16string_view rSource,const OUString & rLanguage,ScriptType eScriptType,const OUString & rSrc,const OUString * pSBLibrary,const OUString * pSBModule,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)787 SvStream& HTMLOutFuncs::OutScript( SvStream& rStrm,
788                                    const OUString& rBaseURL,
789                                    std::u16string_view rSource,
790                                    const OUString& rLanguage,
791                                    ScriptType eScriptType,
792                                    const OUString& rSrc,
793                                    const OUString *pSBLibrary,
794                                    const OUString *pSBModule,
795                                    rtl_TextEncoding eDestEnc,
796                                    OUString *pNonConvertableChars )
797 {
798     if( RTL_TEXTENCODING_DONTKNOW == eDestEnc )
799         eDestEnc = osl_getThreadTextEncoding();
800 
801     // script is not indented!
802     OStringBuffer sOut;
803     sOut.append('<')
804         .append(OOO_STRING_SVTOOLS_HTML_script);
805 
806     if( !rLanguage.isEmpty() )
807     {
808         sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_language "=\"");
809         rStrm.WriteOString( sOut.makeStringAndClear() );
810         Out_String( rStrm, rLanguage, eDestEnc, pNonConvertableChars );
811         sOut.append('\"');
812     }
813 
814     if( !rSrc.isEmpty() )
815     {
816         sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_src "=\"");
817         rStrm.WriteOString( sOut.makeStringAndClear() );
818         Out_String( rStrm, URIHelper::simpleNormalizedMakeRelative(rBaseURL, rSrc), eDestEnc, pNonConvertableChars );
819         sOut.append('\"');
820     }
821 
822     if( STARBASIC != eScriptType && pSBLibrary )
823     {
824         sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_sdlibrary "=\"");
825         rStrm.WriteOString( sOut.makeStringAndClear() );
826         Out_String( rStrm, *pSBLibrary, eDestEnc, pNonConvertableChars );
827         sOut.append('\"');
828     }
829 
830     if( STARBASIC != eScriptType && pSBModule )
831     {
832         sOut.append(" " OOO_STRING_SVTOOLS_HTML_O_sdmodule "=\"");
833         rStrm.WriteOString( sOut.makeStringAndClear() );
834         Out_String( rStrm, *pSBModule, eDestEnc, pNonConvertableChars );
835         sOut.append('\"');
836     }
837 
838     sOut.append('>');
839 
840     rStrm.WriteOString( sOut.makeStringAndClear() );
841 
842     if( !rSource.empty() || pSBLibrary || pSBModule )
843     {
844         rStrm.WriteCharPtr( SAL_NEWLINE_STRING );
845 
846         if( JAVASCRIPT != eScriptType )
847         {
848             rStrm.WriteCharPtr( "<!--" )
849                  .WriteCharPtr( SAL_NEWLINE_STRING );
850         }
851 
852         if( STARBASIC == eScriptType )
853         {
854             if( pSBLibrary )
855             {
856                 sOut.append("' " OOO_STRING_SVTOOLS_HTML_SB_library " " +
857                             OUStringToOString(*pSBLibrary, eDestEnc));
858                 rStrm.WriteOString( sOut.makeStringAndClear() ).WriteCharPtr( SAL_NEWLINE_STRING );
859             }
860 
861             if( pSBModule )
862             {
863                 sOut.append("' " OOO_STRING_SVTOOLS_HTML_SB_module " " +
864                         OUStringToOString(*pSBModule, eDestEnc));
865                 rStrm.WriteOString( sOut.makeStringAndClear() ).WriteCharPtr( SAL_NEWLINE_STRING );
866             }
867         }
868 
869         if( !rSource.empty() )
870         {
871             // we write the module in ANSI-charset, but with
872             // the system new line.
873             const OString sSource(OUStringToOString(rSource, eDestEnc));
874             rStrm.WriteOString( sSource ).WriteCharPtr( SAL_NEWLINE_STRING );
875         }
876         rStrm.WriteCharPtr( SAL_NEWLINE_STRING );
877 
878         if( JAVASCRIPT != eScriptType )
879         {
880             // MIB/MM: if it is not StarBasic, a // could be wrong.
881             // As the comment is removed during reading, it is not helping us...
882             rStrm.WriteCharPtr( STARBASIC == eScriptType ? "' -->" : "// -->" )
883                  .WriteCharPtr( SAL_NEWLINE_STRING );
884         }
885     }
886 
887     HTMLOutFuncs::Out_AsciiTag( rStrm, OOO_STRING_SVTOOLS_HTML_script, false );
888 
889     return rStrm;
890 }
891 
892 
Out_Events(SvStream & rStrm,const SvxMacroTableDtor & rMacroTable,const HTMLOutEvent * pEventTable,bool bOutStarBasic,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)893 SvStream& HTMLOutFuncs::Out_Events( SvStream& rStrm,
894                                     const SvxMacroTableDtor& rMacroTable,
895                                     const HTMLOutEvent *pEventTable,
896                                     bool bOutStarBasic,
897                                     rtl_TextEncoding eDestEnc,
898                                     OUString *pNonConvertableChars )
899 {
900     sal_uInt16 i=0;
901     while( pEventTable[i].pBasicName || pEventTable[i].pJavaName )
902     {
903         const SvxMacro *pMacro =
904             rMacroTable.Get( pEventTable[i].nEvent );
905 
906         if( pMacro && pMacro->HasMacro() &&
907             ( JAVASCRIPT == pMacro->GetScriptType() || bOutStarBasic ))
908         {
909             const char *pStr = STARBASIC == pMacro->GetScriptType()
910                 ? pEventTable[i].pBasicName
911                 : pEventTable[i].pJavaName;
912 
913             if( pStr )
914             {
915                 OString sOut = OString::Concat(" ") + pStr + "=\"";
916                 rStrm.WriteOString( sOut );
917 
918                 Out_String( rStrm, pMacro->GetMacName(), eDestEnc, pNonConvertableChars ).WriteChar( '\"' );
919             }
920         }
921         i++;
922     }
923 
924     return rStrm;
925 }
926 
CreateTableDataOptionsValNum(bool bValue,double fVal,sal_uInt32 nFormat,SvNumberFormatter & rFormatter,rtl_TextEncoding eDestEnc,OUString * pNonConvertableChars)927 OString HTMLOutFuncs::CreateTableDataOptionsValNum(
928             bool bValue,
929             double fVal, sal_uInt32 nFormat, SvNumberFormatter& rFormatter,
930             rtl_TextEncoding eDestEnc, OUString* pNonConvertableChars)
931 {
932     OStringBuffer aStrTD;
933 
934     if ( bValue )
935     {
936         // printf / scanf is not precise enough
937         OUString aValStr;
938         rFormatter.GetInputLineString( fVal, 0, aValStr );
939         OString sTmp(OUStringToOString(aValStr, eDestEnc));
940         aStrTD.append(" " OOO_STRING_SVTOOLS_HTML_O_SDval "=\"" +
941                 sTmp + "\"");
942     }
943     if ( bValue || nFormat )
944     {
945         aStrTD.append(" " OOO_STRING_SVTOOLS_HTML_O_SDnum "=\"" +
946             OString::number(static_cast<sal_uInt16>(
947                 Application::GetSettings().GetLanguageTag().getLanguageType())) +
948                 ";"); // Language for Format 0
949         if ( nFormat )
950         {
951             OString aNumStr;
952             LanguageType nLang;
953             const SvNumberformat* pFormatEntry = rFormatter.GetEntry( nFormat );
954             if ( pFormatEntry )
955             {
956                 aNumStr = ConvertStringToHTML( pFormatEntry->GetFormatstring(),
957                     eDestEnc, pNonConvertableChars );
958                 nLang = pFormatEntry->GetLanguage();
959             }
960             else
961                 nLang = LANGUAGE_SYSTEM;
962             aStrTD.append(static_cast<sal_Int32>(static_cast<sal_uInt16>(nLang))).append(';').
963                 append(aNumStr);
964         }
965         aStrTD.append('\"');
966     }
967     return aStrTD.makeStringAndClear();
968 }
969 
PrivateURLToInternalImg(OUString & rURL)970 bool HTMLOutFuncs::PrivateURLToInternalImg( OUString& rURL )
971 {
972     if( rURL.startsWith(OOO_STRING_SVTOOLS_HTML_private_image) )
973     {
974         rURL = rURL.copy( strlen(OOO_STRING_SVTOOLS_HTML_private_image) );
975         return true;
976     }
977 
978     return false;
979 }
980 
applyColor(HtmlWriter & rHtmlWriter,std::string_view aAttributeName,const Color & rColor)981 void HtmlWriterHelper::applyColor(HtmlWriter& rHtmlWriter, std::string_view aAttributeName, const Color& rColor)
982 {
983     OStringBuffer sBuffer;
984 
985     if( rColor == COL_AUTO )
986     {
987         sBuffer.append("#000000");
988     }
989     else
990     {
991         sBuffer.append('#');
992         std::ostringstream sStringStream;
993         sStringStream
994             << std::right
995             << std::setfill('0')
996             << std::setw(6)
997             << std::hex
998             << sal_uInt32(rColor.GetRGBColor());
999         sBuffer.append(sStringStream.str().c_str());
1000     }
1001 
1002     rHtmlWriter.attribute(aAttributeName, sBuffer.makeStringAndClear());
1003 }
1004 
1005 
applyEvents(HtmlWriter & rHtmlWriter,const SvxMacroTableDtor & rMacroTable,const HTMLOutEvent * pEventTable,bool bOutStarBasic)1006 void HtmlWriterHelper::applyEvents(HtmlWriter& rHtmlWriter, const SvxMacroTableDtor& rMacroTable, const HTMLOutEvent* pEventTable, bool bOutStarBasic)
1007 {
1008     sal_uInt16 i = 0;
1009     while (pEventTable[i].pBasicName || pEventTable[i].pJavaName)
1010     {
1011         const SvxMacro* pMacro = rMacroTable.Get(pEventTable[i].nEvent);
1012 
1013         if (pMacro && pMacro->HasMacro() && (JAVASCRIPT == pMacro->GetScriptType() || bOutStarBasic))
1014         {
1015             const char* pAttributeName = nullptr;
1016             if (STARBASIC == pMacro->GetScriptType())
1017                 pAttributeName = pEventTable[i].pBasicName;
1018             else
1019                 pAttributeName = pEventTable[i].pJavaName;
1020 
1021             if (pAttributeName)
1022             {
1023                 rHtmlWriter.attribute(pAttributeName, OUStringToOString(pMacro->GetMacName(), RTL_TEXTENCODING_UTF8));
1024             }
1025         }
1026         i++;
1027     }
1028 }
1029 
1030 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1031