clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name htmlreqifreader.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/filter/html/htmlreqifreader.cxx
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | #include "htmlreqifreader.hxx" |
11 | |
12 | #include <comphelper/scopeguard.hxx> |
13 | #include <filter/msfilter/rtfutil.hxx> |
14 | #include <rtl/strbuf.hxx> |
15 | #include <sot/storage.hxx> |
16 | #include <svtools/parrtf.hxx> |
17 | #include <svtools/rtfkeywd.hxx> |
18 | #include <svtools/rtftoken.h> |
19 | #include <tools/stream.hxx> |
20 | #include <filter/msfilter/msdffimp.hxx> |
21 | #include <vcl/cvtgrf.hxx> |
22 | #include <ndole.hxx> |
23 | |
24 | namespace |
25 | { |
26 | |
27 | class ReqIfRtfReader : public SvRTFParser |
28 | { |
29 | public: |
30 | ReqIfRtfReader(SvStream& rStream); |
31 | void NextToken(int nToken) override; |
32 | bool WriteObjectData(SvStream& rOLE); |
33 | |
34 | private: |
35 | bool m_bInObjData = false; |
36 | OStringBuffer m_aHex; |
37 | }; |
38 | |
39 | ReqIfRtfReader::ReqIfRtfReader(SvStream& rStream) |
40 | : SvRTFParser(rStream) |
41 | { |
42 | } |
43 | |
44 | void ReqIfRtfReader::NextToken(int nToken) |
45 | { |
46 | switch (nToken) |
47 | { |
48 | case '}': |
49 | m_bInObjData = false; |
50 | break; |
51 | case RTF_TEXTTOKEN: |
52 | if (m_bInObjData) |
53 | m_aHex.append(OUStringToOString(aToken, RTL_TEXTENCODING_ASCII_US)); |
54 | break; |
55 | case RTF_OBJDATA: |
56 | m_bInObjData = true; |
57 | break; |
58 | } |
59 | } |
60 | |
61 | bool ReqIfRtfReader::WriteObjectData(SvStream& rOLE) |
62 | { |
63 | return msfilter::rtfutil::ExtractOLE2FromObjdata(m_aHex.makeStringAndClear(), rOLE); |
64 | } |
65 | |
66 | |
67 | OString ExtractOLEClassName(const tools::SvRef<SotStorage>& xStorage) |
68 | { |
69 | OString aRet; |
70 | |
71 | SotStorageStream* pCompObj = xStorage->OpenSotStream("\1CompObj"); |
72 | if (!pCompObj) |
73 | return aRet; |
74 | |
75 | pCompObj->Seek(0); |
76 | pCompObj->SeekRel(28); |
77 | if (!pCompObj->good()) |
78 | return aRet; |
79 | |
80 | sal_uInt32 nData; |
81 | pCompObj->ReadUInt32(nData); |
82 | pCompObj->SeekRel(nData); |
83 | if (!pCompObj->good()) |
84 | return aRet; |
85 | |
86 | pCompObj->ReadUInt32(nData); |
87 | pCompObj->SeekRel(nData); |
88 | if (!pCompObj->good()) |
89 | return aRet; |
90 | |
91 | pCompObj->ReadUInt32(nData); |
92 | return read_uInt8s_ToOString(*pCompObj, nData - 1); |
93 | } |
94 | |
95 | |
96 | bool ParseOLE2Presentation(SvStream& rOle2, sal_uInt32& nWidth, sal_uInt32& nHeight, |
97 | SvStream& rPresentationData) |
98 | { |
99 | |
100 | rOle2.Seek(0); |
101 | tools::SvRef<SotStorage> pStorage = new SotStorage(rOle2); |
102 | tools::SvRef<SotStorageStream> xOle2Presentation |
103 | = pStorage->OpenSotStream("\002OlePres000", StreamMode::STD_READ); |
104 | |
105 | |
106 | sal_uInt32 nMarkerOrLength = 0; |
107 | xOle2Presentation->ReadUInt32(nMarkerOrLength); |
108 | if (nMarkerOrLength != 0xffffffff) |
109 | |
110 | return false; |
111 | sal_uInt32 nFormatOrAnsiLength = 0; |
112 | xOle2Presentation->ReadUInt32(nFormatOrAnsiLength); |
113 | if (nFormatOrAnsiLength != 0x00000003) |
114 | return false; |
115 | |
116 | |
117 | sal_uInt32 nTargetDeviceSize = 0; |
118 | xOle2Presentation->ReadUInt32(nTargetDeviceSize); |
119 | if (nTargetDeviceSize != 0x00000004) |
120 | |
121 | return false; |
122 | |
123 | sal_uInt32 nAspect = 0; |
124 | xOle2Presentation->ReadUInt32(nAspect); |
125 | sal_uInt32 nLindex = 0; |
126 | xOle2Presentation->ReadUInt32(nLindex); |
127 | sal_uInt32 nAdvf = 0; |
128 | xOle2Presentation->ReadUInt32(nAdvf); |
129 | sal_uInt32 nReserved1 = 0; |
130 | xOle2Presentation->ReadUInt32(nReserved1); |
131 | xOle2Presentation->ReadUInt32(nWidth); |
132 | xOle2Presentation->ReadUInt32(nHeight); |
133 | sal_uInt32 nSize = 0; |
134 | xOle2Presentation->ReadUInt32(nSize); |
135 | |
136 | |
137 | if (nSize > xOle2Presentation->remainingSize()) |
138 | return false; |
139 | std::vector<char> aBuffer(nSize); |
140 | xOle2Presentation->ReadBytes(aBuffer.data(), aBuffer.size()); |
141 | rPresentationData.WriteBytes(aBuffer.data(), aBuffer.size()); |
142 | |
143 | return true; |
144 | } |
145 | |
146 | |
147 | |
148 | |
149 | |
150 | OString InsertOLE1HeaderFromOle10NativeStream(const tools::SvRef<SotStorage>& xStorage, |
151 | SwOLENode& rOLENode, SvStream& rOle1) |
152 | { |
153 | tools::SvRef<SotStorageStream> xOle1Stream |
154 | = xStorage->OpenSotStream("\1Ole10Native", StreamMode::STD_READ); |
155 | sal_uInt32 nOle1Size = 0; |
156 | xOle1Stream->ReadUInt32(nOle1Size); |
157 | |
158 | OString aClassName("Package"); |
159 | |
160 | |
161 | rOle1.Seek(0); |
162 | |
163 | rOle1.WriteUInt32(0x00000501); |
164 | |
165 | |
166 | rOle1.WriteUInt32(0x00000002); |
167 | |
168 | |
169 | rOle1.WriteUInt32(aClassName.isEmpty() ? 0 : aClassName.getLength() + 1); |
170 | if (!aClassName.isEmpty()) |
171 | { |
172 | rOle1.WriteOString(aClassName); |
173 | |
174 | rOle1.WriteChar(0); |
175 | } |
176 | |
177 | |
178 | rOle1.WriteUInt32(0); |
179 | |
180 | |
181 | rOle1.WriteUInt32(0); |
182 | |
183 | |
184 | rOle1.WriteUInt32(nOle1Size); |
185 | |
186 | |
187 | rOle1.WriteStream(*xOle1Stream, nOle1Size); |
188 | |
189 | |
190 | if (!rOLENode.GetGraphic()) |
191 | { |
192 | return aClassName; |
193 | } |
194 | |
195 | const Graphic& rGraphic = *rOLENode.GetGraphic(); |
196 | Size aSize = rOLENode.GetTwipSize(); |
197 | SvMemoryStream aGraphicStream; |
198 | if (GraphicConverter::Export(aGraphicStream, rGraphic, ConvertDataFormat::WMF) != ERRCODE_NONE) |
199 | { |
200 | return aClassName; |
201 | } |
202 | |
203 | auto pGraphicAry = static_cast<const sal_uInt8*>(aGraphicStream.GetData()); |
204 | sal_uInt64 nPresentationData = aGraphicStream.TellEnd(); |
205 | msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nPresentationData); |
206 | |
207 | |
208 | rOle1.WriteUInt32(0x00000501); |
209 | |
210 | rOle1.WriteUInt32(0x00000005); |
211 | |
212 | OString aPresentationClassName("METAFILEPICT"); |
213 | rOle1.WriteUInt32(aPresentationClassName.getLength() + 1); |
214 | rOle1.WriteOString(aPresentationClassName); |
215 | rOle1.WriteChar(0); |
216 | |
217 | rOle1.WriteUInt32(aSize.getWidth()); |
218 | |
219 | rOle1.WriteUInt32(aSize.getHeight() * -1); |
220 | |
221 | rOle1.WriteUInt32(8 + nPresentationData); |
222 | |
223 | rOle1.WriteUInt16(0x0008); |
224 | rOle1.WriteUInt16(0x31b1); |
225 | rOle1.WriteUInt16(0x1dd9); |
226 | rOle1.WriteUInt16(0x0000); |
227 | rOle1.WriteBytes(pGraphicAry, nPresentationData); |
228 | |
229 | return aClassName; |
230 | } |
231 | |
232 | |
233 | |
234 | |
235 | |
236 | |
237 | |
238 | OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1, sal_uInt32& nWidth, sal_uInt32& nHeight, |
239 | SwOLENode& rOLENode, const sal_uInt8* pPresentationData, |
240 | sal_uInt64 nPresentationData) |
241 | { |
242 | rOle2.Seek(0); |
243 | tools::SvRef<SotStorage> xStorage(new SotStorage(rOle2)); |
| |
244 | if (xStorage->GetError() != ERRCODE_NONE) |
| |
245 | return OString(); |
246 | |
247 | if (xStorage->IsStream("\1Ole10Native")) |
248 | { |
249 | return InsertOLE1HeaderFromOle10NativeStream(xStorage, rOLENode, rOle1); |
250 | } |
251 | |
252 | OString aClassName = ExtractOLEClassName(xStorage); |
253 | |
254 | |
255 | rOle1.Seek(0); |
256 | |
257 | rOle1.WriteUInt32(0x00000501); |
258 | |
259 | |
260 | rOle1.WriteUInt32(0x00000002); |
261 | |
262 | |
263 | rOle1.WriteUInt32(aClassName.isEmpty() ? 0 : aClassName.getLength() + 1); |
264 | if (!aClassName.isEmpty()) |
265 | { |
266 | rOle1.WriteOString(aClassName); |
267 | |
268 | rOle1.WriteChar(0); |
269 | } |
270 | |
271 | |
272 | rOle1.WriteUInt32(0); |
273 | |
274 | |
275 | rOle1.WriteUInt32(0); |
276 | |
277 | |
278 | rOle1.WriteUInt32(rOle2.TellEnd()); |
279 | |
280 | |
281 | rOle2.Seek(0); |
282 | rOle1.WriteStream(rOle2); |
283 | |
284 | |
285 | SvMemoryStream aPresentationData; |
286 | |
287 | rOle1.WriteUInt32(0x00000501); |
288 | |
289 | rOle1.WriteUInt32(0x00000005); |
290 | |
291 | OString aPresentationClassName("METAFILEPICT"); |
292 | rOle1.WriteUInt32(aPresentationClassName.getLength() + 1); |
293 | rOle1.WriteOString(aPresentationClassName); |
294 | rOle1.WriteChar(0); |
295 | const sal_uInt8* pBytes = nullptr; |
296 | sal_uInt64 nBytes = 0; |
297 | if (ParseOLE2Presentation(rOle2, nWidth, nHeight, aPresentationData)) |
298 | { |
299 | |
300 | pBytes = static_cast<const sal_uInt8*>(aPresentationData.GetData()); |
301 | nBytes = aPresentationData.Tell(); |
302 | } |
303 | else |
304 | { |
305 | |
306 | pBytes = pPresentationData; |
307 | nBytes = nPresentationData; |
308 | } |
309 | |
310 | rOle1.WriteUInt32(nWidth); |
311 | |
312 | rOle1.WriteUInt32(nHeight * -1); |
313 | |
314 | rOle1.WriteUInt32(8 + nPresentationData); |
315 | |
316 | rOle1.WriteUInt16(0x0008); |
317 | rOle1.WriteUInt16(0x31b1); |
318 | rOle1.WriteUInt16(0x1dd9); |
319 | rOle1.WriteUInt16(0x0000); |
320 | rOle1.WriteBytes(pBytes, nBytes); |
321 | |
322 | return aClassName; |
323 | } |
| 6 | | Potential leak of memory pointed to by 'xStorage.pObj' |
|
324 | |
325 | |
326 | void WrapOleGraphicInRtf(SvStream& rRtf, sal_uInt32 nWidth, sal_uInt32 nHeight, |
327 | const sal_uInt8* pPresentationData, sal_uInt64 nPresentationData) |
328 | { |
329 | |
330 | rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT); |
331 | |
332 | |
333 | rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT); |
334 | |
335 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_WMETAFILE "8"); |
336 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICW); |
337 | rRtf.WriteOString(OString::number(nWidth)); |
338 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICH); |
339 | rRtf.WriteOString(OString::number(nHeight)); |
340 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL); |
341 | rRtf.WriteOString(OString::number(nWidth)); |
342 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL); |
343 | rRtf.WriteOString(OString::number(nHeight)); |
344 | if (pPresentationData) |
345 | { |
346 | rRtf.WriteCharPtr(SAL_NEWLINE_STRING); |
347 | msfilter::rtfutil::WriteHex(pPresentationData, nPresentationData, &rRtf); |
348 | } |
349 | |
350 | |
351 | rRtf.WriteCharPtr("}"); |
352 | |
353 | |
354 | rRtf.WriteCharPtr("}"); |
355 | } |
356 | } |
357 | |
358 | namespace SwReqIfReader |
359 | { |
360 | bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle, bool& bOwnFormat) |
361 | { |
362 | |
363 | SvMemoryStream aRtf; |
364 | aRtf.WriteOString("{\\rtf1"); |
365 | aRtf.WriteStream(rRtf); |
366 | aRtf.WriteOString("}"); |
367 | aRtf.Seek(0); |
368 | |
369 | |
370 | tools::SvRef<ReqIfRtfReader> xReader(new ReqIfRtfReader(aRtf)); |
371 | SvParserState eState = xReader->CallParser(); |
372 | if (eState == SvParserState::Error) |
373 | return false; |
374 | |
375 | |
376 | if (!xReader->WriteObjectData(rOle)) |
377 | return false; |
378 | |
379 | tools::SvRef<SotStorage> pStorage = new SotStorage(rOle); |
380 | OUString aFilterName = SvxMSDffManager::GetFilterNameFromClassID(pStorage->GetClassName()); |
381 | bOwnFormat = !aFilterName.isEmpty(); |
382 | if (!bOwnFormat) |
383 | { |
384 | |
385 | rOle.Seek(0); |
386 | return true; |
387 | } |
388 | |
389 | |
390 | SvMemoryStream aMemory; |
391 | SvxMSDffManager::ExtractOwnStream(*pStorage, aMemory); |
392 | rOle.Seek(0); |
393 | aMemory.Seek(0); |
394 | rOle.WriteStream(aMemory); |
395 | |
396 | rOle.SetStreamSize(aMemory.GetSize() + 1); |
397 | rOle.Seek(0); |
398 | return true; |
399 | } |
400 | |
401 | bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode) |
402 | { |
403 | sal_uInt64 nPos = rOle2.Tell(); |
404 | comphelper::ScopeGuard g([&rOle2, nPos] { rOle2.Seek(nPos); }); |
405 | |
406 | |
407 | SvMemoryStream aOLE1; |
408 | |
409 | |
410 | Size aSize(rOLENode.GetTwipSize()); |
411 | sal_uInt32 nWidth = aSize.getWidth(); |
412 | sal_uInt32 nHeight = aSize.getHeight(); |
413 | const Graphic* pGraphic = rOLENode.GetGraphic(); |
414 | const sal_uInt8* pPresentationData = nullptr; |
415 | sal_uInt64 nPresentationData = 0; |
416 | SvMemoryStream aGraphicStream; |
417 | if (pGraphic) |
| 1 | Assuming 'pGraphic' is null | |
|
| |
418 | { |
419 | if (GraphicConverter::Export(aGraphicStream, *pGraphic, ConvertDataFormat::WMF) |
420 | == ERRCODE_NONE) |
421 | { |
422 | pPresentationData = static_cast<const sal_uInt8*>(aGraphicStream.GetData()); |
423 | nPresentationData = aGraphicStream.TellEnd(); |
424 | msfilter::rtfutil::StripMetafileHeader(pPresentationData, nPresentationData); |
425 | } |
426 | } |
427 | OString aClassName = InsertOLE1Header(rOle2, aOLE1, nWidth, nHeight, rOLENode, |
| 3 | | Calling 'InsertOLE1Header' | |
|
428 | pPresentationData, nPresentationData); |
429 | |
430 | |
431 | rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_OBJECT); |
432 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJEMB); |
433 | |
434 | |
435 | rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_OBJCLASS " "); |
436 | rRtf.WriteOString(aClassName); |
437 | |
438 | rRtf.WriteCharPtr("}"); |
439 | |
440 | |
441 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJW); |
442 | rRtf.WriteOString(OString::number(nWidth)); |
443 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJH); |
444 | rRtf.WriteOString(OString::number(nHeight)); |
445 | |
446 | |
447 | rRtf.WriteCharPtr( |
448 | "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_OBJDATA SAL_NEWLINE_STRING); |
449 | msfilter::rtfutil::WriteHex(static_cast<const sal_uInt8*>(aOLE1.GetData()), aOLE1.GetSize(), |
450 | &rRtf); |
451 | |
452 | rRtf.WriteCharPtr("}"); |
453 | |
454 | if (pPresentationData) |
455 | { |
456 | WrapOleGraphicInRtf(rRtf, nWidth, nHeight, pPresentationData, nPresentationData); |
457 | } |
458 | |
459 | |
460 | rRtf.WriteCharPtr("}"); |
461 | |
462 | return true; |
463 | } |
464 | |
465 | bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream& rRtf) |
466 | { |
467 | rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT); |
468 | |
469 | GfxLink aLink = rGraphic.GetGfxLink(); |
470 | const sal_uInt8* pGraphicAry = aLink.GetData(); |
471 | sal_uInt64 nSize = aLink.GetDataSize(); |
472 | OString aBlipType; |
473 | bool bIsWMF = false; |
474 | switch (aLink.GetType()) |
475 | { |
476 | case GfxLinkType::NativeBmp: |
477 | aBlipType = OOO_STRING_SVTOOLS_RTF_WBITMAP; |
478 | break; |
479 | case GfxLinkType::NativeJpg: |
480 | aBlipType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP; |
481 | break; |
482 | case GfxLinkType::NativePng: |
483 | aBlipType = OOO_STRING_SVTOOLS_RTF_PNGBLIP; |
484 | break; |
485 | case GfxLinkType::NativeWmf: |
486 | if (aLink.IsEMF()) |
487 | aBlipType = OOO_STRING_SVTOOLS_RTF_EMFBLIP; |
488 | else |
489 | { |
490 | aBlipType = OOO_STRING_SVTOOLS_RTF_WMETAFILE; |
491 | bIsWMF = true; |
492 | } |
493 | break; |
494 | default: |
495 | break; |
496 | } |
497 | |
498 | if (aBlipType.isEmpty()) |
499 | return false; |
500 | |
501 | rRtf.WriteOString(aBlipType); |
502 | |
503 | Size aMapped(rGraphic.GetPrefSize()); |
504 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICW); |
505 | rRtf.WriteOString(OString::number(aMapped.Width())); |
506 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICH); |
507 | rRtf.WriteOString(OString::number(aMapped.Height())); |
508 | |
509 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL); |
510 | rRtf.WriteOString(OString::number(rLogicSize.Width())); |
511 | rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL); |
512 | rRtf.WriteOString(OString::number(rLogicSize.Height())); |
513 | |
514 | if (bIsWMF) |
515 | { |
516 | rRtf.WriteOString(OString::number(8)); |
517 | msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize); |
518 | } |
519 | rRtf.WriteOString(SAL_NEWLINE_STRING); |
520 | |
521 | msfilter::rtfutil::WriteHex(pGraphicAry, nSize, &rRtf); |
522 | rRtf.WriteOString(SAL_NEWLINE_STRING); |
523 | |
524 | |
525 | rRtf.WriteCharPtr("}"); |
526 | return true; |
527 | } |
528 | } |
529 | |
530 | |