Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / lotuswordpro / source / filter / lwpframelayout.cxx
blob7c983b01aacecc4117cb80ecf2323c96196fbed5
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 ************************************************************************/
56 /*************************************************************************
57 * @file
58 * the class for VO_FrameLayout
59 ************************************************************************/
61 #include <memory>
62 #include <lwpfilehdr.hxx>
63 #include "lwpcelllayout.hxx"
64 #include "lwpframelayout.hxx"
65 #include "lwppara.hxx"
66 #include <xfilter/xfstylemanager.hxx>
67 #include <xfilter/xffloatframe.hxx>
68 #include <xfilter/xfrubystyle.hxx>
69 #include "lwpoleobject.hxx"
70 #include <lwpglobalmgr.hxx>
72 LwpFrame::LwpFrame(LwpPlacableLayout* pLayout)
73 : m_pLayout(pLayout)
77 LwpFrame::~LwpFrame() {}
78 /**
79 * @descr: parse frame
80 * @param: register frame style
81 * @param: pFrameStyle - Frame Style object
84 void LwpFrame::RegisterStyle(std::unique_ptr<XFFrameStyle>& rFrameStyle)
86 ApplyWrapType(rFrameStyle.get());
87 ApplyMargins(rFrameStyle.get());
88 ApplyPadding(rFrameStyle.get());
89 ApplyBorders(rFrameStyle.get());
90 ApplyColumns(rFrameStyle.get());
91 ApplyShadow(rFrameStyle.get());
92 ApplyBackGround(rFrameStyle.get());
93 ApplyWatermark(rFrameStyle.get());
94 ApplyProtect(rFrameStyle.get());
95 ApplyTextDir(rFrameStyle.get());
96 ApplyPosType(rFrameStyle.get());
98 rFrameStyle->SetStyleName(m_pLayout->GetName().str());
99 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
100 m_StyleName = pXFStyleManager->AddStyle(std::move(rFrameStyle)).m_pStyle->GetStyleName();
101 m_pLayout->SetStyleName(m_StyleName);
105 * @descr: parse frame and set frame properties
106 * @param: pXFFrame - XFFrame object
107 * @param: nPageNo - the page number that the frame anchors
110 void LwpFrame::Parse(XFFrame* pXFFrame, sal_Int32 nPageNo)
112 //set the frame style name
113 pXFFrame->SetStyleName(m_StyleName);
115 //SetAnchorType and position,if it's page anchor,set the page number.
116 ParseAnchorType(pXFFrame);
117 if (nPageNo > 0)
119 pXFFrame->SetAnchorPage(nPageNo);
122 //Set frame Name
123 OUString aFrameName = m_pLayout->GetName().str();
124 if (!aFrameName.isEmpty())
126 //cause the bug of SODC, the linkframe name can not be "Frame1", so I change the frame name
127 /*if(aFrameName.equals("Frame1"))
129 aFrameName = "Frame1_COPY";
131 pXFFrame->SetName(aFrameName);*/
132 pXFFrame->SetName(m_StyleName);
135 LwpLayoutGeometry* pLayoutGeo = m_pLayout->GetGeometry();
136 //Set frame Width and height
137 if (pLayoutGeo)
139 double fWidth = m_pLayout->GetWidth();
140 double fHeight = m_pLayout->GetHeight();
142 pXFFrame->SetWidth(fWidth);
143 pXFFrame->SetHeight(fHeight);
145 //Get content obj;
146 /*LwpObject* pObj =*/m_pLayout->GetContent().obj();
147 if (m_pLayout->IsGroupHead() && (m_pLayout->IsMinimumHeight()))
149 //process grouplayout height. there is problems now
150 pXFFrame->SetHeight(fHeight);
153 else if(m_pLayout->IsFitGraphic() && pObj && pObj->GetTag() == VO_GRAPHIC)
155 //If is graphic, get original size and set it;
156 LwpGraphicObject* pGrpObj = static_cast<LwpGraphicObject*>(pObj);
157 long nHeight =0, nWidth =0;
158 pGrpObj->GetGrafOrgSize(nWidth, nHeight);
159 //add margins to the width and height;
160 fWidth = (double)nWidth/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_LEFT) + m_pLayout->GetMarginsValue(MARGIN_RIGHT);
161 fHeight = (double)nHeight/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_TOP) + m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
162 pXFFrame->SetWidth(fWidth);
163 pXFFrame->SetHeight(fHeight);
166 else if (m_pLayout->IsAutoGrow())
168 pXFFrame->SetMinHeight(fHeight);
172 if (m_pLayout->IsFrame())
174 //Set frame link. Only frame layout has this feature
175 LwpFrameLayout* pLayout = static_cast<LwpFrameLayout*>(m_pLayout);
176 pXFFrame->SetNextLink(pLayout->GetNextLinkName());
180 * @descr: parse frame relative to page, frame or cell
181 * @param: pCont - content container which contains the frame
184 void LwpFrame::XFConvert(XFContentContainer* pCont)
186 // parse the frame which anchor to page
187 rtl::Reference<LwpVirtualLayout> xParent = m_pLayout->GetParentLayout();
188 if (!xParent.is())
189 throw std::runtime_error("missing Parent Layout");
190 if (xParent->IsPage() && xParent->GetParentLayout().is()
191 && xParent->GetParentLayout()->IsPage())
193 //for mirror page, problems exist if the parent layout is header or footer layout,
194 xParent = xParent->GetParentLayout();
196 if (m_pLayout->IsAnchorPage() && xParent->IsPage())
198 //get parent layout
199 if (m_pLayout->IsUseOnPage())
201 sal_Int32 nPageNo = xParent->GetPageNumber(m_pLayout->GetUsePage());
202 if (nPageNo > 0)
203 m_pLayout->XFConvertFrame(pCont, nPageNo);
205 else if (m_pLayout->IsUseOnAllPages())
207 sal_Int32 nFirst = xParent->GetPageNumber(FIRST_LAYOUTPAGENO);
208 sal_Int32 nLast = xParent->GetPageNumber(LAST_LAYOUTPAGENO);
209 if (nLast > 0)
210 m_pLayout->XFConvertFrame(pCont, nFirst, nLast, true);
212 else if (m_pLayout->IsUseOnAllOddPages() || m_pLayout->IsUseOnAllEvenPages())
214 sal_Int32 nFirst = xParent->GetPageNumber(FIRST_LAYOUTPAGENO);
215 sal_Int32 nLast = xParent->GetPageNumber(LAST_LAYOUTPAGENO);
216 if (nLast > 0)
218 sal_uInt16 first = static_cast<sal_uInt16>(nFirst);
219 if ((m_pLayout->IsUseOnAllOddPages() && !LwpTools::IsOddNumber(first))
220 || (m_pLayout->IsUseOnAllEvenPages() && !LwpTools::IsEvenNumber(first)))
221 nFirst++;
222 if (nFirst <= nLast)
224 m_pLayout->XFConvertFrame(pCont, nFirst, nLast);
229 else
231 m_pLayout->XFConvertFrame(pCont);
235 * @descr: set frame wrap type style
236 * @param: pFrameStyle - Frame Style object
239 void LwpFrame::ApplyWrapType(XFFrameStyle* pFrameStyle)
241 enumXFWrap eWrap = enumXFWrapNone;
242 switch (m_pLayout->GetWrapType())
244 case LwpPlacableLayout::LAY_WRAP_AROUND: //fall through
245 case LwpPlacableLayout::LAY_WRAP_IRREG_BIGGEST:
247 //In SODC, if Optimal wrap type is used and the distance between the frame object
248 //and page margins is less than 2cm, the text is not wrapped. While there is no this feature in Word Pro
249 //So the optimal wrap type is translated to left side or right side wrap type according to the distance
250 //between the frame object and page margins
252 eWrap = enumXFWrapBest;
253 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
254 LwpMiddleLayout* pParent = dynamic_cast<LwpMiddleLayout*>(xContainer.get());
255 if (pParent)
257 if (IsLeftWider())
258 eWrap = enumXFWrapLeft;
259 else
260 eWrap = enumXFWrapRight;
262 break;
264 case LwpPlacableLayout::LAY_NO_WRAP_BESIDE:
266 eWrap = enumXFWrapNone;
267 break;
269 case LwpPlacableLayout::LAY_NO_WRAP_AROUND:
271 eWrap = enumXFWrapRunThrough;
272 if (!m_pLayout->GetBackColor() && !m_pLayout->GetWaterMarkLayout().is())
274 //pFrameStyle->SetBackGround(sal_True);
275 XFColor aXFColor(0xffffff); //white color
276 pFrameStyle->SetBackColor(aXFColor);
277 pFrameStyle->SetTransparency(100); //transparency
279 break;
281 case LwpPlacableLayout::LAY_WRAP_LEFT: //fall through
282 case LwpPlacableLayout::LAY_WRAP_IRREG_LEFT:
284 eWrap = enumXFWrapLeft;
285 break;
287 case LwpPlacableLayout::LAY_WRAP_RIGHT: //fall through
288 case LwpPlacableLayout::LAY_WRAP_IRREG_RIGHT:
290 eWrap = enumXFWrapRight;
291 break;
293 case LwpPlacableLayout::LAY_WRAP_BOTH: //fall through
294 case LwpPlacableLayout::LAY_WRAP_IRREG_BOTH:
296 eWrap = enumXFWrapParallel;
297 break;
299 default:
300 break;
303 //If it is the type of with para above, wrap type is enumXFWrapNone
304 if (m_pLayout->GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
306 eWrap = enumXFWrapNone;
309 pFrameStyle->SetWrapType(eWrap);
312 * @descr: set frame margins style
313 * @param: pFrameStyle - Frame Style object
316 void LwpFrame::ApplyMargins(XFFrameStyle* pFrameStyle)
318 double fLeft = m_pLayout->GetExtMarginsValue(MARGIN_LEFT);
319 double fRight = m_pLayout->GetExtMarginsValue(MARGIN_RIGHT);
320 double fTop = m_pLayout->GetExtMarginsValue(MARGIN_TOP);
321 double fBottom = m_pLayout->GetExtMarginsValue(MARGIN_BOTTOM);
322 pFrameStyle->SetMargins(fLeft, fRight, fTop, fBottom);
325 * @descr: set padding border style
326 * @param: pFrameStyle - Frame Style object
329 void LwpFrame::ApplyPadding(XFFrameStyle* pFrameStyle)
331 double fLeft = m_pLayout->GetMarginsValue(MARGIN_LEFT);
332 double fRight = m_pLayout->GetMarginsValue(MARGIN_RIGHT);
333 double fTop = m_pLayout->GetMarginsValue(MARGIN_TOP);
334 double fBottom = m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
335 pFrameStyle->SetPadding(fLeft, fRight, fTop, fBottom);
338 * @descr: set frame border style
339 * @param: pFrameStyle - Frame Style object
342 void LwpFrame::ApplyBorders(XFFrameStyle* pFrameStyle)
344 std::unique_ptr<XFBorders> pBordres = m_pLayout->GetXFBorders();
345 if (pBordres)
347 pFrameStyle->SetBorders(std::move(pBordres));
351 * @descr: set frame columns style
352 * @param: pFrameStyle - Frame Style object
355 void LwpFrame::ApplyColumns(XFFrameStyle* pFrameStyle)
357 XFColumns* pColumns = m_pLayout->GetXFColumns();
358 if (pColumns)
360 pFrameStyle->SetColumns(pColumns);
364 * @descr: set frame shadow style
365 * @param: pFrameStyle - Frame Style object
368 void LwpFrame::ApplyShadow(XFFrameStyle* pFrameStyle)
370 XFShadow* pXFShadow = m_pLayout->GetXFShadow();
371 if (pXFShadow)
373 pFrameStyle->SetShadow(pXFShadow);
377 * @descr: set frame back color style
378 * @param: pFrameStyle - Frame Style object
381 void LwpFrame::ApplyBackColor(XFFrameStyle* pFrameStyle)
383 LwpColor* pColor = m_pLayout->GetBackColor();
384 if (pColor)
386 XFColor aXFColor(pColor->To24Color());
387 pFrameStyle->SetBackColor(aXFColor);
391 * @descr: set frame protect style
392 * @param: pFrameStyle - Frame Style object
395 void LwpFrame::ApplyProtect(XFFrameStyle* pFrameStyle)
397 if (m_pLayout->GetIsProtected())
399 pFrameStyle->SetProtect(true, true, true);
403 * @descr: set frame text direction style
404 * @param: pFrameStyle - Frame Style object
407 void LwpFrame::ApplyTextDir(XFFrameStyle* pFrameStyle)
409 pFrameStyle->SetTextDir(m_pLayout->GetTextDirection());
412 * @descr: set frame position type style
413 * @param: pFrameStyle - Frame Style object
416 void LwpFrame::ApplyPosType(XFFrameStyle* pFrameStyle)
418 enumXFFrameXPos eXPos = enumXFFrameXPosCenter;
419 enumXFFrameXRel eXRel = enumXFFrameXRelPara;
420 enumXFFrameYPos eYPos = enumXFFrameYPosMiddle;
421 enumXFFrameYRel eYRel = enumXFFrameYRelPara;
422 sal_uInt8 nType = m_pLayout->GetRelativeType();
423 switch (nType)
425 case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE: //fall through
426 case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE:
428 //anchor to page, frame and cell
429 eXPos = enumXFFrameXPosFromLeft;
430 eXRel = enumXFFrameXRelPage;
431 //set vertical position
432 if (m_pLayout->IsAnchorPage()) //in page
434 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
435 if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))
437 //Only anchor to para, the frame can display in header and footer of each page
438 eYPos = enumXFFrameYPosFromTop; //from top
439 eYRel = enumXFFrameYRelPara; //from margin
441 else
443 eYPos = enumXFFrameYPosFromTop;
444 eYRel = enumXFFrameYRelPage;
447 if (m_pLayout->IsAnchorFrame()) //in frame
449 eYPos = enumXFFrameYPosFromTop;
450 eYRel = enumXFFrameYRelPage;
452 if (m_pLayout->IsAnchorCell())
454 //SODC has no this type, simulate this feature
455 eYPos = enumXFFrameYPosFromTop; //from top
456 eYRel = enumXFFrameYRelPara; //from margin
458 break;
460 case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text
462 eXPos = enumXFFrameXPosFromLeft;
463 eXRel = enumXFFrameXRelPage;
464 //set vertical position
465 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
466 if (xContainer.is() && xContainer->IsPage()) //in page
468 //eYPos = enumXFFrameYPosFromTop;
469 //eYRel = enumXFFrameYRelPage;
470 eYPos = enumXFFrameYPosBelow;
471 eYRel = enumXFFrameYRelChar;
473 else if (xContainer.is() && xContainer->IsFrame()) //in frame
475 eYPos = enumXFFrameYPosFromTop;
476 eYRel = enumXFFrameYRelPage;
478 else
480 eYPos = enumXFFrameYPosFromTop; //from top
481 eYRel = enumXFFrameYRelPara; //from margin
483 break;
485 case LwpLayoutRelativityGuts::LAY_INLINE: //in text
487 eXPos = enumXFFrameXPosFromLeft; //need not be set
488 eXRel = enumXFFrameXRelParaContent; //need not be set
489 eYPos = enumXFFrameYPosTop; //should be from top
490 eYRel = enumXFFrameYRelBaseLine;
491 sal_Int32 nOffset = m_pLayout->GetBaseLineOffset();
492 if (nOffset > 0)
494 eYPos = enumXFFrameYPosFromTop;
496 break;
498 case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE: //with para above
500 eXPos = enumXFFrameXPosFromLeft;
501 eXRel = enumXFFrameXRelParaContent;
502 //eYPos = enumXFFrameYPosTop;
503 eYPos = enumXFFrameYPosBottom;
504 eYRel = enumXFFrameYRelParaContent;
505 break;
507 case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL: //in text - vertical
509 eXPos = enumXFFrameXPosFromLeft;
510 eXRel = enumXFFrameXRelPage;
511 eYPos = enumXFFrameYPosFromTop; //should be below position
512 eYRel = enumXFFrameYRelChar;
513 break;
515 default:
516 break;
519 pFrameStyle->SetXPosType(eXPos, eXRel);
520 pFrameStyle->SetYPosType(eYPos, eYRel);
523 * @descr: set frame watermark style
524 * @param: pFrameStyle - Frame Style object
527 void LwpFrame::ApplyWatermark(XFFrameStyle* pFrameStyle)
529 std::unique_ptr<XFBGImage> xBGImage(m_pLayout->GetXFBGImage());
530 if (xBGImage)
532 pFrameStyle->SetBackImage(xBGImage);
533 //set watermark transparent
534 rtl::Reference<LwpVirtualLayout> xWaterMarkLayout(m_pLayout->GetWaterMarkLayout());
535 LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xWaterMarkLayout.get());
536 LwpBackgroundStuff* pBackgroundStuff = pLay ? pLay->GetBackgroundStuff() : nullptr;
537 if (pBackgroundStuff && !pBackgroundStuff->IsTransparent())
539 pFrameStyle->SetTransparency(100);
545 * @short Apply pattern fill to frame style
546 * @param pFrameStyle - pointer of XFFrameStyle
547 * @return
549 void LwpFrame::ApplyPatternFill(XFFrameStyle* pFrameStyle)
551 std::unique_ptr<XFBGImage> xXFBGImage(m_pLayout->GetFillPattern());
552 if (xXFBGImage)
554 pFrameStyle->SetBackImage(xXFBGImage);
559 * @short Apply background to frame style
560 * @param pFrameStyle - pointer of XFFrameStyle
561 * @return
563 void LwpFrame::ApplyBackGround(XFFrameStyle* pFrameStyle)
565 if (!m_pLayout)
567 return;
570 if (m_pLayout->IsPatternFill())
572 ApplyPatternFill(pFrameStyle);
574 else
576 ApplyBackColor(pFrameStyle);
581 * @descr: set frame size, anchor type, anchored page number
582 * @param: pXFFrame - XFFrame object
585 void LwpFrame::ParseAnchorType(XFFrame* pXFFrame)
587 //set position
588 double fXOffset = 0;
589 double fYOffset = 0;
590 //set anchor type
591 enumXFAnchor eAnchor = enumXFAnchorNone;
593 LwpLayoutGeometry* pLayoutGeo = m_pLayout->GetGeometry();
594 if (pLayoutGeo)
596 LwpPoint aPoint = pLayoutGeo->GetOrigin();
597 fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
598 fYOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetY());
600 //set anchor type
601 eAnchor = enumXFAnchorNone;
602 sal_uInt8 nType = m_pLayout->GetRelativeType();
603 switch (nType)
605 case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE: //fall through
606 case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE:
608 //anchor to page, frame and cell
609 if (m_pLayout->IsAnchorPage()) //in page
611 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
612 if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))
614 eAnchor = enumXFAnchorPara;
615 fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
617 else
618 eAnchor = enumXFAnchorPage;
620 if (m_pLayout->IsAnchorFrame()) //in frame
622 eAnchor = enumXFAnchorFrame;
624 if (m_pLayout->IsAnchorCell()) //in cell
626 //eAnchor = enumXFAnchorChar;
627 eAnchor = enumXFAnchorPara;
628 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
629 LwpMiddleLayout* pContainer = dynamic_cast<LwpMiddleLayout*>(xContainer.get());
630 if (pContainer)
632 fYOffset -= pContainer->GetMarginsValue(MARGIN_TOP);
635 break;
637 case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text
639 eAnchor = enumXFAnchorChar;
640 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
641 if (xContainer.is() && xContainer->IsPage()) //in page
643 //eAnchor = enumXFAnchorPage;
644 eAnchor = enumXFAnchorChar; // to character
646 else if (xContainer.is() && xContainer->IsFrame()) //in frame
648 eAnchor = enumXFAnchorFrame;
650 else if (xContainer.is() && xContainer->IsCell()) //in cell
652 //eAnchor = enumXFAnchorChar;
653 eAnchor = enumXFAnchorPara;
654 fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
656 else if (xContainer.is()
657 && (xContainer->IsHeader() || xContainer->IsFooter())) //in header or footer
659 eAnchor = enumXFAnchorPara;
660 fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
662 break;
664 case LwpLayoutRelativityGuts::LAY_INLINE: //in text
666 eAnchor = enumXFAnchorAsChar;
667 sal_Int32 nOffset = m_pLayout->GetBaseLineOffset();
668 if (nOffset > 0 && pLayoutGeo)
670 //experiential value
671 fYOffset = -(m_pLayout->GetGeometryHeight()
672 + 2 * m_pLayout->GetExtMarginsValue(MARGIN_BOTTOM)
673 - LwpTools::ConvertFromUnitsToMetric(nOffset));
675 break;
677 case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE: //with para above
679 eAnchor = enumXFAnchorPara;
680 break;
682 case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL: //in text - vertical
684 eAnchor = enumXFAnchorChar;
685 //set vertical position
686 double offset = 0;
688 //because of the different feature between Word Pro and SODC, I simulate the vertical base offset
689 //between anchor and frame origin using the font height.
690 rtl::Reference<XFFont> pFont = m_pLayout->GetFont();
691 if (pFont.is())
693 offset = static_cast<double>(pFont->GetFontSize()) * CM_PER_INCH / POINTS_PER_INCH;
695 fYOffset = offset - fYOffset;
696 break;
698 default:
699 break;
702 pXFFrame->SetX(fXOffset);
703 pXFFrame->SetY(fYOffset);
704 pXFFrame->SetAnchorPage(0);
705 pXFFrame->SetAnchorType(eAnchor);
709 * @descr Calculate the distance between the frame object and the page margins.
710 * And determine which side(left or right) is wider
712 bool LwpFrame::IsLeftWider()
714 rtl::Reference<LwpVirtualLayout> xLayout(m_pLayout->GetContainerLayout());
715 LwpVirtualLayout* pParent = xLayout.get();
716 if (!pParent)
717 return false;
718 LwpPoint aPoint = m_pLayout->GetOrigin();
719 double fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
720 double fWidth = m_pLayout->GetWidth();
721 double fWrapLeft = m_pLayout->GetExtMarginsValue(MARGIN_LEFT);
722 double fWrapRight = m_pLayout->GetExtMarginsValue(MARGIN_RIGHT);
724 //LwpPoint aParentPoint = pParent->GetOrigin();
725 //double fParentXOffset = LwpTools::ConvertFromUnitsToMetric(aParentPoint.GetX());
726 double fParentWidth = pParent->GetWidth();
727 if (pParent->IsCell())
729 //Get actual width of this cell layout
730 fParentWidth = static_cast<LwpCellLayout*>(pParent)->GetActualWidth();
732 double fParentMarginLeft = pParent->GetMarginsValue(MARGIN_LEFT);
733 double fParentMarginRight = pParent->GetMarginsValue(MARGIN_RIGHT);
735 double fLeft = fXOffset - fWrapLeft - fParentMarginLeft;
736 double fRight = fParentWidth - fParentMarginRight - (fXOffset + fWidth + fWrapRight);
737 if (fLeft > fRight)
738 return true;
739 return false;
742 LwpFrameLink::LwpFrameLink() {}
745 * @descr frame link information
748 void LwpFrameLink::Read(LwpObjectStream* pStrm)
750 m_PreviousLayout.ReadIndexed(pStrm);
751 m_NextLayout.ReadIndexed(pStrm);
752 pStrm->SkipExtra();
755 LwpFrameLayout::LwpFrameLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
756 : LwpPlacableLayout(objHdr, pStrm)
757 , m_bGettingMaxWidth(false)
761 LwpFrameLayout::~LwpFrameLayout() {}
764 * @descr read frame layout object
767 void LwpFrameLayout::Read()
769 LwpPlacableLayout::Read();
770 if (LwpFileHeader::m_nFileRevision >= 0x000B)
772 if (m_pObjStrm->QuickReaduInt16())
774 m_Link.Read(m_pObjStrm.get());
777 m_pObjStrm->SkipExtra();
781 * @descr create a xfframe and add into content container
782 * @param: pCont - content container that contains the frame.
785 void LwpFrameLayout::XFConvert(XFContentContainer* pCont)
787 if (!m_pFrame)
788 return;
790 //parse the frame which anchor to paragraph
791 if (IsRelativeAnchored())
793 XFConvertFrame(pCont);
795 else
797 m_pFrame->XFConvert(pCont);
801 * @descr create a xfframe and add into content container, called by XFConvert
802 * @param: pCont - content container that contains the frame.
803 * @param: nPageNo - the page number that the frame anchors
806 void LwpFrameLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd,
807 bool bAll)
809 if (!m_pFrame)
810 return;
812 rtl::Reference<XFFrame> xXFFrame;
813 if (nEnd < nStart)
815 xXFFrame.set(new XFFrame);
817 else
819 xXFFrame.set(new XFFloatFrame(nStart, nEnd, bAll));
822 m_pFrame->Parse(xXFFrame.get(), nStart);
823 //if it is a link frame, parse contents only once
824 if (!HasPreviousLinkLayout())
826 rtl::Reference<LwpObject> content = m_Content.obj();
827 if (content.is())
829 content->DoXFConvert(xXFFrame.get());
830 //set frame size according to ole size
831 ApplyGraphicSize(xXFFrame.get());
834 pCont->Add(xXFFrame.get());
837 * @descr register frame style
840 void LwpFrameLayout::RegisterStyle()
842 //if it is for water mark, don't register style
843 if (IsForWaterMark())
844 return;
846 if (m_pFrame)
847 return;
849 //register frame style
850 std::unique_ptr<XFFrameStyle> xFrameStyle(new XFFrameStyle);
851 m_pFrame.reset(new LwpFrame(this));
852 m_pFrame->RegisterStyle(xFrameStyle);
854 //register content style
855 rtl::Reference<LwpObject> content = m_Content.obj();
856 if (content.is())
858 content->SetFoundry(m_pFoundry);
859 content->DoRegisterStyle();
862 //register child frame style
863 RegisterChildStyle();
867 * @descr get the name of the frame that current frame links
870 OUString LwpFrameLayout::GetNextLinkName()
872 OUString aName;
873 LwpObjectID& rObjectID = m_Link.GetNextLayout();
874 if (!rObjectID.IsNull())
876 LwpLayout* pLayout = dynamic_cast<LwpLayout*>(rObjectID.obj().get());
877 if (pLayout)
879 LwpAtomHolder& rHolder = pLayout->GetName();
880 aName = rHolder.str();
881 //for division name conflict
882 if (!pLayout->GetStyleName().isEmpty())
883 aName = pLayout->GetStyleName();
886 return aName;
889 * @descr whether current frame is linked by other frame
892 bool LwpFrameLayout::HasPreviousLinkLayout()
894 LwpObjectID& rObjectID = m_Link.GetPreviousLayout();
895 return !rObjectID.IsNull();
898 * @descr whether current frame is for water mark. Problem maybe exists by this method, must be tracking
901 bool LwpFrameLayout::IsForWaterMark()
903 if (m_nBuoyancy >= LAY_BUOYLAYER)
905 if (m_Content.IsNull())
906 return false;
907 rtl::Reference<LwpObject> content = m_Content.obj();
908 if (!content.is())
909 return false;
910 if (content->GetTag() == VO_GRAPHIC)
911 return true;
913 return false;
917 * @descr Get frame width
920 double LwpFrameLayout::GetWidth()
922 double fWidth = LwpMiddleLayout::GetWidth();
923 if (IsInlineToMargin() && IsAutoGrowWidth())
925 //for text field entry when choosing maximize field length
926 fWidth = GetMaxWidth();
928 return fWidth;
932 * @descr Get frame width when the text field chooses maximize field length
935 double LwpFrameLayout::GetMaxWidth()
937 if (m_bGettingMaxWidth)
938 throw std::runtime_error("recursive GetMaxWidth");
940 m_bGettingMaxWidth = true;
941 double fActualWidth = 0;
942 rtl::Reference<LwpVirtualLayout> xLayout(GetContainerLayout());
943 LwpMiddleLayout* pParent = dynamic_cast<LwpMiddleLayout*>(xLayout.get());
944 if (pParent)
946 LwpPoint aPoint = GetOrigin();
947 double fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
948 double fWrapRight = GetExtMarginsValue(MARGIN_RIGHT);
950 //Get parent layout width
951 double fParentWidth = pParent->GetWidth();
952 if (pParent->IsCell())
954 //Get actual width of this cell layout
955 fParentWidth = static_cast<LwpCellLayout*>(pParent)->GetActualWidth();
958 double fParentMarginRight = 0;
959 sal_uInt8 nType = GetRelativeType();
960 if (nType == LwpLayoutRelativityGuts::LAY_INLINE
961 || nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
963 fParentMarginRight = pParent->GetMarginsValue(MARGIN_RIGHT);
966 fActualWidth = fParentWidth - fXOffset - fParentMarginRight - fWrapRight;
969 m_bGettingMaxWidth = false;
970 return fActualWidth;
974 * @descr Set frame size according to graphic size
977 void LwpFrameLayout::ApplyGraphicSize(XFFrame* pXFFrame)
979 rtl::Reference<LwpObject> content = m_Content.obj();
980 if (!(content.is() && (content->GetTag() == VO_GRAPHIC || content->GetTag() == VO_OLEOBJECT)))
981 return;
983 LwpGraphicOleObject* pGraOle = static_cast<LwpGraphicOleObject*>(content.get());
984 //Get frame geometry size
985 double fWidth = 0;
986 double fHeight = 0;
987 pGraOle->GetGrafScaledSize(fWidth, fHeight);
988 if (IsFitGraphic())
990 //graphic scaled sze
991 fWidth += GetMarginsValue(MARGIN_LEFT) + GetMarginsValue(MARGIN_RIGHT);
992 fHeight += GetMarginsValue(MARGIN_TOP) + GetMarginsValue(MARGIN_BOTTOM);
994 else if (IsAutoGrowDown() || IsAutoGrowUp())
996 fWidth = GetWidth();
997 fHeight += GetMarginsValue(MARGIN_TOP) + GetMarginsValue(MARGIN_BOTTOM);
999 else if (IsAutoGrowLeft() || IsAutoGrowRight())
1001 fHeight = GetHeight();
1002 fWidth += GetMarginsValue(MARGIN_LEFT) + GetMarginsValue(MARGIN_RIGHT);
1004 else
1006 fWidth = GetWidth();
1007 fHeight = GetHeight();
1009 pXFFrame->SetWidth(fWidth);
1010 pXFFrame->SetHeight(fHeight);
1013 LwpGroupLayout::LwpGroupLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
1014 : LwpPlacableLayout(objHdr, pStrm)
1018 LwpGroupLayout::~LwpGroupLayout() {}
1020 * @descr read group layout object
1023 void LwpGroupLayout::Read()
1025 LwpPlacableLayout::Read();
1026 m_pObjStrm->SkipExtra();
1029 * @descr register group frame style
1032 void LwpGroupLayout::RegisterStyle()
1034 if (m_pFrame)
1035 return;
1037 //register frame style
1038 std::unique_ptr<XFFrameStyle> xFrameStyle(new XFFrameStyle);
1039 m_pFrame.reset(new LwpFrame(this));
1040 m_pFrame->RegisterStyle(xFrameStyle);
1042 //register child frame style
1043 RegisterChildStyle();
1046 * @descr create a xfframe and add into content container
1047 * @param: pCont - content container that contains the frame.
1050 void LwpGroupLayout::XFConvert(XFContentContainer* pCont)
1052 if (!m_pFrame)
1053 return;
1055 //parse the frame which anchor to paragraph
1056 if (IsRelativeAnchored())
1058 XFConvertFrame(pCont);
1060 else
1062 m_pFrame->XFConvert(pCont);
1066 * @descr create a xfframe and add into content container, called by XFConvert
1067 * @param: pCont - content container that contains the frame.
1068 * @param: nPageNo - the page number that the frame anchors
1071 void LwpGroupLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd,
1072 bool bAll)
1074 if (!m_pFrame)
1075 return;
1077 rtl::Reference<XFFrame> xXFFrame;
1078 if (nEnd < nStart)
1080 xXFFrame.set(new XFFrame);
1082 else
1084 xXFFrame.set(new XFFloatFrame(nStart, nEnd, bAll));
1087 m_pFrame->Parse(xXFFrame.get(), nStart);
1089 //add child frame into group
1090 LwpVirtualLayout* pLayout = dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get());
1092 while (pLayout && pLayout != this)
1094 pLayout->DoXFConvert(xXFFrame.get());
1095 pLayout = dynamic_cast<LwpVirtualLayout*>(pLayout->GetNext().obj().get());
1098 pCont->Add(xXFFrame.get());
1101 LwpGroupFrame::LwpGroupFrame(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
1102 : LwpContent(objHdr, pStrm)
1106 LwpGroupFrame::~LwpGroupFrame() {}
1108 void LwpGroupFrame::Read()
1110 LwpContent::Read();
1111 m_pObjStrm->SkipExtra();
1114 void LwpGroupFrame::RegisterStyle() {}
1116 void LwpGroupFrame::XFConvert(XFContentContainer* /*pCont*/) {}
1118 LwpDropcapLayout::LwpDropcapLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
1119 : LwpFrameLayout(objHdr, pStrm)
1120 , m_nLines(3)
1121 , m_nChars(1)
1125 void LwpDropcapLayout::Read()
1127 LwpFrameLayout::Read();
1128 m_nLines = m_pObjStrm->QuickReaduInt16();
1129 m_pObjStrm->SeekRel(1);
1130 m_pObjStrm->SkipExtra();
1133 void LwpDropcapLayout::Parse(IXFStream* pOutputStream)
1135 LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1136 if (!pStory)
1137 return;
1138 rtl::Reference<LwpObject> pPara = pStory->GetFirstPara().obj(VO_PARA);
1139 if (pPara.is())
1141 pPara->SetFoundry(m_pFoundry);
1142 pPara->DoParse(pOutputStream);
1146 void LwpDropcapLayout::XFConvert(XFContentContainer* pCont)
1148 LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1149 if (pStory)
1151 pStory->SetFoundry(m_pFoundry);
1152 pStory->XFConvert(pCont);
1156 void LwpDropcapLayout::RegisterStyle(LwpFoundry* pFoundry)
1158 LwpStory* pStory = dynamic_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1159 if (pStory)
1161 pStory->SetDropcapFlag(true);
1162 pStory->SetFoundry(pFoundry);
1163 LwpPara* pPara = dynamic_cast<LwpPara*>(pStory->GetFirstPara().obj().get());
1164 while (pPara)
1166 pPara->SetFoundry(pFoundry);
1167 pPara->RegisterStyle();
1168 pPara = dynamic_cast<LwpPara*>(pPara->GetNext().obj().get());
1174 * @descr do nothing
1177 void LwpDropcapLayout::RegisterStyle() {}
1179 LwpRubyLayout::LwpRubyLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
1180 : LwpFrameLayout(objHdr, pStrm)
1181 , m_nPlacement(0)
1182 , m_nAlignment(0)
1183 , m_nStateFlag(0)
1184 , m_nXOffset(0)
1185 , m_nYOffset(0)
1189 void LwpRubyLayout::Read()
1191 LwpFrameLayout::Read();
1192 m_nPlacement = m_pObjStrm->QuickReaduInt8();
1193 m_nAlignment = m_pObjStrm->QuickReaduInt8();
1194 m_nStateFlag = m_pObjStrm->QuickReaduInt16();
1195 m_nXOffset = m_pObjStrm->QuickReadInt32();
1196 m_nYOffset = m_pObjStrm->QuickReadInt32();
1197 m_objRubyMarker.ReadIndexed(m_pObjStrm.get());
1198 m_pObjStrm->SkipExtra();
1201 LwpRubyMarker* LwpRubyLayout::GetMarker()
1203 return static_cast<LwpRubyMarker*>(m_objRubyMarker.obj(VO_RUBYMARKER).get());
1206 LwpStory* LwpRubyLayout::GetContentStory()
1208 return static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1211 void LwpRubyLayout::ConvertContentText()
1213 LwpStory* pStory = GetContentStory();
1214 LwpRubyMarker* pMarker = GetMarker();
1215 if (pStory && pMarker)
1216 pMarker->SetRubyText(pStory->GetContentText(true));
1219 void LwpRubyLayout::RegisterStyle()
1221 LwpRubyMarker* pMarker = GetMarker();
1222 if (!pMarker)
1223 throw std::runtime_error("missing Ruby Marker");
1225 std::unique_ptr<XFRubyStyle> xRubyStyle(new XFRubyStyle);
1227 enumXFRubyPosition eType = enumXFRubyLeft;
1228 if (m_nAlignment == LEFT)
1230 eType = enumXFRubyLeft;
1232 else if (m_nAlignment == RIGHT)
1234 eType = enumXFRubyRight;
1236 else if (m_nAlignment == CENTER)
1238 eType = enumXFRubyCenter;
1240 xRubyStyle->SetAlignment(eType);
1242 eType = enumXFRubyTop;
1243 if (m_nPlacement == TOP)
1245 eType = enumXFRubyTop;
1247 else if (m_nPlacement == BOTTOM)
1249 eType = enumXFRubyBottom;
1251 xRubyStyle->SetPosition(eType);
1253 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1254 OUString rubyStyle = pXFStyleManager->AddStyle(std::move(xRubyStyle)).m_pStyle->GetStyleName();
1255 pMarker->SetRubyStyleName(rubyStyle);
1257 LwpStory* pStory = GetContentStory();
1258 pStory->SetFoundry(m_pFoundry);
1259 OUString textStyle = pStory->RegisterFirstFribStyle();
1260 pMarker->SetTextStyleName(textStyle);
1263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */