LibreOffice Module sw (master) 1
rtfsdrexport.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
20#include "rtfsdrexport.hxx"
21#include <memory>
23#include <svtools/rtfkeywd.hxx>
24#include <svtools/unitconv.hxx>
26#include <editeng/editobj.hxx>
27#include <editeng/editids.hrc>
28#include <editeng/fontitem.hxx>
29#include <editeng/fhgtitem.hxx>
30#include <svx/svdotext.hxx>
31#include <svx/unoapi.hxx>
32#include <vcl/cvtgrf.hxx>
33#include <textboxhelper.hxx>
34#include <dcontact.hxx>
36#include <sal/log.hxx>
37#include <algorithm>
38#include "rtfexport.hxx"
39
40#include <com/sun/star/beans/XPropertySet.hpp>
41#include <com/sun/star/graphic/XGraphic.hpp>
42
43using namespace css;
44
47 , m_rExport(rExport)
48 , m_rAttrOutput(static_cast<RtfAttributeOutput&>(m_rExport.AttrOutput()))
49 , m_pSdrObject(nullptr)
50 , m_nShapeType(ESCHER_ShpInst_Nil)
51 , m_nShapeFlags(ShapeFlag::NONE)
52 , m_aShapeStyle(200)
53 , m_pShapeTypeWritten(new bool[ESCHER_ShpInst_COUNT])
54{
55 mnGroupLevel = 1;
56 memset(m_pShapeTypeWritten.get(), 0, ESCHER_ShpInst_COUNT * sizeof(bool));
57}
58
60
61void RtfSdrExport::OpenContainer(sal_uInt16 nEscherContainer, int nRecInstance)
62{
63 EscherEx::OpenContainer(nEscherContainer, nRecInstance);
64
65 if (nEscherContainer == ESCHER_SpContainer)
66 {
68 m_aShapeStyle.setLength(0);
69 m_aShapeStyle.ensureCapacity(200);
70 m_aShapeProps.clear();
71 }
72}
73
75{
76 if (mRecTypes.back() == ESCHER_SpContainer)
77 {
78 // write the shape now when we have all the info
79 sal_Int32 nShapeElement = StartShape();
80 EndShape(nShapeElement);
81
82 // cleanup
84 }
85
87}
88
89sal_uInt32 RtfSdrExport::EnterGroup(const OUString& /*rShapeName*/,
90 const tools::Rectangle* /*pRect*/)
91{
92 m_bInGroup = true;
93 return GenerateShapeId();
94}
95
97
98void RtfSdrExport::AddShape(sal_uInt32 nShapeType, ShapeFlag nShapeFlags, sal_uInt32 /*nShapeId*/)
99{
100 m_nShapeType = nShapeType;
101 m_nShapeFlags = nShapeFlags;
102}
103
104static sal_uInt16 impl_GetUInt16(const sal_uInt8*& pVal)
105{
106 sal_uInt16 nRet = *pVal++;
107 nRet += (*pVal++) << 8;
108 return nRet;
109}
110
111static sal_Int32 impl_GetPointComponent(const sal_uInt8*& pVal, std::size_t& rVerticesPos,
112 sal_uInt16 nPointSize)
113{
114 sal_Int32 nRet = 0;
115 if ((nPointSize == 0xfff0) || (nPointSize == 4))
116 {
117 sal_uInt16 nUnsigned = *pVal++;
118 nUnsigned += (*pVal++) << 8;
119 rVerticesPos += 2;
120
121 nRet = sal_Int16(nUnsigned);
122 }
123 else if (nPointSize == 8)
124 {
125 sal_uInt32 nUnsigned = *pVal++;
126 nUnsigned += (*pVal++) << 8;
127 nUnsigned += (*pVal++) << 16;
128 nUnsigned += (*pVal++) << 24;
129 rVerticesPos += 4;
130
131 nRet = nUnsigned;
132 }
133
134 return nRet;
135}
136
138{
140 return;
141
143 AddLineDimensions(rRect);
144 else
146
147 // properties
148 const EscherProperties& rOpts = rProps.GetOpts();
149 for (const auto& rOpt : rOpts)
150 {
151 sal_uInt16 nId = (rOpt.nPropId & 0x0FFF);
152
153 switch (nId)
154 {
156 {
157 int nWrapType = 0;
158 switch (rOpt.nPropValue)
159 {
161 nWrapType = 2;
162 break;
164 nWrapType = 4;
165 break;
166 case ESCHER_WrapNone:
167 nWrapType = 3;
168 break;
170 nWrapType = 1;
171 break;
173 nWrapType = 5;
174 break;
175 }
176 if (nWrapType)
177 m_aShapeStyle.append(OOO_STRING_SVTOOLS_RTF_SHPWR + OString::number(nWrapType));
178 }
179 break;
181 m_aShapeProps.insert(
182 std::pair<OString, OString>("fillColor", OString::number(rOpt.nPropValue)));
183 break;
185 m_aShapeProps.insert(
186 std::pair<OString, OString>("fillBackColor", OString::number(rOpt.nPropValue)));
187 break;
189 m_aShapeProps.insert(
190 std::pair<OString, OString>("anchorText", OString::number(rOpt.nPropValue)));
191 break;
193 if (rOpt.nPropValue)
194 m_aShapeProps.insert(
195 std::pair<OString, OString>("fNoFillHitTest", OString::number(1)));
196 break;
198 // for some reason the value is set to 0x90000 if lines are switched off
199 if (rOpt.nPropValue == 0x90000)
200 m_aShapeProps.insert(std::pair<OString, OString>("fLine", OString::number(0)));
201 break;
203 m_aShapeProps.insert(
204 std::pair<OString, OString>("lineColor", OString::number(rOpt.nPropValue)));
205 break;
207 m_aShapeProps.insert(
208 std::pair<OString, OString>("lineBackColor", OString::number(rOpt.nPropValue)));
209 break;
211 m_aShapeProps.insert(
212 std::pair<OString, OString>("lineJoinStyle", OString::number(rOpt.nPropValue)));
213 break;
215 if (rOpt.nPropValue)
216 m_aShapeProps.insert(std::pair<OString, OString>("fshadowObscured", "1"));
217 break;
220 {
221 sal_uInt32 nLeft = 0;
222 sal_uInt32 nTop = 0;
223
225 {
226 nLeft = rOpt.nPropValue;
227 rProps.GetOpt(ESCHER_Prop_geoTop, nTop);
228 }
229 else
230 {
231 nTop = rOpt.nPropValue;
232 rProps.GetOpt(ESCHER_Prop_geoLeft, nLeft);
233 }
234
235 m_aShapeProps.insert(
236 std::pair<OString, OString>("geoLeft", OString::number(sal_Int32(nLeft))));
237 m_aShapeProps.insert(
238 std::pair<OString, OString>("geoTop", OString::number(sal_Int32(nTop))));
239 }
240 break;
241
244 {
245 sal_uInt32 nLeft = 0;
246 sal_uInt32 nRight = 0;
247 sal_uInt32 nTop = 0;
248 sal_uInt32 nBottom = 0;
249 rProps.GetOpt(ESCHER_Prop_geoLeft, nLeft);
250 rProps.GetOpt(ESCHER_Prop_geoTop, nTop);
251
253 {
254 nRight = rOpt.nPropValue;
255 rProps.GetOpt(ESCHER_Prop_geoBottom, nBottom);
256 }
257 else
258 {
259 nBottom = rOpt.nPropValue;
260 rProps.GetOpt(ESCHER_Prop_geoRight, nRight);
261 }
262
263 m_aShapeProps.insert(std::pair<OString, OString>(
264 "geoRight", OString::number(sal_Int32(nRight) - sal_Int32(nLeft))));
265 m_aShapeProps.insert(std::pair<OString, OString>(
266 "geoBottom", OString::number(sal_Int32(nBottom) - sal_Int32(nTop))));
267 }
268 break;
271 {
272 EscherPropSortStruct aVertices;
274
275 if (rProps.GetOpt(ESCHER_Prop_pVertices, aVertices)
277 && aVertices.nProp.size() >= 6 && aSegments.nProp.size() >= 6)
278 {
279 const sal_uInt8* pVerticesIt = aVertices.nProp.data() + 6;
280 std::size_t nVerticesPos = 6;
281 const sal_uInt8* pSegmentIt = aSegments.nProp.data();
282
283 OStringBuffer aSegmentInfo(512);
284 OStringBuffer aVerticies(512);
285
286 sal_uInt16 nPointSize = aVertices.nProp[4] + (aVertices.nProp[5] << 8);
287
288 // number of segments
289 sal_uInt16 nSegments = impl_GetUInt16(pSegmentIt);
290 sal_Int32 nVertices = 0;
291 aSegmentInfo.append("2;" + OString::number(nSegments));
292 pSegmentIt += 4;
293
294 for (; nSegments; --nSegments)
295 {
296 sal_uInt16 nSeg = impl_GetUInt16(pSegmentIt);
297
298 // The segment type is stored in the upper 3 bits
299 // and segment count is stored in the lower 13
300 // bits.
301 unsigned char nSegmentType = (nSeg & 0xE000) >> 13;
302 unsigned short nSegmentCount = nSeg & 0x03FF;
303
304 aSegmentInfo.append(";" + OString::number(static_cast<sal_Int32>(nSeg)));
305 switch (nSegmentType)
306 {
307 case msopathLineTo:
308 for (unsigned short i = 0; i < nSegmentCount; ++i)
309 {
310 sal_Int32 nX = impl_GetPointComponent(pVerticesIt, nVerticesPos,
311 nPointSize);
312 sal_Int32 nY = impl_GetPointComponent(pVerticesIt, nVerticesPos,
313 nPointSize);
314 aVerticies.append(";(" + OString::number(nX) + ","
315 + OString::number(nY) + ")");
316 nVertices++;
317 }
318 break;
319 case msopathMoveTo:
320 {
321 sal_Int32 nX
322 = impl_GetPointComponent(pVerticesIt, nVerticesPos, nPointSize);
323 sal_Int32 nY
324 = impl_GetPointComponent(pVerticesIt, nVerticesPos, nPointSize);
325 aVerticies.append(";(" + OString::number(nX) + ","
326 + OString::number(nY) + ")");
327 nVertices++;
328 break;
329 }
330 case msopathCurveTo:
331 for (unsigned short j = 0; j < nSegmentCount; ++j)
332 {
333 for (int i = 0; i < 3; i++)
334 {
335 sal_Int32 nX = impl_GetPointComponent(
336 pVerticesIt, nVerticesPos, nPointSize);
337 sal_Int32 nY = impl_GetPointComponent(
338 pVerticesIt, nVerticesPos, nPointSize);
339 aVerticies.append(";(" + OString::number(nX) + ","
340 + OString::number(nY) + ")");
341 nVertices++;
342 }
343 }
344 break;
345 case msopathEscape:
346 {
347 // If the segment type is msopathEscape, the lower 13 bits are
348 // divided in a 5 bit escape code and 8 bit
349 // vertex count (not segment count!)
350 unsigned char nVertexCount = nSegmentCount & 0x00FF;
351 nVerticesPos += nVertexCount;
352 break;
353 }
355 case msopathClose:
356 case msopathEnd:
357 break;
358 default:
359 SAL_WARN("sw.rtf", "Totally b0rked");
360 break;
361 }
362 }
363
364 if (!aVerticies.isEmpty())
365 {
366 // We know the number of vertices at the end only, so we have to prepend them here.
367 m_aShapeProps.insert(std::pair<OString, OString>(
368 "pVerticies", "8;" + OString::number(nVertices) + aVerticies));
369 }
370 if (!aSegmentInfo.isEmpty())
371 m_aShapeProps.insert(std::pair<OString, OString>(
372 "pSegmentInfo", aSegmentInfo.makeStringAndClear()));
373 }
374 else
375 SAL_INFO(
376 "sw.rtf",
377 __func__
378 << ": unhandled shape path, missing either pVertices or pSegmentInfo");
379 }
380 break;
382 // noop, we use pSegmentInfo instead
383 break;
385 if (!rOpt.nPropValue)
386 m_aShapeProps.insert(std::pair<OString, OString>("fFillOK", "0"));
387 break;
389 m_aShapeProps.insert(
390 std::pair<OString, OString>("dxTextLeft", OString::number(rOpt.nPropValue)));
391 break;
393 m_aShapeProps.insert(
394 std::pair<OString, OString>("dyTextTop", OString::number(rOpt.nPropValue)));
395 break;
397 m_aShapeProps.insert(
398 std::pair<OString, OString>("dxTextRight", OString::number(rOpt.nPropValue)));
399 break;
401 m_aShapeProps.insert(
402 std::pair<OString, OString>("dyTextBottom", OString::number(rOpt.nPropValue)));
403 break;
405 // Size text to fit shape size: not supported by RTF
406 break;
408 m_aShapeProps.insert(
409 std::pair<OString, OString>("adjustValue", OString::number(rOpt.nPropValue)));
410 break;
412 m_aShapeProps.insert(
413 std::pair<OString, OString>("txflTextFlow", OString::number(rOpt.nPropValue)));
414 break;
416 m_aShapeProps.insert(
417 std::pair<OString, OString>("fillType", OString::number(rOpt.nPropValue)));
418 break;
420 m_aShapeProps.insert(
421 std::pair<OString, OString>("fillOpacity", OString::number(rOpt.nPropValue)));
422 break;
424 {
425 int nHeaderSize
426 = 25; // The first bytes are WW8-specific, we're only interested in the PNG
429 + msfilter::rtfutil::WriteHex(rOpt.nProp.data() + nHeaderSize,
430 rOpt.nProp.size() - nHeaderSize)
431 + "}";
432 m_aShapeProps.insert(std::pair<OString, OString>("fillBlip", aBuf));
433 }
434 break;
435 default:
436 SAL_INFO("sw.rtf", __func__ << ": unhandled property: " << nId
437 << " (value: " << rOpt.nPropValue << ")");
438 break;
439 }
440 }
441}
442
444{
445 // We get the position relative to (the current?) character
446 m_aShapeProps.insert(std::pair<OString, OString>("posrelh", "3"));
447
448 if (m_nShapeFlags & ShapeFlag::FlipV)
449 m_aShapeProps.insert(std::pair<OString, OString>("fFlipV", "1"));
450
451 if (m_nShapeFlags & ShapeFlag::FlipH)
452 m_aShapeProps.insert(std::pair<OString, OString>("fFlipH", "1"));
453
454 // the actual dimensions
455 m_aShapeStyle.append(OOO_STRING_SVTOOLS_RTF_SHPLEFT + OString::number(rRectangle.Left()));
456 m_aShapeStyle.append(OOO_STRING_SVTOOLS_RTF_SHPTOP + OString::number(rRectangle.Top()));
457 m_aShapeStyle.append(OOO_STRING_SVTOOLS_RTF_SHPRIGHT + OString::number(rRectangle.Right()));
458 m_aShapeStyle.append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM + OString::number(rRectangle.Bottom()));
459}
460
461void RtfSdrExport::AddRectangleDimensions(OStringBuffer& rBuffer,
462 const tools::Rectangle& rRectangle)
463{
464 // We get the position relative to (the current?) character
465 m_aShapeProps.insert(std::pair<OString, OString>("posrelh", "3"));
466
467 rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPLEFT + OString::number(rRectangle.Left()));
468 rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPTOP + OString::number(rRectangle.Top()));
469 rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPRIGHT + OString::number(rRectangle.Right()));
470 rBuffer.append(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM + OString::number(rRectangle.Bottom()));
471}
472
473static void lcl_AppendSP(OStringBuffer& rRunText, const char* cName, std::string_view rValue)
474{
475 rRunText.append(OString::Concat("{" OOO_STRING_SVTOOLS_RTF_SP "{" OOO_STRING_SVTOOLS_RTF_SN " ")
476 + cName
477 + "}"
479 + rValue
480 + "}"
481 "}");
482}
483
485{
486 // Get the Graphic object from the Sdr one.
487 uno::Reference<drawing::XShape> xShape
489 uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
490
491 uno::Reference<graphic::XGraphic> xGraphic;
492
493 Graphic aGraphic;
494
495 try
496 {
497 xPropertySet->getPropertyValue("Graphic") >>= xGraphic;
498 }
499 catch (beans::UnknownPropertyException const&)
500 {
501 TOOLS_WARN_EXCEPTION("sw.rtf", "failed to fetch graphic");
502 }
503
504 if (xGraphic.is())
505 {
506 aGraphic = Graphic(xGraphic);
507 }
508
509 // Export it to a stream.
510 SvMemoryStream aStream;
511 (void)GraphicConverter::Export(aStream, aGraphic, ConvertDataFormat::PNG);
512 sal_uInt32 nSize = aStream.TellEnd();
513 auto pGraphicAry = static_cast<sal_uInt8 const*>(aStream.GetData());
514
515 Size aMapped(aGraphic.GetPrefSize());
516
517 // Add it to the properties.
520 aBuf->append(OOO_STRING_SVTOOLS_RTF_PICW + OString::number(aMapped.Width()));
521 aBuf->append(OOO_STRING_SVTOOLS_RTF_PICH + OString::number(aMapped.Height())
523 aBuf->append(msfilter::rtfutil::WriteHex(pGraphicAry, nSize));
524 aBuf->append('}');
525 m_aShapeProps.insert(std::pair<OString, OString>("pib", aBuf.makeStringAndClear()));
526}
527
529{
531 return -1;
532
533 m_aShapeProps.insert(std::pair<OString, OString>("shapeType", OString::number(m_nShapeType)));
536
538 m_rAttrOutput.RunText().append(
540
542 m_aShapeStyle.setLength(0);
543 // Ignore \shpbxpage, \shpbxmargin, and \shpbxcolumn, in favor of the posrelh property.
545 // Ignore \shpbypage, \shpbymargin, and \shpbycolumn, in favor of the posrelh property.
547
548 // Write ZOrder.
549 if (!m_bInGroup)
550 {
551 // Order inside the group shape is not relevant for the flat shape list
552 // we write.
554 m_rAttrOutput.RunText().append(static_cast<sal_Int64>(m_pSdrObject->GetOrdNum()));
555 }
556
557 for (auto it = m_aShapeProps.rbegin(); it != m_aShapeProps.rend(); ++it)
558 lcl_AppendSP(m_rAttrOutput.RunText(), (*it).first.getStr(), (*it).second);
559
560 lcl_AppendSP(m_rAttrOutput.RunText(), "wzDescription",
564 m_rAttrOutput.RunText(), "wzName",
566
567 // now check if we have some text
569 if (pShape)
570 {
571 if (SwFrameFormat* pTextBox
573 {
574 ww8::Frame* pFrame = nullptr;
575 for (auto& rFrame : m_rExport.m_aFrames)
576 {
577 if (pTextBox == &rFrame.GetFrameFormat())
578 {
579 pFrame = &rFrame;
580 break;
581 }
582 }
583
584 if (pFrame)
585 m_rAttrOutput.writeTextFrame(*pFrame, /*bTextBox=*/true);
586 return m_nShapeType;
587 }
588 }
589
590 auto pTextObj = DynCastSdrTextObj(m_pSdrObject);
591 if (pTextObj)
592 {
593 const OutlinerParaObject* pParaObj = nullptr;
595
596 /*
597 #i13885#
598 When the object is actively being edited, that text is not set into
599 the objects normal text object, but lives in a separate object.
600 */
601 if (pTextObj->IsTextEditActive())
602 {
603 pOwnedParaObj = pTextObj->CreateEditOutlinerParaObject();
604 if (pOwnedParaObj)
605 pParaObj = &*pOwnedParaObj;
606 }
607 else
608 {
609 pParaObj = pTextObj->GetOutlinerParaObject();
610 }
611
612 if (pParaObj)
613 {
614 // this is reached only in case some text is attached to the shape
615 // Watermark or TextBox?
616 if (pTextObj->TakeObjNameSingul().match("Text Frame"))
617 WriteOutliner(*pParaObj, TXT_HFTXTBOX);
618 else
619 {
620 const EditTextObject& rEditObj = pParaObj->GetTextObject();
621 const SfxItemSet& rItemSet = rEditObj.GetParaAttribs(0);
622
623 lcl_AppendSP(m_rAttrOutput.RunText(), "gtextUNICODE",
626
627 const SvxFontItem* pFontFamily = rItemSet.GetItem(SID_ATTR_CHAR_FONT);
628 if (pFontFamily)
629 {
630 lcl_AppendSP(m_rAttrOutput.RunText(), "gtextFont",
633 }
634
635 auto pFontHeight = rItemSet.GetItem(SID_ATTR_CHAR_FONTHEIGHT);
636 if (pFontHeight)
637 {
638 tools::Long nFontHeight = TransformMetric(pFontHeight->GetHeight(),
639 FieldUnit::TWIP, FieldUnit::POINT);
641 m_rAttrOutput.RunText(), "gtextSize",
642 msfilter::rtfutil::OutString(OUString::number(nFontHeight * RTF_MULTIPLIER),
644 }
645
646 // RTF angle: 0-360 * 2^16 clockwise
647 // LO angle: 0-360 * 100 counter-clockwise
648 sal_Int32 nRotation
649 = -1 * pTextObj->GetGeoStat().m_nRotationAngle.get() * RTF_MULTIPLIER / 100;
650 lcl_AppendSP(m_rAttrOutput.RunText(), "rotation",
651 msfilter::rtfutil::OutString(OUString::number(nRotation),
653 }
654 }
655 }
656
657 return m_nShapeType;
658}
659
661{
662 SAL_INFO("sw.rtf", __func__ << " start");
663
664 const EditTextObject& rEditObj = rParaObj.GetTextObject();
665 MSWord_SdrAttrIter aAttrIter(m_rExport, rEditObj, eType);
666
667 sal_Int32 nPara = rEditObj.GetParagraphCount();
668
669 bool bShape = eType == TXT_HFTXTBOX;
670 if (bShape)
672 for (sal_Int32 n = 0; n < nPara; ++n)
673 {
674 if (n)
675 aAttrIter.NextPara(n);
676
677 rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet();
678
679 OUString aStr(rEditObj.GetText(n));
680 sal_Int32 nCurrentPos = 0;
681 const sal_Int32 nEnd = aStr.getLength();
682
683 aAttrIter.OutParaAttr(false);
685
686 do
687 {
688 const sal_Int32 nNextAttr = std::min(aAttrIter.WhereNext(), nEnd);
689 rtl_TextEncoding eNextChrSet = aAttrIter.GetNextCharSet();
690
691 aAttrIter.OutAttr(nCurrentPos);
692 m_rAttrOutput.RunText().append('{');
695 bool bTextAtr = aAttrIter.IsTextAttr(nCurrentPos);
696 if (!bTextAtr)
697 {
698 OUString aOut(aStr.copy(nCurrentPos, nNextAttr - nCurrentPos));
699 m_rAttrOutput.RunText().append(msfilter::rtfutil::OutString(aOut, eChrSet));
700 }
701
702 m_rAttrOutput.RunText().append('}');
703
704 nCurrentPos = nNextAttr;
705 eChrSet = eNextChrSet;
706 aAttrIter.NextPos();
707 } while (nCurrentPos < nEnd);
708 if (bShape || n + 1 < nPara)
710 }
711 if (bShape)
712 m_rAttrOutput.RunText().append('}');
713
714 SAL_INFO("sw.rtf", __func__ << " end");
715}
716
717void RtfSdrExport::EndShape(sal_Int32 nShapeElement)
718{
719 if (nShapeElement >= 0)
720 {
721 // end of the shape
722 m_rAttrOutput.RunText().append("}}");
723 }
724}
725
727{
728 m_pSdrObject = &rObj;
730}
731
732bool RtfSdrExport::isTextBox(const SwFrameFormat& rFrameFormat)
733{
734 return SwTextBoxHelper::isTextBox(&rFrameFormat, RES_FLYFRMFMT);
735}
736
737/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sal_Int32 GetParagraphCount() const=0
virtual OUString GetText(sal_Int32 nPara) const=0
virtual const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const=0
sal_uInt32 mnGroupLevel
sal_uInt32 AddSdrObject(const SdrObject &rObj, bool ooxmlExport=false, sal_uInt32 nId=0)
virtual sal_uInt32 GenerateShapeId()
virtual void OpenContainer(sal_uInt16 nEscherContainer, int nRecInstance=0)
std::vector< sal_uInt16 > mRecTypes
virtual void CloseContainer()
bool GetOpt(sal_uInt16 nPropertyID, sal_uInt32 &rPropValue) const
const EscherProperties & GetOpts() const
static ErrCode Export(SvStream &rOStm, const Graphic &rGraphic, ConvertDataFormat nFormat)
Size GetPrefSize() const
ww8::Frames m_aFrames
Definition: wrtww8.hxx:496
Used to export formatted text associated to drawings.
Definition: wrtww8.hxx:1465
void OutAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1108
rtl_TextEncoding GetNextCharSet() const
Definition: wrtw8esh.cxx:1034
void OutParaAttr(bool bCharAttr, const std::set< sal_uInt16 > *pWhichsToIgnore=nullptr)
Definition: wrtw8esh.cxx:1271
rtl_TextEncoding GetNodeCharSet() const
Definition: wrtww8.hxx:1502
void NextPara(sal_Int32 nPar)
Definition: wrtw8esh.cxx:1014
bool IsTextAttr(sal_Int32 nSwPos)
Definition: wrtw8esh.cxx:1194
sal_Int32 WhereNext() const
Definition: wrtww8.hxx:1500
const EditTextObject & GetTextObject() const
The class that has handlers for various resource types when exporting as RTF.
void RunText(const OUString &rText, rtl_TextEncoding eCharSet=RTL_TEXTENCODING_UTF8, const OUString &rSymbolFont=OUString()) override
Output text (inside a run).
void writeTextFrame(const ww8::Frame &rFrame, bool bTextBox=false)
Handles just the {\shptxt ...} part of a shape export.
OString MoveCharacterProperties(bool aAutoWriteRtlLtr=false)
The class that does all the actual RTF export-related work.
Definition: rtfexport.hxx:37
rtl_TextEncoding GetCurrentEncoding() const
Definition: rtfexport.hxx:178
void AddRectangleDimensions(OStringBuffer &rBuffer, const tools::Rectangle &rRectangle)
Add position and size to the OStringBuffer.
~RtfSdrExport() override
RtfExport & m_rExport
sal_Int32 StartShape()
void EndShape(sal_Int32 nShapeElement)
sal_uInt32 m_nShapeType
Remember the shape type.
void Commit(EscherPropertyContainer &rProps, const tools::Rectangle &rRect) override
sal_uInt32 EnterGroup(const OUString &rShapeName, const tools::Rectangle *pBoundRect) override
void CloseContainer() override
void WriteOutliner(const OutlinerParaObject &rParaObj, TextTypes eType)
Write editeng text, e.g. shape or comment.
void LeaveGroup() override
OStringBuffer m_aShapeStyle
Remember style, the most important shape attribute ;-)
ShapeFlag m_nShapeFlags
Remember the shape flags.
RtfSdrExport(RtfExport &rExport)
std::map< OString, OString > m_aShapeProps
const SdrObject * m_pSdrObject
void AddSdrObject(const SdrObject &rObj)
Export the sdr object as Sdr.
std::unique_ptr< bool[]> m_pShapeTypeWritten
Remember which shape types we had already written.
void impl_writeGraphic()
Exports the pib property of the shape.
static bool isTextBox(const SwFrameFormat &rFrameFormat)
Is this a standalone TextFrame, or used as a TextBox of a shape?
void AddShape(sal_uInt32 nShapeType, ShapeFlag nShapeFlags, sal_uInt32 nShapeId=0) override
void AddLineDimensions(const tools::Rectangle &rRectangle)
Add starting and ending point of a line to the m_pShapeAttrList.
RtfAttributeOutput & m_rAttrOutput
void OpenContainer(sal_uInt16 nEscherContainer, int nRecInstance=0) override
Wrapper around OStringBuffers, so less hexdump of graphics have to be kept in memory during RTF expor...
sal_uInt32 GetOrdNum() const
virtual OUString GetDescription() const
virtual const OUString & GetName() const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const void * GetData()
virtual sal_uInt64 TellEnd() override
const OUString & GetFamilyName() const
Style of a layout element.
Definition: frmfmt.hxx:72
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
static bool isTextBox(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
Is the frame format a text box?
constexpr tools::Long Top() const
constexpr tools::Long Right() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
Make exporting a Writer Frame easy.
#define SAL_NEWLINE_STRING
SwFrameFormat * FindFrameFormat(SdrObject *pObj)
The Get reverse way: seeks the format to the specified object.
Definition: dcontact.cxx:121
#define TOOLS_WARN_EXCEPTION(area, stream)
#define ESCHER_Prop_lineColor
#define ESCHER_Prop_shapePath
std::vector< EscherPropSortStruct > EscherProperties
#define ESCHER_ShpInst_COUNT
#define ESCHER_Prop_fNoFillHitTest
ESCHER_WrapNone
ESCHER_WrapByPoints
ESCHER_WrapSquare
ESCHER_WrapThrough
ESCHER_WrapTopBottom
#define ESCHER_Prop_lineJoinStyle
#define ESCHER_Prop_fshadowObscured
#define ESCHER_Prop_geoRight
#define ESCHER_Prop_FitTextToShape
#define ESCHER_Prop_fNoLineDrawDash
#define ESCHER_Prop_AnchorText
#define ESCHER_Prop_WrapText
#define ESCHER_Prop_txflTextFlow
#define ESCHER_Prop_geoLeft
#define ESCHER_Prop_lineBackColor
#define ESCHER_Prop_dxTextLeft
msopathLineTo
msopathCurveTo
msopathClientEscape
msopathClose
msopathMoveTo
msopathEscape
msopathEnd
#define ESCHER_Prop_pSegmentInfo
#define ESCHER_Prop_geoBottom
#define ESCHER_Prop_dyTextTop
#define ESCHER_Prop_fillBackColor
#define ESCHER_Prop_pVertices
#define ESCHER_Prop_fillBlip
#define ESCHER_Prop_fFillOK
#define ESCHER_Prop_dyTextBottom
#define ESCHER_Prop_geoTop
#define ESCHER_ShpInst_Nil
#define ESCHER_Prop_fillType
#define ESCHER_Prop_adjustValue
ShapeFlag
#define ESCHER_Prop_fillOpacity
#define ESCHER_SpContainer
#define ESCHER_Prop_dxTextRight
#define ESCHER_Prop_fillColor
#define ESCHER_ShpInst_Line
#define ESCHER_ShpInst_PictureFrame
DocumentType eType
constexpr TypedWhichId< SwFlyFrameFormat > RES_FLYFRMFMT(162)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(165)
sal_Int64 n
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
aBuf
int i
OString OutString(std::u16string_view rStr, rtl_TextEncoding eDestEnc, bool bUnicode=true)
OString WriteHex(const sal_uInt8 *pData, sal_uInt32 nSize, SvStream *pStream=nullptr, sal_uInt32 nLimit=64)
std::shared_ptr< T > make_shared(Args &&... args)
long Long
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
sal_Int16 nId
#define OOO_STRING_SVTOOLS_RTF_SV
#define OOO_STRING_SVTOOLS_RTF_SHPRIGHT
#define OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE
#define OOO_STRING_SVTOOLS_RTF_SP
#define OOO_STRING_SVTOOLS_RTF_SHP
#define OOO_STRING_SVTOOLS_RTF_PAR
#define OOO_STRING_SVTOOLS_RTF_PICW
#define OOO_STRING_SVTOOLS_RTF_SHPINST
#define OOO_STRING_SVTOOLS_RTF_SHPLEFT
#define OOO_STRING_SVTOOLS_RTF_SHPWR
#define OOO_STRING_SVTOOLS_RTF_SHPBOTTOM
#define OOO_STRING_SVTOOLS_RTF_PICH
#define OOO_STRING_SVTOOLS_RTF_SHPTOP
#define OOO_STRING_SVTOOLS_RTF_SHPTXT
#define OOO_STRING_SVTOOLS_RTF_SN
#define OOO_STRING_SVTOOLS_RTF_SHPZ
#define OOO_STRING_SVTOOLS_RTF_IGNORE
#define OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE
#define OOO_STRING_SVTOOLS_RTF_PICT
#define OOO_STRING_SVTOOLS_RTF_PNGBLIP
static void lcl_AppendSP(OStringBuffer &rRunText, const char *cName, std::string_view rValue)
static sal_Int32 impl_GetPointComponent(const sal_uInt8 *&pVal, std::size_t &rVerticesPos, sal_uInt16 nPointSize)
static sal_uInt16 impl_GetUInt16(const sal_uInt8 *&pVal)
#define RTF_MULTIPLIER
std::vector< sal_uInt8 > nProp
SVXCORE_DLLPUBLIC SdrTextObj * DynCastSdrTextObj(SdrObject *)
unsigned char sal_uInt8
SVT_DLLPUBLIC tools::Long TransformMetric(tools::Long nVal, FieldUnit aOld, FieldUnit aNew)
SVXCORE_DLLPUBLIC css::uno::Reference< css::drawing::XShape > GetXShapeForSdrObject(SdrObject *pObj) noexcept
std::vector< ISegmentProgressBarRef > aSegments
TextTypes
Definition: wrtww8.hxx:157
@ TXT_HFTXTBOX
Definition: wrtww8.hxx:159