1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 /*************************************************************************
58 * the class for VO_FrameLayout
59 ************************************************************************/
62 #include <lwpfilehdr.hxx>
63 #include "lwpcelllayout.hxx"
64 #include "lwpframelayout.hxx"
65 #include "lwppara.hxx"
66 #include <xfilter/xfstylemanager.hxx>
67 #include <xfilter/xffloatframe.hxx>
68 #include <xfilter/xfrubystyle.hxx>
69 #include "lwpoleobject.hxx"
70 #include <lwpglobalmgr.hxx>
72 LwpFrame::LwpFrame(LwpPlacableLayout
* pLayout
)
77 LwpFrame::~LwpFrame() {}
80 * @param: register frame style
81 * @param: pFrameStyle - Frame Style object
84 void LwpFrame::RegisterStyle(std::unique_ptr
<XFFrameStyle
>& rFrameStyle
)
86 ApplyWrapType(rFrameStyle
.get());
87 ApplyMargins(rFrameStyle
.get());
88 ApplyPadding(rFrameStyle
.get());
89 ApplyBorders(rFrameStyle
.get());
90 ApplyColumns(rFrameStyle
.get());
91 ApplyShadow(rFrameStyle
.get());
92 ApplyBackGround(rFrameStyle
.get());
93 ApplyWatermark(rFrameStyle
.get());
94 ApplyProtect(rFrameStyle
.get());
95 ApplyTextDir(rFrameStyle
.get());
96 ApplyPosType(rFrameStyle
.get());
98 rFrameStyle
->SetStyleName(m_pLayout
->GetName().str());
99 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
100 m_StyleName
= pXFStyleManager
->AddStyle(std::move(rFrameStyle
)).m_pStyle
->GetStyleName();
101 m_pLayout
->SetStyleName(m_StyleName
);
105 * @descr: parse frame and set frame properties
106 * @param: pXFFrame - XFFrame object
107 * @param: nPageNo - the page number that the frame anchors
110 void LwpFrame::Parse(XFFrame
* pXFFrame
, sal_Int32 nPageNo
)
112 //set the frame style name
113 pXFFrame
->SetStyleName(m_StyleName
);
115 //SetAnchorType and position,if it's page anchor,set the page number.
116 ParseAnchorType(pXFFrame
);
119 pXFFrame
->SetAnchorPage(nPageNo
);
123 OUString aFrameName
= m_pLayout
->GetName().str();
124 if (!aFrameName
.isEmpty())
126 //cause the bug of SODC, the linkframe name can not be "Frame1", so I change the frame name
127 /*if(aFrameName.equals("Frame1"))
129 aFrameName = "Frame1_COPY";
131 pXFFrame->SetName(aFrameName);*/
132 pXFFrame
->SetName(m_StyleName
);
135 LwpLayoutGeometry
* pLayoutGeo
= m_pLayout
->GetGeometry();
136 //Set frame Width and height
139 double fWidth
= m_pLayout
->GetWidth();
140 double fHeight
= m_pLayout
->GetHeight();
142 pXFFrame
->SetWidth(fWidth
);
143 pXFFrame
->SetHeight(fHeight
);
146 /*LwpObject* pObj =*/m_pLayout
->GetContent().obj();
147 if (m_pLayout
->IsGroupHead() && (m_pLayout
->IsMinimumHeight()))
149 //process grouplayout height. there is problems now
150 pXFFrame
->SetHeight(fHeight
);
153 else if(m_pLayout->IsFitGraphic() && pObj && pObj->GetTag() == VO_GRAPHIC)
155 //If is graphic, get original size and set it;
156 LwpGraphicObject* pGrpObj = static_cast<LwpGraphicObject*>(pObj);
157 long nHeight =0, nWidth =0;
158 pGrpObj->GetGrafOrgSize(nWidth, nHeight);
159 //add margins to the width and height;
160 fWidth = (double)nWidth/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_LEFT) + m_pLayout->GetMarginsValue(MARGIN_RIGHT);
161 fHeight = (double)nHeight/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_TOP) + m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
162 pXFFrame->SetWidth(fWidth);
163 pXFFrame->SetHeight(fHeight);
166 else if (m_pLayout
->IsAutoGrow())
168 pXFFrame
->SetMinHeight(fHeight
);
172 if (m_pLayout
->IsFrame())
174 //Set frame link. Only frame layout has this feature
175 LwpFrameLayout
* pLayout
= static_cast<LwpFrameLayout
*>(m_pLayout
);
176 pXFFrame
->SetNextLink(pLayout
->GetNextLinkName());
180 * @descr: parse frame relative to page, frame or cell
181 * @param: pCont - content container which contains the frame
184 void LwpFrame::XFConvert(XFContentContainer
* pCont
)
186 // parse the frame which anchor to page
187 rtl::Reference
<LwpVirtualLayout
> xParent
= m_pLayout
->GetParentLayout();
189 throw std::runtime_error("missing Parent Layout");
190 if (xParent
->IsPage() && xParent
->GetParentLayout().is()
191 && xParent
->GetParentLayout()->IsPage())
193 //for mirror page, problems exist if the parent layout is header or footer layout,
194 xParent
= xParent
->GetParentLayout();
196 if (m_pLayout
->IsAnchorPage() && xParent
->IsPage())
199 if (m_pLayout
->IsUseOnPage())
201 sal_Int32 nPageNo
= xParent
->GetPageNumber(m_pLayout
->GetUsePage());
203 m_pLayout
->XFConvertFrame(pCont
, nPageNo
);
205 else if (m_pLayout
->IsUseOnAllPages())
207 sal_Int32 nFirst
= xParent
->GetPageNumber(FIRST_LAYOUTPAGENO
);
208 sal_Int32 nLast
= xParent
->GetPageNumber(LAST_LAYOUTPAGENO
);
210 m_pLayout
->XFConvertFrame(pCont
, nFirst
, nLast
, true);
212 else if (m_pLayout
->IsUseOnAllOddPages() || m_pLayout
->IsUseOnAllEvenPages())
214 sal_Int32 nFirst
= xParent
->GetPageNumber(FIRST_LAYOUTPAGENO
);
215 sal_Int32 nLast
= xParent
->GetPageNumber(LAST_LAYOUTPAGENO
);
218 sal_uInt16 first
= static_cast<sal_uInt16
>(nFirst
);
219 if ((m_pLayout
->IsUseOnAllOddPages() && !LwpTools::IsOddNumber(first
))
220 || (m_pLayout
->IsUseOnAllEvenPages() && !LwpTools::IsEvenNumber(first
)))
224 m_pLayout
->XFConvertFrame(pCont
, nFirst
, nLast
);
231 m_pLayout
->XFConvertFrame(pCont
);
235 * @descr: set frame wrap type style
236 * @param: pFrameStyle - Frame Style object
239 void LwpFrame::ApplyWrapType(XFFrameStyle
* pFrameStyle
)
241 enumXFWrap eWrap
= enumXFWrapNone
;
242 switch (m_pLayout
->GetWrapType())
244 case LwpPlacableLayout::LAY_WRAP_AROUND
: //fall through
245 case LwpPlacableLayout::LAY_WRAP_IRREG_BIGGEST
:
247 //In SODC, if Optimal wrap type is used and the distance between the frame object
248 //and page margins is less than 2cm, the text is not wrapped. While there is no this feature in Word Pro
249 //So the optimal wrap type is translated to left side or right side wrap type according to the distance
250 //between the frame object and page margins
252 eWrap
= enumXFWrapBest
;
253 rtl::Reference
<LwpVirtualLayout
> xContainer(m_pLayout
->GetContainerLayout());
254 LwpMiddleLayout
* pParent
= dynamic_cast<LwpMiddleLayout
*>(xContainer
.get());
258 eWrap
= enumXFWrapLeft
;
260 eWrap
= enumXFWrapRight
;
264 case LwpPlacableLayout::LAY_NO_WRAP_BESIDE
:
266 eWrap
= enumXFWrapNone
;
269 case LwpPlacableLayout::LAY_NO_WRAP_AROUND
:
271 eWrap
= enumXFWrapRunThrough
;
272 if (!m_pLayout
->GetBackColor() && !m_pLayout
->GetWaterMarkLayout().is())
274 //pFrameStyle->SetBackGround(sal_True);
275 XFColor
aXFColor(0xffffff); //white color
276 pFrameStyle
->SetBackColor(aXFColor
);
277 pFrameStyle
->SetTransparency(100); //transparency
281 case LwpPlacableLayout::LAY_WRAP_LEFT
: //fall through
282 case LwpPlacableLayout::LAY_WRAP_IRREG_LEFT
:
284 eWrap
= enumXFWrapLeft
;
287 case LwpPlacableLayout::LAY_WRAP_RIGHT
: //fall through
288 case LwpPlacableLayout::LAY_WRAP_IRREG_RIGHT
:
290 eWrap
= enumXFWrapRight
;
293 case LwpPlacableLayout::LAY_WRAP_BOTH
: //fall through
294 case LwpPlacableLayout::LAY_WRAP_IRREG_BOTH
:
296 eWrap
= enumXFWrapParallel
;
303 //If it is the type of with para above, wrap type is enumXFWrapNone
304 if (m_pLayout
->GetRelativeType() == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
)
306 eWrap
= enumXFWrapNone
;
309 pFrameStyle
->SetWrapType(eWrap
);
312 * @descr: set frame margins style
313 * @param: pFrameStyle - Frame Style object
316 void LwpFrame::ApplyMargins(XFFrameStyle
* pFrameStyle
)
318 double fLeft
= m_pLayout
->GetExtMarginsValue(MARGIN_LEFT
);
319 double fRight
= m_pLayout
->GetExtMarginsValue(MARGIN_RIGHT
);
320 double fTop
= m_pLayout
->GetExtMarginsValue(MARGIN_TOP
);
321 double fBottom
= m_pLayout
->GetExtMarginsValue(MARGIN_BOTTOM
);
322 pFrameStyle
->SetMargins(fLeft
, fRight
, fTop
, fBottom
);
325 * @descr: set padding border style
326 * @param: pFrameStyle - Frame Style object
329 void LwpFrame::ApplyPadding(XFFrameStyle
* pFrameStyle
)
331 double fLeft
= m_pLayout
->GetMarginsValue(MARGIN_LEFT
);
332 double fRight
= m_pLayout
->GetMarginsValue(MARGIN_RIGHT
);
333 double fTop
= m_pLayout
->GetMarginsValue(MARGIN_TOP
);
334 double fBottom
= m_pLayout
->GetMarginsValue(MARGIN_BOTTOM
);
335 pFrameStyle
->SetPadding(fLeft
, fRight
, fTop
, fBottom
);
338 * @descr: set frame border style
339 * @param: pFrameStyle - Frame Style object
342 void LwpFrame::ApplyBorders(XFFrameStyle
* pFrameStyle
)
344 std::unique_ptr
<XFBorders
> pBordres
= m_pLayout
->GetXFBorders();
347 pFrameStyle
->SetBorders(std::move(pBordres
));
351 * @descr: set frame columns style
352 * @param: pFrameStyle - Frame Style object
355 void LwpFrame::ApplyColumns(XFFrameStyle
* pFrameStyle
)
357 XFColumns
* pColumns
= m_pLayout
->GetXFColumns();
360 pFrameStyle
->SetColumns(pColumns
);
364 * @descr: set frame shadow style
365 * @param: pFrameStyle - Frame Style object
368 void LwpFrame::ApplyShadow(XFFrameStyle
* pFrameStyle
)
370 XFShadow
* pXFShadow
= m_pLayout
->GetXFShadow();
373 pFrameStyle
->SetShadow(pXFShadow
);
377 * @descr: set frame back color style
378 * @param: pFrameStyle - Frame Style object
381 void LwpFrame::ApplyBackColor(XFFrameStyle
* pFrameStyle
)
383 LwpColor
* pColor
= m_pLayout
->GetBackColor();
386 XFColor
aXFColor(pColor
->To24Color());
387 pFrameStyle
->SetBackColor(aXFColor
);
391 * @descr: set frame protect style
392 * @param: pFrameStyle - Frame Style object
395 void LwpFrame::ApplyProtect(XFFrameStyle
* pFrameStyle
)
397 if (m_pLayout
->GetIsProtected())
399 pFrameStyle
->SetProtect(true, true, true);
403 * @descr: set frame text direction style
404 * @param: pFrameStyle - Frame Style object
407 void LwpFrame::ApplyTextDir(XFFrameStyle
* pFrameStyle
)
409 pFrameStyle
->SetTextDir(m_pLayout
->GetTextDirection());
412 * @descr: set frame position type style
413 * @param: pFrameStyle - Frame Style object
416 void LwpFrame::ApplyPosType(XFFrameStyle
* pFrameStyle
)
418 enumXFFrameXPos eXPos
= enumXFFrameXPosCenter
;
419 enumXFFrameXRel eXRel
= enumXFFrameXRelPara
;
420 enumXFFrameYPos eYPos
= enumXFFrameYPosMiddle
;
421 enumXFFrameYRel eYRel
= enumXFFrameYRelPara
;
422 sal_uInt8 nType
= m_pLayout
->GetRelativeType();
425 case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE
: //fall through
426 case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE
:
428 //anchor to page, frame and cell
429 eXPos
= enumXFFrameXPosFromLeft
;
430 eXRel
= enumXFFrameXRelPage
;
431 //set vertical position
432 if (m_pLayout
->IsAnchorPage()) //in page
434 rtl::Reference
<LwpVirtualLayout
> xContainer(m_pLayout
->GetContainerLayout());
435 if (xContainer
.is() && (xContainer
->IsHeader() || xContainer
->IsFooter()))
437 //Only anchor to para, the frame can display in header and footer of each page
438 eYPos
= enumXFFrameYPosFromTop
; //from top
439 eYRel
= enumXFFrameYRelPara
; //from margin
443 eYPos
= enumXFFrameYPosFromTop
;
444 eYRel
= enumXFFrameYRelPage
;
447 if (m_pLayout
->IsAnchorFrame()) //in frame
449 eYPos
= enumXFFrameYPosFromTop
;
450 eYRel
= enumXFFrameYRelPage
;
452 if (m_pLayout
->IsAnchorCell())
454 //SODC has no this type, simulate this feature
455 eYPos
= enumXFFrameYPosFromTop
; //from top
456 eYRel
= enumXFFrameYRelPara
; //from margin
460 case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE
: //same page as text
462 eXPos
= enumXFFrameXPosFromLeft
;
463 eXRel
= enumXFFrameXRelPage
;
464 //set vertical position
465 rtl::Reference
<LwpVirtualLayout
> xContainer(m_pLayout
->GetContainerLayout());
466 if (xContainer
.is() && xContainer
->IsPage()) //in page
468 //eYPos = enumXFFrameYPosFromTop;
469 //eYRel = enumXFFrameYRelPage;
470 eYPos
= enumXFFrameYPosBelow
;
471 eYRel
= enumXFFrameYRelChar
;
473 else if (xContainer
.is() && xContainer
->IsFrame()) //in frame
475 eYPos
= enumXFFrameYPosFromTop
;
476 eYRel
= enumXFFrameYRelPage
;
480 eYPos
= enumXFFrameYPosFromTop
; //from top
481 eYRel
= enumXFFrameYRelPara
; //from margin
485 case LwpLayoutRelativityGuts::LAY_INLINE
: //in text
487 eXPos
= enumXFFrameXPosFromLeft
; //need not be set
488 eXRel
= enumXFFrameXRelParaContent
; //need not be set
489 eYPos
= enumXFFrameYPosTop
; //should be from top
490 eYRel
= enumXFFrameYRelBaseLine
;
491 sal_Int32 nOffset
= m_pLayout
->GetBaseLineOffset();
494 eYPos
= enumXFFrameYPosFromTop
;
498 case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
: //with para above
500 eXPos
= enumXFFrameXPosFromLeft
;
501 eXRel
= enumXFFrameXRelParaContent
;
502 //eYPos = enumXFFrameYPosTop;
503 eYPos
= enumXFFrameYPosBottom
;
504 eYRel
= enumXFFrameYRelParaContent
;
507 case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL
: //in text - vertical
509 eXPos
= enumXFFrameXPosFromLeft
;
510 eXRel
= enumXFFrameXRelPage
;
511 eYPos
= enumXFFrameYPosFromTop
; //should be below position
512 eYRel
= enumXFFrameYRelChar
;
519 pFrameStyle
->SetXPosType(eXPos
, eXRel
);
520 pFrameStyle
->SetYPosType(eYPos
, eYRel
);
523 * @descr: set frame watermark style
524 * @param: pFrameStyle - Frame Style object
527 void LwpFrame::ApplyWatermark(XFFrameStyle
* pFrameStyle
)
529 std::unique_ptr
<XFBGImage
> xBGImage(m_pLayout
->GetXFBGImage());
532 pFrameStyle
->SetBackImage(xBGImage
);
533 //set watermark transparent
534 rtl::Reference
<LwpVirtualLayout
> xWaterMarkLayout(m_pLayout
->GetWaterMarkLayout());
535 LwpMiddleLayout
* pLay
= dynamic_cast<LwpMiddleLayout
*>(xWaterMarkLayout
.get());
536 LwpBackgroundStuff
* pBackgroundStuff
= pLay
? pLay
->GetBackgroundStuff() : nullptr;
537 if (pBackgroundStuff
&& !pBackgroundStuff
->IsTransparent())
539 pFrameStyle
->SetTransparency(100);
545 * @short Apply pattern fill to frame style
546 * @param pFrameStyle - pointer of XFFrameStyle
549 void LwpFrame::ApplyPatternFill(XFFrameStyle
* pFrameStyle
)
551 std::unique_ptr
<XFBGImage
> xXFBGImage(m_pLayout
->GetFillPattern());
554 pFrameStyle
->SetBackImage(xXFBGImage
);
559 * @short Apply background to frame style
560 * @param pFrameStyle - pointer of XFFrameStyle
563 void LwpFrame::ApplyBackGround(XFFrameStyle
* pFrameStyle
)
570 if (m_pLayout
->IsPatternFill())
572 ApplyPatternFill(pFrameStyle
);
576 ApplyBackColor(pFrameStyle
);
581 * @descr: set frame size, anchor type, anchored page number
582 * @param: pXFFrame - XFFrame object
585 void LwpFrame::ParseAnchorType(XFFrame
* pXFFrame
)
591 enumXFAnchor eAnchor
= enumXFAnchorNone
;
593 LwpLayoutGeometry
* pLayoutGeo
= m_pLayout
->GetGeometry();
596 LwpPoint aPoint
= pLayoutGeo
->GetOrigin();
597 fXOffset
= LwpTools::ConvertFromUnits(aPoint
.GetX());
598 fYOffset
= LwpTools::ConvertFromUnits(aPoint
.GetY());
601 eAnchor
= enumXFAnchorNone
;
602 sal_uInt8 nType
= m_pLayout
->GetRelativeType();
605 case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE
: //fall through
606 case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE
:
608 //anchor to page, frame and cell
609 if (m_pLayout
->IsAnchorPage()) //in page
611 rtl::Reference
<LwpVirtualLayout
> xContainer(m_pLayout
->GetContainerLayout());
612 if (xContainer
.is() && (xContainer
->IsHeader() || xContainer
->IsFooter()))
614 eAnchor
= enumXFAnchorPara
;
615 fYOffset
-= xContainer
->GetMarginsValue(MARGIN_TOP
);
618 eAnchor
= enumXFAnchorPage
;
620 if (m_pLayout
->IsAnchorFrame()) //in frame
622 eAnchor
= enumXFAnchorFrame
;
624 if (m_pLayout
->IsAnchorCell()) //in cell
626 //eAnchor = enumXFAnchorChar;
627 eAnchor
= enumXFAnchorPara
;
628 rtl::Reference
<LwpVirtualLayout
> xContainer(m_pLayout
->GetContainerLayout());
629 LwpMiddleLayout
* pContainer
= dynamic_cast<LwpMiddleLayout
*>(xContainer
.get());
632 fYOffset
-= pContainer
->GetMarginsValue(MARGIN_TOP
);
637 case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE
: //same page as text
639 eAnchor
= enumXFAnchorChar
;
640 rtl::Reference
<LwpVirtualLayout
> xContainer(m_pLayout
->GetContainerLayout());
641 if (xContainer
.is() && xContainer
->IsPage()) //in page
643 //eAnchor = enumXFAnchorPage;
644 eAnchor
= enumXFAnchorChar
; // to character
646 else if (xContainer
.is() && xContainer
->IsFrame()) //in frame
648 eAnchor
= enumXFAnchorFrame
;
650 else if (xContainer
.is() && xContainer
->IsCell()) //in cell
652 //eAnchor = enumXFAnchorChar;
653 eAnchor
= enumXFAnchorPara
;
654 fYOffset
-= xContainer
->GetMarginsValue(MARGIN_TOP
);
656 else if (xContainer
.is()
657 && (xContainer
->IsHeader() || xContainer
->IsFooter())) //in header or footer
659 eAnchor
= enumXFAnchorPara
;
660 fYOffset
-= xContainer
->GetMarginsValue(MARGIN_TOP
);
664 case LwpLayoutRelativityGuts::LAY_INLINE
: //in text
666 eAnchor
= enumXFAnchorAsChar
;
667 sal_Int32 nOffset
= m_pLayout
->GetBaseLineOffset();
668 if (nOffset
> 0 && pLayoutGeo
)
671 fYOffset
= -(m_pLayout
->GetGeometryHeight()
672 + 2 * m_pLayout
->GetExtMarginsValue(MARGIN_BOTTOM
)
673 - LwpTools::ConvertFromUnits(nOffset
));
677 case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
: //with para above
679 eAnchor
= enumXFAnchorPara
;
682 case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL
: //in text - vertical
684 eAnchor
= enumXFAnchorChar
;
685 //set vertical position
688 //because of the different feature between Word Pro and SODC, I simulate the vertical base offset
689 //between anchor and frame origin using the font height.
690 rtl::Reference
<XFFont
> pFont
= m_pLayout
->GetFont();
693 offset
= o3tl::convert
<double>(pFont
->GetFontSize(), o3tl::Length::pt
,
696 fYOffset
= offset
- fYOffset
;
703 pXFFrame
->SetX(fXOffset
);
704 pXFFrame
->SetY(fYOffset
);
705 pXFFrame
->SetAnchorPage(0);
706 pXFFrame
->SetAnchorType(eAnchor
);
710 * @descr Calculate the distance between the frame object and the page margins.
711 * And determine which side(left or right) is wider
713 bool LwpFrame::IsLeftWider()
715 rtl::Reference
<LwpVirtualLayout
> xLayout(m_pLayout
->GetContainerLayout());
716 LwpVirtualLayout
* pParent
= xLayout
.get();
719 LwpPoint aPoint
= m_pLayout
->GetOrigin();
720 double fXOffset
= LwpTools::ConvertFromUnits(aPoint
.GetX());
721 double fWidth
= m_pLayout
->GetWidth();
722 double fWrapLeft
= m_pLayout
->GetExtMarginsValue(MARGIN_LEFT
);
723 double fWrapRight
= m_pLayout
->GetExtMarginsValue(MARGIN_RIGHT
);
725 //LwpPoint aParentPoint = pParent->GetOrigin();
726 //double fParentXOffset = LwpTools::ConvertFromUnitsToMetric(aParentPoint.GetX());
727 double fParentWidth
= pParent
->GetWidth();
728 if (pParent
->IsCell())
730 //Get actual width of this cell layout
731 fParentWidth
= static_cast<LwpCellLayout
*>(pParent
)->GetActualWidth();
733 double fParentMarginLeft
= pParent
->GetMarginsValue(MARGIN_LEFT
);
734 double fParentMarginRight
= pParent
->GetMarginsValue(MARGIN_RIGHT
);
736 double fLeft
= fXOffset
- fWrapLeft
- fParentMarginLeft
;
737 double fRight
= fParentWidth
- fParentMarginRight
- (fXOffset
+ fWidth
+ fWrapRight
);
743 LwpFrameLink::LwpFrameLink() {}
746 * @descr frame link information
749 void LwpFrameLink::Read(LwpObjectStream
* pStrm
)
751 m_PreviousLayout
.ReadIndexed(pStrm
);
752 m_NextLayout
.ReadIndexed(pStrm
);
756 LwpFrameLayout::LwpFrameLayout(LwpObjectHeader
const& objHdr
, LwpSvStream
* pStrm
)
757 : LwpPlacableLayout(objHdr
, pStrm
)
758 , m_bGettingMaxWidth(false)
762 LwpFrameLayout::~LwpFrameLayout() {}
765 * @descr read frame layout object
768 void LwpFrameLayout::Read()
770 LwpPlacableLayout::Read();
771 if (LwpFileHeader::m_nFileRevision
>= 0x000B)
773 if (m_pObjStrm
->QuickReaduInt16())
775 m_Link
.Read(m_pObjStrm
.get());
778 m_pObjStrm
->SkipExtra();
782 * @descr create a xfframe and add into content container
783 * @param: pCont - content container that contains the frame.
786 void LwpFrameLayout::XFConvert(XFContentContainer
* pCont
)
791 //parse the frame which anchor to paragraph
792 if (IsRelativeAnchored())
794 XFConvertFrame(pCont
);
798 m_pFrame
->XFConvert(pCont
);
802 * @descr create a xfframe and add into content container, called by XFConvert
803 * @param: pCont - content container that contains the frame.
804 * @param: nPageNo - the page number that the frame anchors
807 void LwpFrameLayout::XFConvertFrame(XFContentContainer
* pCont
, sal_Int32 nStart
, sal_Int32 nEnd
,
813 rtl::Reference
<XFFrame
> xXFFrame
;
816 xXFFrame
.set(new XFFrame
);
820 xXFFrame
.set(new XFFloatFrame(nStart
, nEnd
, bAll
));
823 m_pFrame
->Parse(xXFFrame
.get(), nStart
);
824 //if it is a link frame, parse contents only once
825 if (!HasPreviousLinkLayout())
827 rtl::Reference
<LwpObject
> content
= m_Content
.obj();
830 content
->DoXFConvert(xXFFrame
.get());
831 //set frame size according to ole size
832 ApplyGraphicSize(xXFFrame
.get());
835 pCont
->Add(xXFFrame
.get());
838 * @descr register frame style
841 void LwpFrameLayout::RegisterStyle()
843 //if it is for water mark, don't register style
844 if (IsForWaterMark())
850 //register frame style
851 std::unique_ptr
<XFFrameStyle
> xFrameStyle(new XFFrameStyle
);
852 m_pFrame
.reset(new LwpFrame(this));
853 m_pFrame
->RegisterStyle(xFrameStyle
);
855 //register content style
856 rtl::Reference
<LwpObject
> content
= m_Content
.obj();
859 content
->SetFoundry(m_pFoundry
);
860 content
->DoRegisterStyle();
863 //register child frame style
864 RegisterChildStyle();
868 * @descr get the name of the frame that current frame links
871 OUString
LwpFrameLayout::GetNextLinkName()
874 LwpObjectID
& rObjectID
= m_Link
.GetNextLayout();
875 if (!rObjectID
.IsNull())
877 LwpLayout
* pLayout
= dynamic_cast<LwpLayout
*>(rObjectID
.obj().get());
880 LwpAtomHolder
& rHolder
= pLayout
->GetName();
881 aName
= rHolder
.str();
882 //for division name conflict
883 if (!pLayout
->GetStyleName().isEmpty())
884 aName
= pLayout
->GetStyleName();
890 * @descr whether current frame is linked by other frame
893 bool LwpFrameLayout::HasPreviousLinkLayout()
895 LwpObjectID
& rObjectID
= m_Link
.GetPreviousLayout();
896 return !rObjectID
.IsNull();
899 * @descr whether current frame is for water mark. Problem maybe exists by this method, must be tracking
902 bool LwpFrameLayout::IsForWaterMark()
904 if (m_nBuoyancy
>= LAY_BUOYLAYER
)
906 if (m_Content
.IsNull())
908 rtl::Reference
<LwpObject
> content
= m_Content
.obj();
911 if (content
->GetTag() == VO_GRAPHIC
)
918 * @descr Get frame width
921 double LwpFrameLayout::GetWidth()
923 double fWidth
= LwpMiddleLayout::GetWidth();
924 if (IsInlineToMargin() && IsAutoGrowWidth())
926 //for text field entry when choosing maximize field length
927 fWidth
= GetMaxWidth();
933 * @descr Get frame width when the text field chooses maximize field length
936 double LwpFrameLayout::GetMaxWidth()
938 if (m_bGettingMaxWidth
)
939 throw std::runtime_error("recursive GetMaxWidth");
941 m_bGettingMaxWidth
= true;
942 double fActualWidth
= 0;
943 rtl::Reference
<LwpVirtualLayout
> xLayout(GetContainerLayout());
944 LwpMiddleLayout
* pParent
= dynamic_cast<LwpMiddleLayout
*>(xLayout
.get());
947 LwpPoint aPoint
= GetOrigin();
948 double fXOffset
= LwpTools::ConvertFromUnits(aPoint
.GetX());
949 double fWrapRight
= GetExtMarginsValue(MARGIN_RIGHT
);
951 //Get parent layout width
952 double fParentWidth
= pParent
->GetWidth();
953 if (pParent
->IsCell())
955 //Get actual width of this cell layout
956 fParentWidth
= static_cast<LwpCellLayout
*>(pParent
)->GetActualWidth();
959 double fParentMarginRight
= 0;
960 sal_uInt8 nType
= GetRelativeType();
961 if (nType
== LwpLayoutRelativityGuts::LAY_INLINE
962 || nType
== LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE
)
964 fParentMarginRight
= pParent
->GetMarginsValue(MARGIN_RIGHT
);
967 fActualWidth
= fParentWidth
- fXOffset
- fParentMarginRight
- fWrapRight
;
970 m_bGettingMaxWidth
= false;
975 * @descr Set frame size according to graphic size
978 void LwpFrameLayout::ApplyGraphicSize(XFFrame
* pXFFrame
)
980 rtl::Reference
<LwpObject
> content
= m_Content
.obj();
981 if (!(content
.is() && (content
->GetTag() == VO_GRAPHIC
|| content
->GetTag() == VO_OLEOBJECT
)))
984 LwpGraphicOleObject
* pGraOle
= static_cast<LwpGraphicOleObject
*>(content
.get());
985 //Get frame geometry size
988 pGraOle
->GetGrafScaledSize(fWidth
, fHeight
);
992 fWidth
+= GetMarginsValue(MARGIN_LEFT
) + GetMarginsValue(MARGIN_RIGHT
);
993 fHeight
+= GetMarginsValue(MARGIN_TOP
) + GetMarginsValue(MARGIN_BOTTOM
);
995 else if (IsAutoGrowDown() || IsAutoGrowUp())
998 fHeight
+= GetMarginsValue(MARGIN_TOP
) + GetMarginsValue(MARGIN_BOTTOM
);
1000 else if (IsAutoGrowLeft() || IsAutoGrowRight())
1002 fHeight
= GetHeight();
1003 fWidth
+= GetMarginsValue(MARGIN_LEFT
) + GetMarginsValue(MARGIN_RIGHT
);
1007 fWidth
= GetWidth();
1008 fHeight
= GetHeight();
1010 pXFFrame
->SetWidth(fWidth
);
1011 pXFFrame
->SetHeight(fHeight
);
1014 LwpGroupLayout::LwpGroupLayout(LwpObjectHeader
const& objHdr
, LwpSvStream
* pStrm
)
1015 : LwpPlacableLayout(objHdr
, pStrm
)
1019 LwpGroupLayout::~LwpGroupLayout() {}
1021 * @descr read group layout object
1024 void LwpGroupLayout::Read()
1026 LwpPlacableLayout::Read();
1027 m_pObjStrm
->SkipExtra();
1030 * @descr register group frame style
1033 void LwpGroupLayout::RegisterStyle()
1038 //register frame style
1039 std::unique_ptr
<XFFrameStyle
> xFrameStyle(new XFFrameStyle
);
1040 m_pFrame
.reset(new LwpFrame(this));
1041 m_pFrame
->RegisterStyle(xFrameStyle
);
1043 //register child frame style
1044 RegisterChildStyle();
1047 * @descr create a xfframe and add into content container
1048 * @param: pCont - content container that contains the frame.
1051 void LwpGroupLayout::XFConvert(XFContentContainer
* pCont
)
1056 //parse the frame which anchor to paragraph
1057 if (IsRelativeAnchored())
1059 XFConvertFrame(pCont
);
1063 m_pFrame
->XFConvert(pCont
);
1067 * @descr create a xfframe and add into content container, called by XFConvert
1068 * @param: pCont - content container that contains the frame.
1069 * @param: nPageNo - the page number that the frame anchors
1072 void LwpGroupLayout::XFConvertFrame(XFContentContainer
* pCont
, sal_Int32 nStart
, sal_Int32 nEnd
,
1078 rtl::Reference
<XFFrame
> xXFFrame
;
1081 xXFFrame
.set(new XFFrame
);
1085 xXFFrame
.set(new XFFloatFrame(nStart
, nEnd
, bAll
));
1088 m_pFrame
->Parse(xXFFrame
.get(), nStart
);
1090 //add child frame into group
1091 LwpVirtualLayout
* pLayout
= dynamic_cast<LwpVirtualLayout
*>(GetChildHead().obj().get());
1093 while (pLayout
&& pLayout
!= this)
1095 pLayout
->DoXFConvert(xXFFrame
.get());
1096 pLayout
= dynamic_cast<LwpVirtualLayout
*>(pLayout
->GetNext().obj().get());
1099 pCont
->Add(xXFFrame
.get());
1102 LwpGroupFrame::LwpGroupFrame(LwpObjectHeader
const& objHdr
, LwpSvStream
* pStrm
)
1103 : LwpContent(objHdr
, pStrm
)
1107 LwpGroupFrame::~LwpGroupFrame() {}
1109 void LwpGroupFrame::Read()
1112 m_pObjStrm
->SkipExtra();
1115 void LwpGroupFrame::RegisterStyle() {}
1117 void LwpGroupFrame::XFConvert(XFContentContainer
* /*pCont*/) {}
1119 LwpDropcapLayout::LwpDropcapLayout(LwpObjectHeader
const& objHdr
, LwpSvStream
* pStrm
)
1120 : LwpFrameLayout(objHdr
, pStrm
)
1126 void LwpDropcapLayout::Read()
1128 LwpFrameLayout::Read();
1129 m_nLines
= m_pObjStrm
->QuickReaduInt16();
1130 m_pObjStrm
->SeekRel(1);
1131 m_pObjStrm
->SkipExtra();
1134 void LwpDropcapLayout::Parse(IXFStream
* pOutputStream
)
1136 LwpStory
* pStory
= static_cast<LwpStory
*>(m_Content
.obj(VO_STORY
).get());
1139 rtl::Reference
<LwpObject
> pPara
= pStory
->GetFirstPara().obj(VO_PARA
);
1142 pPara
->SetFoundry(m_pFoundry
);
1143 pPara
->DoParse(pOutputStream
);
1147 void LwpDropcapLayout::XFConvert(XFContentContainer
* pCont
)
1149 LwpStory
* pStory
= static_cast<LwpStory
*>(m_Content
.obj(VO_STORY
).get());
1152 pStory
->SetFoundry(m_pFoundry
);
1153 pStory
->XFConvert(pCont
);
1157 void LwpDropcapLayout::RegisterStyle(LwpFoundry
* pFoundry
)
1159 LwpStory
* pStory
= dynamic_cast<LwpStory
*>(m_Content
.obj(VO_STORY
).get());
1162 pStory
->SetDropcapFlag(true);
1163 pStory
->SetFoundry(pFoundry
);
1164 LwpPara
* pPara
= dynamic_cast<LwpPara
*>(pStory
->GetFirstPara().obj().get());
1167 pPara
->SetFoundry(pFoundry
);
1168 pPara
->RegisterStyle();
1169 pPara
= dynamic_cast<LwpPara
*>(pPara
->GetNext().obj().get());
1178 void LwpDropcapLayout::RegisterStyle() {}
1180 LwpRubyLayout::LwpRubyLayout(LwpObjectHeader
const& objHdr
, LwpSvStream
* pStrm
)
1181 : LwpFrameLayout(objHdr
, pStrm
)
1190 void LwpRubyLayout::Read()
1192 LwpFrameLayout::Read();
1193 m_nPlacement
= m_pObjStrm
->QuickReaduInt8();
1194 m_nAlignment
= m_pObjStrm
->QuickReaduInt8();
1195 m_nStateFlag
= m_pObjStrm
->QuickReaduInt16();
1196 m_nXOffset
= m_pObjStrm
->QuickReadInt32();
1197 m_nYOffset
= m_pObjStrm
->QuickReadInt32();
1198 m_objRubyMarker
.ReadIndexed(m_pObjStrm
.get());
1199 m_pObjStrm
->SkipExtra();
1202 LwpRubyMarker
* LwpRubyLayout::GetMarker()
1204 return static_cast<LwpRubyMarker
*>(m_objRubyMarker
.obj(VO_RUBYMARKER
).get());
1207 LwpStory
* LwpRubyLayout::GetContentStory()
1209 return static_cast<LwpStory
*>(m_Content
.obj(VO_STORY
).get());
1212 void LwpRubyLayout::ConvertContentText()
1214 LwpStory
* pStory
= GetContentStory();
1215 LwpRubyMarker
* pMarker
= GetMarker();
1216 if (pStory
&& pMarker
)
1217 pMarker
->SetRubyText(pStory
->GetContentText(true));
1220 void LwpRubyLayout::RegisterStyle()
1222 LwpRubyMarker
* pMarker
= GetMarker();
1224 throw std::runtime_error("missing Ruby Marker");
1226 std::unique_ptr
<XFRubyStyle
> xRubyStyle(new XFRubyStyle
);
1228 enumXFRubyPosition eType
= enumXFRubyLeft
;
1229 if (m_nAlignment
== LEFT
)
1231 eType
= enumXFRubyLeft
;
1233 else if (m_nAlignment
== RIGHT
)
1235 eType
= enumXFRubyRight
;
1237 else if (m_nAlignment
== CENTER
)
1239 eType
= enumXFRubyCenter
;
1241 xRubyStyle
->SetAlignment(eType
);
1243 eType
= enumXFRubyTop
;
1244 if (m_nPlacement
== TOP
)
1246 eType
= enumXFRubyTop
;
1248 else if (m_nPlacement
== BOTTOM
)
1250 eType
= enumXFRubyBottom
;
1252 xRubyStyle
->SetPosition(eType
);
1254 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1255 OUString rubyStyle
= pXFStyleManager
->AddStyle(std::move(xRubyStyle
)).m_pStyle
->GetStyleName();
1256 pMarker
->SetRubyStyleName(rubyStyle
);
1258 LwpStory
* pStory
= GetContentStory();
1259 pStory
->SetFoundry(m_pFoundry
);
1260 OUString textStyle
= pStory
->RegisterFirstFribStyle();
1261 pMarker
->SetTextStyleName(textStyle
);
1264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */