Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / starmath / source / rtfexport.cxx
blob9835ffbf9f4a88cc634d9cbedcd22141ecd24a50
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "rtfexport.hxx"
11 #include <node.hxx>
13 #include <svtools/rtfkeywd.hxx>
14 #include <filter/msfilter/rtfutil.hxx>
16 SmRtfExport::SmRtfExport(const SmNode* pIn)
17 : SmWordExportBase(pIn)
18 , m_pBuffer(nullptr)
19 , m_nEncoding(RTL_TEXTENCODING_DONTKNOW)
23 void SmRtfExport::ConvertFromStarMath(OStringBuffer& rBuffer, rtl_TextEncoding nEncoding)
25 if (!m_pTree)
26 return;
27 m_pBuffer = &rBuffer;
28 m_nEncoding = nEncoding;
29 m_pBuffer->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE LO_STRING_SVTOOLS_RTF_MOMATH " ");
30 HandleNode(m_pTree, 0);
31 m_pBuffer->append("}"); // moMath
34 // NOTE: This is still work in progress and unfinished, but it already covers a good
35 // part of the rtf math stuff.
37 void SmRtfExport::HandleVerticalStack(const SmNode* pNode, int nLevel)
39 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MEQARR " ");
40 int size = pNode->GetNumSubNodes();
41 for (int i = 0; i < size; ++i)
43 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
44 HandleNode(pNode->GetSubNode(i), nLevel + 1);
45 m_pBuffer->append("}"); // me
47 m_pBuffer->append("}"); // meqArr
50 void SmRtfExport::HandleText(const SmNode* pNode, int /*nLevel*/)
52 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MR " ");
54 if (pNode->GetToken().eType == TTEXT) // literal text
55 m_pBuffer->append(LO_STRING_SVTOOLS_RTF_MNOR " ");
57 auto pTemp = static_cast<const SmTextNode*>(pNode);
58 SAL_INFO("starmath.rtf", "Text: " << pTemp->GetText());
59 for (sal_Int32 i = 0; i < pTemp->GetText().getLength(); i++)
61 sal_uInt16 nChar = pTemp->GetText()[i];
62 OUString aValue(SmTextNode::ConvertSymbolToUnicode(nChar));
63 m_pBuffer->append(msfilter::rtfutil::OutString(aValue, m_nEncoding));
66 m_pBuffer->append("}"); // mr
69 void SmRtfExport::HandleFractions(const SmNode* pNode, int nLevel, const char* type)
71 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MF " ");
72 if (type)
74 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MFPR " ");
75 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MTYPE " ");
76 m_pBuffer->append(type);
77 m_pBuffer->append("}"); // mtype
78 m_pBuffer->append("}"); // mfPr
80 assert(pNode->GetNumSubNodes() == 3);
81 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MNUM " ");
82 HandleNode(pNode->GetSubNode(0), nLevel + 1);
83 m_pBuffer->append("}"); // mnum
84 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEN " ");
85 HandleNode(pNode->GetSubNode(2), nLevel + 1);
86 m_pBuffer->append("}"); // mden
87 m_pBuffer->append("}"); // mf
90 void SmRtfExport::HandleAttribute(const SmAttributNode* pNode, int nLevel)
92 switch (pNode->Attribute()->GetToken().eType)
94 case TCHECK:
95 case TACUTE:
96 case TGRAVE:
97 case TBREVE:
98 case TCIRCLE:
99 case TVEC:
100 case TTILDE:
101 case THAT:
102 case TDOT:
103 case TDDOT:
104 case TDDDOT:
105 case TWIDETILDE:
106 case TWIDEHAT:
107 case TWIDEVEC:
108 case TBAR:
110 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MACC " ");
111 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MACCPR " ");
112 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MCHR " ");
113 OUString aValue(pNode->Attribute()->GetToken().cMathChar);
114 m_pBuffer->append(msfilter::rtfutil::OutString(aValue, m_nEncoding));
115 m_pBuffer->append("}"); // mchr
116 m_pBuffer->append("}"); // maccPr
117 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
118 HandleNode(pNode->Body(), nLevel + 1);
119 m_pBuffer->append("}"); // me
120 m_pBuffer->append("}"); // macc
121 break;
123 case TOVERLINE:
124 case TUNDERLINE:
125 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBAR " ");
126 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBARPR " ");
127 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MPOS " ");
128 m_pBuffer->append((pNode->Attribute()->GetToken().eType == TUNDERLINE) ? "bot" : "top");
129 m_pBuffer->append("}"); // mpos
130 m_pBuffer->append("}"); // mbarPr
131 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
132 HandleNode(pNode->Body(), nLevel + 1);
133 m_pBuffer->append("}"); // me
134 m_pBuffer->append("}"); // mbar
135 break;
136 case TOVERSTRIKE:
137 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBORDERBOX " ");
138 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBORDERBOXPR " ");
139 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDETOP " 1}");
140 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDEBOT " 1}");
141 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDELEFT " 1}");
142 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDERIGHT " 1}");
143 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSTRIKEH " 1}");
144 m_pBuffer->append("}"); // mborderBoxPr
145 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
146 HandleNode(pNode->Body(), nLevel + 1);
147 m_pBuffer->append("}"); // me
148 m_pBuffer->append("}"); // mborderBox
149 break;
150 default:
151 HandleAllSubNodes(pNode, nLevel);
152 break;
156 void SmRtfExport::HandleRoot(const SmRootNode* pNode, int nLevel)
158 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MRAD " ");
159 if (const SmNode* argument = pNode->Argument())
161 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEG " ");
162 HandleNode(argument, nLevel + 1);
163 m_pBuffer->append("}"); // mdeg
165 else
167 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MRADPR " ");
168 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEGHIDE " 1}");
169 m_pBuffer->append("}"); // mradPr
170 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEG " }"); // empty but present
172 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
173 HandleNode(pNode->Body(), nLevel + 1);
174 m_pBuffer->append("}"); // me
175 m_pBuffer->append("}"); // mrad
178 namespace
180 OString mathSymbolToString(const SmNode* node, rtl_TextEncoding nEncoding)
182 assert(node->GetType() == SmNodeType::Math || node->GetType() == SmNodeType::MathIdent);
183 auto txtnode = static_cast<const SmTextNode*>(node);
184 if (txtnode->GetText().isEmpty())
185 return OString();
186 assert(txtnode->GetText().getLength() == 1);
187 sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode(txtnode->GetText()[0]);
188 OUString aValue(chr);
189 return msfilter::rtfutil::OutString(aValue, nEncoding);
193 void SmRtfExport::HandleOperator(const SmOperNode* pNode, int nLevel)
195 SAL_INFO("starmath.rtf", "Operator: " << int(pNode->GetToken().eType));
196 switch (pNode->GetToken().eType)
198 case TINT:
199 case TINTD:
200 case TIINT:
201 case TIIINT:
202 case TLINT:
203 case TLLINT:
204 case TLLLINT:
205 case TPROD:
206 case TCOPROD:
207 case TSUM:
209 const SmSubSupNode* subsup
210 = pNode->GetSubNode(0)->GetType() == SmNodeType::SubSup
211 ? static_cast<const SmSubSupNode*>(pNode->GetSubNode(0))
212 : nullptr;
213 const SmNode* operation = subsup ? subsup->GetBody() : pNode->GetSubNode(0);
214 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MNARY " ");
215 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MNARYPR " ");
216 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MCHR " ");
217 m_pBuffer->append(mathSymbolToString(operation, m_nEncoding));
218 m_pBuffer->append("}"); // mchr
219 if (!subsup || !subsup->GetSubSup(CSUB))
220 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUBHIDE " 1}");
221 if (!subsup || !subsup->GetSubSup(CSUP))
222 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUPHIDE " 1}");
223 m_pBuffer->append("}"); // mnaryPr
224 if (!subsup || !subsup->GetSubSup(CSUB))
225 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " }");
226 else
228 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
229 HandleNode(subsup->GetSubSup(CSUB), nLevel + 1);
230 m_pBuffer->append("}"); // msub
232 if (!subsup || !subsup->GetSubSup(CSUP))
233 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " }");
234 else
236 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
237 HandleNode(subsup->GetSubSup(CSUP), nLevel + 1);
238 m_pBuffer->append("}"); // msup
240 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
241 HandleNode(pNode->GetSubNode(1), nLevel + 1); // body
242 m_pBuffer->append("}"); // me
243 m_pBuffer->append("}"); // mnary
244 break;
246 case TLIM:
247 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MFUNC " ");
248 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MFNAME " ");
249 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMLOW " ");
250 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
251 HandleNode(pNode->GetSymbol(), nLevel + 1);
252 m_pBuffer->append("}"); // me
253 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
254 if (const SmSubSupNode* subsup
255 = pNode->GetSubNode(0)->GetType() == SmNodeType::SubSup
256 ? static_cast<const SmSubSupNode*>(pNode->GetSubNode(0))
257 : nullptr)
258 if (subsup->GetSubSup(CSUB))
259 HandleNode(subsup->GetSubSup(CSUB), nLevel + 1);
260 m_pBuffer->append("}"); // mlim
261 m_pBuffer->append("}"); // mlimLow
262 m_pBuffer->append("}"); // mfName
263 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
264 HandleNode(pNode->GetSubNode(1), nLevel + 1); // body
265 m_pBuffer->append("}"); // me
266 m_pBuffer->append("}"); // mfunc
267 break;
268 default:
269 SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled oper type");
270 break;
274 void SmRtfExport::HandleSubSupScriptInternal(const SmSubSupNode* pNode, int nLevel, int flags)
276 // rtf supports only a certain combination of sub/super scripts, but LO can have any,
277 // so try to merge it using several tags if necessary
278 if (flags == 0) // none
279 return;
280 if ((flags & (1 << RSUP | 1 << RSUB)) == (1 << RSUP | 1 << RSUB))
282 // m:sSubSup
283 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSSUBSUP " ");
284 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
285 flags &= ~(1 << RSUP | 1 << RSUB);
286 if (flags == 0)
287 HandleNode(pNode->GetBody(), nLevel + 1);
288 else
289 HandleSubSupScriptInternal(pNode, nLevel, flags);
290 m_pBuffer->append("}"); // me
291 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
292 HandleNode(pNode->GetSubSup(RSUB), nLevel + 1);
293 m_pBuffer->append("}"); // msub
294 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
295 HandleNode(pNode->GetSubSup(RSUP), nLevel + 1);
296 m_pBuffer->append("}"); // msup
297 m_pBuffer->append("}"); // msubSup
299 else if ((flags & (1 << RSUB)) == 1 << RSUB)
301 // m:sSub
302 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSSUB " ");
303 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
304 flags &= ~(1 << RSUB);
305 if (flags == 0)
306 HandleNode(pNode->GetBody(), nLevel + 1);
307 else
308 HandleSubSupScriptInternal(pNode, nLevel, flags);
309 m_pBuffer->append("}"); // me
310 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
311 HandleNode(pNode->GetSubSup(RSUB), nLevel + 1);
312 m_pBuffer->append("}"); // msub
313 m_pBuffer->append("}"); // msSub
315 else if ((flags & (1 << RSUP)) == 1 << RSUP)
317 // m:sSup
318 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSSUP " ");
319 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
320 flags &= ~(1 << RSUP);
321 if (flags == 0)
322 HandleNode(pNode->GetBody(), nLevel + 1);
323 else
324 HandleSubSupScriptInternal(pNode, nLevel, flags);
325 m_pBuffer->append("}"); // me
326 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
327 HandleNode(pNode->GetSubSup(RSUP), nLevel + 1);
328 m_pBuffer->append("}"); // msup
329 m_pBuffer->append("}"); // msSup
331 else if ((flags & (1 << LSUP | 1 << LSUB)) == (1 << LSUP | 1 << LSUB))
333 // m:sPre
334 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSPRE " ");
335 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
336 HandleNode(pNode->GetSubSup(LSUB), nLevel + 1);
337 m_pBuffer->append("}"); // msub
338 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
339 HandleNode(pNode->GetSubSup(LSUP), nLevel + 1);
340 m_pBuffer->append("}"); // msup
341 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
342 flags &= ~(1 << LSUP | 1 << LSUB);
343 if (flags == 0)
344 HandleNode(pNode->GetBody(), nLevel + 1);
345 else
346 HandleSubSupScriptInternal(pNode, nLevel, flags);
347 m_pBuffer->append("}"); // me
348 m_pBuffer->append("}"); // msPre
350 else if ((flags & (1 << CSUB)) == (1 << CSUB))
352 // m:limLow looks like a good element for central superscript
353 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMLOW " ");
354 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
355 flags &= ~(1 << CSUB);
356 if (flags == 0)
357 HandleNode(pNode->GetBody(), nLevel + 1);
358 else
359 HandleSubSupScriptInternal(pNode, nLevel, flags);
360 m_pBuffer->append("}"); // me
361 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
362 HandleNode(pNode->GetSubSup(CSUB), nLevel + 1);
363 m_pBuffer->append("}"); // mlim
364 m_pBuffer->append("}"); // mlimLow
366 else if ((flags & (1 << CSUP)) == (1 << CSUP))
368 // m:limUpp looks like a good element for central superscript
369 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMUPP " ");
370 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
371 flags &= ~(1 << CSUP);
372 if (flags == 0)
373 HandleNode(pNode->GetBody(), nLevel + 1);
374 else
375 HandleSubSupScriptInternal(pNode, nLevel, flags);
376 m_pBuffer->append("}"); // me
377 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
378 HandleNode(pNode->GetSubSup(CSUP), nLevel + 1);
379 m_pBuffer->append("}"); // mlim
380 m_pBuffer->append("}"); // mlimUpp
382 else
383 SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled subsup type");
386 void SmRtfExport::HandleMatrix(const SmMatrixNode* pNode, int nLevel)
388 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MM " ");
389 for (size_t row = 0; row < pNode->GetNumRows(); ++row)
391 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MMR " ");
392 for (size_t col = 0; col < pNode->GetNumCols(); ++col)
394 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
395 if (const SmNode* node = pNode->GetSubNode(row * pNode->GetNumCols() + col))
396 HandleNode(node, nLevel + 1);
397 m_pBuffer->append("}"); // me
399 m_pBuffer->append("}"); // mmr
401 m_pBuffer->append("}"); // mm
404 void SmRtfExport::HandleBrace(const SmBraceNode* pNode, int nLevel)
406 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MD " ");
407 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDPR " ");
408 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBEGCHR " ");
409 m_pBuffer->append(mathSymbolToString(pNode->OpeningBrace(), m_nEncoding));
410 m_pBuffer->append("}"); // mbegChr
411 std::vector<const SmNode*> subnodes;
412 if (pNode->Body()->GetType() == SmNodeType::Bracebody)
414 auto body = static_cast<const SmBracebodyNode*>(pNode->Body());
415 bool separatorWritten = false; // assume all separators are the same
416 for (size_t i = 0; i < body->GetNumSubNodes(); ++i)
418 const SmNode* subnode = body->GetSubNode(i);
419 if (subnode->GetType() == SmNodeType::Math
420 || subnode->GetType() == SmNodeType::MathIdent)
422 // do not write, but write what separator it is
423 auto math = static_cast<const SmMathSymbolNode*>(subnode);
424 if (!separatorWritten)
426 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSEPCHR " ");
427 m_pBuffer->append(mathSymbolToString(math, m_nEncoding));
428 m_pBuffer->append("}"); // msepChr
429 separatorWritten = true;
432 else
433 subnodes.push_back(subnode);
436 else
437 subnodes.push_back(pNode->Body());
438 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MENDCHR " ");
439 m_pBuffer->append(mathSymbolToString(pNode->ClosingBrace(), m_nEncoding));
440 m_pBuffer->append("}"); // mendChr
441 m_pBuffer->append("}"); // mdPr
442 for (const SmNode* subnode : subnodes)
444 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
445 HandleNode(subnode, nLevel + 1);
446 m_pBuffer->append("}"); // me
448 m_pBuffer->append("}"); // md
451 void SmRtfExport::HandleVerticalBrace(const SmVerticalBraceNode* pNode, int nLevel)
453 SAL_INFO("starmath.rtf", "Vertical: " << int(pNode->GetToken().eType));
454 switch (pNode->GetToken().eType)
456 case TOVERBRACE:
457 case TUNDERBRACE:
459 bool top = (pNode->GetToken().eType == TOVERBRACE);
460 if (top)
461 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMUPP " ");
462 else
463 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMLOW " ");
464 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
465 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MGROUPCHR " ");
466 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MGROUPCHRPR " ");
467 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MCHR " ");
468 m_pBuffer->append(mathSymbolToString(pNode->Brace(), m_nEncoding));
469 m_pBuffer->append("}"); // mchr
470 // TODO not sure if pos and vertJc are correct
471 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MPOS " ")
472 .append(top ? "top" : "bot")
473 .append("}");
474 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MVERTJC " ")
475 .append(top ? "bot" : "top")
476 .append("}");
477 m_pBuffer->append("}"); // mgroupChrPr
478 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
479 HandleNode(pNode->Body(), nLevel + 1);
480 m_pBuffer->append("}"); // me
481 m_pBuffer->append("}"); // mgroupChr
482 m_pBuffer->append("}"); // me
483 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
484 HandleNode(pNode->Script(), nLevel + 1);
485 m_pBuffer->append("}"); // mlim
486 m_pBuffer->append("}"); // mlimUpp or mlimLow
487 break;
489 default:
490 SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled vertical brace type");
491 break;
495 void SmRtfExport::HandleBlank()
497 m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MR " ");
498 m_pBuffer->append(" ");
499 m_pBuffer->append("}"); // mr
502 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */