summaryrefslogtreecommitdiffstats
path: root/lotuswordpro/source/filter/lwpframelayout.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /lotuswordpro/source/filter/lwpframelayout.cxx
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lotuswordpro/source/filter/lwpframelayout.cxx')
-rw-r--r--lotuswordpro/source/filter/lwpframelayout.cxx1263
1 files changed, 1263 insertions, 0 deletions
diff --git a/lotuswordpro/source/filter/lwpframelayout.cxx b/lotuswordpro/source/filter/lwpframelayout.cxx
new file mode 100644
index 000000000..7c983b01a
--- /dev/null
+++ b/lotuswordpro/source/filter/lwpframelayout.cxx
@@ -0,0 +1,1263 @@
+/* -*- 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
+ * the class for VO_FrameLayout
+ ************************************************************************/
+
+#include <memory>
+#include <lwpfilehdr.hxx>
+#include "lwpcelllayout.hxx"
+#include "lwpframelayout.hxx"
+#include "lwppara.hxx"
+#include <xfilter/xfstylemanager.hxx>
+#include <xfilter/xffloatframe.hxx>
+#include <xfilter/xfrubystyle.hxx>
+#include "lwpoleobject.hxx"
+#include <lwpglobalmgr.hxx>
+
+LwpFrame::LwpFrame(LwpPlacableLayout* pLayout)
+ : m_pLayout(pLayout)
+{
+}
+
+LwpFrame::~LwpFrame() {}
+/**
+* @descr: parse frame
+* @param: register frame style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::RegisterStyle(std::unique_ptr<XFFrameStyle>& rFrameStyle)
+{
+ ApplyWrapType(rFrameStyle.get());
+ ApplyMargins(rFrameStyle.get());
+ ApplyPadding(rFrameStyle.get());
+ ApplyBorders(rFrameStyle.get());
+ ApplyColumns(rFrameStyle.get());
+ ApplyShadow(rFrameStyle.get());
+ ApplyBackGround(rFrameStyle.get());
+ ApplyWatermark(rFrameStyle.get());
+ ApplyProtect(rFrameStyle.get());
+ ApplyTextDir(rFrameStyle.get());
+ ApplyPosType(rFrameStyle.get());
+
+ rFrameStyle->SetStyleName(m_pLayout->GetName().str());
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ m_StyleName = pXFStyleManager->AddStyle(std::move(rFrameStyle)).m_pStyle->GetStyleName();
+ m_pLayout->SetStyleName(m_StyleName);
+}
+
+/**
+* @descr: parse frame and set frame properties
+* @param: pXFFrame - XFFrame object
+* @param: nPageNo - the page number that the frame anchors
+*
+*/
+void LwpFrame::Parse(XFFrame* pXFFrame, sal_Int32 nPageNo)
+{
+ //set the frame style name
+ pXFFrame->SetStyleName(m_StyleName);
+
+ //SetAnchorType and position,if it's page anchor,set the page number.
+ ParseAnchorType(pXFFrame);
+ if (nPageNo > 0)
+ {
+ pXFFrame->SetAnchorPage(nPageNo);
+ }
+
+ //Set frame Name
+ OUString aFrameName = m_pLayout->GetName().str();
+ if (!aFrameName.isEmpty())
+ {
+ //cause the bug of SODC, the linkframe name can not be "Frame1", so I change the frame name
+ /*if(aFrameName.equals("Frame1"))
+ {
+ aFrameName = "Frame1_COPY";
+ }
+ pXFFrame->SetName(aFrameName);*/
+ pXFFrame->SetName(m_StyleName);
+ }
+
+ LwpLayoutGeometry* pLayoutGeo = m_pLayout->GetGeometry();
+ //Set frame Width and height
+ if (pLayoutGeo)
+ {
+ double fWidth = m_pLayout->GetWidth();
+ double fHeight = m_pLayout->GetHeight();
+
+ pXFFrame->SetWidth(fWidth);
+ pXFFrame->SetHeight(fHeight);
+
+ //Get content obj;
+ /*LwpObject* pObj =*/m_pLayout->GetContent().obj();
+ if (m_pLayout->IsGroupHead() && (m_pLayout->IsMinimumHeight()))
+ {
+ //process grouplayout height. there is problems now
+ pXFFrame->SetHeight(fHeight);
+ }
+ /*
+ else if(m_pLayout->IsFitGraphic() && pObj && pObj->GetTag() == VO_GRAPHIC)
+ {
+ //If is graphic, get original size and set it;
+ LwpGraphicObject* pGrpObj = static_cast<LwpGraphicObject*>(pObj);
+ long nHeight =0, nWidth =0;
+ pGrpObj->GetGrafOrgSize(nWidth, nHeight);
+ //add margins to the width and height;
+ fWidth = (double)nWidth/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_LEFT) + m_pLayout->GetMarginsValue(MARGIN_RIGHT);
+ fHeight = (double)nHeight/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_TOP) + m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
+ pXFFrame->SetWidth(fWidth);
+ pXFFrame->SetHeight(fHeight);
+ }
+ */
+ else if (m_pLayout->IsAutoGrow())
+ {
+ pXFFrame->SetMinHeight(fHeight);
+ }
+ }
+
+ if (m_pLayout->IsFrame())
+ {
+ //Set frame link. Only frame layout has this feature
+ LwpFrameLayout* pLayout = static_cast<LwpFrameLayout*>(m_pLayout);
+ pXFFrame->SetNextLink(pLayout->GetNextLinkName());
+ }
+}
+/**
+* @descr: parse frame relative to page, frame or cell
+* @param: pCont - content container which contains the frame
+*
+*/
+void LwpFrame::XFConvert(XFContentContainer* pCont)
+{
+ // parse the frame which anchor to page
+ rtl::Reference<LwpVirtualLayout> xParent = m_pLayout->GetParentLayout();
+ if (!xParent.is())
+ throw std::runtime_error("missing Parent Layout");
+ if (xParent->IsPage() && xParent->GetParentLayout().is()
+ && xParent->GetParentLayout()->IsPage())
+ {
+ //for mirror page, problems exist if the parent layout is header or footer layout,
+ xParent = xParent->GetParentLayout();
+ }
+ if (m_pLayout->IsAnchorPage() && xParent->IsPage())
+ {
+ //get parent layout
+ if (m_pLayout->IsUseOnPage())
+ {
+ sal_Int32 nPageNo = xParent->GetPageNumber(m_pLayout->GetUsePage());
+ if (nPageNo > 0)
+ m_pLayout->XFConvertFrame(pCont, nPageNo);
+ }
+ else if (m_pLayout->IsUseOnAllPages())
+ {
+ sal_Int32 nFirst = xParent->GetPageNumber(FIRST_LAYOUTPAGENO);
+ sal_Int32 nLast = xParent->GetPageNumber(LAST_LAYOUTPAGENO);
+ if (nLast > 0)
+ m_pLayout->XFConvertFrame(pCont, nFirst, nLast, true);
+ }
+ else if (m_pLayout->IsUseOnAllOddPages() || m_pLayout->IsUseOnAllEvenPages())
+ {
+ sal_Int32 nFirst = xParent->GetPageNumber(FIRST_LAYOUTPAGENO);
+ sal_Int32 nLast = xParent->GetPageNumber(LAST_LAYOUTPAGENO);
+ if (nLast > 0)
+ {
+ sal_uInt16 first = static_cast<sal_uInt16>(nFirst);
+ if ((m_pLayout->IsUseOnAllOddPages() && !LwpTools::IsOddNumber(first))
+ || (m_pLayout->IsUseOnAllEvenPages() && !LwpTools::IsEvenNumber(first)))
+ nFirst++;
+ if (nFirst <= nLast)
+ {
+ m_pLayout->XFConvertFrame(pCont, nFirst, nLast);
+ }
+ }
+ }
+ }
+ else
+ {
+ m_pLayout->XFConvertFrame(pCont);
+ }
+}
+/**
+* @descr: set frame wrap type style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyWrapType(XFFrameStyle* pFrameStyle)
+{
+ enumXFWrap eWrap = enumXFWrapNone;
+ switch (m_pLayout->GetWrapType())
+ {
+ case LwpPlacableLayout::LAY_WRAP_AROUND: //fall through
+ case LwpPlacableLayout::LAY_WRAP_IRREG_BIGGEST:
+ {
+ //In SODC, if Optimal wrap type is used and the distance between the frame object
+ //and page margins is less than 2cm, the text is not wrapped. While there is no this feature in Word Pro
+ //So the optimal wrap type is translated to left side or right side wrap type according to the distance
+ //between the frame object and page margins
+
+ eWrap = enumXFWrapBest;
+ rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
+ LwpMiddleLayout* pParent = dynamic_cast<LwpMiddleLayout*>(xContainer.get());
+ if (pParent)
+ {
+ if (IsLeftWider())
+ eWrap = enumXFWrapLeft;
+ else
+ eWrap = enumXFWrapRight;
+ }
+ break;
+ }
+ case LwpPlacableLayout::LAY_NO_WRAP_BESIDE:
+ {
+ eWrap = enumXFWrapNone;
+ break;
+ }
+ case LwpPlacableLayout::LAY_NO_WRAP_AROUND:
+ {
+ eWrap = enumXFWrapRunThrough;
+ if (!m_pLayout->GetBackColor() && !m_pLayout->GetWaterMarkLayout().is())
+ {
+ //pFrameStyle->SetBackGround(sal_True);
+ XFColor aXFColor(0xffffff); //white color
+ pFrameStyle->SetBackColor(aXFColor);
+ pFrameStyle->SetTransparency(100); //transparency
+ }
+ break;
+ }
+ case LwpPlacableLayout::LAY_WRAP_LEFT: //fall through
+ case LwpPlacableLayout::LAY_WRAP_IRREG_LEFT:
+ {
+ eWrap = enumXFWrapLeft;
+ break;
+ }
+ case LwpPlacableLayout::LAY_WRAP_RIGHT: //fall through
+ case LwpPlacableLayout::LAY_WRAP_IRREG_RIGHT:
+ {
+ eWrap = enumXFWrapRight;
+ break;
+ }
+ case LwpPlacableLayout::LAY_WRAP_BOTH: //fall through
+ case LwpPlacableLayout::LAY_WRAP_IRREG_BOTH:
+ {
+ eWrap = enumXFWrapParallel;
+ break;
+ }
+ default:
+ break;
+ }
+
+ //If it is the type of with para above, wrap type is enumXFWrapNone
+ if (m_pLayout->GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
+ {
+ eWrap = enumXFWrapNone;
+ }
+
+ pFrameStyle->SetWrapType(eWrap);
+}
+/**
+* @descr: set frame margins style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyMargins(XFFrameStyle* pFrameStyle)
+{
+ double fLeft = m_pLayout->GetExtMarginsValue(MARGIN_LEFT);
+ double fRight = m_pLayout->GetExtMarginsValue(MARGIN_RIGHT);
+ double fTop = m_pLayout->GetExtMarginsValue(MARGIN_TOP);
+ double fBottom = m_pLayout->GetExtMarginsValue(MARGIN_BOTTOM);
+ pFrameStyle->SetMargins(fLeft, fRight, fTop, fBottom);
+}
+/**
+* @descr: set padding border style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyPadding(XFFrameStyle* pFrameStyle)
+{
+ double fLeft = m_pLayout->GetMarginsValue(MARGIN_LEFT);
+ double fRight = m_pLayout->GetMarginsValue(MARGIN_RIGHT);
+ double fTop = m_pLayout->GetMarginsValue(MARGIN_TOP);
+ double fBottom = m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
+ pFrameStyle->SetPadding(fLeft, fRight, fTop, fBottom);
+}
+/**
+* @descr: set frame border style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyBorders(XFFrameStyle* pFrameStyle)
+{
+ std::unique_ptr<XFBorders> pBordres = m_pLayout->GetXFBorders();
+ if (pBordres)
+ {
+ pFrameStyle->SetBorders(std::move(pBordres));
+ }
+}
+/**
+* @descr: set frame columns style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyColumns(XFFrameStyle* pFrameStyle)
+{
+ XFColumns* pColumns = m_pLayout->GetXFColumns();
+ if (pColumns)
+ {
+ pFrameStyle->SetColumns(pColumns);
+ }
+}
+/**
+* @descr: set frame shadow style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyShadow(XFFrameStyle* pFrameStyle)
+{
+ XFShadow* pXFShadow = m_pLayout->GetXFShadow();
+ if (pXFShadow)
+ {
+ pFrameStyle->SetShadow(pXFShadow);
+ }
+}
+/**
+* @descr: set frame back color style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyBackColor(XFFrameStyle* pFrameStyle)
+{
+ LwpColor* pColor = m_pLayout->GetBackColor();
+ if (pColor)
+ {
+ XFColor aXFColor(pColor->To24Color());
+ pFrameStyle->SetBackColor(aXFColor);
+ }
+}
+/**
+* @descr: set frame protect style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyProtect(XFFrameStyle* pFrameStyle)
+{
+ if (m_pLayout->GetIsProtected())
+ {
+ pFrameStyle->SetProtect(true, true, true);
+ }
+}
+/**
+* @descr: set frame text direction style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyTextDir(XFFrameStyle* pFrameStyle)
+{
+ pFrameStyle->SetTextDir(m_pLayout->GetTextDirection());
+}
+/**
+* @descr: set frame position type style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyPosType(XFFrameStyle* pFrameStyle)
+{
+ enumXFFrameXPos eXPos = enumXFFrameXPosCenter;
+ enumXFFrameXRel eXRel = enumXFFrameXRelPara;
+ enumXFFrameYPos eYPos = enumXFFrameYPosMiddle;
+ enumXFFrameYRel eYRel = enumXFFrameYRelPara;
+ sal_uInt8 nType = m_pLayout->GetRelativeType();
+ switch (nType)
+ {
+ case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE: //fall through
+ case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE:
+ {
+ //anchor to page, frame and cell
+ eXPos = enumXFFrameXPosFromLeft;
+ eXRel = enumXFFrameXRelPage;
+ //set vertical position
+ if (m_pLayout->IsAnchorPage()) //in page
+ {
+ rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
+ if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))
+ {
+ //Only anchor to para, the frame can display in header and footer of each page
+ eYPos = enumXFFrameYPosFromTop; //from top
+ eYRel = enumXFFrameYRelPara; //from margin
+ }
+ else
+ {
+ eYPos = enumXFFrameYPosFromTop;
+ eYRel = enumXFFrameYRelPage;
+ }
+ }
+ if (m_pLayout->IsAnchorFrame()) //in frame
+ {
+ eYPos = enumXFFrameYPosFromTop;
+ eYRel = enumXFFrameYRelPage;
+ }
+ if (m_pLayout->IsAnchorCell())
+ {
+ //SODC has no this type, simulate this feature
+ eYPos = enumXFFrameYPosFromTop; //from top
+ eYRel = enumXFFrameYRelPara; //from margin
+ }
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text
+ {
+ eXPos = enumXFFrameXPosFromLeft;
+ eXRel = enumXFFrameXRelPage;
+ //set vertical position
+ rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
+ if (xContainer.is() && xContainer->IsPage()) //in page
+ {
+ //eYPos = enumXFFrameYPosFromTop;
+ //eYRel = enumXFFrameYRelPage;
+ eYPos = enumXFFrameYPosBelow;
+ eYRel = enumXFFrameYRelChar;
+ }
+ else if (xContainer.is() && xContainer->IsFrame()) //in frame
+ {
+ eYPos = enumXFFrameYPosFromTop;
+ eYRel = enumXFFrameYRelPage;
+ }
+ else
+ {
+ eYPos = enumXFFrameYPosFromTop; //from top
+ eYRel = enumXFFrameYRelPara; //from margin
+ }
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_INLINE: //in text
+ {
+ eXPos = enumXFFrameXPosFromLeft; //need not be set
+ eXRel = enumXFFrameXRelParaContent; //need not be set
+ eYPos = enumXFFrameYPosTop; //should be from top
+ eYRel = enumXFFrameYRelBaseLine;
+ sal_Int32 nOffset = m_pLayout->GetBaseLineOffset();
+ if (nOffset > 0)
+ {
+ eYPos = enumXFFrameYPosFromTop;
+ }
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE: //with para above
+ {
+ eXPos = enumXFFrameXPosFromLeft;
+ eXRel = enumXFFrameXRelParaContent;
+ //eYPos = enumXFFrameYPosTop;
+ eYPos = enumXFFrameYPosBottom;
+ eYRel = enumXFFrameYRelParaContent;
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL: //in text - vertical
+ {
+ eXPos = enumXFFrameXPosFromLeft;
+ eXRel = enumXFFrameXRelPage;
+ eYPos = enumXFFrameYPosFromTop; //should be below position
+ eYRel = enumXFFrameYRelChar;
+ break;
+ }
+ default:
+ break;
+ }
+
+ pFrameStyle->SetXPosType(eXPos, eXRel);
+ pFrameStyle->SetYPosType(eYPos, eYRel);
+}
+/**
+* @descr: set frame watermark style
+* @param: pFrameStyle - Frame Style object
+*
+*/
+void LwpFrame::ApplyWatermark(XFFrameStyle* pFrameStyle)
+{
+ std::unique_ptr<XFBGImage> xBGImage(m_pLayout->GetXFBGImage());
+ if (xBGImage)
+ {
+ pFrameStyle->SetBackImage(xBGImage);
+ //set watermark transparent
+ rtl::Reference<LwpVirtualLayout> xWaterMarkLayout(m_pLayout->GetWaterMarkLayout());
+ LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xWaterMarkLayout.get());
+ LwpBackgroundStuff* pBackgroundStuff = pLay ? pLay->GetBackgroundStuff() : nullptr;
+ if (pBackgroundStuff && !pBackgroundStuff->IsTransparent())
+ {
+ pFrameStyle->SetTransparency(100);
+ }
+ }
+}
+
+/**
+ * @short Apply pattern fill to frame style
+ * @param pFrameStyle - pointer of XFFrameStyle
+ * @return
+ */
+void LwpFrame::ApplyPatternFill(XFFrameStyle* pFrameStyle)
+{
+ std::unique_ptr<XFBGImage> xXFBGImage(m_pLayout->GetFillPattern());
+ if (xXFBGImage)
+ {
+ pFrameStyle->SetBackImage(xXFBGImage);
+ }
+}
+
+/**
+ * @short Apply background to frame style
+ * @param pFrameStyle - pointer of XFFrameStyle
+ * @return
+ */
+void LwpFrame::ApplyBackGround(XFFrameStyle* pFrameStyle)
+{
+ if (!m_pLayout)
+ {
+ return;
+ }
+
+ if (m_pLayout->IsPatternFill())
+ {
+ ApplyPatternFill(pFrameStyle);
+ }
+ else
+ {
+ ApplyBackColor(pFrameStyle);
+ }
+}
+
+/**
+* @descr: set frame size, anchor type, anchored page number
+* @param: pXFFrame - XFFrame object
+*
+*/
+void LwpFrame::ParseAnchorType(XFFrame* pXFFrame)
+{
+ //set position
+ double fXOffset = 0;
+ double fYOffset = 0;
+ //set anchor type
+ enumXFAnchor eAnchor = enumXFAnchorNone;
+
+ LwpLayoutGeometry* pLayoutGeo = m_pLayout->GetGeometry();
+ if (pLayoutGeo)
+ {
+ LwpPoint aPoint = pLayoutGeo->GetOrigin();
+ fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
+ fYOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetY());
+ }
+ //set anchor type
+ eAnchor = enumXFAnchorNone;
+ sal_uInt8 nType = m_pLayout->GetRelativeType();
+ switch (nType)
+ {
+ case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE: //fall through
+ case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE:
+ {
+ //anchor to page, frame and cell
+ if (m_pLayout->IsAnchorPage()) //in page
+ {
+ rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
+ if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))
+ {
+ eAnchor = enumXFAnchorPara;
+ fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
+ }
+ else
+ eAnchor = enumXFAnchorPage;
+ }
+ if (m_pLayout->IsAnchorFrame()) //in frame
+ {
+ eAnchor = enumXFAnchorFrame;
+ }
+ if (m_pLayout->IsAnchorCell()) //in cell
+ {
+ //eAnchor = enumXFAnchorChar;
+ eAnchor = enumXFAnchorPara;
+ rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
+ LwpMiddleLayout* pContainer = dynamic_cast<LwpMiddleLayout*>(xContainer.get());
+ if (pContainer)
+ {
+ fYOffset -= pContainer->GetMarginsValue(MARGIN_TOP);
+ }
+ }
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text
+ {
+ eAnchor = enumXFAnchorChar;
+ rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
+ if (xContainer.is() && xContainer->IsPage()) //in page
+ {
+ //eAnchor = enumXFAnchorPage;
+ eAnchor = enumXFAnchorChar; // to character
+ }
+ else if (xContainer.is() && xContainer->IsFrame()) //in frame
+ {
+ eAnchor = enumXFAnchorFrame;
+ }
+ else if (xContainer.is() && xContainer->IsCell()) //in cell
+ {
+ //eAnchor = enumXFAnchorChar;
+ eAnchor = enumXFAnchorPara;
+ fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
+ }
+ else if (xContainer.is()
+ && (xContainer->IsHeader() || xContainer->IsFooter())) //in header or footer
+ {
+ eAnchor = enumXFAnchorPara;
+ fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
+ }
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_INLINE: //in text
+ {
+ eAnchor = enumXFAnchorAsChar;
+ sal_Int32 nOffset = m_pLayout->GetBaseLineOffset();
+ if (nOffset > 0 && pLayoutGeo)
+ {
+ //experiential value
+ fYOffset = -(m_pLayout->GetGeometryHeight()
+ + 2 * m_pLayout->GetExtMarginsValue(MARGIN_BOTTOM)
+ - LwpTools::ConvertFromUnitsToMetric(nOffset));
+ }
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE: //with para above
+ {
+ eAnchor = enumXFAnchorPara;
+ break;
+ }
+ case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL: //in text - vertical
+ {
+ eAnchor = enumXFAnchorChar;
+ //set vertical position
+ double offset = 0;
+
+ //because of the different feature between Word Pro and SODC, I simulate the vertical base offset
+ //between anchor and frame origin using the font height.
+ rtl::Reference<XFFont> pFont = m_pLayout->GetFont();
+ if (pFont.is())
+ {
+ offset = static_cast<double>(pFont->GetFontSize()) * CM_PER_INCH / POINTS_PER_INCH;
+ }
+ fYOffset = offset - fYOffset;
+ break;
+ }
+ default:
+ break;
+ }
+
+ pXFFrame->SetX(fXOffset);
+ pXFFrame->SetY(fYOffset);
+ pXFFrame->SetAnchorPage(0);
+ pXFFrame->SetAnchorType(eAnchor);
+}
+
+/**
+ * @descr Calculate the distance between the frame object and the page margins.
+ * And determine which side(left or right) is wider
+ */
+bool LwpFrame::IsLeftWider()
+{
+ rtl::Reference<LwpVirtualLayout> xLayout(m_pLayout->GetContainerLayout());
+ LwpVirtualLayout* pParent = xLayout.get();
+ if (!pParent)
+ return false;
+ LwpPoint aPoint = m_pLayout->GetOrigin();
+ double fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
+ double fWidth = m_pLayout->GetWidth();
+ double fWrapLeft = m_pLayout->GetExtMarginsValue(MARGIN_LEFT);
+ double fWrapRight = m_pLayout->GetExtMarginsValue(MARGIN_RIGHT);
+
+ //LwpPoint aParentPoint = pParent->GetOrigin();
+ //double fParentXOffset = LwpTools::ConvertFromUnitsToMetric(aParentPoint.GetX());
+ double fParentWidth = pParent->GetWidth();
+ if (pParent->IsCell())
+ {
+ //Get actual width of this cell layout
+ fParentWidth = static_cast<LwpCellLayout*>(pParent)->GetActualWidth();
+ }
+ double fParentMarginLeft = pParent->GetMarginsValue(MARGIN_LEFT);
+ double fParentMarginRight = pParent->GetMarginsValue(MARGIN_RIGHT);
+
+ double fLeft = fXOffset - fWrapLeft - fParentMarginLeft;
+ double fRight = fParentWidth - fParentMarginRight - (fXOffset + fWidth + fWrapRight);
+ if (fLeft > fRight)
+ return true;
+ return false;
+}
+
+LwpFrameLink::LwpFrameLink() {}
+
+/**
+ * @descr frame link information
+ *
+ */
+void LwpFrameLink::Read(LwpObjectStream* pStrm)
+{
+ m_PreviousLayout.ReadIndexed(pStrm);
+ m_NextLayout.ReadIndexed(pStrm);
+ pStrm->SkipExtra();
+}
+
+LwpFrameLayout::LwpFrameLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
+ : LwpPlacableLayout(objHdr, pStrm)
+ , m_bGettingMaxWidth(false)
+{
+}
+
+LwpFrameLayout::~LwpFrameLayout() {}
+
+/**
+ * @descr read frame layout object
+ *
+ */
+void LwpFrameLayout::Read()
+{
+ LwpPlacableLayout::Read();
+ if (LwpFileHeader::m_nFileRevision >= 0x000B)
+ {
+ if (m_pObjStrm->QuickReaduInt16())
+ {
+ m_Link.Read(m_pObjStrm.get());
+ }
+ }
+ m_pObjStrm->SkipExtra();
+}
+
+/**
+ * @descr create a xfframe and add into content container
+ * @param: pCont - content container that contains the frame.
+ *
+ */
+void LwpFrameLayout::XFConvert(XFContentContainer* pCont)
+{
+ if (!m_pFrame)
+ return;
+
+ //parse the frame which anchor to paragraph
+ if (IsRelativeAnchored())
+ {
+ XFConvertFrame(pCont);
+ }
+ else
+ {
+ m_pFrame->XFConvert(pCont);
+ }
+}
+/**
+ * @descr create a xfframe and add into content container, called by XFConvert
+ * @param: pCont - content container that contains the frame.
+ * @param: nPageNo - the page number that the frame anchors
+ *
+ */
+void LwpFrameLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd,
+ bool bAll)
+{
+ if (!m_pFrame)
+ return;
+
+ rtl::Reference<XFFrame> xXFFrame;
+ if (nEnd < nStart)
+ {
+ xXFFrame.set(new XFFrame);
+ }
+ else
+ {
+ xXFFrame.set(new XFFloatFrame(nStart, nEnd, bAll));
+ }
+
+ m_pFrame->Parse(xXFFrame.get(), nStart);
+ //if it is a link frame, parse contents only once
+ if (!HasPreviousLinkLayout())
+ {
+ rtl::Reference<LwpObject> content = m_Content.obj();
+ if (content.is())
+ {
+ content->DoXFConvert(xXFFrame.get());
+ //set frame size according to ole size
+ ApplyGraphicSize(xXFFrame.get());
+ }
+ }
+ pCont->Add(xXFFrame.get());
+}
+/**
+ * @descr register frame style
+ *
+ */
+void LwpFrameLayout::RegisterStyle()
+{
+ //if it is for water mark, don't register style
+ if (IsForWaterMark())
+ return;
+
+ if (m_pFrame)
+ return;
+
+ //register frame style
+ std::unique_ptr<XFFrameStyle> xFrameStyle(new XFFrameStyle);
+ m_pFrame.reset(new LwpFrame(this));
+ m_pFrame->RegisterStyle(xFrameStyle);
+
+ //register content style
+ rtl::Reference<LwpObject> content = m_Content.obj();
+ if (content.is())
+ {
+ content->SetFoundry(m_pFoundry);
+ content->DoRegisterStyle();
+ }
+
+ //register child frame style
+ RegisterChildStyle();
+}
+
+/**
+ * @descr get the name of the frame that current frame links
+ *
+ */
+OUString LwpFrameLayout::GetNextLinkName()
+{
+ OUString aName;
+ LwpObjectID& rObjectID = m_Link.GetNextLayout();
+ if (!rObjectID.IsNull())
+ {
+ LwpLayout* pLayout = dynamic_cast<LwpLayout*>(rObjectID.obj().get());
+ if (pLayout)
+ {
+ LwpAtomHolder& rHolder = pLayout->GetName();
+ aName = rHolder.str();
+ //for division name conflict
+ if (!pLayout->GetStyleName().isEmpty())
+ aName = pLayout->GetStyleName();
+ }
+ }
+ return aName;
+}
+/**
+ * @descr whether current frame is linked by other frame
+ *
+ */
+bool LwpFrameLayout::HasPreviousLinkLayout()
+{
+ LwpObjectID& rObjectID = m_Link.GetPreviousLayout();
+ return !rObjectID.IsNull();
+}
+/**
+ * @descr whether current frame is for water mark. Problem maybe exists by this method, must be tracking
+ *
+ */
+bool LwpFrameLayout::IsForWaterMark()
+{
+ if (m_nBuoyancy >= LAY_BUOYLAYER)
+ {
+ if (m_Content.IsNull())
+ return false;
+ rtl::Reference<LwpObject> content = m_Content.obj();
+ if (!content.is())
+ return false;
+ if (content->GetTag() == VO_GRAPHIC)
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @descr Get frame width
+ *
+ */
+double LwpFrameLayout::GetWidth()
+{
+ double fWidth = LwpMiddleLayout::GetWidth();
+ if (IsInlineToMargin() && IsAutoGrowWidth())
+ {
+ //for text field entry when choosing maximize field length
+ fWidth = GetMaxWidth();
+ }
+ return fWidth;
+}
+
+/**
+ * @descr Get frame width when the text field chooses maximize field length
+ *
+ */
+double LwpFrameLayout::GetMaxWidth()
+{
+ if (m_bGettingMaxWidth)
+ throw std::runtime_error("recursive GetMaxWidth");
+
+ m_bGettingMaxWidth = true;
+ double fActualWidth = 0;
+ rtl::Reference<LwpVirtualLayout> xLayout(GetContainerLayout());
+ LwpMiddleLayout* pParent = dynamic_cast<LwpMiddleLayout*>(xLayout.get());
+ if (pParent)
+ {
+ LwpPoint aPoint = GetOrigin();
+ double fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
+ double fWrapRight = GetExtMarginsValue(MARGIN_RIGHT);
+
+ //Get parent layout width
+ double fParentWidth = pParent->GetWidth();
+ if (pParent->IsCell())
+ {
+ //Get actual width of this cell layout
+ fParentWidth = static_cast<LwpCellLayout*>(pParent)->GetActualWidth();
+ }
+
+ double fParentMarginRight = 0;
+ sal_uInt8 nType = GetRelativeType();
+ if (nType == LwpLayoutRelativityGuts::LAY_INLINE
+ || nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
+ {
+ fParentMarginRight = pParent->GetMarginsValue(MARGIN_RIGHT);
+ }
+
+ fActualWidth = fParentWidth - fXOffset - fParentMarginRight - fWrapRight;
+ }
+
+ m_bGettingMaxWidth = false;
+ return fActualWidth;
+}
+
+/**
+ * @descr Set frame size according to graphic size
+ *
+ */
+void LwpFrameLayout::ApplyGraphicSize(XFFrame* pXFFrame)
+{
+ rtl::Reference<LwpObject> content = m_Content.obj();
+ if (!(content.is() && (content->GetTag() == VO_GRAPHIC || content->GetTag() == VO_OLEOBJECT)))
+ return;
+
+ LwpGraphicOleObject* pGraOle = static_cast<LwpGraphicOleObject*>(content.get());
+ //Get frame geometry size
+ double fWidth = 0;
+ double fHeight = 0;
+ pGraOle->GetGrafScaledSize(fWidth, fHeight);
+ if (IsFitGraphic())
+ {
+ //graphic scaled sze
+ fWidth += GetMarginsValue(MARGIN_LEFT) + GetMarginsValue(MARGIN_RIGHT);
+ fHeight += GetMarginsValue(MARGIN_TOP) + GetMarginsValue(MARGIN_BOTTOM);
+ }
+ else if (IsAutoGrowDown() || IsAutoGrowUp())
+ {
+ fWidth = GetWidth();
+ fHeight += GetMarginsValue(MARGIN_TOP) + GetMarginsValue(MARGIN_BOTTOM);
+ }
+ else if (IsAutoGrowLeft() || IsAutoGrowRight())
+ {
+ fHeight = GetHeight();
+ fWidth += GetMarginsValue(MARGIN_LEFT) + GetMarginsValue(MARGIN_RIGHT);
+ }
+ else
+ {
+ fWidth = GetWidth();
+ fHeight = GetHeight();
+ }
+ pXFFrame->SetWidth(fWidth);
+ pXFFrame->SetHeight(fHeight);
+}
+
+LwpGroupLayout::LwpGroupLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
+ : LwpPlacableLayout(objHdr, pStrm)
+{
+}
+
+LwpGroupLayout::~LwpGroupLayout() {}
+/**
+ * @descr read group layout object
+ *
+ */
+void LwpGroupLayout::Read()
+{
+ LwpPlacableLayout::Read();
+ m_pObjStrm->SkipExtra();
+}
+/**
+ * @descr register group frame style
+ *
+ */
+void LwpGroupLayout::RegisterStyle()
+{
+ if (m_pFrame)
+ return;
+
+ //register frame style
+ std::unique_ptr<XFFrameStyle> xFrameStyle(new XFFrameStyle);
+ m_pFrame.reset(new LwpFrame(this));
+ m_pFrame->RegisterStyle(xFrameStyle);
+
+ //register child frame style
+ RegisterChildStyle();
+}
+/**
+ * @descr create a xfframe and add into content container
+ * @param: pCont - content container that contains the frame.
+ *
+ */
+void LwpGroupLayout::XFConvert(XFContentContainer* pCont)
+{
+ if (!m_pFrame)
+ return;
+
+ //parse the frame which anchor to paragraph
+ if (IsRelativeAnchored())
+ {
+ XFConvertFrame(pCont);
+ }
+ else
+ {
+ m_pFrame->XFConvert(pCont);
+ }
+}
+/**
+ * @descr create a xfframe and add into content container, called by XFConvert
+ * @param: pCont - content container that contains the frame.
+ * @param: nPageNo - the page number that the frame anchors
+ *
+ */
+void LwpGroupLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart, sal_Int32 nEnd,
+ bool bAll)
+{
+ if (!m_pFrame)
+ return;
+
+ rtl::Reference<XFFrame> xXFFrame;
+ if (nEnd < nStart)
+ {
+ xXFFrame.set(new XFFrame);
+ }
+ else
+ {
+ xXFFrame.set(new XFFloatFrame(nStart, nEnd, bAll));
+ }
+
+ m_pFrame->Parse(xXFFrame.get(), nStart);
+
+ //add child frame into group
+ LwpVirtualLayout* pLayout = dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get());
+
+ while (pLayout && pLayout != this)
+ {
+ pLayout->DoXFConvert(xXFFrame.get());
+ pLayout = dynamic_cast<LwpVirtualLayout*>(pLayout->GetNext().obj().get());
+ }
+
+ pCont->Add(xXFFrame.get());
+}
+
+LwpGroupFrame::LwpGroupFrame(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
+ : LwpContent(objHdr, pStrm)
+{
+}
+
+LwpGroupFrame::~LwpGroupFrame() {}
+
+void LwpGroupFrame::Read()
+{
+ LwpContent::Read();
+ m_pObjStrm->SkipExtra();
+}
+
+void LwpGroupFrame::RegisterStyle() {}
+
+void LwpGroupFrame::XFConvert(XFContentContainer* /*pCont*/) {}
+
+LwpDropcapLayout::LwpDropcapLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
+ : LwpFrameLayout(objHdr, pStrm)
+ , m_nLines(3)
+ , m_nChars(1)
+{
+}
+
+void LwpDropcapLayout::Read()
+{
+ LwpFrameLayout::Read();
+ m_nLines = m_pObjStrm->QuickReaduInt16();
+ m_pObjStrm->SeekRel(1);
+ m_pObjStrm->SkipExtra();
+}
+
+void LwpDropcapLayout::Parse(IXFStream* pOutputStream)
+{
+ LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
+ if (!pStory)
+ return;
+ rtl::Reference<LwpObject> pPara = pStory->GetFirstPara().obj(VO_PARA);
+ if (pPara.is())
+ {
+ pPara->SetFoundry(m_pFoundry);
+ pPara->DoParse(pOutputStream);
+ }
+}
+
+void LwpDropcapLayout::XFConvert(XFContentContainer* pCont)
+{
+ LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
+ if (pStory)
+ {
+ pStory->SetFoundry(m_pFoundry);
+ pStory->XFConvert(pCont);
+ }
+}
+
+void LwpDropcapLayout::RegisterStyle(LwpFoundry* pFoundry)
+{
+ LwpStory* pStory = dynamic_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
+ if (pStory)
+ {
+ pStory->SetDropcapFlag(true);
+ pStory->SetFoundry(pFoundry);
+ LwpPara* pPara = dynamic_cast<LwpPara*>(pStory->GetFirstPara().obj().get());
+ while (pPara)
+ {
+ pPara->SetFoundry(pFoundry);
+ pPara->RegisterStyle();
+ pPara = dynamic_cast<LwpPara*>(pPara->GetNext().obj().get());
+ }
+ }
+}
+
+/**
+ * @descr do nothing
+ *
+ */
+void LwpDropcapLayout::RegisterStyle() {}
+
+LwpRubyLayout::LwpRubyLayout(LwpObjectHeader const& objHdr, LwpSvStream* pStrm)
+ : LwpFrameLayout(objHdr, pStrm)
+ , m_nPlacement(0)
+ , m_nAlignment(0)
+ , m_nStateFlag(0)
+ , m_nXOffset(0)
+ , m_nYOffset(0)
+{
+}
+
+void LwpRubyLayout::Read()
+{
+ LwpFrameLayout::Read();
+ m_nPlacement = m_pObjStrm->QuickReaduInt8();
+ m_nAlignment = m_pObjStrm->QuickReaduInt8();
+ m_nStateFlag = m_pObjStrm->QuickReaduInt16();
+ m_nXOffset = m_pObjStrm->QuickReadInt32();
+ m_nYOffset = m_pObjStrm->QuickReadInt32();
+ m_objRubyMarker.ReadIndexed(m_pObjStrm.get());
+ m_pObjStrm->SkipExtra();
+}
+
+LwpRubyMarker* LwpRubyLayout::GetMarker()
+{
+ return static_cast<LwpRubyMarker*>(m_objRubyMarker.obj(VO_RUBYMARKER).get());
+}
+
+LwpStory* LwpRubyLayout::GetContentStory()
+{
+ return static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
+}
+
+void LwpRubyLayout::ConvertContentText()
+{
+ LwpStory* pStory = GetContentStory();
+ LwpRubyMarker* pMarker = GetMarker();
+ if (pStory && pMarker)
+ pMarker->SetRubyText(pStory->GetContentText(true));
+}
+
+void LwpRubyLayout::RegisterStyle()
+{
+ LwpRubyMarker* pMarker = GetMarker();
+ if (!pMarker)
+ throw std::runtime_error("missing Ruby Marker");
+
+ std::unique_ptr<XFRubyStyle> xRubyStyle(new XFRubyStyle);
+
+ enumXFRubyPosition eType = enumXFRubyLeft;
+ if (m_nAlignment == LEFT)
+ {
+ eType = enumXFRubyLeft;
+ }
+ else if (m_nAlignment == RIGHT)
+ {
+ eType = enumXFRubyRight;
+ }
+ else if (m_nAlignment == CENTER)
+ {
+ eType = enumXFRubyCenter;
+ }
+ xRubyStyle->SetAlignment(eType);
+
+ eType = enumXFRubyTop;
+ if (m_nPlacement == TOP)
+ {
+ eType = enumXFRubyTop;
+ }
+ else if (m_nPlacement == BOTTOM)
+ {
+ eType = enumXFRubyBottom;
+ }
+ xRubyStyle->SetPosition(eType);
+
+ XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
+ OUString rubyStyle = pXFStyleManager->AddStyle(std::move(xRubyStyle)).m_pStyle->GetStyleName();
+ pMarker->SetRubyStyleName(rubyStyle);
+
+ LwpStory* pStory = GetContentStory();
+ pStory->SetFoundry(m_pFoundry);
+ OUString textStyle = pStory->RegisterFirstFribStyle();
+ pMarker->SetTextStyleName(textStyle);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */