tdf#131098 docx export: write fill property of graphic
[LibreOffice.git] / lotuswordpro / source / filter / lwplayout.cxx
bloba0230a62aba2dd3f2589b3c4f5c571116b201062
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 * For LWP filter architecture prototype
59 ************************************************************************/
61 #include <memory>
62 #include "lwplayout.hxx"
63 #include "lwpusewhen.hxx"
64 #include <lwptools.hxx>
65 #include "lwplaypiece.hxx"
66 #include <xfilter/xfcolumns.hxx>
67 #include "lwpstory.hxx"
68 #include "lwpparastyle.hxx"
69 #include "lwpholder.hxx"
70 #include "lwpdoc.hxx"
71 #include "lwpgrfobj.hxx"
72 #include <lwpfilehdr.hxx>
73 #include <osl/thread.h>
74 #include <sal/log.hxx>
75 #include <o3tl/sorted_vector.hxx>
77 LwpVirtualLayout::LwpVirtualLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
78 : LwpDLNFPVList(objHdr, pStrm)
79 , m_bGettingHonorProtection(false)
80 , m_bGettingMarginsSameAsParent(false)
81 , m_bGettingHasProtection(false)
82 , m_bGettingIsProtected(false)
83 , m_bGettingIsAutoGrowDown(false)
84 , m_bGettingMarginsValue(false)
85 , m_bGettingExtMarginsValue(false)
86 , m_bGettingUsePrinterSettings(false)
87 , m_bGettingScaleCenter(false)
88 , m_bGettingBorderStuff(false)
89 , m_bGettingUseWhen(false)
90 , m_bGettingStyleLayout(false)
91 , m_bGettingAutoGrowUp(false)
92 , m_nAttributes(0)
93 , m_nAttributes2(0)
94 , m_nAttributes3(0)
95 , m_nOverrideFlag(0)
96 , m_nDirection(0)
97 , m_nEditorID(0)
101 void LwpVirtualLayout::Read()
103 LwpDLNFPVList::Read();
105 LwpObjectStream* pStrm = m_pObjStrm.get();
106 m_nAttributes = pStrm->QuickReaduInt32();
107 m_nAttributes2 = pStrm->QuickReaduInt32();
108 m_nAttributes3 = pStrm->QuickReaduInt32();
109 m_nOverrideFlag = pStrm->QuickReaduInt32();
110 m_nDirection = pStrm->QuickReaduInt16();
112 //Note that two bytes is read into m_nEditorID instead of one byte.
113 m_nEditorID = pStrm->QuickReaduInt16();
115 m_NextEnumerated.ReadIndexed(pStrm);
116 m_PreviousEnumerated.ReadIndexed(pStrm);
118 pStrm->SkipExtra();
121 bool LwpVirtualLayout::MarginsSameAsParent()
123 return (m_nAttributes2 & STYLE2_MARGINSSAMEASPARENT) != 0;
127 * @descr: Get the gap between columns
130 double LwpVirtualLayout::GetColGap(sal_uInt16 /*nIndex*/)
132 //return DEFAULTGAPSIZE;
133 //return LwpTools::ConvertToMetric(0.17);//DEFAULTGAPSIZE=0.17
134 return o3tl::convert(0.17, o3tl::Length::in, o3tl::Length::cm);
138 * @descr: Whether it is honoring protection
141 bool LwpVirtualLayout::HonorProtection()
143 if (!(m_nAttributes2 & STYLE2_HONORPROTECTION))
144 return false;
146 rtl::Reference<LwpVirtualLayout> xParent(
147 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
148 if (xParent.is() && !xParent->IsHeader())
150 return xParent->GetHonorProtection();
153 if (m_pFoundry) //is null now
155 LwpDocument* pDoc = m_pFoundry->GetDocument();
156 if (pDoc && pDoc->GetRootDocument())
157 return pDoc->GetRootDocument()->GetHonorProtection();
160 return true;
164 * @descr: Whether it is protected
167 bool LwpVirtualLayout::IsProtected()
169 bool bProtected = (m_nAttributes & STYLE_PROTECTED) != 0;
171 rtl::Reference<LwpVirtualLayout> xParent(
172 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
173 if (xParent.is() && !xParent->IsHeader())
175 if (xParent->GetHonorProtection() && (xParent->GetHasProtection() || bProtected))
177 return true;
180 else if (m_pFoundry) //is null now
182 LwpDocument* pDoc = m_pFoundry->GetDocument();
183 if (pDoc)
185 if (pDoc->GetHonorProtection() && bProtected)
187 return true;
192 return false;
196 * @descr: Whether it has protection
199 bool LwpVirtualLayout::HasProtection()
201 if (m_nAttributes & STYLE_PROTECTED)
202 return true;
204 rtl::Reference<LwpVirtualLayout> xParent(
205 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
206 if (xParent.is() && !xParent->IsHeader())
208 return xParent->GetHasProtection();
211 return false;
215 * @descr: Whether it is a mirror layout
218 bool LwpVirtualLayout::IsComplex() const { return (m_nAttributes & STYLE_COMPLEX) != 0; }
221 * @descr: Get usewhen pointer
224 LwpUseWhen* LwpVirtualLayout::GetUseWhen()
226 if (m_bGettingUseWhen)
227 throw std::runtime_error("recursion in layout");
228 m_bGettingUseWhen = true;
230 LwpUseWhen* pRet = nullptr;
233 If we have a parent, and I'm not a page layout,
234 use my parents information.
236 if (GetLayoutType() != LWP_PAGE_LAYOUT)
238 //get parent
239 rtl::Reference<LwpVirtualLayout> xParent(
240 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
241 if (xParent.is() && !xParent->IsHeader() && (xParent->GetLayoutType() != LWP_PAGE_LAYOUT))
242 pRet = xParent->GetUseWhen();
245 if (!pRet)
246 pRet = VirtualGetUseWhen();
248 m_bGettingUseWhen = false;
250 return pRet;
253 * @descr: Whether this layout is page layout or not
255 bool LwpVirtualLayout::IsPage() { return (GetLayoutType() == LWP_PAGE_LAYOUT); }
257 * @descr: Whether this layout is header layout or not
259 bool LwpVirtualLayout::IsHeader() { return (GetLayoutType() == LWP_HEADER_LAYOUT); }
261 * @descr: Whether this layout is footer layout or not
263 bool LwpVirtualLayout::IsFooter() { return (GetLayoutType() == LWP_FOOTER_LAYOUT); }
265 * @descr: Whether this layout is frame layout or not
267 bool LwpVirtualLayout::IsFrame() { return (GetLayoutType() == LWP_FRAME_LAYOUT); }
270 * @descr: Whether this layout is cell layout or not
272 bool LwpVirtualLayout::IsCell()
274 return (GetLayoutType() == LWP_CELL_LAYOUT || GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT
275 || GetLayoutType() == LWP_HIDDEN_CELL_LAYOUT);
278 * @descr: Whether this layout is supertable layout or not
280 bool LwpVirtualLayout::IsSuperTable() { return (GetLayoutType() == LWP_SUPERTABLE_LAYOUT); }
282 * @descr: Whether this layout is group layout or not
284 bool LwpVirtualLayout::IsGroupHead() { return (GetLayoutType() == LWP_GROUP_LAYOUT); }
286 * @descr: get the relative type
288 sal_uInt8 LwpVirtualLayout::GetRelativeType()
290 return LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE;
293 * @descr: whether it is relative anchored layout
295 bool LwpVirtualLayout::IsRelativeAnchored()
297 sal_uInt8 nType;
299 nType = GetRelativeType();
300 return (nType == LwpLayoutRelativityGuts::LAY_PARA_RELATIVE)
301 || (nType == LwpLayoutRelativityGuts::LAY_INLINE)
302 || (nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
303 || (nType == LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL);
306 * @descr: whether it is MinimumHeight layout
308 bool LwpVirtualLayout::IsMinimumHeight() const
310 return ((m_nAttributes3 & STYLE3_MINHEIGHTVALID) != 0);
314 * @descr: Get parent layout
317 rtl::Reference<LwpVirtualLayout> LwpVirtualLayout::GetParentLayout()
319 return rtl::Reference<LwpVirtualLayout>(
320 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
324 * @descr: Register child layout style
327 void LwpVirtualLayout::RegisterChildStyle()
329 //Register all children styles
330 rtl::Reference<LwpVirtualLayout> xLayout(
331 dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get()));
332 while (xLayout.is())
334 xLayout->SetFoundry(m_pFoundry);
335 xLayout->DoRegisterStyle();
336 xLayout.set(dynamic_cast<LwpVirtualLayout*>(xLayout->GetNext().obj().get()));
340 bool LwpVirtualLayout::NoContentReference()
342 return (m_nAttributes2 & STYLE2_NOCONTENTREFERENCE) != 0;
345 bool LwpVirtualLayout::IsStyleLayout()
347 if (m_bGettingStyleLayout)
348 throw std::runtime_error("recursion in layout");
349 m_bGettingStyleLayout = true;
351 bool bRet = false;
352 if (m_nAttributes3 & STYLE3_STYLELAYOUT)
353 bRet = true;
354 else
356 rtl::Reference<LwpVirtualLayout> xParent(
357 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
358 if (xParent.is())
359 bRet = xParent->IsStyleLayout();
362 m_bGettingStyleLayout = false;
363 return bRet;
367 * @descr: Find child layout by layout type
370 LwpVirtualLayout* LwpVirtualLayout::FindChildByType(LWP_LAYOUT_TYPE eType)
372 LwpObjectID* pID = &GetChildHead();
373 o3tl::sorted_vector<LwpVirtualLayout*> aSeen;
375 while (pID && !pID->IsNull())
377 LwpVirtualLayout* pLayout = dynamic_cast<LwpVirtualLayout*>(pID->obj().get());
378 if (!pLayout)
379 break;
381 bool bAlreadySeen = !aSeen.insert(pLayout).second;
382 if (bAlreadySeen)
384 SAL_WARN("lwp", "loop in layout");
385 break;
388 if (pLayout->GetLayoutType() == eType)
389 return pLayout;
391 pID = &pLayout->GetNext();
394 return nullptr;
398 * @descr: Whether the size of layout is fit the graphic
401 bool LwpVirtualLayout::IsFitGraphic()
403 return IsAutoGrowRight() && !IsAutoGrowLeft() && GetIsAutoGrowDown();
407 * @descr: Whether the width of layout is auto grow
410 bool LwpVirtualLayout::IsAutoGrowWidth() { return IsAutoGrowLeft() || IsAutoGrowRight(); }
413 * @descr: Determine whether the layout width is to margin
416 bool LwpVirtualLayout::IsInlineToMargin() const
418 return (m_nAttributes3 & STYLE3_INLINETOMARGIN) != 0;
421 void LwpAssociatedLayouts::Read(LwpObjectStream* pStrm)
423 m_OnlyLayout.ReadIndexed(pStrm);
424 m_Layouts.Read(pStrm);
425 pStrm->SkipExtra();
429 * @descr: Looking for the layout which follows the pStartLayout
430 * @param: pStartLayout - the layout which is used for looking for its following layout
432 rtl::Reference<LwpVirtualLayout>
433 LwpAssociatedLayouts::GetLayout(LwpVirtualLayout const* pStartLayout)
435 if (!pStartLayout && !m_OnlyLayout.IsNull())
436 /* Looking for the first layout and there's only one layout in the list.*/
437 return rtl::Reference<LwpVirtualLayout>(
438 dynamic_cast<LwpVirtualLayout*>(m_OnlyLayout.obj().get()));
440 rtl::Reference<LwpObjectHolder> xObjHolder(
441 dynamic_cast<LwpObjectHolder*>(m_Layouts.GetHead().obj().get()));
442 if (xObjHolder.is())
444 rtl::Reference<LwpVirtualLayout> xLayout(
445 dynamic_cast<LwpVirtualLayout*>(xObjHolder->GetObject().obj().get()));
446 if (!pStartLayout)
447 return xLayout;
449 while (xObjHolder.is() && pStartLayout != xLayout.get())
451 xObjHolder.set(dynamic_cast<LwpObjectHolder*>(xObjHolder->GetNext().obj().get()));
452 if (xObjHolder.is())
454 xLayout.set(dynamic_cast<LwpVirtualLayout*>(xObjHolder->GetObject().obj().get()));
458 if (xObjHolder.is())
460 xObjHolder.set(dynamic_cast<LwpObjectHolder*>(xObjHolder->GetNext().obj().get()));
461 if (xObjHolder.is())
463 xLayout.set(dynamic_cast<LwpVirtualLayout*>(xObjHolder->GetObject().obj().get()));
464 return xLayout;
469 return rtl::Reference<LwpVirtualLayout>();
472 LwpHeadLayout::LwpHeadLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
473 : LwpVirtualLayout(objHdr, pStrm)
477 void LwpHeadLayout::Read()
479 LwpVirtualLayout::Read();
480 //For PermissiveLayout
481 m_pObjStrm->SkipExtra();
482 //For me
483 m_pObjStrm->SkipExtra();
486 void LwpHeadLayout::RegisterStyle()
488 //Register all children styles
489 rtl::Reference<LwpVirtualLayout> xLayout(
490 dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get()));
491 o3tl::sorted_vector<LwpVirtualLayout*> aSeen;
492 while (xLayout.is())
494 bool bAlreadySeen = !aSeen.insert(xLayout.get()).second;
495 if (bAlreadySeen)
496 throw std::runtime_error("loop in conversion");
497 xLayout->SetFoundry(m_pFoundry);
498 //if the layout is relative to para, the layout will be registered in para
499 if (!xLayout->IsRelativeAnchored())
500 xLayout->DoRegisterStyle();
501 xLayout.set(dynamic_cast<LwpVirtualLayout*>(xLayout->GetNext().obj().get()));
506 * @descr find endnote supertable layout from the child layout list. Suppose that there is only one endnote supertablelayout in one division
507 * @return pointer to endnote supertable layout
509 rtl::Reference<LwpVirtualLayout> LwpHeadLayout::FindEnSuperTableLayout()
511 rtl::Reference<LwpVirtualLayout> xLayout(
512 dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get()));
513 o3tl::sorted_vector<LwpVirtualLayout*> aSeen;
514 while (xLayout)
516 bool bAlreadySeen = !aSeen.insert(xLayout.get()).second;
517 if (bAlreadySeen)
518 throw std::runtime_error("loop in conversion");
519 if (xLayout->GetLayoutType() == LWP_ENDNOTE_SUPERTABLE_LAYOUT)
521 return xLayout;
523 xLayout.set(dynamic_cast<LwpVirtualLayout*>(xLayout->GetNext().obj().get()));
525 return rtl::Reference<LwpVirtualLayout>();
528 LwpLayoutStyle::LwpLayoutStyle()
529 : m_nStyleDefinition(0)
530 , m_nKey(0)
534 LwpLayoutStyle::~LwpLayoutStyle() {}
536 void LwpLayoutStyle::Read(LwpObjectStream* pStrm)
538 m_nStyleDefinition = pStrm->QuickReaduInt32();
539 m_aDescription.Read(pStrm);
540 if (pStrm->CheckExtra())
542 m_nKey = pStrm->QuickReaduInt16();
543 pStrm->SkipExtra();
547 LwpLayoutMisc::LwpLayoutMisc()
548 : m_nGridDistance(0)
549 , m_nGridType(0)
553 LwpLayoutMisc::~LwpLayoutMisc() {}
555 void LwpLayoutMisc::Read(LwpObjectStream* pStrm)
557 m_nGridType = pStrm->QuickReaduInt16();
558 m_nGridDistance = pStrm->QuickReadInt32();
559 m_aContentStyle.Read(pStrm);
560 pStrm->SkipExtra();
563 LwpMiddleLayout::LwpMiddleLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
564 : LwpVirtualLayout(objHdr, pStrm)
565 , m_bGettingGeometry(false)
566 , m_bGettingBackgroundStuff(false)
570 LwpMiddleLayout::~LwpMiddleLayout() {}
572 void LwpMiddleLayout::Read()
574 LwpObjectStream* pStrm = m_pObjStrm.get();
576 LwpVirtualLayout::Read();
578 //skip CLiteLayout data;
579 LwpAtomHolder ContentClass;
580 ContentClass.Read(pStrm);
581 pStrm->SkipExtra();
583 // before layout hierarchy rework
584 if (LwpFileHeader::m_nFileRevision < 0x000B)
585 return;
587 m_Content.ReadIndexed(pStrm);
589 // 01/20/2005
590 m_BasedOnStyle.ReadIndexed(pStrm);
591 m_TabPiece.ReadIndexed(pStrm);
593 sal_uInt8 nWhatsItGot = pStrm->QuickReaduInt8();
595 if (nWhatsItGot & DISK_GOT_STYLE_STUFF)
597 m_aStyleStuff.Read(pStrm);
599 if (nWhatsItGot & DISK_GOT_MISC_STUFF)
601 m_aMiscStuff.Read(pStrm);
604 m_LayGeometry.ReadIndexed(pStrm);
605 m_LayScale.ReadIndexed(pStrm);
606 m_LayMargins.ReadIndexed(pStrm);
607 m_LayBorderStuff.ReadIndexed(pStrm);
608 m_LayBackgroundStuff.ReadIndexed(pStrm);
610 if (pStrm->CheckExtra())
612 m_LayExtBorderStuff.ReadIndexed(pStrm);
613 pStrm->SkipExtra();
617 rtl::Reference<LwpObject> LwpMiddleLayout::GetBasedOnStyle() const
619 rtl::Reference<LwpObject> xRet(m_BasedOnStyle.obj());
620 if (xRet.get() == this)
622 SAL_WARN("lwp", "style based on itself");
623 return rtl::Reference<LwpObject>();
625 return xRet;
629 * @descr: Get the geometry of current layout
632 LwpLayoutGeometry* LwpMiddleLayout::GetGeometry()
634 if (m_bGettingGeometry)
635 throw std::runtime_error("recursion in layout");
636 m_bGettingGeometry = true;
638 LwpLayoutGeometry* pRet = nullptr;
639 if (!m_LayGeometry.IsNull())
641 pRet = dynamic_cast<LwpLayoutGeometry*>(m_LayGeometry.obj().get());
643 else
645 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
646 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
648 pRet = pLay->GetGeometry();
652 m_bGettingGeometry = false;
653 return pRet;
657 * @descr: Get layout height, measured by "cm"
660 double LwpMiddleLayout::GetGeometryHeight()
662 LwpLayoutGeometry* pGeo = GetGeometry();
663 if (pGeo)
665 return LwpTools::ConvertFromUnits(pGeo->GetHeight());
667 else
668 return -1;
672 * @descr: Get layout width, measured by "cm"
675 double LwpMiddleLayout::GetGeometryWidth()
677 LwpLayoutGeometry* pGeo = GetGeometry();
678 if (pGeo)
680 return LwpTools::ConvertFromUnits(pGeo->GetWidth());
682 else
683 return -1;
687 * @descr: Whether the margins is same as parent layout
690 bool LwpMiddleLayout::MarginsSameAsParent()
692 if (m_nOverrideFlag & OVER_MARGINS)
694 return LwpVirtualLayout::MarginsSameAsParent();
696 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
697 if (LwpVirtualLayout* pLay = dynamic_cast<LwpVirtualLayout*>(xBase.get()))
699 pLay->GetMarginsSameAsParent();
701 return LwpVirtualLayout::MarginsSameAsParent();
705 * @descr: Get margin
706 * @param: nWhichSide - 0: left, 1: right, 2:top, 3: bottom
708 double LwpMiddleLayout::MarginsValue(sal_uInt8 nWhichSide)
710 double fValue = 0;
711 if ((nWhichSide == MARGIN_LEFT) || (nWhichSide == MARGIN_RIGHT))
713 if (GetMarginsSameAsParent())
715 rtl::Reference<LwpVirtualLayout> xParent(
716 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
717 if (xParent.is() && !xParent->IsHeader())
719 fValue = xParent->GetMarginsValue(nWhichSide);
720 return fValue;
725 if (m_nOverrideFlag & OVER_MARGINS)
727 LwpLayoutMargins* pMar1 = dynamic_cast<LwpLayoutMargins*>(m_LayMargins.obj().get());
728 if (pMar1)
730 fValue = pMar1->GetMargins().GetMarginsValue(nWhichSide);
731 return fValue;
734 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
735 LwpVirtualLayout* pStyle = dynamic_cast<LwpVirtualLayout*>(xBase.get());
736 if (pStyle)
738 fValue = pStyle->GetMarginsValue(nWhichSide);
739 return fValue;
741 return LwpVirtualLayout::MarginsValue(nWhichSide);
744 * @descr: Get extmargin value
745 * @param: nWhichSide - 0: left, 1: right, 2:top, 3: bottom
746 * @param:
747 * @return:
749 double LwpMiddleLayout::ExtMarginsValue(sal_uInt8 nWhichSide)
751 double fValue = 0;
752 if (m_nOverrideFlag & OVER_MARGINS)
754 LwpLayoutMargins* pMar1 = dynamic_cast<LwpLayoutMargins*>(m_LayMargins.obj().get());
755 if (pMar1)
757 fValue = pMar1->GetExtMargins().GetMarginsValue(nWhichSide);
758 return fValue;
761 LwpVirtualLayout* pStyle = dynamic_cast<LwpVirtualLayout*>(GetBasedOnStyle().get());
762 if (pStyle)
764 fValue = pStyle->GetExtMarginsValue(nWhichSide);
765 return fValue;
767 return LwpVirtualLayout::ExtMarginsValue(nWhichSide);
770 * @descr: Get the LwpBorderStuff object according to m_LayBorderStuff id.
772 LwpBorderStuff* LwpMiddleLayout::GetBorderStuff()
774 if (m_bGettingBorderStuff)
775 throw std::runtime_error("recursion in layout");
776 m_bGettingBorderStuff = true;
778 LwpBorderStuff* pRet = nullptr;
780 if (m_nOverrideFlag & OVER_BORDERS)
782 LwpLayoutBorder* pLayoutBorder
783 = dynamic_cast<LwpLayoutBorder*>(m_LayBorderStuff.obj().get());
784 pRet = pLayoutBorder ? &pLayoutBorder->GetBorderStuff() : nullptr;
786 else
788 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
789 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
791 pRet = pLay->GetBorderStuff();
795 m_bGettingBorderStuff = false;
796 return pRet;
800 * @descr: Get LwpBackgroundStuff object according to m_LayBackgroundStuff id;
802 LwpBackgroundStuff* LwpMiddleLayout::GetBackgroundStuff()
804 if (m_bGettingBackgroundStuff)
805 throw std::runtime_error("recursion in layout");
806 m_bGettingBackgroundStuff = true;
808 LwpBackgroundStuff* pRet = nullptr;
810 if (m_nOverrideFlag & OVER_BACKGROUND)
812 LwpLayoutBackground* pLayoutBackground
813 = dynamic_cast<LwpLayoutBackground*>(m_LayBackgroundStuff.obj().get());
814 pRet = pLayoutBackground ? &pLayoutBackground->GetBackgoudStuff() : nullptr;
816 else
818 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
819 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
821 pRet = pLay->GetBackgroundStuff();
825 m_bGettingBackgroundStuff = false;
826 return pRet;
830 * @descr: create xfborder.
832 std::unique_ptr<XFBorders> LwpMiddleLayout::GetXFBorders()
834 LwpBorderStuff* pBorderStuff = GetBorderStuff();
835 if (pBorderStuff && pBorderStuff->GetSide() != 0)
837 //copy from lwpparastyle.
838 std::unique_ptr<XFBorders> xXFBorders(new XFBorders);
839 // apply 4 borders respectively
840 LwpBorderStuff::BorderType const pType[] = { LwpBorderStuff::LEFT, LwpBorderStuff::RIGHT,
841 LwpBorderStuff::TOP, LwpBorderStuff::BOTTOM };
843 for (LwpBorderStuff::BorderType nC : pType)
845 if (pBorderStuff->HasSide(nC))
847 LwpParaStyle::ApplySubBorder(pBorderStuff, nC, xXFBorders.get());
850 return xXFBorders;
852 return nullptr;
856 * @descr: Get text direction settings.
858 enumXFTextDir LwpMiddleLayout::GetTextDirection()
860 enumXFTextDir eTextDir = enumXFTextDirNone;
861 sal_uInt8 nDirection = GetContentOrientation();
862 switch (nDirection)
864 case TEXT_ORIENT_LRTB:
866 eTextDir = enumXFTextDirLR_TB;
867 break;
869 case TEXT_ORIENT_TBRL:
871 eTextDir = enumXFTextDirTB_RL;
872 break;
874 case TEXT_ORIENT_RLBT: // not supported now
876 eTextDir = enumXFTextDirNone;
877 break;
879 case TEXT_ORIENT_BTLR: // not supported now
881 eTextDir = enumXFTextDirNone;
882 break;
884 default:
885 break;
887 return eTextDir;
890 * @descr: Get background color.
892 LwpColor* LwpMiddleLayout::GetBackColor()
894 LwpBackgroundStuff* pBackgroundStuff = GetBackgroundStuff();
895 if (pBackgroundStuff && !pBackgroundStuff->IsTransparent())
897 LwpColor* pColor = pBackgroundStuff->GetFillColor();
898 if (pColor->IsValidColor())
900 return pColor;
903 return nullptr;
907 * @descr: Add back color settings into xfpagemaster.
909 LwpTabOverride* LwpMiddleLayout::GetTabOverride()
911 if (m_nAttributes & OVER_TABS)
913 if (!m_TabPiece.IsNull())
915 LwpTabPiece* pPiece = dynamic_cast<LwpTabPiece*>(m_TabPiece.obj().get());
916 return static_cast<LwpTabOverride*>(pPiece ? pPiece->GetOverride() : nullptr);
918 return nullptr;
920 else
922 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
923 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
925 return pLay->GetTabOverride();
928 return nullptr;
932 * @descr: Layscale for graphic & watermark
934 sal_uInt16 LwpMiddleLayout::GetScaleMode()
936 if ((m_nOverrideFlag & OVER_SCALING) && m_LayScale.obj().is() && GetLayoutScale())
937 return GetLayoutScale()->GetScaleMode();
938 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
939 if (xBase.is())
940 return dynamic_cast<LwpMiddleLayout&>(*xBase).GetScaleMode();
941 else
942 return (LwpLayoutScale::FIT_IN_FRAME | LwpLayoutScale::MAINTAIN_ASPECT_RATIO);
945 sal_uInt16 LwpMiddleLayout::GetScaleTile()
947 if ((m_nOverrideFlag & OVER_SCALING) && m_LayScale.obj().is() && GetLayoutScale())
948 return (GetLayoutScale()->GetPlacement() & LwpLayoutScale::TILED) ? 1 : 0;
949 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
950 if (xBase.is())
951 return dynamic_cast<LwpMiddleLayout&>(*xBase).GetScaleTile();
952 else
953 return 0;
956 sal_uInt16 LwpMiddleLayout::GetScaleCenter()
958 if (m_bGettingScaleCenter)
959 throw std::runtime_error("recursion in layout");
960 m_bGettingScaleCenter = true;
962 sal_uInt16 nRet = 0;
964 if ((m_nOverrideFlag & OVER_SCALING) && m_LayScale.obj().is() && GetLayoutScale())
966 nRet = (GetLayoutScale()->GetPlacement() & LwpLayoutScale::CENTERED) ? 1 : 0;
968 else
970 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
971 if (xBase.is())
972 nRet = dynamic_cast<LwpMiddleLayout&>(*xBase).GetScaleCenter();
975 m_bGettingScaleCenter = false;
976 return nRet;
979 bool LwpMiddleLayout::CanSizeRight()
981 sal_uInt8 RelType = GetRelativeType();
983 return !(RelType == LwpLayoutRelativityGuts::LAY_INLINE
984 || RelType == LwpLayoutRelativityGuts::LAY_PARA_RELATIVE
985 || RelType == LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL);
987 sal_Int32 LwpMiddleLayout::GetMinimumWidth()
989 if (((m_nAttributes3 & STYLE3_WIDTHVALID) != 0) && GetGeometry())
991 return GetGeometry()->GetWidth();
993 else if (m_nOverrideFlag & OVER_SIZE)
995 return DetermineWidth();
997 return 0;
999 sal_Int32 LwpMiddleLayout::DetermineWidth()
1001 if (IsSizeRightToContent())
1003 assert(false);
1005 else if (IsSizeRightToContainer())
1007 assert(false);
1009 else if (LwpLayoutGeometry* pGeo = GetGeometry())
1011 m_nAttributes3 |= STYLE3_WIDTHVALID;
1012 return pGeo->GetWidth();
1014 return 0;
1016 bool LwpMiddleLayout::IsSizeRightToContainer()
1018 if (!CanSizeRight())
1019 return false;
1021 if (m_nOverrideFlag & OVER_SIZE)
1023 return (m_nDirection & ((LAY_USEDIRECTION | LAY_AUTOSIZE | LAY_TOCONTAINER) << SHIFT_RIGHT))
1024 == ((LAY_USEDIRECTION | LAY_TOCONTAINER | LAY_AUTOSIZE) << SHIFT_RIGHT);
1026 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1027 if (xBase.is())
1029 LwpMiddleLayout* pLayout = dynamic_cast<LwpMiddleLayout*>(xBase.get());
1030 return pLayout && pLayout->IsSizeRightToContainer();
1032 else
1033 return false;
1035 bool LwpMiddleLayout::IsSizeRightToContent()
1037 if (!CanSizeRight())
1038 return false;
1040 if (m_nOverrideFlag & OVER_SIZE)
1042 return (m_nDirection & ((LAY_USEDIRECTION | LAY_AUTOSIZE | LAY_TOCONTAINER) << SHIFT_RIGHT))
1043 == ((LAY_USEDIRECTION | LAY_AUTOSIZE) << SHIFT_RIGHT);
1045 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1046 if (xBase.is())
1048 LwpMiddleLayout* pLayout = dynamic_cast<LwpMiddleLayout*>(xBase.get());
1049 return pLayout && pLayout->IsSizeRightToContent();
1051 else
1052 return false;
1056 * @descr: Get layout height
1059 double LwpMiddleLayout::GetHeight() { return GetGeometryHeight(); }
1062 * @descr: Get layout height
1065 double LwpMiddleLayout::GetWidth() { return GetGeometryWidth(); }
1067 * @descr: Get layout origin point
1070 LwpPoint LwpMiddleLayout::GetOrigin()
1072 LwpLayoutGeometry* pGeo = GetGeometry();
1073 if (pGeo)
1075 sal_uInt8 nType = GetRelativeType();
1076 if (nType == LwpLayoutRelativityGuts::LAY_INLINE
1077 || nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
1079 return pGeo->GetAbsoluteOrigin();
1081 else
1082 return pGeo->GetOrigin();
1085 return LwpPoint();
1089 * @descr: Whether the fill is pattern fill or not
1090 * @return: True if yes, false if not.
1092 bool LwpMiddleLayout::IsPatternFill()
1094 LwpBackgroundStuff* pBackgroundStuff = GetBackgroundStuff();
1095 if (pBackgroundStuff)
1097 return pBackgroundStuff->IsPatternFill();
1100 return false;
1104 * @descr: Get the fill pattern style. Data are saved in a XFBGImage object
1105 * @return: the fill pattern style.
1107 std::unique_ptr<XFBGImage> LwpMiddleLayout::GetFillPattern()
1109 LwpBackgroundStuff* pBackgroundStuff = GetBackgroundStuff();
1110 if (pBackgroundStuff)
1112 return pBackgroundStuff->GetFillPattern();
1115 return std::unique_ptr<XFBGImage>();
1119 * @descr: Whether the height and width of layout is auto grow
1122 bool LwpMiddleLayout::IsAutoGrow()
1124 if (m_nOverrideFlag & OVER_SIZE)
1126 return (m_nDirection
1127 & ((LAY_AUTOGROW << SHIFT_UP) | (LAY_AUTOGROW << SHIFT_DOWN)
1128 | (LAY_AUTOGROW << SHIFT_RIGHT) | (LAY_AUTOGROW << SHIFT_LEFT)))
1129 != 0;
1131 else
1133 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1134 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1136 return pLay->IsAutoGrow();
1139 return LwpVirtualLayout::IsAutoGrow();
1143 * @descr: Whether the height of layout is auto grow down
1146 bool LwpMiddleLayout::IsAutoGrowDown()
1148 if (m_nOverrideFlag & OVER_SIZE)
1150 return (m_nDirection & (LAY_AUTOGROW << SHIFT_DOWN)) != 0;
1152 else
1154 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1155 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1157 return pLay->GetIsAutoGrowDown();
1160 return LwpVirtualLayout::IsAutoGrowDown();
1164 * @descr: Whether the height of layout is auto grow up
1167 bool LwpMiddleLayout::IsAutoGrowUp()
1169 if (m_bGettingAutoGrowUp)
1170 throw std::runtime_error("recursion in layout");
1171 m_bGettingAutoGrowUp = true;
1173 bool bRet;
1175 if (m_nOverrideFlag & OVER_SIZE)
1177 bRet = (m_nDirection & (LAY_AUTOGROW << SHIFT_UP)) != 0;
1179 else
1181 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1182 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1183 bRet = pLay->IsAutoGrowUp();
1184 else
1185 bRet = LwpVirtualLayout::IsAutoGrowUp();
1188 m_bGettingAutoGrowUp = false;
1189 return bRet;
1193 * @descr: Whether the height of layout is auto grow down
1196 bool LwpMiddleLayout::IsAutoGrowLeft()
1198 if (m_nOverrideFlag & OVER_SIZE)
1200 return (m_nDirection & (LAY_AUTOGROW << SHIFT_LEFT)) != 0;
1202 else
1204 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1205 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1207 return pLay->IsAutoGrowLeft();
1210 return LwpVirtualLayout::IsAutoGrowLeft();
1214 * @descr: Whether the height of layout is auto grow down
1217 bool LwpMiddleLayout::IsAutoGrowRight()
1219 if (m_nOverrideFlag & OVER_SIZE)
1221 return (m_nDirection & (LAY_AUTOGROW << SHIFT_RIGHT)) != 0;
1223 else
1225 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1226 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1228 return pLay->IsAutoGrowRight();
1231 return LwpVirtualLayout::IsAutoGrowRight();
1235 * @descr: Get contents orientation
1238 sal_uInt8 LwpMiddleLayout::GetContentOrientation()
1240 //content orientation in Graphic objects and OLE objects not supported now
1241 if ((m_nOverrideFlag & OVER_ROTATION) && !m_LayGeometry.IsNull())
1243 LwpLayoutGeometry* pLayGeometry
1244 = dynamic_cast<LwpLayoutGeometry*>(m_LayGeometry.obj().get());
1245 if (pLayGeometry)
1246 return pLayGeometry->GetContentOrientation();
1248 else
1250 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1251 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1253 return pLay->GetContentOrientation();
1256 return LwpVirtualLayout::GetContentOrientation();
1260 * @descr: Whether it is honoring protection
1263 bool LwpMiddleLayout::HonorProtection()
1265 if (m_nOverrideFlag & OVER_MISC)
1267 if (!(m_nAttributes2 & STYLE2_HONORPROTECTION))
1268 return false;
1270 rtl::Reference<LwpVirtualLayout> xParent(
1271 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
1272 if (xParent.is() && !xParent->IsHeader())
1274 return xParent->GetHonorProtection();
1277 if (m_pFoundry) //is null now
1279 LwpDocument* pDoc = m_pFoundry->GetDocument();
1280 if (pDoc)
1282 return pDoc->GetHonorProtection();
1286 else
1288 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1289 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1291 return pLay->GetHonorProtection();
1295 return LwpVirtualLayout::HonorProtection();
1299 * @descr: Whether it is protected
1302 bool LwpMiddleLayout::IsProtected()
1304 bool bProtected = false;
1305 if (m_nOverrideFlag & OVER_MISC)
1307 bProtected = (m_nAttributes & STYLE_PROTECTED) != 0;
1309 else
1311 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1312 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1314 bProtected = pLay->GetIsProtected();
1316 else
1317 bProtected = LwpVirtualLayout::IsProtected();
1320 rtl::Reference<LwpVirtualLayout> xParent(
1321 dynamic_cast<LwpVirtualLayout*>(GetParent().obj().get()));
1322 if (xParent.is() && !xParent->IsHeader())
1324 /* If a parent's protected then none of its children can be accessed. */
1325 if (xParent->GetIsProtected())
1326 return true;
1328 if (xParent->GetHonorProtection())
1329 return bProtected;
1331 /* If our parent isn't honoring protection then we aren't protected. */
1332 return false;
1334 if (m_pFoundry) //is null now
1336 LwpDocument* pDoc = m_pFoundry->GetDocument();
1337 if (pDoc)
1339 if (pDoc->GetHonorProtection())
1340 return bProtected;
1342 /* If the document isn't honoring protection then we aren't protected.*/
1343 return false;
1347 return bProtected;
1351 * @descr: Get watermark layout
1354 rtl::Reference<LwpVirtualLayout> LwpMiddleLayout::GetWaterMarkLayout()
1356 rtl::Reference<LwpVirtualLayout> xLay(
1357 dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get()));
1358 o3tl::sorted_vector<LwpVirtualLayout*> aSeen;
1359 while (xLay.is())
1361 bool bAlreadySeen = !aSeen.insert(xLay.get()).second;
1362 if (bAlreadySeen)
1363 throw std::runtime_error("loop in conversion");
1364 if (xLay->IsForWaterMark())
1366 return xLay;
1368 xLay.set(dynamic_cast<LwpVirtualLayout*>(xLay->GetNext().obj().get()));
1370 return rtl::Reference<LwpVirtualLayout>();
1374 * @descr: Create and return xfbgimage object for watermark
1377 std::unique_ptr<XFBGImage> LwpMiddleLayout::GetXFBGImage()
1379 std::unique_ptr<XFBGImage> xXFBGImage;
1381 rtl::Reference<LwpVirtualLayout> xWaterMarkLayout(GetWaterMarkLayout());
1382 LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xWaterMarkLayout.get());
1383 if (pLay)
1385 //test BGImage
1386 LwpGraphicObject* pGrfObj = dynamic_cast<LwpGraphicObject*>(pLay->GetContent().obj().get());
1387 if (pGrfObj)
1389 xXFBGImage.reset(new XFBGImage);
1390 if (pGrfObj->IsLinked())
1392 //set file link
1393 OUString linkedfilepath = pGrfObj->GetLinkedFilePath();
1394 OUString fileURL = LwpTools::convertToFileUrl(
1395 OUStringToOString(linkedfilepath, osl_getThreadTextEncoding()));
1396 xXFBGImage->SetFileLink(fileURL);
1398 else
1400 std::vector<sal_uInt8> aGrafData = pGrfObj->GetRawGrafData();
1401 xXFBGImage->SetImageData(aGrafData.data(), aGrafData.size());
1404 //automatic, top left
1405 xXFBGImage->SetPosition(enumXFAlignStart, enumXFAlignTop);
1406 if (pLay->GetScaleCenter())
1408 //center
1409 xXFBGImage->SetPosition();
1411 else if (pLay->GetScaleTile())
1413 //tile
1414 xXFBGImage->SetRepeate();
1416 //fit type, area type
1417 if ((pLay->GetScaleMode() & LwpLayoutScale::FIT_IN_FRAME) != 0)
1419 if ((pLay->GetScaleMode() & LwpLayoutScale::MAINTAIN_ASPECT_RATIO) == 0)
1421 xXFBGImage->SetStretch();
1426 return xXFBGImage;
1430 * @descr: Whether the page uses the printer setting
1433 bool LwpMiddleLayout::GetUsePrinterSettings()
1435 if (m_bGettingUsePrinterSettings)
1436 throw std::runtime_error("recursion in layout");
1437 m_bGettingUsePrinterSettings = true;
1439 bool bRet = false;
1441 if (m_nOverrideFlag & OVER_SIZE)
1443 bRet = (m_nAttributes3 & STYLE3_USEPRINTERSETTINGS) != 0;
1445 else
1447 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1448 if (LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xBase.get()))
1450 bRet = pLay->GetUsePrinterSettings();
1454 m_bGettingUsePrinterSettings = false;
1455 return bRet;
1458 //Check whether there are contents in the layout
1459 bool LwpMiddleLayout::HasContent()
1461 rtl::Reference<LwpObject> content = m_Content.obj();
1462 return content.is();
1465 LwpLayout::LwpLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
1466 : LwpMiddleLayout(objHdr, pStrm)
1467 , m_bGettingShadow(false)
1468 , m_bGettingNumCols(false)
1472 LwpLayout::~LwpLayout() {}
1474 void LwpLayout::Read()
1476 LwpObjectStream* pStrm = m_pObjStrm.get();
1478 LwpMiddleLayout::Read();
1479 if (LwpFileHeader::m_nFileRevision < 0x000B)
1481 // read PreRevBLayout...
1483 else
1485 sal_uInt16 nSimple = pStrm->QuickReaduInt16();
1487 if (!nSimple)
1489 m_aUseWhen.Read(pStrm);
1491 sal_uInt8 nFlag = pStrm->QuickReaduInt8();
1492 if (nFlag)
1493 m_Position.ReadIndexed(pStrm);
1496 m_LayColumns.ReadIndexed(pStrm);
1497 m_LayGutterStuff.ReadIndexed(pStrm);
1498 m_LayJoinStuff.ReadIndexed(pStrm);
1499 m_LayShadow.ReadIndexed(pStrm);
1501 if (pStrm->CheckExtra())
1503 m_LayExtJoinStuff.ReadIndexed(pStrm);
1504 pStrm->SkipExtra();
1510 * @descr: Get columns number
1513 sal_uInt16 LwpLayout::GetNumCols()
1515 if (m_bGettingNumCols)
1516 throw std::runtime_error("recursion in layout");
1517 m_bGettingNumCols = true;
1519 sal_uInt16 nRet = 0;
1520 LwpLayoutColumns* pLayColumns = (m_nOverrideFlag & OVER_COLUMNS)
1521 ? dynamic_cast<LwpLayoutColumns*>(m_LayColumns.obj().get())
1522 : nullptr;
1523 if (pLayColumns)
1525 nRet = pLayColumns->GetNumCols();
1527 else
1529 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1530 LwpVirtualLayout* pStyle = dynamic_cast<LwpVirtualLayout*>(xBase.get());
1531 nRet = pStyle ? pStyle->GetNumCols() : LwpVirtualLayout::GetNumCols();
1533 m_bGettingNumCols = false;
1534 return nRet;
1538 * @descr: Get gap between columns
1539 * @param: the order of column
1541 double LwpLayout::GetColGap(sal_uInt16 nIndex)
1543 if ((m_nOverrideFlag & OVER_COLUMNS) || (m_nAttributes2 & STYLE2_LOCALCOLUMNINFO))
1545 LwpLayoutColumns* pLayColumns = dynamic_cast<LwpLayoutColumns*>(m_LayColumns.obj().get());
1546 if (pLayColumns)
1548 return pLayColumns->GetColGap(nIndex);
1552 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1553 LwpVirtualLayout* pStyle = dynamic_cast<LwpVirtualLayout*>(xBase.get());
1554 if (pStyle)
1556 return pStyle->GetColGap(nIndex);
1559 return LwpVirtualLayout::GetColGap(nIndex);
1563 * @descr: Create and return XFColumns object
1566 XFColumns* LwpLayout::GetXFColumns()
1568 //if there is only one column, do not need insert columns
1569 sal_uInt16 nCols = GetNumCols();
1570 if (nCols == 1)
1572 return nullptr;
1575 std::unique_ptr<XFColumns> xColumns(new XFColumns);
1576 //set XFColumnSep
1577 std::unique_ptr<XFColumnSep> xColumnSep(GetColumnSep());
1578 if (xColumnSep)
1580 xColumns->SetSeparator(*xColumnSep);
1583 //set column count and column gap
1584 xColumns->SetCount(nCols);
1585 double fGap = GetColGap(0);
1586 xColumns->SetGap(fGap);
1588 //set xfcolumn
1589 for (sal_uInt16 nIndex = 0; nIndex < nCols; nIndex++)
1591 XFColumn aColumn;
1592 sal_Int32 nWidth = 8305 / nCols; //relative width
1593 aColumn.SetRelWidth(nWidth);
1595 //the left and right margins is 0;
1596 double nGap = GetColGap(nIndex) / 2;
1597 aColumn.SetMargins(nGap, nGap);
1598 if (nIndex == 0)
1600 aColumn.SetMargins(0, nGap);
1602 if (nIndex == (nCols - 1))
1604 aColumn.SetMargins(nGap, 0);
1606 xColumns->AddColumn(aColumn);
1609 return xColumns.release();
1613 * @descr: Create and return XFColumnSep object
1616 XFColumnSep* LwpLayout::GetColumnSep()
1618 //Get LwpLayoutGutters
1619 LwpLayoutGutters* pLayoutGutters
1620 = dynamic_cast<LwpLayoutGutters*>(m_LayGutterStuff.obj().get());
1621 if (!pLayoutGutters)
1623 return nullptr;
1626 LwpBorderStuff& rBorderStuff = pLayoutGutters->GetBorderStuff();
1628 LwpBorderStuff::BorderType eType = LwpBorderStuff::LEFT;
1629 LwpColor aColor = rBorderStuff.GetSideColor(eType);
1630 double fWidth = rBorderStuff.GetSideWidth(eType);
1631 //sal_uInt16 nType = rBorderStuff->GetSideType(eType);
1633 XFColumnSep* pColumnSep = new XFColumnSep();
1634 XFColor aXFColor(aColor.To24Color());
1635 pColumnSep->SetColor(aXFColor);
1636 pColumnSep->SetWidth(fWidth);
1637 pColumnSep->SetRelHeight(100);
1638 pColumnSep->SetVerticalAlign(enumXFAlignTop);
1640 return pColumnSep;
1644 * @descr: Get use when type
1647 LwpLayout::UseWhenType LwpLayout::GetUseWhenType()
1649 UseWhenType eType = StartWithinPage;
1650 LwpUseWhen* pUseWhen = GetUseWhen();
1651 if (pUseWhen)
1653 if (pUseWhen->IsStartOnThisHF())
1655 eType = StartWithinColume;
1657 else if (pUseWhen->IsStartOnThisPage())
1659 eType = StartWithinPage;
1661 else if (pUseWhen->IsStartOnNextPage())
1663 eType = StartOnNextPage;
1665 else if (pUseWhen->IsStartOnNextOddPage())
1667 eType = StartOnOddPage;
1669 else if (pUseWhen->IsStartOnNextEvenPage())
1671 eType = StartOnEvenPage;
1674 else
1676 eType = StartOnNextPage;
1678 return eType;
1682 * @descr: Get use page
1685 sal_uInt16 LwpLayout::GetUsePage()
1687 if (m_nOverrideFlag & OVER_PLACEMENT)
1689 LwpUseWhen* pUseWhen = GetUseWhen();
1690 if (pUseWhen)
1691 return pUseWhen->GetUsePage();
1692 else
1693 return 0;
1695 else
1697 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1698 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1700 return pLay->GetUsePage();
1703 return 0;
1707 * @descr: Get usewhen pointer
1710 LwpUseWhen* LwpLayout::VirtualGetUseWhen()
1712 if (m_nOverrideFlag & OVER_PLACEMENT)
1714 return &m_aUseWhen;
1716 else
1718 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1719 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1721 return pLay->VirtualGetUseWhen();
1724 return LwpVirtualLayout::VirtualGetUseWhen();
1728 * @descr: Whether it is use on all pages
1731 bool LwpLayout::IsUseOnAllPages()
1733 if (m_nOverrideFlag & OVER_PLACEMENT)
1735 LwpUseWhen* pUseWhen = GetUseWhen();
1736 if (pUseWhen)
1737 return pUseWhen->IsUseOnAllPages();
1738 else
1739 return false;
1741 else
1743 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1744 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1746 return pLay->IsUseOnAllPages();
1749 return LwpVirtualLayout::IsUseOnAllPages();
1753 * @descr: Whether it is use on all even pages
1756 bool LwpLayout::IsUseOnAllEvenPages()
1758 if (m_nOverrideFlag & OVER_PLACEMENT)
1760 LwpUseWhen* pUseWhen = GetUseWhen();
1761 if (pUseWhen)
1762 return pUseWhen->IsUseOnAllEvenPages();
1763 else
1764 return false;
1766 else
1768 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1769 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1771 return pLay->IsUseOnAllEvenPages();
1774 return LwpVirtualLayout::IsUseOnAllEvenPages();
1778 * @descr: Whether it is use on all odd pages
1781 bool LwpLayout::IsUseOnAllOddPages()
1783 if (m_nOverrideFlag & OVER_PLACEMENT)
1785 LwpUseWhen* pUseWhen = GetUseWhen();
1786 if (pUseWhen)
1787 return pUseWhen->IsUseOnAllOddPages();
1788 else
1789 return false;
1791 else
1793 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1794 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1796 return pLay->IsUseOnAllOddPages();
1799 return LwpVirtualLayout::IsUseOnAllOddPages();
1803 * @descr: Whether it is use on current page
1806 bool LwpLayout::IsUseOnPage()
1808 if (m_nOverrideFlag & OVER_PLACEMENT)
1810 LwpUseWhen* pUseWhen = GetUseWhen();
1811 if (pUseWhen)
1812 return pUseWhen->IsUseOnPage();
1813 else
1814 return false;
1816 else
1818 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1819 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1821 return pLay->IsUseOnPage();
1824 return LwpVirtualLayout::IsUseOnPage();
1828 * @descr: Get the LwpShadow object according to m_LayShadow id.
1830 LwpShadow* LwpLayout::GetShadow()
1832 if (m_bGettingShadow)
1833 throw std::runtime_error("recursion in layout");
1834 m_bGettingShadow = true;
1835 LwpShadow* pRet = nullptr;
1836 if (m_nOverrideFlag & OVER_SHADOW)
1838 LwpLayoutShadow* pLayoutShadow = dynamic_cast<LwpLayoutShadow*>(m_LayShadow.obj().get());
1839 pRet = pLayoutShadow ? &pLayoutShadow->GetShadow() : nullptr;
1841 else
1843 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1844 if (LwpLayout* pLay = dynamic_cast<LwpLayout*>(xBase.get()))
1846 pRet = pLay->GetShadow();
1849 m_bGettingShadow = false;
1850 return pRet;
1854 * @descr: create xfshadow
1856 XFShadow* LwpLayout::GetXFShadow()
1858 LwpShadow* pShadow = GetShadow();
1859 if (!pShadow)
1860 return nullptr;
1861 LwpColor color = pShadow->GetColor();
1862 double offsetX = pShadow->GetOffsetX();
1863 double offsetY = pShadow->GetOffsetY();
1865 if (!offsetX || !offsetY || !color.IsValidColor())
1866 return nullptr;
1867 XFShadow* pXFShadow = new XFShadow();
1868 enumXFShadowPos eXFShadowPos = enumXFShadowLeftTop;
1869 double fOffset = 0;
1871 bool left = false;
1872 bool top = false;
1873 if (offsetX < 0)
1874 left = true;
1875 if (offsetY < 0)
1876 top = true;
1877 if (left)
1879 fOffset = -offsetX;
1880 if (top)
1881 eXFShadowPos = enumXFShadowLeftTop;
1882 else
1883 eXFShadowPos = enumXFShadowLeftBottom;
1885 else
1887 fOffset = offsetX;
1888 if (top)
1889 eXFShadowPos = enumXFShadowRightTop;
1890 else
1891 eXFShadowPos = enumXFShadowRightBottom;
1894 pXFShadow->SetPosition(eXFShadowPos);
1895 pXFShadow->SetOffset(fOffset);
1896 pXFShadow->SetColor(XFColor(color.To24Color()));
1898 return pXFShadow;
1902 * @descr get the layout that containers the current frame layout
1905 rtl::Reference<LwpVirtualLayout> LwpLayout::GetContainerLayout()
1907 if (IsRelativeAnchored())
1909 //get position
1910 LwpPara* pPara = dynamic_cast<LwpPara*>(GetPosition().obj().get());
1911 if (pPara)
1913 LwpStory* pStory = pPara->GetStory();
1914 return pStory ? pStory->GetTabLayout() : nullptr;
1917 return GetParentLayout();
1920 LwpPlacableLayout::LwpPlacableLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
1921 : LwpLayout(objHdr, pStrm)
1922 , m_bGettingWrapType(false)
1923 , m_bGettingLayoutRelativity(false)
1924 , m_nWrapType(0)
1925 , m_nBuoyancy(0)
1926 , m_nBaseLineOffset(0)
1930 LwpPlacableLayout::~LwpPlacableLayout() {}
1932 void LwpPlacableLayout::Read()
1934 LwpObjectStream* pStrm = m_pObjStrm.get();
1935 LwpLayout::Read();
1936 if (LwpFileHeader::m_nFileRevision < 0x000B)
1938 assert(false);
1940 else
1942 sal_uInt16 simple = pStrm->QuickReaduInt16();
1943 if (!simple)
1945 m_nWrapType = pStrm->QuickReaduInt8();
1946 m_nBuoyancy = pStrm->QuickReaduInt8();
1947 m_nBaseLineOffset = pStrm->QuickReadInt32();
1948 m_Script.Read(pStrm);
1950 else
1952 m_nWrapType = LAY_WRAP_AROUND;
1953 m_nBuoyancy = LAY_BUOYNEUTRAL;
1954 m_nBaseLineOffset = 0;
1956 m_LayRelativity.ReadIndexed(pStrm);
1957 if (pStrm->CheckExtra())
1959 sal_uInt16 count = pStrm->QuickReaduInt16();
1960 if (count)
1962 // skip 'count' of LwpPoints, each of which is 2 Int32s
1963 pStrm->SeekRel(count * 8);
1965 pStrm->SkipExtra();
1970 * @descr: get wrap type
1972 sal_uInt8 LwpPlacableLayout::GetWrapType()
1974 if (m_bGettingWrapType)
1975 throw std::runtime_error("recursion in layout");
1976 m_bGettingWrapType = true;
1977 sal_uInt8 nWrapType = LAY_WRAP_AROUND;
1978 if (m_nOverrideFlag & OVER_PLACEMENT)
1980 nWrapType = m_nWrapType;
1982 else
1984 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
1985 if (LwpPlacableLayout* pLay = dynamic_cast<LwpPlacableLayout*>(xBase.get()))
1987 nWrapType = pLay->GetWrapType();
1990 m_bGettingWrapType = false;
1991 return nWrapType;
1994 * @descr: get LayoutRelativity
1996 LwpLayoutRelativity* LwpPlacableLayout::GetRelativityPiece()
1998 if (m_bGettingLayoutRelativity)
1999 throw std::runtime_error("recursion in layout");
2000 m_bGettingLayoutRelativity = true;
2001 LwpLayoutRelativity* pRet = nullptr;
2002 if (!m_LayRelativity.IsNull())
2004 if (m_nOverrideFlag & OVER_PLACEMENT)
2006 pRet = dynamic_cast<LwpLayoutRelativity*>(m_LayRelativity.obj().get());
2009 else
2011 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
2012 if (LwpPlacableLayout* pLay = dynamic_cast<LwpPlacableLayout*>(xBase.get()))
2014 pRet = pLay->GetRelativityPiece();
2017 m_bGettingLayoutRelativity = false;
2018 return pRet;
2021 * @descr: Get relative type
2024 sal_uInt8 LwpPlacableLayout::GetRelativeType()
2026 LwpLayoutRelativity* pLayRel = GetRelativityPiece();
2027 if (pLayRel)
2029 return pLayRel->GetRelGuts().GetRelativeType();
2031 return LwpVirtualLayout::GetRelativeType();
2034 * @descr: Get offset from the baseline
2037 sal_Int32 LwpPlacableLayout::GetBaseLineOffset()
2039 /* The baseline is only valid if this is flow-with-text */
2040 if (GetRelativeType() != LwpLayoutRelativityGuts::LAY_INLINE)
2042 return 0;
2045 // First, ask our content if it has a baseline, ignore now
2047 if (Content && Content->GetBaseLineOffset(&Baseline))
2048 return Baseline;
2051 if (m_nOverrideFlag & OVER_PLACEMENT)
2053 return m_nBaseLineOffset;
2055 else
2057 rtl::Reference<LwpObject> xBase(GetBasedOnStyle());
2058 if (LwpPlacableLayout* pLay = dynamic_cast<LwpPlacableLayout*>(xBase.get()))
2060 return pLay->GetBaseLineOffset();
2063 return 0;
2066 * @descr: whether the parent layout is page layout
2069 bool LwpPlacableLayout::IsAnchorPage()
2071 if (IsRelativeAnchored())
2072 return false;
2074 rtl::Reference<LwpVirtualLayout> xLayout = GetParentLayout();
2075 return xLayout.is() && (xLayout->IsPage() || xLayout->IsHeader() || xLayout->IsFooter());
2078 * @descr: whether the parent layout is frame layout
2081 bool LwpPlacableLayout::IsAnchorFrame()
2083 if (IsRelativeAnchored())
2084 return false;
2086 rtl::Reference<LwpVirtualLayout> xLayout = GetParentLayout();
2087 return xLayout.is() && (xLayout->IsFrame() || xLayout->IsGroupHead());
2090 * @descr: whether the parent layout is cell layout
2093 bool LwpPlacableLayout::IsAnchorCell()
2095 if (IsRelativeAnchored())
2096 return false;
2098 rtl::Reference<LwpVirtualLayout> xLayout = GetParentLayout();
2099 return xLayout.is() && xLayout->IsCell();
2103 * @descr: Set font style for setting position of frame
2106 void LwpPlacableLayout::SetFont(rtl::Reference<XFFont> const& pFont) { m_pFont = pFont; }
2108 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */