tdf#131098 docx export: write fill property of graphic
[LibreOffice.git] / lotuswordpro / source / filter / lwpgrfobj.cxx
blobfddd72bd7dd259355159cf079c2dc435db77f6b6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
57 /**
58 * @file
59 * For LWP filter architecture prototype
61 #include <memory>
62 #include <string_view>
64 #include <lwpfilehdr.hxx>
65 #include "lwpgrfobj.hxx"
66 #include "lwpsdwfileloader.hxx"
67 #include "bento.hxx"
69 #include <lwpglobalmgr.hxx>
70 #include <o3tl/numeric.hxx>
71 #include <o3tl/sprintf.hxx>
72 #include <rtl/string.hxx>
73 #include "lwpframelayout.hxx"
75 #include <xfilter/xfframe.hxx>
76 #include <xfilter/xfimage.hxx>
77 #include <xfilter/xfimagestyle.hxx>
78 #include <xfilter/xfstylemanager.hxx>
79 #include <xfilter/xfparagraph.hxx>
80 #include <xfilter/xfannotation.hxx>
82 //For chart
83 #include <string.h>
85 #include <osl/thread.h>
86 #include <sal/log.hxx>
88 #define EF_NONE 0x0000
89 #define EF_ODMA 0x0002
91 LwpGraphicObject::LwpGraphicObject(LwpObjectHeader const &objHdr, LwpSvStream* pStrm)
92 : LwpGraphicOleObject(objHdr, pStrm)
93 , m_nCachedBaseLine(0)
94 , m_bIsLinked(0)
95 , m_bCompressed(0)
99 LwpGraphicObject::~LwpGraphicObject()
103 void LwpGraphicObject::Read()
105 LwpGraphicOleObject::Read();
106 m_pObjStrm->QuickReaduInt16(); //disksize
107 sal_uInt16 strsize = m_pObjStrm->QuickReaduInt16();
108 if (strsize<AFID_MAX_FILE_FORMAT_SIZE)
110 m_pObjStrm->QuickRead(m_sDataFormat,strsize);
111 m_sDataFormat[strsize] = '\0';
113 sal_uInt32 nServerContextSize = m_pObjStrm->QuickReaduInt32();
114 if (nServerContextSize > 0)
116 sal_uInt16 nMaxPossibleSize = m_pObjStrm->remainingSize();
118 if (nServerContextSize > nMaxPossibleSize)
120 SAL_WARN("lwp", "stream too short for claimed no of records");
121 nServerContextSize = nMaxPossibleSize;
124 std::vector<unsigned char> aServerContext(nServerContextSize);
125 m_pObjStrm->QuickRead(aServerContext.data(), static_cast<sal_uInt16>(nServerContextSize));
126 if (nServerContextSize > 44)
128 m_aIPData.nBrightness = aServerContext[14];
129 m_aIPData.nContrast = aServerContext[19];
130 m_aIPData.nEdgeEnhancement = aServerContext[24];
131 m_aIPData.nSmoothing = aServerContext[29];
132 m_aIPData.bInvertImage = (aServerContext[34] == 0x01);
133 m_aIPData.bAutoContrast = (aServerContext[44] == 0x00);
136 m_pObjStrm->QuickReaduInt16(); //disksize
137 strsize = m_pObjStrm->QuickReaduInt16();
138 if (strsize<AFID_MAX_FILE_FORMAT_SIZE)
140 m_pObjStrm->QuickRead(m_sServerContextFormat,strsize);
141 m_sServerContextFormat[strsize] = '\0';
143 if (nServerContextSize == 0)
145 if (strcmp(reinterpret_cast<char *>(m_sServerContextFormat), ".cht") == 0 &&
146 strcmp(reinterpret_cast<char *>(m_sDataFormat), ".sdw") == 0)
148 strcpy(reinterpret_cast<char *>(m_sServerContextFormat), ".lch");
149 strcpy(reinterpret_cast<char *>(m_sDataFormat), ".lch");
152 m_nCachedBaseLine = m_pObjStrm->QuickReadInt32();
153 m_bIsLinked = m_pObjStrm->QuickReadInt16();
155 if (m_bIsLinked)
157 m_LinkedFilePath = m_pObjStrm->QuickReadStringPtr();
159 sal_uInt32 nFilterContextSize = m_pObjStrm->QuickReaduInt32();
160 if (nFilterContextSize > 0)
162 sal_uInt16 nMaxPossibleSize = m_pObjStrm->remainingSize();
164 if (nFilterContextSize > nMaxPossibleSize)
166 SAL_WARN("lwp", "stream too short for claimed no of records");
167 nFilterContextSize = nMaxPossibleSize;
170 std::vector<unsigned char> aFilterContext(nFilterContextSize);
171 m_pObjStrm->QuickRead(aFilterContext.data(), static_cast<sal_uInt16>(nFilterContextSize));
173 if (LwpFileHeader::m_nFileRevision >= 0x000b)
176 // read external file object stuff
177 sal_uInt16 type = m_pObjStrm->QuickReaduInt16();
178 if ((EF_ODMA != type) && (EF_NONE != type)) // don't know about this
180 sal_uInt32 size = m_pObjStrm->QuickReaduInt32();
181 m_pObjStrm->SeekRel(static_cast<sal_uInt16>(size));
183 // else no external file object
187 if (LwpFileHeader::m_nFileRevision >= 0x000b)
189 m_bCompressed = m_pObjStrm->QuickReadInt16();
190 m_Cache.LinkedFileSize = m_pObjStrm->QuickReaduInt32();
191 m_Cache.LinkedFileTime = m_pObjStrm->QuickReaduInt32();
192 m_Cache.Width = m_pObjStrm->QuickReadInt32();
193 m_Cache.Height = m_pObjStrm->QuickReadInt32();
196 if(LwpFileHeader::m_nFileRevision >= 0x000c)
198 m_WatermarkName = m_pObjStrm->QuickReadStringPtr();
202 void LwpGraphicObject::XFConvert (XFContentContainer* pCont)
204 if (m_sServerContextFormat[1]=='s'&&m_sServerContextFormat[2]=='d'&&m_sServerContextFormat[3]=='w')
206 for (auto const& vXFDrawObject : m_vXFDrawObjects)
208 pCont->Add(vXFDrawObject.get());
211 else if (IsGrafFormatValid() && !m_vXFDrawObjects.empty())
213 XFImage* pImage = static_cast<XFImage*>(m_vXFDrawObjects.front().get());
215 if (m_bIsLinked)
217 OUString fileURL = LwpTools::convertToFileUrl(OUStringToOString(m_LinkedFilePath, osl_getThreadTextEncoding()));
218 pImage->SetFileURL(fileURL);
220 else
222 std::vector<sal_uInt8> aGrafData = GetRawGrafData();
223 pImage->SetImageData(aGrafData.data(), aGrafData.size());
226 pCont->Add(pImage);
228 else if(m_sServerContextFormat[1]=='t'&&m_sServerContextFormat[2]=='e'&&m_sServerContextFormat[3]=='x')
230 XFConvertEquation(pCont);
235 * @descr judge if the graphic format is what we can support: bmp, jpg, wmf, gif, tgf(tif). other format will be filtered to
236 * these formats by Word Pro.
237 * @return sal_True if yes sal_False if not.
239 bool LwpGraphicObject::IsGrafFormatValid() const
241 return (m_sServerContextFormat[1]=='b'&& m_sServerContextFormat[2]=='m' && m_sServerContextFormat[3]=='p')
242 || (m_sServerContextFormat[1]=='j' && m_sServerContextFormat[2]=='p' && m_sServerContextFormat[3]=='g')
243 || (m_sServerContextFormat[1]=='w' && m_sServerContextFormat[2]=='m' && m_sServerContextFormat[3]=='f')
244 || (m_sServerContextFormat[1]=='g' && m_sServerContextFormat[2]=='i' && m_sServerContextFormat[3]=='f')
245 || (m_sServerContextFormat[1]=='t' && m_sServerContextFormat[2]=='g' && m_sServerContextFormat[3]=='f')
246 || (m_sServerContextFormat[1]=='p' && m_sServerContextFormat[2]=='n' && m_sServerContextFormat[3]=='g')
247 || (m_sServerContextFormat[1]=='e' && m_sServerContextFormat[2]=='p' && m_sServerContextFormat[3]=='s');
251 * @descr create drawing object and image object.
253 void LwpGraphicObject::RegisterStyle()
255 if (m_sServerContextFormat[1]=='s'&&m_sServerContextFormat[2]=='d'&&m_sServerContextFormat[3]=='w')
257 CreateDrawObjects();
259 // test codes for importing pictures
260 else if(IsGrafFormatValid())
262 CreateGrafObject();
265 if (m_sServerContextFormat[1]=='l'&&m_sServerContextFormat[2]=='c'&&m_sServerContextFormat[3]=='h')
267 rtl::Reference<LwpVirtualLayout> xMyLayout(GetLayout(nullptr));
268 if (xMyLayout.is() && xMyLayout->IsFrame())
270 std::unique_ptr<XFFrameStyle> pXFFrameStyle(new XFFrameStyle());
271 pXFFrameStyle->SetXPosType(enumXFFrameXPosFromLeft, enumXFFrameXRelFrame);
272 pXFFrameStyle->SetYPosType(enumXFFrameYPosFromTop, enumXFFrameYRelPara);
273 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
274 m_strStyleName = pXFStyleManager->AddStyle(std::move(pXFFrameStyle)).m_pStyle->GetStyleName();
281 * @descr create drawing object.
283 void LwpGraphicObject::CreateDrawObjects()
285 // if small file, use the compressed stream for BENTO
286 LwpSvStream* pStream = m_pStrm->GetCompressedStream() ? m_pStrm->GetCompressedStream(): m_pStrm;
288 std::unique_ptr<OpenStormBento::LtcBenContainer> pBentoContainer;
289 OpenStormBento::BenError ulRet = OpenStormBento::BenOpenContainer(pStream, &pBentoContainer);
290 if (ulRet != OpenStormBento::BenErr_OK)
291 return;
293 // get graphic object's bento object name
294 LwpObjectID& rMyID = GetObjectID();
295 std::string aGrfObjName;
296 GetBentoNamebyID(rMyID, aGrfObjName);
298 // get bento stream by the name
299 std::vector<sal_uInt8> aData = pBentoContainer->GetGraphicData(aGrfObjName.c_str());
300 if (!aData.empty())
302 SvMemoryStream aDrawObjStream(aData.data(), aData.size(), StreamMode::READ);
304 LwpSdwFileLoader fileLoader(&aDrawObjStream, this);
305 fileLoader.CreateDrawObjects(&m_vXFDrawObjects);
310 * @descr create drawing object.
312 void LwpGraphicObject::GetBentoNamebyID(LwpObjectID const & rMyID, std::string& rName)
314 sal_uInt16 nHigh = rMyID.GetHigh();
315 sal_uInt32 nLow = rMyID.GetLow();
316 char pTempStr[32];
317 rName = std::string("Gr");
318 o3tl::sprintf(pTempStr, "%X,%" SAL_PRIXUINT32, nHigh, nLow);
319 rName.append(pTempStr);
323 * @descr get the image data read from bento stream according to the VO_GRAPHIC ID.
324 * @return the image data.
326 std::vector<sal_uInt8> LwpGraphicObject::GetRawGrafData()
328 std::vector<sal_uInt8> aGrafData;
330 // create graphic object
331 // if small file, use the compressed stream for BENTO
332 LwpSvStream* pStream = m_pStrm->GetCompressedStream() ? m_pStrm->GetCompressedStream(): m_pStrm;
334 std::unique_ptr<OpenStormBento::LtcBenContainer> pBentoContainer;
336 OpenStormBento::BenError ulRet = OpenStormBento::BenOpenContainer(pStream, &pBentoContainer);
337 if (ulRet != OpenStormBento::BenErr_OK)
338 return aGrafData;
341 // get graphic object's bento object name
342 LwpObjectID& rMyID = GetObjectID();
343 std::string aGrfObjName;
344 GetBentoNamebyID(rMyID, aGrfObjName);
346 // get bento stream by the name and read image data
347 return pBentoContainer->GetGraphicData(aGrfObjName.c_str());
351 * @descr get the image data (only -D data) read from bento stream according to the VO_GRAPHIC ID.
352 * @param pGrafData the array to store the image data. the pointer need to be deleted outside.
353 * @return the length of the image data.
355 sal_uInt32 LwpGraphicObject::GetGrafData(std::unique_ptr<sal_uInt8[]>& pGrafData)
357 // create graphic object
358 // if small file, use the compressed stream for BENTO
359 LwpSvStream* pStream = m_pStrm->GetCompressedStream() ? m_pStrm->GetCompressedStream(): m_pStrm;
361 std::unique_ptr<OpenStormBento::LtcBenContainer> pBentoContainer;
362 OpenStormBento::BenError ulRet = OpenStormBento::BenOpenContainer(pStream, &pBentoContainer);
363 if (ulRet != OpenStormBento::BenErr_OK)
364 return 0;
366 SvStream* pGrafStream = nullptr;
368 // get graphic object's bento object name
369 LwpObjectID& rMyID = GetObjectID();
370 std::string aGrfObjName;
371 GetBentoNamebyID(rMyID, aGrfObjName);
373 OString sDName=OString::Concat(std::string_view(aGrfObjName)) + "-D";
375 // get bento stream by the name
376 pGrafStream = pBentoContainer->FindValueStreamWithPropertyName(sDName.getStr());
378 std::unique_ptr<SvMemoryStream> pMemGrafStream(static_cast<SvMemoryStream*>(pGrafStream));
380 if (pMemGrafStream)
382 // read image data
383 sal_uInt32 nDataLen = pGrafStream->TellEnd();
385 pGrafData.reset(new sal_uInt8 [nDataLen]);
386 pMemGrafStream->ReadBytes(pGrafData.get(), nDataLen);
388 return nDataLen;
391 return 0;
395 * @descr create xf-image object and save it in the container: m_vXFDrawObjects.
397 void LwpGraphicObject::CreateGrafObject()
399 rtl::Reference<XFImage> pImage = new XFImage();
401 // set image processing styles
402 std::unique_ptr<XFImageStyle> xImageStyle(new XFImageStyle);
403 if (m_sServerContextFormat[1]!='w' || m_sServerContextFormat[2]!='m' || m_sServerContextFormat[3]!='f')
405 if (m_aIPData.nBrightness != 50)
407 sal_Int32 nSODCBrightness = static_cast<sal_Int32>(m_aIPData.nBrightness)*2 - 100;
408 xImageStyle->SetBrightness(nSODCBrightness);
410 if (m_aIPData.nContrast != 50)
412 sal_Int32 nSODCContrast = static_cast<sal_Int32>(80 - static_cast<double>(m_aIPData.nContrast)*1.6);
413 xImageStyle->SetContrast(nSODCContrast);
417 // set scale and crop styles
418 LwpAssociatedLayouts& rLayoutWithMe = GetLayoutsWithMe();
419 LwpFrameLayout* pMyFrameLayout =
420 static_cast<LwpFrameLayout*>(rLayoutWithMe.GetOnlyLayout().obj(VO_FRAMELAYOUT).get());
421 if (pMyFrameLayout)
423 LwpLayoutScale* pMyScale = pMyFrameLayout->GetLayoutScale();
424 LwpLayoutGeometry* pFrameGeo = pMyFrameLayout->GetGeometry();
426 // original image size
427 double fOrgGrafWidth = LwpTools::ConvertFromTwips(m_Cache.Width);
428 double fOrgGrafHeight = LwpTools::ConvertFromTwips(m_Cache.Height);
430 // get margin values
431 double fLeftMargin = pMyFrameLayout->GetMarginsValue(MARGIN_LEFT);
432 double fRightMargin = pMyFrameLayout->GetMarginsValue(MARGIN_RIGHT);
433 double fTopMargin = pMyFrameLayout->GetMarginsValue(MARGIN_TOP);
434 double fBottomMargin = pMyFrameLayout->GetMarginsValue(MARGIN_BOTTOM);
436 if (pMyScale && pFrameGeo)
438 if (fOrgGrafHeight == 0.0 || fOrgGrafWidth == 0.0)
439 throw o3tl::divide_by_zero();
441 // frame size
442 double fFrameWidth = LwpTools::ConvertFromUnits(pFrameGeo->GetWidth());
443 double fFrameHeight = LwpTools::ConvertFromUnits(pFrameGeo->GetHeight());
445 // calculate the displayed size of the frame
446 double fDisFrameWidth = fFrameWidth - (fLeftMargin+fRightMargin);
447 double fDisFrameHeight = fFrameHeight - (fTopMargin+fBottomMargin);
449 // scaled image size
450 double fSclGrafWidth = fOrgGrafWidth;
451 double fSclGrafHeight = fOrgGrafHeight;
453 // get scale mode
454 sal_uInt16 nScalemode = pMyScale->GetScaleMode();
455 if (nScalemode & LwpLayoutScale::CUSTOM)
457 fSclGrafWidth = LwpTools::ConvertFromUnits(pMyScale->GetScaleWidth());
458 fSclGrafHeight = LwpTools::ConvertFromUnits(pMyScale->GetScaleHeight());
460 else if (nScalemode & LwpLayoutScale::PERCENTAGE)
462 double fScalePercentage = static_cast<double>(pMyScale->GetScalePercentage()) / 1000;
463 fSclGrafWidth = fScalePercentage * fOrgGrafWidth;
464 fSclGrafHeight = fScalePercentage * fOrgGrafHeight;
466 else if (nScalemode & LwpLayoutScale::FIT_IN_FRAME)
468 if (pMyFrameLayout->IsFitGraphic())
470 fSclGrafWidth = fOrgGrafWidth;
471 fSclGrafHeight = fOrgGrafHeight;
473 else if (nScalemode & LwpLayoutScale::MAINTAIN_ASPECT_RATIO)
475 if (fDisFrameHeight == 0.0)
476 throw o3tl::divide_by_zero();
477 if (fOrgGrafWidth/fOrgGrafHeight >= fDisFrameWidth/fDisFrameHeight)
479 fSclGrafWidth = fDisFrameWidth;
480 fSclGrafHeight = (fDisFrameWidth/fOrgGrafWidth) * fOrgGrafHeight;
482 else
484 fSclGrafHeight = fDisFrameHeight;
485 fSclGrafWidth = (fDisFrameHeight/fOrgGrafHeight) * fOrgGrafWidth;
488 else
490 fSclGrafWidth = fDisFrameWidth;
491 fSclGrafHeight = fDisFrameHeight;
495 // scaled ratio
496 double fXRatio = fSclGrafWidth / fOrgGrafWidth;
497 double fYRatio = fSclGrafHeight / fOrgGrafHeight;
499 // set image to scaled size.
500 pImage->SetWidth(fSclGrafWidth);
501 pImage->SetHeight(fSclGrafHeight);
503 // placement:centered or tiled. tiled style is not supported so it's processed together with centered.
504 if (pMyFrameLayout->GetScaleCenter() || pMyFrameLayout->GetScaleTile())
506 // set center alignment
507 xImageStyle->SetXPosType(enumXFFrameXPosCenter, enumXFFrameXRelFrame);
508 xImageStyle->SetYPosType(enumXFFrameYPosMiddle, enumXFFrameYRelFrame);
510 // need horizontal crop?
511 double fClipWidth = 0;
512 double fClipHeight = 0;
513 bool sal_bCropped = false;
514 if (fSclGrafWidth > fDisFrameWidth)
516 if (fXRatio == 0.0)
517 throw o3tl::divide_by_zero();
518 fClipWidth = (fSclGrafWidth-fDisFrameWidth ) / 2 / fXRatio;
519 sal_bCropped = true;
522 // need vertical crop?
523 if (fSclGrafHeight > fDisFrameHeight)
525 if (fYRatio == 0.0)
526 throw o3tl::divide_by_zero();
527 fClipHeight = (fSclGrafHeight-fDisFrameHeight ) / 2 / fYRatio;
528 sal_bCropped = true;
531 if (sal_bCropped)
533 xImageStyle->SetClip(fClipWidth, fClipWidth, fClipHeight, fClipHeight);
534 pImage->SetWidth(fDisFrameWidth);
535 pImage->SetHeight(fDisFrameHeight);
538 // placement:automatic
539 else
541 // set left-top alignment
542 xImageStyle->SetYPosType(enumXFFrameYPosFromTop, enumXFFrameYRelFrame);
543 xImageStyle->SetXPosType(enumXFFrameXPosFromLeft, enumXFFrameXRelFrame);
545 // get image position offset
546 LwpPoint& rOffset = pMyScale->GetOffset();
547 double fOffsetX = LwpTools::ConvertFromUnits(rOffset.GetX());
548 double fOffsetY = LwpTools::ConvertFromUnits(rOffset.GetY());
550 struct LwpRect
552 double fLeft;
553 double fRight;
554 double fTop;
555 double fBottom;
557 LwpRect()
559 fLeft = 0.00;
560 fRight = 0.00;
561 fTop = 0.00;
562 fBottom = 0.00;
564 LwpRect(double fL, double fR, double fT, double fB)
566 fLeft = fL;
567 fRight = fR;
568 fTop = fT;
569 fBottom = fB;
572 LwpRect aFrameRect(-fOffsetX, (fDisFrameWidth-fOffsetX), (-fOffsetY), (fDisFrameHeight-fOffsetY));
573 LwpRect aImageRect(0, fSclGrafWidth, 0, fSclGrafHeight);
575 if (aFrameRect.fRight <= aImageRect.fLeft || aFrameRect.fLeft >= aImageRect.fRight
576 ||aFrameRect.fBottom <= aImageRect.fTop|| aFrameRect.fTop >= aImageRect.fBottom)
578 // display blank
580 else// need cropped
582 // horizontal crop
583 LwpRect aCropRect;
584 if (aFrameRect.fLeft > aImageRect.fLeft)
586 aCropRect.fLeft = (aFrameRect.fLeft - aImageRect.fLeft) / fXRatio;
589 if (aFrameRect.fRight < aImageRect.fRight)
591 aCropRect.fRight = (aImageRect.fRight - aFrameRect.fRight) / fXRatio;
594 // vertical crop
595 if (aFrameRect.fTop > aImageRect.fTop)
597 aCropRect.fTop = (aFrameRect.fTop - aImageRect.fTop) / fYRatio;
599 if (aFrameRect.fBottom < aImageRect.fBottom)
601 aCropRect.fBottom = (aImageRect.fBottom - aFrameRect.fBottom) / fYRatio;
604 xImageStyle->SetClip(aCropRect.fLeft, aCropRect.fRight, aCropRect.fTop, aCropRect.fBottom);
605 double fPicWidth = fSclGrafWidth - (aCropRect.fLeft+aCropRect.fRight)*fXRatio;
606 double fPicHeight = fSclGrafHeight- (aCropRect.fTop+aCropRect.fBottom)*fYRatio;
607 double fX = fOffsetX > 0 ? fOffsetX : 0.00;
608 double fY = fOffsetY > 0 ? fOffsetY : 0.00;
609 pImage->SetPosition((fX+fLeftMargin), (fY+fTopMargin), fPicWidth, fPicHeight);
615 // set style for the image
616 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
617 pImage->SetStyleName(pXFStyleManager->AddStyle(std::move(xImageStyle)).m_pStyle->GetStyleName());
619 // set anchor to frame
620 pImage->SetAnchorType(enumXFAnchorFrame);
622 // set object name
623 LwpAtomHolder& rHolder = GetName();
624 if ( !rHolder.str().isEmpty() )
626 pImage->SetName(rHolder.str());
629 // insert image object into array
630 m_vXFDrawObjects.emplace_back(pImage.get());
635 * @descr Reserve the equation text in a note in the context.
637 void LwpGraphicObject::XFConvertEquation(XFContentContainer * pCont)
639 std::unique_ptr<sal_uInt8[]> pGrafData;
640 sal_uInt32 nDataLen = GetGrafData(pGrafData);
641 if(!pGrafData)
642 return;
644 //convert equation
645 XFParagraph* pXFPara = new XFParagraph;
646 pXFPara->Add(u"Formula:"_ustr);
647 //add notes
648 XFAnnotation* pXFNote = new XFAnnotation;
649 //add equation to comment notes
650 XFParagraph* pXFNotePara = new XFParagraph;
651 //equation header text: Times New Roman,
652 // 18,12,0,0,0,0,0.
653 // .TCIformat{2}
654 //total head length = 45
655 bool bOk = true;
656 sal_uInt32 nBegin = 45;
657 sal_uInt32 nEnd = 0;
658 if (nDataLen >= 1)
659 nEnd = nDataLen - 1;
660 else
661 bOk = false;
663 if (bOk && pGrafData[nEnd] == '$' && nEnd > 0 && pGrafData[nEnd-1] != '\\')
665 //equation body is contained by '$';
666 nBegin++;
667 nEnd--;
670 bOk &= nEnd >= nBegin;
671 if (bOk)
673 std::unique_ptr<sal_uInt8[]> pEquData( new sal_uInt8[nEnd - nBegin + 1] );
674 for(sal_uInt32 nIndex = 0; nIndex < nEnd - nBegin +1 ; nIndex++)
676 pEquData[nIndex] = pGrafData[nBegin + nIndex];
678 pXFNotePara->Add(OUString(reinterpret_cast<char*>(pEquData.get()), (nEnd - nBegin + 1), osl_getThreadTextEncoding()));
680 pXFNote->Add(pXFNotePara);
682 pXFPara->Add(pXFNote);
683 pCont->Add(pXFPara);
686 void LwpGraphicObject::GetGrafOrgSize(double & rWidth, double & rHeight)
688 // original image size
689 rWidth = LwpTools::ConvertFromTwips(m_Cache.Width);
690 rHeight = LwpTools::ConvertFromTwips(m_Cache.Height);
693 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */