/* -*- 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 ************************************************************************/ /************************************************************************* * Change History Mar 2005 Created ************************************************************************/ #include "lwpframelayout.hxx" #include "lwppara.hxx" #include "xfilter/xfstylemanager.hxx" #include "xfilter/xfparagraph.hxx" #include "xfilter/xffloatframe.hxx" #include "xfilter/xfrubystyle.hxx" #include "lwppagelayout.hxx" #include "lwpoleobject.hxx" #include "lwptablelayout.hxx" #include "lwpgrfobj.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(XFFrameStyle* pFrameStyle) { ApplyWrapType(pFrameStyle); ApplyMargins(pFrameStyle); ApplyPadding(pFrameStyle); ApplyBorders(pFrameStyle); ApplyColumns(pFrameStyle); ApplyShadow(pFrameStyle); ApplyBackGround(pFrameStyle); ApplyWatermark(pFrameStyle); // ApplyBackColor(pFrameStyle); ApplyProtect(pFrameStyle); ApplyTextDir(pFrameStyle); ApplyPosType(pFrameStyle); pFrameStyle->SetStyleName(m_pLayout->GetName().str()); XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager(); m_StyleName = pXFStyleManager->AddStyle(pFrameStyle).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(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(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 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(nFirst); if((m_pLayout->IsUseOnAllOddPages() && !LwpTools::IsOddNumber(first)) || (m_pLayout->IsUseOnAllEvenPages() && !LwpTools::IsEvenNumber(first))) nFirst++; if(nFirst <= nLast) { m_pLayout->XFConvertFrame(pCont, nFirst, nLast, false); } } } } 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 xContainer(m_pLayout->GetContainerLayout()); LwpMiddleLayout* pParent = dynamic_cast(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) { XFBorders* pBordres = m_pLayout->GetXFBorders(); if(pBordres) { pFrameStyle->SetBorders(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 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; eYPos = enumXFFrameYPosBelow; //below eYRel = enumXFFrameYRelChar; //from char //set vertical position rtl::Reference 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) { XFBGImage* pBGImage = m_pLayout->GetXFBGImage(); if(pBGImage) { pFrameStyle->SetBackImage(pBGImage); //set watermark transparent rtl::Reference xWaterMarkLayout(m_pLayout->GetWaterMarkLayout()); LwpMiddleLayout* pLay = dynamic_cast(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) { XFBGImage* pXFBGImage = m_pLayout->GetFillPattern(); if (pXFBGImage) { pFrameStyle->SetBackImage(pXFBGImage); } } /** * @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; //page number sal_uInt16 nPageNum = 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 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 xContainer(m_pLayout->GetContainerLayout()); LwpMiddleLayout* pContainer = dynamic_cast(xContainer.get()); if (pContainer) { fYOffset -= pContainer->GetMarginsValue(MARGIN_TOP); } } break; } case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text { eAnchor = enumXFAnchorChar; rtl::Reference 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 pFont = m_pLayout->GetFont(); if(pFont.is()) { offset = (double)(pFont->GetFontSize())*CM_PER_INCH/POINTS_PER_INCH; } fYOffset = offset-fYOffset; break; } default: break; } pXFFrame->SetX(fXOffset); pXFFrame->SetY(fYOffset); pXFFrame->SetAnchorPage(nPageNum); 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 xLayout(m_pLayout->GetContainerLayout()); LwpVirtualLayout* pParent = dynamic_cast(xLayout.get()); if (pParent) { 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(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() {} LwpFrameLink::~LwpFrameLink() {} /** * @descr frame link information * */ void LwpFrameLink::Read(LwpObjectStream* pStrm) { m_PreviousLayout.ReadIndexed(pStrm); m_NextLayout.ReadIndexed(pStrm); pStrm->SkipExtra(); } LwpFrameLayout::LwpFrameLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm) : LwpPlacableLayout(objHdr, pStrm), m_pFrame(NULL) { } LwpFrameLayout::~LwpFrameLayout() { delete m_pFrame; } /** * @descr read frame layout object * */ void LwpFrameLayout::Read() { LwpPlacableLayout::Read(); if(LwpFileHeader::m_nFileRevision >= 0x000B) { if(m_pObjStrm->QuickReaduInt16()) { m_Link.Read(m_pObjStrm); } } 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) { //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) { XFFrame* pXFFrame = NULL; if(nEnd < nStart) { pXFFrame = new XFFrame(); } else { pXFFrame = new XFFloatFrame(nStart, nEnd, bAll); } m_pFrame->Parse(pXFFrame, nStart); //if it is a link frame, parse contents only once if(!HasPreviousLinkLayout()) { rtl::Reference content = m_Content.obj(); if (content.is()) { content->XFConvert(pXFFrame); //set frame size according to ole size ApplyGraphicSize(pXFFrame); } } pCont ->Add(pXFFrame); } } /** * @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 XFFrameStyle* pFrameStyle = new XFFrameStyle(); m_pFrame = new LwpFrame(this); m_pFrame->RegisterStyle(pFrameStyle); //register content style rtl::Reference 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(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(); if(rObjectID.IsNull()) return false; return true; } /** * @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 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() { double fActualWidth = 0; rtl::Reference xLayout(GetContainerLayout()); LwpMiddleLayout* pParent = dynamic_cast(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(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; } return fActualWidth; } /** * @descr Set frame size according to graphic size * */ void LwpFrameLayout::ApplyGraphicSize(XFFrame * pXFFrame) { rtl::Reference content = m_Content.obj(); if(content.is() && (content->GetTag() == VO_GRAPHIC || content->GetTag() == VO_OLEOBJECT )) { LwpGraphicOleObject* pGraOle = static_cast(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 &objHdr, LwpSvStream* pStrm) : LwpPlacableLayout(objHdr, pStrm) , m_pFrame(NULL) { } LwpGroupLayout::~LwpGroupLayout() { delete m_pFrame; } /** * @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 XFFrameStyle* pFrameStyle = new XFFrameStyle(); m_pFrame = new LwpFrame(this); m_pFrame->RegisterStyle(pFrameStyle); //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) { //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) { XFFrame* pXFFrame = NULL; if(nEnd < nStart) { pXFFrame = new XFFrame(); } else { pXFFrame = new XFFloatFrame(nStart, nEnd, bAll); } m_pFrame->Parse(pXFFrame, nStart); //add child frame into group LwpVirtualLayout* pLayout = dynamic_cast(GetChildHead().obj().get()); while(pLayout) { pLayout->XFConvert(pXFFrame); pLayout = dynamic_cast(pLayout->GetNext().obj().get()); } pCont ->Add(pXFFrame); } } LwpGroupFrame::LwpGroupFrame(LwpObjectHeader &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 &objHdr, LwpSvStream* pStrm) : LwpFrameLayout(objHdr, pStrm) { m_nChars = 1; m_nLines = 3; } 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(m_Content.obj(VO_STORY).get()); if (!pStory) return; rtl::Reference 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(m_Content.obj(VO_STORY).get()); if (pStory) { pStory->SetFoundry(m_pFoundry); pStory->XFConvert(pCont); } } LwpStory* LwpDropcapLayout::GetContentStory() { return static_cast(m_Content.obj(VO_STORY).get()); } void LwpDropcapLayout::RegisterStyle(LwpFoundry* pFoundry) { LwpStory* pStory = GetContentStory(); if (pStory) { pStory->SetDropcapFlag(true); pStory->SetFoundry(pFoundry); LwpPara* pPara = dynamic_cast(pStory->GetFirstPara().obj().get()); while(pPara) { pPara->SetFoundry(pFoundry); pPara->RegisterStyle(); pPara = dynamic_cast(pPara->GetNext().obj().get()); } } } /** * @descr do nothing * */ void LwpDropcapLayout::RegisterStyle() { } LwpRubyLayout::LwpRubyLayout(LwpObjectHeader &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); m_pObjStrm->SkipExtra(); } LwpRubyMarker* LwpRubyLayout::GetMarker() { return static_cast(m_objRubyMarker.obj(VO_RUBYMARKER).get()); } LwpStory* LwpRubyLayout::GetContentStory() { return static_cast(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"); XFRubyStyle* pRubyStyle = 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; } pRubyStyle->SetAlignment(eType); eType = enumXFRubyTop; if (m_nPlacement == TOP) { eType = enumXFRubyTop; } else if(m_nPlacement == BOTTOM) { eType = enumXFRubyBottom; } pRubyStyle->SetPosition(eType); XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager(); OUString rubyStyle = pXFStyleManager->AddStyle(pRubyStyle).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: */