From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- lotuswordpro/source/filter/lwplayout.cxx | 2119 ++++++++++++++++++++++++++++++ 1 file changed, 2119 insertions(+) create mode 100644 lotuswordpro/source/filter/lwplayout.cxx (limited to 'lotuswordpro/source/filter/lwplayout.cxx') diff --git a/lotuswordpro/source/filter/lwplayout.cxx b/lotuswordpro/source/filter/lwplayout.cxx new file mode 100644 index 000000000..6405e2277 --- /dev/null +++ b/lotuswordpro/source/filter/lwplayout.cxx @@ -0,0 +1,2119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: IBM Corporation + * + * Copyright: 2008 by IBM Corporation + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +/************************************************************************* + * @file + * For LWP filter architecture prototype + ************************************************************************/ + +#include +#include "lwplayout.hxx" +#include "lwpusewhen.hxx" +#include +#include "lwplaypiece.hxx" +#include +#include "lwpstory.hxx" +#include "lwpparastyle.hxx" +#include "lwpholder.hxx" +#include "lwpdoc.hxx" +#include "lwpgrfobj.hxx" +#include +#include +#include +#include + +LwpVirtualLayout::LwpVirtualLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm) + : LwpDLNFPVList(objHdr, pStrm) + , m_bGettingHonorProtection(false) + , m_bGettingMarginsSameAsParent(false) + , m_bGettingHasProtection(false) + , m_bGettingIsProtected(false) + , m_bGettingIsAutoGrowDown(false) + , m_bGettingMarginsValue(false) + , m_bGettingExtMarginsValue(false) + , m_bGettingUsePrinterSettings(false) + , m_bGettingScaleCenter(false) + , m_bGettingBorderStuff(false) + , m_bGettingUseWhen(false) + , m_bGettingStyleLayout(false) + , m_bGettingAutoGrowUp(false) + , m_nAttributes(0) + , m_nAttributes2(0) + , m_nAttributes3(0) + , m_nOverrideFlag(0) + , m_nDirection(0) + , m_nEditorID(0) +{ +} + +void LwpVirtualLayout::Read() +{ + LwpDLNFPVList::Read(); + + LwpObjectStream* pStrm = m_pObjStrm.get(); + m_nAttributes = pStrm->QuickReaduInt32(); + m_nAttributes2 = pStrm->QuickReaduInt32(); + m_nAttributes3 = pStrm->QuickReaduInt32(); + m_nOverrideFlag = pStrm->QuickReaduInt32(); + m_nDirection = pStrm->QuickReaduInt16(); + + //Note that two bytes is read into m_nEditorID instead of one byte. + m_nEditorID = pStrm->QuickReaduInt16(); + + m_NextEnumerated.ReadIndexed(pStrm); + m_PreviousEnumerated.ReadIndexed(pStrm); + + pStrm->SkipExtra(); +} + +bool LwpVirtualLayout::MarginsSameAsParent() +{ + return (m_nAttributes2 & STYLE2_MARGINSSAMEASPARENT) != 0; +} + +/** +* @descr: Get the gap between columns +* +*/ +double LwpVirtualLayout::GetColGap(sal_uInt16 /*nIndex*/) +{ + //return DEFAULTGAPSIZE; + //return LwpTools::ConvertToMetric(0.17);//DEFAULTGAPSIZE=0.17 + return LwpTools::ConvertToMetric(0.17); +} + +/** +* @descr: Whether it is honoring protection +* +*/ +bool LwpVirtualLayout::HonorProtection() +{ + if (!(m_nAttributes2 & STYLE2_HONORPROTECTION)) + return false; + + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader()) + { + return xParent->GetHonorProtection(); + } + + if (m_pFoundry) //is null now + { + LwpDocument* pDoc = m_pFoundry->GetDocument(); + if (pDoc && pDoc->GetRootDocument()) + return pDoc->GetRootDocument()->GetHonorProtection(); + } + + return true; +} + +/** +* @descr: Whether it is protected +* +*/ +bool LwpVirtualLayout::IsProtected() +{ + bool bProtected = (m_nAttributes & STYLE_PROTECTED) != 0; + + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader()) + { + if (xParent->GetHonorProtection() && (xParent->GetHasProtection() || bProtected)) + { + return true; + } + } + else if (m_pFoundry) //is null now + { + LwpDocument* pDoc = m_pFoundry->GetDocument(); + if (pDoc) + { + if (pDoc->GetHonorProtection() && bProtected) + { + return true; + } + } + } + + return false; +} + +/** +* @descr: Whether it has protection +* +*/ +bool LwpVirtualLayout::HasProtection() +{ + if (m_nAttributes & STYLE_PROTECTED) + return true; + + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader()) + { + return xParent->GetHasProtection(); + } + + return false; +} + +/** +* @descr: Whether it is a mirror layout +* +*/ +bool LwpVirtualLayout::IsComplex() const { return (m_nAttributes & STYLE_COMPLEX) != 0; } + +/** +* @descr: Get usewhen pointer +* +*/ +LwpUseWhen* LwpVirtualLayout::GetUseWhen() +{ + if (m_bGettingUseWhen) + throw std::runtime_error("recursion in layout"); + m_bGettingUseWhen = true; + + LwpUseWhen* pRet = nullptr; + + /* + If we have a parent, and I'm not a page layout, + use my parents information. + */ + if (GetLayoutType() != LWP_PAGE_LAYOUT) + { + //get parent + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader() && (xParent->GetLayoutType() != LWP_PAGE_LAYOUT)) + pRet = xParent->GetUseWhen(); + } + + if (!pRet) + pRet = VirtualGetUseWhen(); + + m_bGettingUseWhen = false; + + return pRet; +} +/** + * @descr: Whether this layout is page layout or not +*/ +bool LwpVirtualLayout::IsPage() { return (GetLayoutType() == LWP_PAGE_LAYOUT); } +/** + * @descr: Whether this layout is header layout or not +*/ +bool LwpVirtualLayout::IsHeader() { return (GetLayoutType() == LWP_HEADER_LAYOUT); } +/** + * @descr: Whether this layout is footer layout or not +*/ +bool LwpVirtualLayout::IsFooter() { return (GetLayoutType() == LWP_FOOTER_LAYOUT); } +/** + * @descr: Whether this layout is frame layout or not +*/ +bool LwpVirtualLayout::IsFrame() { return (GetLayoutType() == LWP_FRAME_LAYOUT); } + +/** + * @descr: Whether this layout is cell layout or not +*/ +bool LwpVirtualLayout::IsCell() +{ + return (GetLayoutType() == LWP_CELL_LAYOUT || GetLayoutType() == LWP_CONNECTED_CELL_LAYOUT + || GetLayoutType() == LWP_HIDDEN_CELL_LAYOUT); +} +/** + * @descr: Whether this layout is supertable layout or not +*/ +bool LwpVirtualLayout::IsSuperTable() { return (GetLayoutType() == LWP_SUPERTABLE_LAYOUT); } +/** + * @descr: Whether this layout is group layout or not +*/ +bool LwpVirtualLayout::IsGroupHead() { return (GetLayoutType() == LWP_GROUP_LAYOUT); } +/** + * @descr: get the relative type +*/ +sal_uInt8 LwpVirtualLayout::GetRelativeType() +{ + return LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE; +} +/** + * @descr: whether it is relative anchored layout +*/ +bool LwpVirtualLayout::IsRelativeAnchored() +{ + sal_uInt8 nType; + + nType = GetRelativeType(); + return (nType == LwpLayoutRelativityGuts::LAY_PARA_RELATIVE) + || (nType == LwpLayoutRelativityGuts::LAY_INLINE) + || (nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE) + || (nType == LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL); +} +/** + * @descr: whether it is MinimumHeight layout +*/ +bool LwpVirtualLayout::IsMinimumHeight() const +{ + return ((m_nAttributes3 & STYLE3_MINHEIGHTVALID) != 0); +} + +/** +* @descr: Get parent layout +* +*/ +rtl::Reference LwpVirtualLayout::GetParentLayout() +{ + return rtl::Reference( + dynamic_cast(GetParent().obj().get())); +} + +/** +* @descr: Register child layout style +* +*/ +void LwpVirtualLayout::RegisterChildStyle() +{ + //Register all children styles + rtl::Reference xLayout( + dynamic_cast(GetChildHead().obj().get())); + while (xLayout.is()) + { + xLayout->SetFoundry(m_pFoundry); + xLayout->DoRegisterStyle(); + xLayout.set(dynamic_cast(xLayout->GetNext().obj().get())); + } +} + +bool LwpVirtualLayout::NoContentReference() +{ + return (m_nAttributes2 & STYLE2_NOCONTENTREFERENCE) != 0; +} + +bool LwpVirtualLayout::IsStyleLayout() +{ + if (m_bGettingStyleLayout) + throw std::runtime_error("recursion in layout"); + m_bGettingStyleLayout = true; + + bool bRet = false; + if (m_nAttributes3 & STYLE3_STYLELAYOUT) + bRet = true; + else + { + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is()) + bRet = xParent->IsStyleLayout(); + } + + m_bGettingStyleLayout = false; + return bRet; +} + +/** +* @descr: Find child layout by layout type +* +*/ +LwpVirtualLayout* LwpVirtualLayout::FindChildByType(LWP_LAYOUT_TYPE eType) +{ + LwpObjectID* pID = &GetChildHead(); + LwpVirtualLayout* pPrevLayout = nullptr; + + while (pID && !pID->IsNull()) + { + LwpVirtualLayout* pLayout = dynamic_cast(pID->obj().get()); + if (!pLayout) + break; + + if (pPrevLayout && pLayout == pPrevLayout) + { + SAL_WARN("lwp", "loop in layout"); + break; + } + + pPrevLayout = pLayout; + + if (pLayout->GetLayoutType() == eType) + return pLayout; + + pID = &pLayout->GetNext(); + } + + return nullptr; +} + +/** +* @descr: Whether the size of layout is fit the graphic +* +*/ +bool LwpVirtualLayout::IsFitGraphic() +{ + return IsAutoGrowRight() && !IsAutoGrowLeft() && GetIsAutoGrowDown(); +} + +/** +* @descr: Whether the width of layout is auto grow +* +*/ +bool LwpVirtualLayout::IsAutoGrowWidth() { return IsAutoGrowLeft() || IsAutoGrowRight(); } + +/** +* @descr: Determine whether the layout width is to margin +* +*/ +bool LwpVirtualLayout::IsInlineToMargin() const +{ + return (m_nAttributes3 & STYLE3_INLINETOMARGIN) != 0; +} + +void LwpAssociatedLayouts::Read(LwpObjectStream* pStrm) +{ + m_OnlyLayout.ReadIndexed(pStrm); + m_Layouts.Read(pStrm); + pStrm->SkipExtra(); +} + +/** +* @descr: Looking for the layout which follows the pStartLayout +* @param: pStartLayout - the layout which is used for looking for its following layout +*/ +rtl::Reference +LwpAssociatedLayouts::GetLayout(LwpVirtualLayout const* pStartLayout) +{ + if (!pStartLayout && !m_OnlyLayout.IsNull()) + /* Looking for the first layout and there's only one layout in the list.*/ + return rtl::Reference( + dynamic_cast(m_OnlyLayout.obj().get())); + + rtl::Reference xObjHolder( + dynamic_cast(m_Layouts.GetHead().obj().get())); + if (xObjHolder.is()) + { + rtl::Reference xLayout( + dynamic_cast(xObjHolder->GetObject().obj().get())); + if (!pStartLayout) + return xLayout; + + while (xObjHolder.is() && pStartLayout != xLayout.get()) + { + xObjHolder.set(dynamic_cast(xObjHolder->GetNext().obj().get())); + if (xObjHolder.is()) + { + xLayout.set(dynamic_cast(xObjHolder->GetObject().obj().get())); + } + } + + if (xObjHolder.is()) + { + xObjHolder.set(dynamic_cast(xObjHolder->GetNext().obj().get())); + if (xObjHolder.is()) + { + xLayout.set(dynamic_cast(xObjHolder->GetObject().obj().get())); + return xLayout; + } + } + } + + return rtl::Reference(); +} + +LwpHeadLayout::LwpHeadLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm) + : LwpVirtualLayout(objHdr, pStrm) +{ +} + +void LwpHeadLayout::Read() +{ + LwpVirtualLayout::Read(); + //For PermissiveLayout + m_pObjStrm->SkipExtra(); + //For me + m_pObjStrm->SkipExtra(); +} + +void LwpHeadLayout::RegisterStyle() +{ + //Register all children styles + rtl::Reference xLayout( + dynamic_cast(GetChildHead().obj().get())); + o3tl::sorted_vector aSeen; + while (xLayout.is()) + { + bool bAlreadySeen = !aSeen.insert(xLayout.get()).second; + if (bAlreadySeen) + throw std::runtime_error("loop in conversion"); + xLayout->SetFoundry(m_pFoundry); + //if the layout is relative to para, the layout will be registered in para + if (!xLayout->IsRelativeAnchored()) + xLayout->DoRegisterStyle(); + rtl::Reference xNext( + dynamic_cast(xLayout->GetNext().obj().get())); + xLayout = xNext; + } +} + +/** + * @descr find endnote supertable layout from the child layout list. Suppose that there is only one endnote supertablelayout in one division + * @return pointer to endnote supertable layout + */ +rtl::Reference LwpHeadLayout::FindEnSuperTableLayout() +{ + rtl::Reference xLayout( + dynamic_cast(GetChildHead().obj().get())); + o3tl::sorted_vector aSeen; + while (xLayout) + { + bool bAlreadySeen = !aSeen.insert(xLayout.get()).second; + if (bAlreadySeen) + throw std::runtime_error("loop in conversion"); + if (xLayout->GetLayoutType() == LWP_ENDNOTE_SUPERTABLE_LAYOUT) + { + return xLayout; + } + xLayout.set(dynamic_cast(xLayout->GetNext().obj().get())); + } + return rtl::Reference(); +} + +LwpLayoutStyle::LwpLayoutStyle() + : m_nStyleDefinition(0) + , m_pDescription(new LwpAtomHolder) + , m_nKey(0) +{ +} + +LwpLayoutStyle::~LwpLayoutStyle() {} + +void LwpLayoutStyle::Read(LwpObjectStream* pStrm) +{ + m_nStyleDefinition = pStrm->QuickReaduInt32(); + m_pDescription->Read(pStrm); + if (pStrm->CheckExtra()) + { + m_nKey = pStrm->QuickReaduInt16(); + pStrm->SkipExtra(); + } +} + +LwpLayoutMisc::LwpLayoutMisc() + : m_nGridDistance(0) + , m_nGridType(0) +{ +} + +LwpLayoutMisc::~LwpLayoutMisc() {} + +void LwpLayoutMisc::Read(LwpObjectStream* pStrm) +{ + m_nGridType = pStrm->QuickReaduInt16(); + m_nGridDistance = pStrm->QuickReadInt32(); + m_aContentStyle.Read(pStrm); + pStrm->SkipExtra(); +} + +LwpMiddleLayout::LwpMiddleLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm) + : LwpVirtualLayout(objHdr, pStrm) + , m_bGettingGeometry(false) + , m_bGettingBackgroundStuff(false) +{ +} + +LwpMiddleLayout::~LwpMiddleLayout() {} + +void LwpMiddleLayout::Read() +{ + LwpObjectStream* pStrm = m_pObjStrm.get(); + + LwpVirtualLayout::Read(); + + //skip CLiteLayout data; + LwpAtomHolder ContentClass; + ContentClass.Read(pStrm); + pStrm->SkipExtra(); + + // before layout hierarchy rework + if (LwpFileHeader::m_nFileRevision < 0x000B) + return; + + m_Content.ReadIndexed(pStrm); + + // 01/20/2005 + m_BasedOnStyle.ReadIndexed(pStrm); + m_TabPiece.ReadIndexed(pStrm); + + sal_uInt8 nWhatsItGot = pStrm->QuickReaduInt8(); + + if (nWhatsItGot & DISK_GOT_STYLE_STUFF) + { + m_aStyleStuff.Read(pStrm); + } + if (nWhatsItGot & DISK_GOT_MISC_STUFF) + { + m_aMiscStuff.Read(pStrm); + } + + m_LayGeometry.ReadIndexed(pStrm); + m_LayScale.ReadIndexed(pStrm); + m_LayMargins.ReadIndexed(pStrm); + m_LayBorderStuff.ReadIndexed(pStrm); + m_LayBackgroundStuff.ReadIndexed(pStrm); + + if (pStrm->CheckExtra()) + { + m_LayExtBorderStuff.ReadIndexed(pStrm); + pStrm->SkipExtra(); + } +} + +rtl::Reference LwpMiddleLayout::GetBasedOnStyle() const +{ + rtl::Reference xRet(m_BasedOnStyle.obj()); + if (xRet.get() == this) + { + SAL_WARN("lwp", "style based on itself"); + return rtl::Reference(); + } + return xRet; +} + +/** +* @descr: Get the geometry of current layout +* +*/ +LwpLayoutGeometry* LwpMiddleLayout::GetGeometry() +{ + if (m_bGettingGeometry) + throw std::runtime_error("recursion in layout"); + m_bGettingGeometry = true; + + LwpLayoutGeometry* pRet = nullptr; + if (!m_LayGeometry.IsNull()) + { + pRet = dynamic_cast(m_LayGeometry.obj().get()); + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + pRet = pLay->GetGeometry(); + } + } + + m_bGettingGeometry = false; + return pRet; +} + +/** +* @descr: Get layout height, measured by "cm" +* +*/ +double LwpMiddleLayout::GetGeometryHeight() +{ + LwpLayoutGeometry* pGeo = GetGeometry(); + if (pGeo) + { + return LwpTools::ConvertFromUnitsToMetric(pGeo->GetHeight()); + } + else + return -1; +} + +/** +* @descr: Get layout width, measured by "cm" +* +*/ +double LwpMiddleLayout::GetGeometryWidth() +{ + LwpLayoutGeometry* pGeo = GetGeometry(); + if (pGeo) + { + return LwpTools::ConvertFromUnitsToMetric(pGeo->GetWidth()); + } + else + return -1; +} + +/** +* @descr: Whether the margins is same as parent layout +* +*/ +bool LwpMiddleLayout::MarginsSameAsParent() +{ + if (m_nOverrideFlag & OVER_MARGINS) + { + return LwpVirtualLayout::MarginsSameAsParent(); + } + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpVirtualLayout* pLay = dynamic_cast(xBase.get())) + { + pLay->GetMarginsSameAsParent(); + } + return LwpVirtualLayout::MarginsSameAsParent(); +} + +/** +* @descr: Get margin +* @param: nWhichSide - 0: left, 1: right, 2:top, 3: bottom +*/ +double LwpMiddleLayout::MarginsValue(sal_uInt8 nWhichSide) +{ + double fValue = 0; + if ((nWhichSide == MARGIN_LEFT) || (nWhichSide == MARGIN_RIGHT)) + { + if (GetMarginsSameAsParent()) + { + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader()) + { + fValue = xParent->GetMarginsValue(nWhichSide); + return fValue; + } + } + } + + if (m_nOverrideFlag & OVER_MARGINS) + { + LwpLayoutMargins* pMar1 = dynamic_cast(m_LayMargins.obj().get()); + if (pMar1) + { + fValue = pMar1->GetMargins().GetMarginsValue(nWhichSide); + return fValue; + } + } + rtl::Reference xBase(GetBasedOnStyle()); + LwpVirtualLayout* pStyle = dynamic_cast(xBase.get()); + if (pStyle) + { + fValue = pStyle->GetMarginsValue(nWhichSide); + return fValue; + } + return LwpVirtualLayout::MarginsValue(nWhichSide); +} +/** + * @descr: Get extmargin value + * @param: nWhichSide - 0: left, 1: right, 2:top, 3: bottom + * @param: + * @return: +*/ +double LwpMiddleLayout::ExtMarginsValue(sal_uInt8 nWhichSide) +{ + double fValue = 0; + if (m_nOverrideFlag & OVER_MARGINS) + { + LwpLayoutMargins* pMar1 = dynamic_cast(m_LayMargins.obj().get()); + if (pMar1) + { + fValue = pMar1->GetExtMargins().GetMarginsValue(nWhichSide); + return fValue; + } + } + LwpVirtualLayout* pStyle = dynamic_cast(GetBasedOnStyle().get()); + if (pStyle) + { + fValue = pStyle->GetExtMarginsValue(nWhichSide); + return fValue; + } + return LwpVirtualLayout::ExtMarginsValue(nWhichSide); +} +/** + * @descr: Get the LwpBorderStuff object according to m_LayBorderStuff id. +*/ +LwpBorderStuff* LwpMiddleLayout::GetBorderStuff() +{ + if (m_bGettingBorderStuff) + throw std::runtime_error("recursion in layout"); + m_bGettingBorderStuff = true; + + LwpBorderStuff* pRet = nullptr; + + if (m_nOverrideFlag & OVER_BORDERS) + { + LwpLayoutBorder* pLayoutBorder + = dynamic_cast(m_LayBorderStuff.obj().get()); + pRet = pLayoutBorder ? &pLayoutBorder->GetBorderStuff() : nullptr; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + pRet = pLay->GetBorderStuff(); + } + } + + m_bGettingBorderStuff = false; + return pRet; +} + +/** + * @descr: Get LwpBackgroundStuff object according to m_LayBackgroundStuff id; +*/ +LwpBackgroundStuff* LwpMiddleLayout::GetBackgroundStuff() +{ + if (m_bGettingBackgroundStuff) + throw std::runtime_error("recursion in layout"); + m_bGettingBackgroundStuff = true; + + LwpBackgroundStuff* pRet = nullptr; + + if (m_nOverrideFlag & OVER_BACKGROUND) + { + LwpLayoutBackground* pLayoutBackground + = dynamic_cast(m_LayBackgroundStuff.obj().get()); + pRet = pLayoutBackground ? &pLayoutBackground->GetBackgoudStuff() : nullptr; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + pRet = pLay->GetBackgroundStuff(); + } + } + + m_bGettingBackgroundStuff = false; + return pRet; +} + +/** + * @descr: create xfborder. +*/ +std::unique_ptr LwpMiddleLayout::GetXFBorders() +{ + LwpBorderStuff* pBorderStuff = GetBorderStuff(); + if (pBorderStuff && pBorderStuff->GetSide() != 0) + { + //copy from lwpparastyle. + std::unique_ptr xXFBorders(new XFBorders); + // apply 4 borders respectively + LwpBorderStuff::BorderType const pType[] = { LwpBorderStuff::LEFT, LwpBorderStuff::RIGHT, + LwpBorderStuff::TOP, LwpBorderStuff::BOTTOM }; + + for (LwpBorderStuff::BorderType nC : pType) + { + if (pBorderStuff->HasSide(nC)) + { + LwpParaStyle::ApplySubBorder(pBorderStuff, nC, xXFBorders.get()); + } + } + return xXFBorders; + } + return nullptr; +} + +/** + * @descr: Get text direction settings. +*/ +enumXFTextDir LwpMiddleLayout::GetTextDirection() +{ + enumXFTextDir eTextDir = enumXFTextDirNone; + sal_uInt8 nDirection = GetContentOrientation(); + switch (nDirection) + { + case TEXT_ORIENT_LRTB: + { + eTextDir = enumXFTextDirLR_TB; + break; + } + case TEXT_ORIENT_TBRL: + { + eTextDir = enumXFTextDirTB_RL; + break; + } + case TEXT_ORIENT_RLBT: // not supported now + { + eTextDir = enumXFTextDirNone; + break; + } + case TEXT_ORIENT_BTLR: // not supported now + { + eTextDir = enumXFTextDirNone; + break; + } + default: + break; + } + return eTextDir; +} +/** + * @descr: Get background color. +*/ +LwpColor* LwpMiddleLayout::GetBackColor() +{ + LwpBackgroundStuff* pBackgroundStuff = GetBackgroundStuff(); + if (pBackgroundStuff && !pBackgroundStuff->IsTransparent()) + { + LwpColor* pColor = pBackgroundStuff->GetFillColor(); + if (pColor->IsValidColor()) + { + return pColor; + } + } + return nullptr; +} + +/** + * @descr: Add back color settings into xfpagemaster. +*/ +LwpTabOverride* LwpMiddleLayout::GetTabOverride() +{ + if (m_nAttributes & OVER_TABS) + { + if (!m_TabPiece.IsNull()) + { + LwpTabPiece* pPiece = dynamic_cast(m_TabPiece.obj().get()); + return static_cast(pPiece ? pPiece->GetOverride() : nullptr); + } + return nullptr; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->GetTabOverride(); + } + } + return nullptr; +} + +/** + * @descr: Layscale for graphic & watermark +*/ +sal_uInt16 LwpMiddleLayout::GetScaleMode() +{ + if ((m_nOverrideFlag & OVER_SCALING) && m_LayScale.obj().is() && GetLayoutScale()) + return GetLayoutScale()->GetScaleMode(); + rtl::Reference xBase(GetBasedOnStyle()); + if (xBase.is()) + return dynamic_cast(*xBase).GetScaleMode(); + else + return (LwpLayoutScale::FIT_IN_FRAME | LwpLayoutScale::MAINTAIN_ASPECT_RATIO); +} + +sal_uInt16 LwpMiddleLayout::GetScaleTile() +{ + if ((m_nOverrideFlag & OVER_SCALING) && m_LayScale.obj().is() && GetLayoutScale()) + return (GetLayoutScale()->GetPlacement() & LwpLayoutScale::TILED) ? 1 : 0; + rtl::Reference xBase(GetBasedOnStyle()); + if (xBase.is()) + return dynamic_cast(*xBase).GetScaleTile(); + else + return 0; +} + +sal_uInt16 LwpMiddleLayout::GetScaleCenter() +{ + if (m_bGettingScaleCenter) + throw std::runtime_error("recursion in layout"); + m_bGettingScaleCenter = true; + + sal_uInt16 nRet = 0; + + if ((m_nOverrideFlag & OVER_SCALING) && m_LayScale.obj().is() && GetLayoutScale()) + { + nRet = (GetLayoutScale()->GetPlacement() & LwpLayoutScale::CENTERED) ? 1 : 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (xBase.is()) + nRet = dynamic_cast(*xBase).GetScaleCenter(); + } + + m_bGettingScaleCenter = false; + return nRet; +} + +bool LwpMiddleLayout::CanSizeRight() +{ + sal_uInt8 RelType = GetRelativeType(); + + return !(RelType == LwpLayoutRelativityGuts::LAY_INLINE + || RelType == LwpLayoutRelativityGuts::LAY_PARA_RELATIVE + || RelType == LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL); +} +sal_Int32 LwpMiddleLayout::GetMinimumWidth() +{ + if (((m_nAttributes3 & STYLE3_WIDTHVALID) != 0) && GetGeometry()) + { + return GetGeometry()->GetWidth(); + } + else if (m_nOverrideFlag & OVER_SIZE) + { + return DetermineWidth(); + } + return 0; +} +sal_Int32 LwpMiddleLayout::DetermineWidth() +{ + if (IsSizeRightToContent()) + { + assert(false); + } + else if (IsSizeRightToContainer()) + { + assert(false); + } + else if (LwpLayoutGeometry* pGeo = GetGeometry()) + { + m_nAttributes3 |= STYLE3_WIDTHVALID; + return pGeo->GetWidth(); + } + return 0; +} +bool LwpMiddleLayout::IsSizeRightToContainer() +{ + if (!CanSizeRight()) + return false; + + if (m_nOverrideFlag & OVER_SIZE) + { + return (m_nDirection & ((LAY_USEDIRECTION | LAY_AUTOSIZE | LAY_TOCONTAINER) << SHIFT_RIGHT)) + == ((LAY_USEDIRECTION | LAY_TOCONTAINER | LAY_AUTOSIZE) << SHIFT_RIGHT); + } + rtl::Reference xBase(GetBasedOnStyle()); + if (xBase.is()) + { + LwpMiddleLayout* pLayout = dynamic_cast(xBase.get()); + return pLayout && pLayout->IsSizeRightToContainer(); + } + else + return false; +} +bool LwpMiddleLayout::IsSizeRightToContent() +{ + if (!CanSizeRight()) + return false; + + if (m_nOverrideFlag & OVER_SIZE) + { + return (m_nDirection & ((LAY_USEDIRECTION | LAY_AUTOSIZE | LAY_TOCONTAINER) << SHIFT_RIGHT)) + == ((LAY_USEDIRECTION | LAY_AUTOSIZE) << SHIFT_RIGHT); + } + rtl::Reference xBase(GetBasedOnStyle()); + if (xBase.is()) + { + LwpMiddleLayout* pLayout = dynamic_cast(xBase.get()); + return pLayout && pLayout->IsSizeRightToContent(); + } + else + return false; +} + +/** +* @descr: Get layout height +* +*/ +double LwpMiddleLayout::GetHeight() { return GetGeometryHeight(); } + +/** +* @descr: Get layout height +* +*/ +double LwpMiddleLayout::GetWidth() { return GetGeometryWidth(); } +/** +* @descr: Get layout origin point +* +*/ +LwpPoint LwpMiddleLayout::GetOrigin() +{ + LwpLayoutGeometry* pGeo = GetGeometry(); + if (pGeo) + { + sal_uInt8 nType = GetRelativeType(); + if (nType == LwpLayoutRelativityGuts::LAY_INLINE + || nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE) + { + return pGeo->GetAbsoluteOrigin(); + } + else + return pGeo->GetOrigin(); + } + + return LwpPoint(); +} + +/** +* @descr: Whether the fill is pattern fill or not +* @return: True if yes, false if not. +*/ +bool LwpMiddleLayout::IsPatternFill() +{ + LwpBackgroundStuff* pBackgroundStuff = GetBackgroundStuff(); + if (pBackgroundStuff) + { + return pBackgroundStuff->IsPatternFill(); + } + + return false; +} + +/** +* @descr: Get the fill pattern style. Data are saved in a XFBGImage object +* @return: the fill pattern style. +*/ +std::unique_ptr LwpMiddleLayout::GetFillPattern() +{ + LwpBackgroundStuff* pBackgroundStuff = GetBackgroundStuff(); + if (pBackgroundStuff) + { + return pBackgroundStuff->GetFillPattern(); + } + + return std::unique_ptr(); +} + +/** +* @descr: Whether the height and width of layout is auto grow +* +*/ +bool LwpMiddleLayout::IsAutoGrow() +{ + if (m_nOverrideFlag & OVER_SIZE) + { + return (m_nDirection + & ((LAY_AUTOGROW << SHIFT_UP) | (LAY_AUTOGROW << SHIFT_DOWN) + | (LAY_AUTOGROW << SHIFT_RIGHT) | (LAY_AUTOGROW << SHIFT_LEFT))) + != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsAutoGrow(); + } + } + return LwpVirtualLayout::IsAutoGrow(); +} + +/** +* @descr: Whether the height of layout is auto grow down +* +*/ +bool LwpMiddleLayout::IsAutoGrowDown() +{ + if (m_nOverrideFlag & OVER_SIZE) + { + return (m_nDirection & (LAY_AUTOGROW << SHIFT_DOWN)) != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->GetIsAutoGrowDown(); + } + } + return LwpVirtualLayout::IsAutoGrowDown(); +} + +/** +* @descr: Whether the height of layout is auto grow up +* +*/ +bool LwpMiddleLayout::IsAutoGrowUp() +{ + if (m_bGettingAutoGrowUp) + throw std::runtime_error("recursion in layout"); + m_bGettingAutoGrowUp = true; + + bool bRet; + + if (m_nOverrideFlag & OVER_SIZE) + { + bRet = (m_nDirection & (LAY_AUTOGROW << SHIFT_UP)) != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + bRet = pLay->IsAutoGrowUp(); + else + bRet = LwpVirtualLayout::IsAutoGrowUp(); + } + + m_bGettingAutoGrowUp = false; + return bRet; +} + +/** +* @descr: Whether the height of layout is auto grow down +* +*/ +bool LwpMiddleLayout::IsAutoGrowLeft() +{ + if (m_nOverrideFlag & OVER_SIZE) + { + return (m_nDirection & (LAY_AUTOGROW << SHIFT_LEFT)) != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsAutoGrowLeft(); + } + } + return LwpVirtualLayout::IsAutoGrowLeft(); +} + +/** +* @descr: Whether the height of layout is auto grow down +* +*/ +bool LwpMiddleLayout::IsAutoGrowRight() +{ + if (m_nOverrideFlag & OVER_SIZE) + { + return (m_nDirection & (LAY_AUTOGROW << SHIFT_RIGHT)) != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsAutoGrowRight(); + } + } + return LwpVirtualLayout::IsAutoGrowRight(); +} + +/** +* @descr: Get contents orientation +* +*/ +sal_uInt8 LwpMiddleLayout::GetContentOrientation() +{ + //content orientation in Graphic objects and OLE objects not supported now + if ((m_nOverrideFlag & OVER_ROTATION) && !m_LayGeometry.IsNull()) + { + LwpLayoutGeometry* pLayGeometry + = dynamic_cast(m_LayGeometry.obj().get()); + if (pLayGeometry) + return pLayGeometry->GetContentOrientation(); + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->GetContentOrientation(); + } + } + return LwpVirtualLayout::GetContentOrientation(); +} + +/** +* @descr: Whether it is honoring protection +* +*/ +bool LwpMiddleLayout::HonorProtection() +{ + if (m_nOverrideFlag & OVER_MISC) + { + if (!(m_nAttributes2 & STYLE2_HONORPROTECTION)) + return false; + + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader()) + { + return xParent->GetHonorProtection(); + } + + if (m_pFoundry) //is null now + { + LwpDocument* pDoc = m_pFoundry->GetDocument(); + if (pDoc) + { + return pDoc->GetHonorProtection(); + } + } + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->GetHonorProtection(); + } + } + + return LwpVirtualLayout::HonorProtection(); +} + +/** +* @descr: Whether it is protected +* +*/ +bool LwpMiddleLayout::IsProtected() +{ + bool bProtected = false; + if (m_nOverrideFlag & OVER_MISC) + { + bProtected = (m_nAttributes & STYLE_PROTECTED) != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + bProtected = pLay->GetIsProtected(); + } + else + bProtected = LwpVirtualLayout::IsProtected(); + } + + rtl::Reference xParent( + dynamic_cast(GetParent().obj().get())); + if (xParent.is() && !xParent->IsHeader()) + { + /* If a parent's protected then none of its children can be accessed. */ + if (xParent->GetIsProtected()) + return true; + + if (xParent->GetHonorProtection()) + return bProtected; + + /* If our parent isn't honoring protection then we aren't protected. */ + return false; + } + if (m_pFoundry) //is null now + { + LwpDocument* pDoc = m_pFoundry->GetDocument(); + if (pDoc) + { + if (pDoc->GetHonorProtection()) + return bProtected; + + /* If the document isn't honoring protection then we aren't protected.*/ + return false; + } + } + + return bProtected; +} + +/** +* @descr: Get watermark layout +* +*/ +rtl::Reference LwpMiddleLayout::GetWaterMarkLayout() +{ + rtl::Reference xLay( + dynamic_cast(GetChildHead().obj().get())); + o3tl::sorted_vector aSeen; + while (xLay.is()) + { + bool bAlreadySeen = !aSeen.insert(xLay.get()).second; + if (bAlreadySeen) + throw std::runtime_error("loop in conversion"); + if (xLay->IsForWaterMark()) + { + return xLay; + } + rtl::Reference xNext( + dynamic_cast(xLay->GetNext().obj().get())); + xLay = xNext; + } + return rtl::Reference(); +} + +/** +* @descr: Create and return xfbgimage object for watermark +* +*/ +std::unique_ptr LwpMiddleLayout::GetXFBGImage() +{ + std::unique_ptr xXFBGImage; + + rtl::Reference xWaterMarkLayout(GetWaterMarkLayout()); + LwpMiddleLayout* pLay = dynamic_cast(xWaterMarkLayout.get()); + if (pLay) + { + //test BGImage + LwpGraphicObject* pGrfObj = dynamic_cast(pLay->GetContent().obj().get()); + if (pGrfObj) + { + xXFBGImage.reset(new XFBGImage); + if (pGrfObj->IsLinked()) + { + //set file link + OUString linkedfilepath = pGrfObj->GetLinkedFilePath(); + OUString fileURL = LwpTools::convertToFileUrl( + OUStringToOString(linkedfilepath, osl_getThreadTextEncoding())); + xXFBGImage->SetFileLink(fileURL); + } + else + { + std::vector aGrafData = pGrfObj->GetRawGrafData(); + xXFBGImage->SetImageData(aGrafData.data(), aGrafData.size()); + } + + //automatic, top left + xXFBGImage->SetPosition(enumXFAlignStart, enumXFAlignTop); + if (pLay->GetScaleCenter()) + { + //center + xXFBGImage->SetPosition(); + } + else if (pLay->GetScaleTile()) + { + //tile + xXFBGImage->SetRepeate(); + } + //fit type, area type + if ((pLay->GetScaleMode() & LwpLayoutScale::FIT_IN_FRAME) != 0) + { + if ((pLay->GetScaleMode() & LwpLayoutScale::MAINTAIN_ASPECT_RATIO) == 0) + { + xXFBGImage->SetStretch(); + } + } + } + } + return xXFBGImage; +} + +/** +* @descr: Whether the page uses the printer setting +* +*/ +bool LwpMiddleLayout::GetUsePrinterSettings() +{ + if (m_bGettingUsePrinterSettings) + throw std::runtime_error("recursion in layout"); + m_bGettingUsePrinterSettings = true; + + bool bRet = false; + + if (m_nOverrideFlag & OVER_SIZE) + { + bRet = (m_nAttributes3 & STYLE3_USEPRINTERSETTINGS) != 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpMiddleLayout* pLay = dynamic_cast(xBase.get())) + { + bRet = pLay->GetUsePrinterSettings(); + } + } + + m_bGettingUsePrinterSettings = false; + return bRet; +} + +//Check whether there are contents in the layout +bool LwpMiddleLayout::HasContent() +{ + rtl::Reference content = m_Content.obj(); + return content.is(); +} + +LwpLayout::LwpLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm) + : LwpMiddleLayout(objHdr, pStrm) + , m_bGettingShadow(false) + , m_bGettingNumCols(false) +{ +} + +LwpLayout::~LwpLayout() {} + +void LwpLayout::Read() +{ + LwpObjectStream* pStrm = m_pObjStrm.get(); + + LwpMiddleLayout::Read(); + if (LwpFileHeader::m_nFileRevision < 0x000B) + { + // read PreRevBLayout... + } + else + { + sal_uInt16 nSimple = pStrm->QuickReaduInt16(); + + if (!nSimple) + { + m_aUseWhen.Read(pStrm); + + sal_uInt8 nFlag = pStrm->QuickReaduInt8(); + if (nFlag) + m_Position.ReadIndexed(pStrm); + } + + m_LayColumns.ReadIndexed(pStrm); + m_LayGutterStuff.ReadIndexed(pStrm); + m_LayJoinStuff.ReadIndexed(pStrm); + m_LayShadow.ReadIndexed(pStrm); + + if (pStrm->CheckExtra()) + { + m_LayExtJoinStuff.ReadIndexed(pStrm); + pStrm->SkipExtra(); + } + } +} + +/** +* @descr: Get columns number +* +*/ +sal_uInt16 LwpLayout::GetNumCols() +{ + if (m_bGettingNumCols) + throw std::runtime_error("recursion in layout"); + m_bGettingNumCols = true; + + sal_uInt16 nRet = 0; + LwpLayoutColumns* pLayColumns = (m_nOverrideFlag & OVER_COLUMNS) + ? dynamic_cast(m_LayColumns.obj().get()) + : nullptr; + if (pLayColumns) + { + nRet = pLayColumns->GetNumCols(); + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + LwpVirtualLayout* pStyle = dynamic_cast(xBase.get()); + nRet = pStyle ? pStyle->GetNumCols() : LwpVirtualLayout::GetNumCols(); + } + m_bGettingNumCols = false; + return nRet; +} + +/** +* @descr: Get gap between columns +* @param: the order of column +*/ +double LwpLayout::GetColGap(sal_uInt16 nIndex) +{ + if ((m_nOverrideFlag & OVER_COLUMNS) || (m_nAttributes2 & STYLE2_LOCALCOLUMNINFO)) + { + LwpLayoutColumns* pLayColumns = dynamic_cast(m_LayColumns.obj().get()); + if (pLayColumns) + { + return pLayColumns->GetColGap(nIndex); + } + } + + rtl::Reference xBase(GetBasedOnStyle()); + LwpVirtualLayout* pStyle = dynamic_cast(xBase.get()); + if (pStyle) + { + return pStyle->GetColGap(nIndex); + } + + return LwpVirtualLayout::GetColGap(nIndex); +} + +/** +* @descr: Create and return XFColumns object +* +*/ +XFColumns* LwpLayout::GetXFColumns() +{ + //if there is only one column, do not need insert columns + sal_uInt16 nCols = GetNumCols(); + if (nCols == 1) + { + return nullptr; + } + + std::unique_ptr xColumns(new XFColumns); + //set XFColumnSep + std::unique_ptr xColumnSep(GetColumnSep()); + if (xColumnSep) + { + xColumns->SetSeparator(*xColumnSep); + } + + //set column count and column gap + xColumns->SetCount(nCols); + double fGap = GetColGap(0); + xColumns->SetGap(fGap); + + //set xfcolumn + for (sal_uInt16 nIndex = 0; nIndex < nCols; nIndex++) + { + XFColumn aColumn; + sal_Int32 nWidth = 8305 / nCols; //relative width + aColumn.SetRelWidth(nWidth); + + //the left and right margins is 0; + double nGap = GetColGap(nIndex) / 2; + aColumn.SetMargins(nGap, nGap); + if (nIndex == 0) + { + aColumn.SetMargins(0, nGap); + } + if (nIndex == (nCols - 1)) + { + aColumn.SetMargins(nGap, 0); + } + xColumns->AddColumn(aColumn); + } + + return xColumns.release(); +} + +/** +* @descr: Create and return XFColumnSep object +* +*/ +XFColumnSep* LwpLayout::GetColumnSep() +{ + //Get LwpLayoutGutters + LwpLayoutGutters* pLayoutGutters + = dynamic_cast(m_LayGutterStuff.obj().get()); + if (!pLayoutGutters) + { + return nullptr; + } + + LwpBorderStuff& rBorderStuff = pLayoutGutters->GetBorderStuff(); + + LwpBorderStuff::BorderType eType = LwpBorderStuff::LEFT; + LwpColor aColor = rBorderStuff.GetSideColor(eType); + double fWidth = rBorderStuff.GetSideWidth(eType); + //sal_uInt16 nType = rBorderStuff->GetSideType(eType); + + XFColumnSep* pColumnSep = new XFColumnSep(); + XFColor aXFColor(aColor.To24Color()); + pColumnSep->SetColor(aXFColor); + pColumnSep->SetWidth(fWidth); + pColumnSep->SetRelHeight(100); + pColumnSep->SetVerticalAlign(enumXFAlignTop); + + return pColumnSep; +} + +/** +* @descr: Get use when type +* +*/ +LwpLayout::UseWhenType LwpLayout::GetUseWhenType() +{ + UseWhenType eType = StartWithinPage; + LwpUseWhen* pUseWhen = GetUseWhen(); + if (pUseWhen) + { + if (pUseWhen->IsStartOnThisHF()) + { + eType = StartWithinColume; + } + else if (pUseWhen->IsStartOnThisPage()) + { + eType = StartWithinPage; + } + else if (pUseWhen->IsStartOnNextPage()) + { + eType = StartOnNextPage; + } + else if (pUseWhen->IsStartOnNextOddPage()) + { + eType = StartOnOddPage; + } + else if (pUseWhen->IsStartOnNextEvenPage()) + { + eType = StartOnEvenPage; + } + } + else + { + eType = StartOnNextPage; + } + return eType; +} + +/** +* @descr: Get use page +* +*/ +sal_uInt16 LwpLayout::GetUsePage() +{ + if (m_nOverrideFlag & OVER_PLACEMENT) + { + LwpUseWhen* pUseWhen = GetUseWhen(); + if (pUseWhen) + return pUseWhen->GetUsePage(); + else + return 0; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->GetUsePage(); + } + } + return 0; +} + +/** +* @descr: Get usewhen pointer +* +*/ +LwpUseWhen* LwpLayout::VirtualGetUseWhen() +{ + if (m_nOverrideFlag & OVER_PLACEMENT) + { + return &m_aUseWhen; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->VirtualGetUseWhen(); + } + } + return LwpVirtualLayout::VirtualGetUseWhen(); +} + +/** +* @descr: Whether it is use on all pages +* +*/ +bool LwpLayout::IsUseOnAllPages() +{ + if (m_nOverrideFlag & OVER_PLACEMENT) + { + LwpUseWhen* pUseWhen = GetUseWhen(); + if (pUseWhen) + return pUseWhen->IsUseOnAllPages(); + else + return false; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsUseOnAllPages(); + } + } + return LwpVirtualLayout::IsUseOnAllPages(); +} + +/** +* @descr: Whether it is use on all even pages +* +*/ +bool LwpLayout::IsUseOnAllEvenPages() +{ + if (m_nOverrideFlag & OVER_PLACEMENT) + { + LwpUseWhen* pUseWhen = GetUseWhen(); + if (pUseWhen) + return pUseWhen->IsUseOnAllEvenPages(); + else + return false; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsUseOnAllEvenPages(); + } + } + return LwpVirtualLayout::IsUseOnAllEvenPages(); +} + +/** +* @descr: Whether it is use on all odd pages +* +*/ +bool LwpLayout::IsUseOnAllOddPages() +{ + if (m_nOverrideFlag & OVER_PLACEMENT) + { + LwpUseWhen* pUseWhen = GetUseWhen(); + if (pUseWhen) + return pUseWhen->IsUseOnAllOddPages(); + else + return false; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsUseOnAllOddPages(); + } + } + return LwpVirtualLayout::IsUseOnAllOddPages(); +} + +/** +* @descr: Whether it is use on current page +* +*/ +bool LwpLayout::IsUseOnPage() +{ + if (m_nOverrideFlag & OVER_PLACEMENT) + { + LwpUseWhen* pUseWhen = GetUseWhen(); + if (pUseWhen) + return pUseWhen->IsUseOnPage(); + else + return false; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->IsUseOnPage(); + } + } + return LwpVirtualLayout::IsUseOnPage(); +} + +/** + * @descr: Get the LwpShadow object according to m_LayShadow id. +*/ +LwpShadow* LwpLayout::GetShadow() +{ + if (m_bGettingShadow) + throw std::runtime_error("recursion in layout"); + m_bGettingShadow = true; + LwpShadow* pRet = nullptr; + if (m_nOverrideFlag & OVER_SHADOW) + { + LwpLayoutShadow* pLayoutShadow = dynamic_cast(m_LayShadow.obj().get()); + pRet = pLayoutShadow ? &pLayoutShadow->GetShadow() : nullptr; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpLayout* pLay = dynamic_cast(xBase.get())) + { + pRet = pLay->GetShadow(); + } + } + m_bGettingShadow = false; + return pRet; +} + +/** + * @descr: create xfshadow +*/ +XFShadow* LwpLayout::GetXFShadow() +{ + LwpShadow* pShadow = GetShadow(); + if (!pShadow) + return nullptr; + LwpColor color = pShadow->GetColor(); + double offsetX = pShadow->GetOffsetX(); + double offsetY = pShadow->GetOffsetY(); + + if (!offsetX || !offsetY || !color.IsValidColor()) + return nullptr; + XFShadow* pXFShadow = new XFShadow(); + enumXFShadowPos eXFShadowPos = enumXFShadowLeftTop; + double fOffset = 0; + + bool left = false; + bool top = false; + if (offsetX < 0) + left = true; + if (offsetY < 0) + top = true; + if (left) + { + fOffset = -offsetX; + if (top) + eXFShadowPos = enumXFShadowLeftTop; + else + eXFShadowPos = enumXFShadowLeftBottom; + } + else + { + fOffset = offsetX; + if (top) + eXFShadowPos = enumXFShadowRightTop; + else + eXFShadowPos = enumXFShadowRightBottom; + } + + pXFShadow->SetPosition(eXFShadowPos); + pXFShadow->SetOffset(fOffset); + pXFShadow->SetColor(XFColor(color.To24Color())); + + return pXFShadow; +} + +/** + * @descr get the layout that containers the current frame layout + * + */ +rtl::Reference LwpLayout::GetContainerLayout() +{ + if (IsRelativeAnchored()) + { + //get position + LwpPara* pPara = dynamic_cast(GetPosition().obj().get()); + if (pPara) + { + LwpStory* pStory = pPara->GetStory(); + return pStory ? pStory->GetTabLayout() : nullptr; + } + } + return GetParentLayout(); +} + +LwpPlacableLayout::LwpPlacableLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm) + : LwpLayout(objHdr, pStrm) + , m_bGettingWrapType(false) + , m_bGettingLayoutRelativity(false) + , m_nWrapType(0) + , m_nBuoyancy(0) + , m_nBaseLineOffset(0) +{ +} + +LwpPlacableLayout::~LwpPlacableLayout() {} + +void LwpPlacableLayout::Read() +{ + LwpObjectStream* pStrm = m_pObjStrm.get(); + LwpLayout::Read(); + if (LwpFileHeader::m_nFileRevision < 0x000B) + { + assert(false); + } + else + { + sal_uInt16 simple = pStrm->QuickReaduInt16(); + if (!simple) + { + m_nWrapType = pStrm->QuickReaduInt8(); + m_nBuoyancy = pStrm->QuickReaduInt8(); + m_nBaseLineOffset = pStrm->QuickReadInt32(); + m_Script.Read(pStrm); + } + else + { + m_nWrapType = LAY_WRAP_AROUND; + m_nBuoyancy = LAY_BUOYNEUTRAL; + m_nBaseLineOffset = 0; + } + m_LayRelativity.ReadIndexed(pStrm); + if (pStrm->CheckExtra()) + { + sal_uInt16 count = pStrm->QuickReaduInt16(); + if (count) + { + // temporarily added by to avoid assertion + while (count) + { + LwpPoint aPoint; + aPoint.Read(pStrm); + count--; + } + } + pStrm->SkipExtra(); + } + } +} +/** + * @descr: get wrap type +*/ +sal_uInt8 LwpPlacableLayout::GetWrapType() +{ + if (m_bGettingWrapType) + throw std::runtime_error("recursion in layout"); + m_bGettingWrapType = true; + sal_uInt8 nWrapType = LAY_WRAP_AROUND; + if (m_nOverrideFlag & OVER_PLACEMENT) + { + nWrapType = m_nWrapType; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpPlacableLayout* pLay = dynamic_cast(xBase.get())) + { + nWrapType = pLay->GetWrapType(); + } + } + m_bGettingWrapType = false; + return nWrapType; +} +/** + * @descr: get LayoutRelativity +*/ +LwpLayoutRelativity* LwpPlacableLayout::GetRelativityPiece() +{ + if (m_bGettingLayoutRelativity) + throw std::runtime_error("recursion in layout"); + m_bGettingLayoutRelativity = true; + LwpLayoutRelativity* pRet = nullptr; + if (!m_LayRelativity.IsNull()) + { + if (m_nOverrideFlag & OVER_PLACEMENT) + { + pRet = dynamic_cast(m_LayRelativity.obj().get()); + } + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpPlacableLayout* pLay = dynamic_cast(xBase.get())) + { + pRet = pLay->GetRelativityPiece(); + } + } + m_bGettingLayoutRelativity = false; + return pRet; +} +/** +* @descr: Get relative type +* +*/ +sal_uInt8 LwpPlacableLayout::GetRelativeType() +{ + LwpLayoutRelativity* pLayRel = GetRelativityPiece(); + if (pLayRel) + { + return pLayRel->GetRelGuts().GetRelativeType(); + } + return LwpVirtualLayout::GetRelativeType(); +} +/** +* @descr: Get offset from the baseline +* +*/ +sal_Int32 LwpPlacableLayout::GetBaseLineOffset() +{ + /* The baseline is only valid if this is flow-with-text */ + if (GetRelativeType() != LwpLayoutRelativityGuts::LAY_INLINE) + { + return 0; + } + + // First, ask our content if it has a baseline, ignore now + /* + if (Content && Content->GetBaseLineOffset(&Baseline)) + return Baseline; + */ + + if (m_nOverrideFlag & OVER_PLACEMENT) + { + return m_nBaseLineOffset; + } + else + { + rtl::Reference xBase(GetBasedOnStyle()); + if (LwpPlacableLayout* pLay = dynamic_cast(xBase.get())) + { + return pLay->GetBaseLineOffset(); + } + } + return 0; +} +/** +* @descr: whether the parent layout is page layout +* +*/ +bool LwpPlacableLayout::IsAnchorPage() +{ + if (IsRelativeAnchored()) + return false; + + rtl::Reference xLayout = GetParentLayout(); + return xLayout.is() && (xLayout->IsPage() || xLayout->IsHeader() || xLayout->IsFooter()); +} +/** +* @descr: whether the parent layout is frame layout +* +*/ +bool LwpPlacableLayout::IsAnchorFrame() +{ + if (IsRelativeAnchored()) + return false; + + rtl::Reference xLayout = GetParentLayout(); + return xLayout.is() && (xLayout->IsFrame() || xLayout->IsGroupHead()); +} +/** +* @descr: whether the parent layout is cell layout +* +*/ +bool LwpPlacableLayout::IsAnchorCell() +{ + if (IsRelativeAnchored()) + return false; + + rtl::Reference xLayout = GetParentLayout(); + return xLayout.is() && xLayout->IsCell(); +} + +/** +* @descr: Set font style for setting position of frame +* +*/ +void LwpPlacableLayout::SetFont(rtl::Reference const& pFont) { m_pFont = pFont; } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3