/* -*- 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::ConvertFromUnits(aPoint.GetX());
fYOffset = LwpTools::ConvertFromUnits(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::ConvertFromUnits(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 = o3tl::convert<double>(pFont->GetFontSize(), o3tl::Length::pt,
o3tl::Length::cm);
}
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::ConvertFromUnits(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::ConvertFromUnits(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: */
↑ V1048 The 'eYRel' variable was assigned the same value.
↑ V1048 The 'eYRel' variable was assigned the same value.
↑ V1048 The 'eAnchor' variable was assigned the same value.
↑ V1048 The 'eType' variable was assigned the same value.
↑ V1048 The 'eType' variable was assigned the same value.