Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / lotuswordpro / source / filter / lwpframelayout.cxx
blob7f593e4a2cd713d3d65c244d1f8f6461394ebd8a
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,
29 * MA 02111-1307 USA
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 /*************************************************************************
57 * @file
58 * the class for VO_FrameLayout
59 ************************************************************************/
61 #include "lwpframelayout.hxx"
62 #include "lwppara.hxx"
63 #include "xfilter/xfstylemanager.hxx"
64 #include "xfilter/xfparagraph.hxx"
65 #include "xfilter/xffloatframe.hxx"
66 #include "xfilter/xfrubystyle.hxx"
67 #include "lwppagelayout.hxx"
68 #include "lwpoleobject.hxx"
69 #include "lwptablelayout.hxx"
70 #include "lwpgrfobj.hxx"
71 #include "lwpglobalmgr.hxx"
73 LwpFrame::LwpFrame(LwpPlacableLayout* pLayout):m_pLayout(pLayout)
77 LwpFrame::~LwpFrame()
80 /**
81 * @descr: parse frame
82 * @param: register frame style
83 * @param: pFrameStyle - Frame Style object
86 void LwpFrame::RegisterStyle(XFFrameStyle* pFrameStyle)
88 ApplyWrapType(pFrameStyle);
89 ApplyMargins(pFrameStyle);
90 ApplyPadding(pFrameStyle);
91 ApplyBorders(pFrameStyle);
92 ApplyColumns(pFrameStyle);
93 ApplyShadow(pFrameStyle);
94 ApplyBackGround(pFrameStyle);
95 ApplyWatermark(pFrameStyle);
96 // ApplyBackColor(pFrameStyle);
97 ApplyProtect(pFrameStyle);
98 ApplyTextDir(pFrameStyle);
99 ApplyPosType(pFrameStyle);
101 pFrameStyle->SetStyleName(m_pLayout->GetName().str());
102 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
103 m_StyleName = pXFStyleManager->AddStyle(pFrameStyle).m_pStyle->GetStyleName();
104 m_pLayout->SetStyleName(m_StyleName);
107 * @descr: parse frame and set frame properties
108 * @param: pXFFrame - XFFrame object
109 * @param: nPageNo - the page number that the frame anchors
112 void LwpFrame::Parse(XFFrame* pXFFrame, sal_Int32 nPageNo)
114 //set the frame style name
115 pXFFrame->SetStyleName(m_StyleName);
117 //SetAnchorType and position,if it's page anchor,set the page number.
118 ParseAnchorType(pXFFrame);
119 if(nPageNo>0)
121 pXFFrame->SetAnchorPage(nPageNo);
124 //Set frame Name
125 OUString aFrameName = m_pLayout->GetName().str();
126 if(!aFrameName.isEmpty())
128 //cause the bug of SODC, the linkframe name can not be "Frame1", so I change the frame name
129 /*if(aFrameName.equals("Frame1"))
131 aFrameName = "Frame1_COPY";
133 pXFFrame->SetName(aFrameName);*/
134 pXFFrame->SetName(m_StyleName);
137 LwpLayoutGeometry* pLayoutGeo = m_pLayout->GetGeometry();
138 //Set frame Width and height
139 if(pLayoutGeo)
141 double fWidth = m_pLayout->GetWidth();
142 double fHeight = m_pLayout->GetHeight();
144 pXFFrame->SetWidth( fWidth );
145 pXFFrame->SetHeight( fHeight );
147 //Get content obj;
148 /*LwpObject* pObj =*/ m_pLayout->GetContent().obj();
149 if(m_pLayout->IsGroupHead()&&(m_pLayout->IsMinimumHeight()))
151 //process grouplayout height. there is problems now
152 pXFFrame->SetHeight( fHeight );
155 else if(m_pLayout->IsFitGraphic() && pObj && pObj->GetTag() == VO_GRAPHIC)
157 //If is graphic, get original size and set it;
158 LwpGraphicObject* pGrpObj = static_cast<LwpGraphicObject*>(pObj);
159 long nHeight =0, nWidth =0;
160 pGrpObj->GetGrafOrgSize(nWidth, nHeight);
161 //add margins to the width and height;
162 fWidth = (double)nWidth/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_LEFT) + m_pLayout->GetMarginsValue(MARGIN_RIGHT);
163 fHeight = (double)nHeight/TWIPS_PER_CM + m_pLayout->GetMarginsValue(MARGIN_TOP) + m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
164 pXFFrame->SetWidth(fWidth);
165 pXFFrame->SetHeight(fHeight);
168 else if(m_pLayout->IsAutoGrow())
170 pXFFrame->SetMinHeight( fHeight );
174 if(m_pLayout->IsFrame())
176 //Set frame link. Only frame layout has this feature
177 LwpFrameLayout* pLayout= static_cast<LwpFrameLayout*>(m_pLayout);
178 pXFFrame->SetNextLink(pLayout->GetNextLinkName());
183 * @descr: parse frame relative to page, frame or cell
184 * @param: pCont - content container which contains the frame
187 void LwpFrame::XFConvert(XFContentContainer* pCont)
189 // parse the frame which anchor to page
190 rtl::Reference<LwpVirtualLayout> xParent = m_pLayout->GetParentLayout();
191 if (!xParent.is())
192 throw std::runtime_error("missing Parent Layout");
193 if (xParent->IsPage() && xParent->GetParentLayout().is() && xParent->GetParentLayout()->IsPage())
195 //for mirror page, problems exist if the parent layout is header or footer layout,
196 xParent = xParent->GetParentLayout();
198 if(m_pLayout->IsAnchorPage()&& xParent->IsPage())
200 //get parent layout
201 if(m_pLayout->IsUseOnPage())
203 sal_Int32 nPageNo = xParent->GetPageNumber(m_pLayout->GetUsePage());
204 if(nPageNo>0)
205 m_pLayout->XFConvertFrame(pCont, nPageNo);
207 else if(m_pLayout->IsUseOnAllPages())
209 sal_Int32 nFirst = xParent->GetPageNumber(FIRST_LAYOUTPAGENO);
210 sal_Int32 nLast = xParent->GetPageNumber(LAST_LAYOUTPAGENO);
211 if(nLast > 0)
212 m_pLayout->XFConvertFrame(pCont, nFirst, nLast, true);
215 else if(m_pLayout->IsUseOnAllOddPages()||m_pLayout->IsUseOnAllEvenPages())
217 sal_Int32 nFirst = xParent->GetPageNumber(FIRST_LAYOUTPAGENO);
218 sal_Int32 nLast = xParent->GetPageNumber(LAST_LAYOUTPAGENO);
219 if(nLast > 0)
221 sal_uInt16 first = static_cast<sal_uInt16>(nFirst);
222 if((m_pLayout->IsUseOnAllOddPages() && !LwpTools::IsOddNumber(first))
223 || (m_pLayout->IsUseOnAllEvenPages() && !LwpTools::IsEvenNumber(first)))
224 nFirst++;
225 if(nFirst <= nLast)
227 m_pLayout->XFConvertFrame(pCont, nFirst, nLast);
232 else
234 m_pLayout->XFConvertFrame(pCont);
239 * @descr: set frame wrap type style
240 * @param: pFrameStyle - Frame Style object
243 void LwpFrame::ApplyWrapType(XFFrameStyle *pFrameStyle)
245 enumXFWrap eWrap = enumXFWrapNone;
246 switch(m_pLayout->GetWrapType())
248 case LwpPlacableLayout::LAY_WRAP_AROUND: //fall through
249 case LwpPlacableLayout::LAY_WRAP_IRREG_BIGGEST:
251 //In SODC, if Optimal wrap type is used and the distance between the frame object
252 //and page margins is less than 2cm, the text is not wrapped. While there is no this feature in Word Pro
253 //So the optimal wrap type is translated to left side or right side wrap type according to the distance
254 //between the frame object and page margins
256 eWrap = enumXFWrapBest;
257 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
258 LwpMiddleLayout* pParent = dynamic_cast<LwpMiddleLayout*>(xContainer.get());
259 if(pParent)
261 if(IsLeftWider())
262 eWrap = enumXFWrapLeft;
263 else
264 eWrap = enumXFWrapRight;
266 break;
268 case LwpPlacableLayout::LAY_NO_WRAP_BESIDE:
270 eWrap = enumXFWrapNone;
271 break;
273 case LwpPlacableLayout::LAY_NO_WRAP_AROUND:
275 eWrap = enumXFWrapRunThrough;
276 if(!m_pLayout->GetBackColor() && !m_pLayout->GetWaterMarkLayout().is())
278 //pFrameStyle->SetBackGround(sal_True);
279 XFColor aXFColor(0xffffff); //white color
280 pFrameStyle->SetBackColor(aXFColor);
281 pFrameStyle->SetTransparency(100); //transparency
283 break;
285 case LwpPlacableLayout::LAY_WRAP_LEFT: //fall through
286 case LwpPlacableLayout::LAY_WRAP_IRREG_LEFT:
288 eWrap = enumXFWrapLeft;
289 break;
291 case LwpPlacableLayout::LAY_WRAP_RIGHT: //fall through
292 case LwpPlacableLayout::LAY_WRAP_IRREG_RIGHT:
294 eWrap = enumXFWrapRight;
295 break;
297 case LwpPlacableLayout::LAY_WRAP_BOTH: //fall through
298 case LwpPlacableLayout::LAY_WRAP_IRREG_BOTH:
300 eWrap = enumXFWrapParallel;
301 break;
303 default:
304 break;
307 //If it is the type of with para above, wrap type is enumXFWrapNone
308 if(m_pLayout->GetRelativeType()==LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE)
310 eWrap = enumXFWrapNone;
313 pFrameStyle->SetWrapType(eWrap);
316 * @descr: set frame margins style
317 * @param: pFrameStyle - Frame Style object
320 void LwpFrame::ApplyMargins(XFFrameStyle *pFrameStyle)
322 double fLeft = m_pLayout->GetExtMarginsValue(MARGIN_LEFT);
323 double fRight = m_pLayout->GetExtMarginsValue(MARGIN_RIGHT);
324 double fTop = m_pLayout->GetExtMarginsValue(MARGIN_TOP);
325 double fBottom = m_pLayout->GetExtMarginsValue(MARGIN_BOTTOM);
326 pFrameStyle->SetMargins(fLeft,fRight,fTop,fBottom);
329 * @descr: set padding border style
330 * @param: pFrameStyle - Frame Style object
333 void LwpFrame::ApplyPadding(XFFrameStyle *pFrameStyle)
335 double fLeft = m_pLayout->GetMarginsValue(MARGIN_LEFT);
336 double fRight = m_pLayout->GetMarginsValue(MARGIN_RIGHT);
337 double fTop = m_pLayout->GetMarginsValue(MARGIN_TOP);
338 double fBottom = m_pLayout->GetMarginsValue(MARGIN_BOTTOM);
339 pFrameStyle->SetPadding(fLeft,fRight,fTop,fBottom);
342 * @descr: set frame border style
343 * @param: pFrameStyle - Frame Style object
346 void LwpFrame::ApplyBorders(XFFrameStyle *pFrameStyle)
348 XFBorders* pBordres = m_pLayout->GetXFBorders();
349 if(pBordres)
351 pFrameStyle->SetBorders(pBordres);
355 * @descr: set frame columns style
356 * @param: pFrameStyle - Frame Style object
359 void LwpFrame::ApplyColumns(XFFrameStyle *pFrameStyle)
361 XFColumns* pColumns = m_pLayout->GetXFColumns();
362 if(pColumns)
364 pFrameStyle->SetColumns(pColumns);
368 * @descr: set frame shadow style
369 * @param: pFrameStyle - Frame Style object
372 void LwpFrame::ApplyShadow(XFFrameStyle* pFrameStyle)
374 XFShadow* pXFShadow = m_pLayout->GetXFShadow();
375 if(pXFShadow)
377 pFrameStyle->SetShadow(pXFShadow);
381 * @descr: set frame back color style
382 * @param: pFrameStyle - Frame Style object
385 void LwpFrame::ApplyBackColor(XFFrameStyle* pFrameStyle)
387 LwpColor* pColor = m_pLayout->GetBackColor();
388 if(pColor)
390 XFColor aXFColor(pColor->To24Color());
391 pFrameStyle->SetBackColor(aXFColor);
395 * @descr: set frame protect style
396 * @param: pFrameStyle - Frame Style object
399 void LwpFrame::ApplyProtect(XFFrameStyle* pFrameStyle)
401 if(m_pLayout->GetIsProtected())
403 pFrameStyle->SetProtect(true,true,true);
407 * @descr: set frame text direction style
408 * @param: pFrameStyle - Frame Style object
411 void LwpFrame::ApplyTextDir(XFFrameStyle* pFrameStyle)
413 pFrameStyle->SetTextDir(m_pLayout->GetTextDirection());
416 * @descr: set frame position type style
417 * @param: pFrameStyle - Frame Style object
420 void LwpFrame::ApplyPosType(XFFrameStyle* pFrameStyle)
422 enumXFFrameXPos eXPos = enumXFFrameXPosCenter;
423 enumXFFrameXRel eXRel = enumXFFrameXRelPara;
424 enumXFFrameYPos eYPos = enumXFFrameYPosMiddle;
425 enumXFFrameYRel eYRel = enumXFFrameYRelPara;
426 sal_uInt8 nType = m_pLayout->GetRelativeType();
427 switch(nType)
429 case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE://fall through
430 case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE:
432 //anchor to page, frame and cell
433 eXPos = enumXFFrameXPosFromLeft;
434 eXRel = enumXFFrameXRelPage;
435 //set vertical position
436 if(m_pLayout->IsAnchorPage())//in page
438 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
439 if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))
441 //Only anchor to para, the frame can display in header and footer of each page
442 eYPos = enumXFFrameYPosFromTop; //from top
443 eYRel = enumXFFrameYRelPara; //from margin
445 else
447 eYPos = enumXFFrameYPosFromTop;
448 eYRel = enumXFFrameYRelPage;
451 if(m_pLayout->IsAnchorFrame()) //in frame
453 eYPos = enumXFFrameYPosFromTop;
454 eYRel = enumXFFrameYRelPage;
456 if(m_pLayout->IsAnchorCell())
458 //SODC has no this type, simulate this feature
459 eYPos = enumXFFrameYPosFromTop; //from top
460 eYRel = enumXFFrameYRelPara; //from margin
462 break;
464 case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text
466 eXPos = enumXFFrameXPosFromLeft;
467 eXRel = enumXFFrameXRelPage;
468 //set vertical position
469 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
470 if (xContainer.is() && xContainer->IsPage())//in page
472 //eYPos = enumXFFrameYPosFromTop;
473 //eYRel = enumXFFrameYRelPage;
474 eYPos = enumXFFrameYPosBelow;
475 eYRel = enumXFFrameYRelChar;
477 else if (xContainer.is() && xContainer->IsFrame()) //in frame
479 eYPos = enumXFFrameYPosFromTop;
480 eYRel = enumXFFrameYRelPage;
482 else
484 eYPos = enumXFFrameYPosFromTop; //from top
485 eYRel = enumXFFrameYRelPara; //from margin
487 break;
489 case LwpLayoutRelativityGuts::LAY_INLINE: //in text
491 eXPos = enumXFFrameXPosFromLeft; //need not be set
492 eXRel = enumXFFrameXRelParaContent; //need not be set
493 eYPos = enumXFFrameYPosTop; //should be from top
494 eYRel = enumXFFrameYRelBaseLine;
495 sal_Int32 nOffset = m_pLayout->GetBaseLineOffset();
496 if(nOffset>0)
498 eYPos = enumXFFrameYPosFromTop;
500 break;
502 case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE: //with para above
504 eXPos = enumXFFrameXPosFromLeft;
505 eXRel = enumXFFrameXRelParaContent;
506 //eYPos = enumXFFrameYPosTop;
507 eYPos = enumXFFrameYPosBottom;
508 eYRel = enumXFFrameYRelParaContent;
509 break;
511 case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL: //in text - vertical
513 eXPos = enumXFFrameXPosFromLeft;
514 eXRel = enumXFFrameXRelPage;
515 eYPos = enumXFFrameYPosFromTop; //should be below position
516 eYRel = enumXFFrameYRelChar;
517 break;
519 default:
520 break;
523 pFrameStyle->SetXPosType(eXPos,eXRel);
524 pFrameStyle->SetYPosType(eYPos,eYRel);
527 * @descr: set frame watermark style
528 * @param: pFrameStyle - Frame Style object
531 void LwpFrame::ApplyWatermark(XFFrameStyle *pFrameStyle)
533 XFBGImage* pBGImage = m_pLayout->GetXFBGImage();
534 if(pBGImage)
536 pFrameStyle->SetBackImage(pBGImage);
537 //set watermark transparent
538 rtl::Reference<LwpVirtualLayout> xWaterMarkLayout(m_pLayout->GetWaterMarkLayout());
539 LwpMiddleLayout* pLay = dynamic_cast<LwpMiddleLayout*>(xWaterMarkLayout.get());
540 LwpBackgroundStuff* pBackgroundStuff = pLay ? pLay->GetBackgroundStuff() : nullptr;
541 if(pBackgroundStuff && !pBackgroundStuff->IsTransparent())
543 pFrameStyle->SetTransparency(100);
549 * @short Apply pattern fill to frame style
550 * @param pFrameStyle - pointer of XFFrameStyle
551 * @return
553 void LwpFrame::ApplyPatternFill(XFFrameStyle* pFrameStyle)
555 XFBGImage* pXFBGImage = m_pLayout->GetFillPattern();
556 if (pXFBGImage)
558 pFrameStyle->SetBackImage(pXFBGImage);
563 * @short Apply background to frame style
564 * @param pFrameStyle - pointer of XFFrameStyle
565 * @return
567 void LwpFrame::ApplyBackGround(XFFrameStyle* pFrameStyle)
569 if (!m_pLayout)
571 return;
574 if (m_pLayout->IsPatternFill())
576 ApplyPatternFill(pFrameStyle);
578 else
580 ApplyBackColor(pFrameStyle);
585 * @descr: set frame size, anchor type, anchored page number
586 * @param: pXFFrame - XFFrame object
589 void LwpFrame::ParseAnchorType(XFFrame *pXFFrame)
591 //set position
592 double fXOffset = 0;
593 double fYOffset = 0;
594 //page number
595 sal_uInt16 nPageNum = 0;
596 //set anchor type
597 enumXFAnchor eAnchor = enumXFAnchorNone;
599 LwpLayoutGeometry* pLayoutGeo = m_pLayout->GetGeometry();
600 if(pLayoutGeo)
602 LwpPoint aPoint = pLayoutGeo->GetOrigin();
603 fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
604 fYOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetY());
606 //set anchor type
607 eAnchor = enumXFAnchorNone;
608 sal_uInt8 nType = m_pLayout->GetRelativeType();
609 switch(nType)
611 case LwpLayoutRelativityGuts::LAY_PARENT_RELATIVE://fall through
612 case LwpLayoutRelativityGuts::LAY_CONTENT_RELATIVE:
614 //anchor to page, frame and cell
615 if(m_pLayout->IsAnchorPage())//in page
617 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
618 if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))
620 eAnchor = enumXFAnchorPara;
621 fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
623 else
624 eAnchor = enumXFAnchorPage;
626 if(m_pLayout->IsAnchorFrame()) //in frame
628 eAnchor = enumXFAnchorFrame;
630 if(m_pLayout->IsAnchorCell()) //in cell
632 //eAnchor = enumXFAnchorChar;
633 eAnchor = enumXFAnchorPara;
634 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
635 LwpMiddleLayout* pContainer = dynamic_cast<LwpMiddleLayout*>(xContainer.get());
636 if (pContainer)
638 fYOffset -= pContainer->GetMarginsValue(MARGIN_TOP);
641 break;
643 case LwpLayoutRelativityGuts::LAY_PARA_RELATIVE: //same page as text
645 eAnchor = enumXFAnchorChar;
646 rtl::Reference<LwpVirtualLayout> xContainer(m_pLayout->GetContainerLayout());
647 if (xContainer.is() && xContainer->IsPage())//in page
649 //eAnchor = enumXFAnchorPage;
650 eAnchor = enumXFAnchorChar;// to character
652 else if (xContainer.is() && xContainer->IsFrame()) //in frame
654 eAnchor = enumXFAnchorFrame;
656 else if (xContainer.is() && xContainer->IsCell()) //in cell
658 //eAnchor = enumXFAnchorChar;
659 eAnchor = enumXFAnchorPara;
660 fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
662 else if (xContainer.is() && (xContainer->IsHeader() || xContainer->IsFooter()))//in header or footer
664 eAnchor = enumXFAnchorPara;
665 fYOffset -= xContainer->GetMarginsValue(MARGIN_TOP);
667 break;
669 case LwpLayoutRelativityGuts::LAY_INLINE: //in text
671 eAnchor = enumXFAnchorAsChar;
672 sal_Int32 nOffset = m_pLayout->GetBaseLineOffset();
673 if(nOffset>0 && pLayoutGeo)
675 //experiential value
676 fYOffset =-(m_pLayout->GetGeometryHeight()+2*m_pLayout->GetExtMarginsValue(MARGIN_BOTTOM)-LwpTools::ConvertFromUnitsToMetric(nOffset));
678 break;
680 case LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE: //with para above
682 eAnchor = enumXFAnchorPara;
683 break;
685 case LwpLayoutRelativityGuts::LAY_INLINE_VERTICAL: //in text - vertical
687 eAnchor = enumXFAnchorChar;
688 //set vertical position
689 double offset = 0;
691 //because of the different feature between Word Pro and SODC, I simulate the vertical base offset
692 //between anchor and frame origin using the font height.
693 rtl::Reference<XFFont> pFont = m_pLayout->GetFont();
694 if(pFont.is())
696 offset = (double)(pFont->GetFontSize())*CM_PER_INCH/POINTS_PER_INCH;
698 fYOffset = offset-fYOffset;
699 break;
701 default:
702 break;
705 pXFFrame->SetX(fXOffset);
706 pXFFrame->SetY(fYOffset);
707 pXFFrame->SetAnchorPage(nPageNum);
708 pXFFrame->SetAnchorType(eAnchor);
712 * @descr Calculate the distance between the frame object and the page margins.
713 * And determine which side(left or right) is wider
715 bool LwpFrame::IsLeftWider()
717 rtl::Reference<LwpVirtualLayout> xLayout(m_pLayout->GetContainerLayout());
718 LwpVirtualLayout* pParent = dynamic_cast<LwpVirtualLayout*>(xLayout.get());
719 if (pParent)
721 LwpPoint aPoint = m_pLayout->GetOrigin();
722 double fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
723 double fWidth = m_pLayout->GetWidth();
724 double fWrapLeft = m_pLayout->GetExtMarginsValue(MARGIN_LEFT);
725 double fWrapRight = m_pLayout->GetExtMarginsValue(MARGIN_RIGHT);
727 //LwpPoint aParentPoint = pParent->GetOrigin();
728 //double fParentXOffset = LwpTools::ConvertFromUnitsToMetric(aParentPoint.GetX());
729 double fParentWidth = pParent->GetWidth();
730 if(pParent->IsCell())
732 //Get actual width of this cell layout
733 fParentWidth = static_cast<LwpCellLayout*>(pParent)->GetActualWidth();
735 double fParentMarginLeft = pParent->GetMarginsValue(MARGIN_LEFT);
736 double fParentMarginRight = pParent->GetMarginsValue(MARGIN_RIGHT);
738 double fLeft = fXOffset - fWrapLeft -fParentMarginLeft;
739 double fRight = fParentWidth - fParentMarginRight -(fXOffset + fWidth + fWrapRight);
740 if(fLeft > fRight)
741 return true;
743 return false;
746 LwpFrameLink::LwpFrameLink()
749 LwpFrameLink::~LwpFrameLink()
753 * @descr frame link information
756 void LwpFrameLink::Read(LwpObjectStream* pStrm)
758 m_PreviousLayout.ReadIndexed(pStrm);
759 m_NextLayout.ReadIndexed(pStrm);
760 pStrm->SkipExtra();
763 LwpFrameLayout::LwpFrameLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
764 : LwpPlacableLayout(objHdr, pStrm), m_pFrame(nullptr)
768 LwpFrameLayout::~LwpFrameLayout()
770 delete m_pFrame;
774 * @descr read frame layout object
777 void LwpFrameLayout::Read()
779 LwpPlacableLayout::Read();
780 if(LwpFileHeader::m_nFileRevision >= 0x000B)
782 if(m_pObjStrm->QuickReaduInt16())
784 m_Link.Read(m_pObjStrm);
787 m_pObjStrm->SkipExtra();
791 * @descr create a xfframe and add into content container
792 * @param: pCont - content container that contains the frame.
795 void LwpFrameLayout::XFConvert(XFContentContainer* pCont)
797 if(m_pFrame)
799 //parse the frame which anchor to paragraph
800 if(IsRelativeAnchored())
802 XFConvertFrame(pCont);
804 else
806 m_pFrame->XFConvert(pCont);
812 * @descr create a xfframe and add into content container, called by XFConvert
813 * @param: pCont - content container that contains the frame.
814 * @param: nPageNo - the page number that the frame anchors
817 void LwpFrameLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart , sal_Int32 nEnd, bool bAll )
819 if(m_pFrame)
821 XFFrame* pXFFrame = nullptr;
822 if(nEnd < nStart)
824 pXFFrame = new XFFrame();
826 else
828 pXFFrame = new XFFloatFrame(nStart, nEnd, bAll);
831 m_pFrame->Parse(pXFFrame, nStart);
832 //if it is a link frame, parse contents only once
833 if(!HasPreviousLinkLayout())
835 rtl::Reference<LwpObject> content = m_Content.obj();
836 if (content.is())
838 content->DoXFConvert(pXFFrame);
839 //set frame size according to ole size
840 ApplyGraphicSize(pXFFrame);
843 pCont ->Add(pXFFrame);
847 * @descr register frame style
850 void LwpFrameLayout::RegisterStyle()
852 //if it is for water mark, don't register style
853 if (IsForWaterMark())
854 return;
856 if (m_pFrame)
857 return;
859 //register frame style
860 XFFrameStyle* pFrameStyle = new XFFrameStyle();
861 m_pFrame = new LwpFrame(this);
862 m_pFrame->RegisterStyle(pFrameStyle);
864 //register content style
865 rtl::Reference<LwpObject> content = m_Content.obj();
866 if (content.is())
868 content->SetFoundry(m_pFoundry);
869 content->DoRegisterStyle();
872 //register child frame style
873 RegisterChildStyle();
877 * @descr get the name of the frame that current frame links
880 OUString LwpFrameLayout::GetNextLinkName()
882 OUString aName;
883 LwpObjectID& rObjectID = m_Link.GetNextLayout();
884 if(!rObjectID.IsNull())
886 LwpLayout* pLayout = dynamic_cast<LwpLayout*>(rObjectID.obj().get());
887 if (pLayout)
889 LwpAtomHolder& rHolder = pLayout->GetName();
890 aName = rHolder.str();
891 //for division name conflict
892 if(!pLayout->GetStyleName().isEmpty())
893 aName = pLayout->GetStyleName();
896 return aName;
899 * @descr whether current frame is linked by other frame
902 bool LwpFrameLayout::HasPreviousLinkLayout()
904 LwpObjectID& rObjectID = m_Link.GetPreviousLayout();
905 if(rObjectID.IsNull())
906 return false;
907 return true;
910 * @descr whether current frame is for water mark. Problem maybe exists by this method, must be tracking
913 bool LwpFrameLayout::IsForWaterMark()
915 if(m_nBuoyancy >=LAY_BUOYLAYER)
917 if (m_Content.IsNull())
918 return false;
919 rtl::Reference<LwpObject> content = m_Content.obj();
920 if (!content.is())
921 return false;
922 if (content->GetTag() == VO_GRAPHIC)
923 return true;
925 return false;
929 * @descr Get frame width
932 double LwpFrameLayout::GetWidth()
934 double fWidth = LwpMiddleLayout::GetWidth();
935 if(IsInlineToMargin() && IsAutoGrowWidth())
937 //for text field entry when choosing maximize field length
938 fWidth = GetMaxWidth();
940 return fWidth;
944 * @descr Get frame width when the text field chooses maximize field length
947 double LwpFrameLayout::GetMaxWidth()
949 double fActualWidth = 0;
950 rtl::Reference<LwpVirtualLayout> xLayout(GetContainerLayout());
951 LwpMiddleLayout* pParent = dynamic_cast<LwpMiddleLayout*>(xLayout.get());
952 if (pParent)
954 LwpPoint aPoint = GetOrigin();
955 double fXOffset = LwpTools::ConvertFromUnitsToMetric(aPoint.GetX());
956 double fWrapRight = GetExtMarginsValue(MARGIN_RIGHT);
958 //Get parent layout width
959 double fParentWidth = pParent->GetWidth();
960 if(pParent->IsCell())
962 //Get actual width of this cell layout
963 fParentWidth = static_cast<LwpCellLayout*>(pParent)->GetActualWidth();
966 double fParentMarginRight = 0;
967 sal_uInt8 nType = GetRelativeType();
968 if(nType == LwpLayoutRelativityGuts::LAY_INLINE
969 || nType == LwpLayoutRelativityGuts::LAY_INLINE_NEWLINE )
971 fParentMarginRight = pParent->GetMarginsValue(MARGIN_RIGHT);
974 fActualWidth = fParentWidth - fXOffset - fParentMarginRight - fWrapRight;
977 return fActualWidth;
981 * @descr Set frame size according to graphic size
984 void LwpFrameLayout::ApplyGraphicSize(XFFrame * pXFFrame)
986 rtl::Reference<LwpObject> content = m_Content.obj();
987 if(content.is() && (content->GetTag() == VO_GRAPHIC
988 || content->GetTag() == VO_OLEOBJECT ))
990 LwpGraphicOleObject* pGraOle = static_cast<LwpGraphicOleObject*>(content.get());
991 //Get frame geometry size
992 double fWidth = 0;
993 double fHeight = 0;
994 pGraOle->GetGrafScaledSize(fWidth, fHeight);
995 if( IsFitGraphic())
997 //graphic scaled sze
998 fWidth += GetMarginsValue(MARGIN_LEFT) + GetMarginsValue(MARGIN_RIGHT);
999 fHeight += GetMarginsValue(MARGIN_TOP) + GetMarginsValue(MARGIN_BOTTOM);
1001 else if(IsAutoGrowDown() || IsAutoGrowUp())
1003 fWidth = GetWidth();
1004 fHeight += GetMarginsValue(MARGIN_TOP) + GetMarginsValue(MARGIN_BOTTOM);
1006 else if( IsAutoGrowLeft() || IsAutoGrowRight())
1008 fHeight = GetHeight();
1009 fWidth += GetMarginsValue(MARGIN_LEFT) + GetMarginsValue(MARGIN_RIGHT);
1011 else
1013 fWidth = GetWidth();
1014 fHeight = GetHeight();
1016 pXFFrame->SetWidth(fWidth);
1017 pXFFrame->SetHeight(fHeight);
1021 LwpGroupLayout::LwpGroupLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1022 : LwpPlacableLayout(objHdr, pStrm)
1023 , m_pFrame(nullptr)
1028 LwpGroupLayout::~LwpGroupLayout()
1030 delete m_pFrame;
1033 * @descr read group layout object
1036 void LwpGroupLayout::Read()
1038 LwpPlacableLayout::Read();
1039 m_pObjStrm->SkipExtra();
1042 * @descr register group frame style
1045 void LwpGroupLayout::RegisterStyle()
1047 if (m_pFrame)
1048 return;
1050 //register frame style
1051 XFFrameStyle* pFrameStyle = new XFFrameStyle();
1052 m_pFrame = new LwpFrame(this);
1053 m_pFrame->RegisterStyle(pFrameStyle);
1055 //register child frame style
1056 RegisterChildStyle();
1059 * @descr create a xfframe and add into content container
1060 * @param: pCont - content container that contains the frame.
1063 void LwpGroupLayout::XFConvert(XFContentContainer *pCont)
1065 if(m_pFrame)
1067 //parse the frame which anchor to paragraph
1068 if(IsRelativeAnchored())
1070 XFConvertFrame(pCont);
1072 else
1074 m_pFrame->XFConvert(pCont);
1080 * @descr create a xfframe and add into content container, called by XFConvert
1081 * @param: pCont - content container that contains the frame.
1082 * @param: nPageNo - the page number that the frame anchors
1085 void LwpGroupLayout::XFConvertFrame(XFContentContainer* pCont, sal_Int32 nStart , sal_Int32 nEnd, bool bAll)
1087 if(m_pFrame)
1089 XFFrame* pXFFrame = nullptr;
1090 if(nEnd < nStart)
1092 pXFFrame = new XFFrame();
1094 else
1096 pXFFrame = new XFFloatFrame(nStart, nEnd, bAll);
1099 m_pFrame->Parse(pXFFrame, nStart);
1101 //add child frame into group
1102 LwpVirtualLayout* pLayout = dynamic_cast<LwpVirtualLayout*>(GetChildHead().obj().get());
1104 while (pLayout && pLayout != this)
1106 pLayout->DoXFConvert(pXFFrame);
1107 pLayout = dynamic_cast<LwpVirtualLayout*>(pLayout->GetNext().obj().get());
1110 pCont ->Add(pXFFrame);
1114 LwpGroupFrame::LwpGroupFrame(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1115 :LwpContent(objHdr, pStrm)
1118 LwpGroupFrame::~LwpGroupFrame()
1121 void LwpGroupFrame::Read()
1123 LwpContent::Read();
1124 m_pObjStrm->SkipExtra();
1128 void LwpGroupFrame::RegisterStyle()
1132 void LwpGroupFrame::XFConvert(XFContentContainer* /*pCont*/)
1136 LwpDropcapLayout::LwpDropcapLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1137 : LwpFrameLayout(objHdr, pStrm)
1139 m_nChars = 1;
1140 m_nLines = 3;
1143 void LwpDropcapLayout::Read()
1145 LwpFrameLayout::Read();
1146 m_nLines = m_pObjStrm->QuickReaduInt16();
1147 m_pObjStrm->SeekRel(1);
1148 m_pObjStrm->SkipExtra();
1151 void LwpDropcapLayout::Parse(IXFStream* pOutputStream)
1153 LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1154 if (!pStory)
1155 return;
1156 rtl::Reference<LwpObject> pPara = pStory->GetFirstPara().obj(VO_PARA);
1157 if(pPara.is())
1159 pPara->SetFoundry(m_pFoundry);
1160 pPara->DoParse(pOutputStream);
1164 void LwpDropcapLayout::XFConvert(XFContentContainer* pCont)
1166 LwpStory* pStory = static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1167 if (pStory)
1169 pStory->SetFoundry(m_pFoundry);
1170 pStory->XFConvert(pCont);
1174 LwpStory* LwpDropcapLayout::GetContentStory()
1176 return static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1179 void LwpDropcapLayout::RegisterStyle(LwpFoundry* pFoundry)
1181 LwpStory* pStory = GetContentStory();
1182 if (pStory)
1184 pStory->SetDropcapFlag(true);
1185 pStory->SetFoundry(pFoundry);
1186 LwpPara* pPara = dynamic_cast<LwpPara*>(pStory->GetFirstPara().obj().get());
1187 while(pPara)
1189 pPara->SetFoundry(pFoundry);
1190 pPara->RegisterStyle();
1191 pPara = dynamic_cast<LwpPara*>(pPara->GetNext().obj().get());
1197 * @descr do nothing
1200 void LwpDropcapLayout::RegisterStyle()
1204 LwpRubyLayout::LwpRubyLayout(LwpObjectHeader &objHdr, LwpSvStream* pStrm)
1205 : LwpFrameLayout(objHdr, pStrm)
1206 , m_nPlacement(0)
1207 , m_nAlignment(0)
1208 , m_nStateFlag(0)
1209 , m_nXOffset(0)
1210 , m_nYOffset(0)
1214 void LwpRubyLayout::Read()
1216 LwpFrameLayout::Read();
1217 m_nPlacement = m_pObjStrm->QuickReaduInt8();
1218 m_nAlignment = m_pObjStrm->QuickReaduInt8();
1219 m_nStateFlag = m_pObjStrm->QuickReaduInt16();
1220 m_nXOffset = m_pObjStrm->QuickReadInt32();
1221 m_nYOffset = m_pObjStrm->QuickReadInt32();
1222 m_objRubyMarker.ReadIndexed(m_pObjStrm);
1223 m_pObjStrm->SkipExtra();
1226 LwpRubyMarker* LwpRubyLayout::GetMarker()
1228 return static_cast<LwpRubyMarker*>(m_objRubyMarker.obj(VO_RUBYMARKER).get());
1231 LwpStory* LwpRubyLayout::GetContentStory()
1233 return static_cast<LwpStory*>(m_Content.obj(VO_STORY).get());
1236 void LwpRubyLayout::ConvertContentText()
1238 LwpStory* pStory = GetContentStory();
1239 LwpRubyMarker* pMarker = GetMarker();
1240 if (pStory && pMarker)
1241 pMarker->SetRubyText(pStory->GetContentText(true));
1244 void LwpRubyLayout::RegisterStyle()
1246 LwpRubyMarker* pMarker = GetMarker();
1247 if (!pMarker)
1248 throw std::runtime_error("missing Ruby Marker");
1250 XFRubyStyle* pRubyStyle = new XFRubyStyle;
1252 enumXFRubyPosition eType = enumXFRubyLeft;
1253 if (m_nAlignment == LEFT)
1255 eType = enumXFRubyLeft;
1257 else if(m_nAlignment == RIGHT)
1259 eType = enumXFRubyRight;
1261 else if(m_nAlignment == CENTER)
1263 eType = enumXFRubyCenter;
1265 pRubyStyle->SetAlignment(eType);
1267 eType = enumXFRubyTop;
1268 if (m_nPlacement == TOP)
1270 eType = enumXFRubyTop;
1272 else if(m_nPlacement == BOTTOM)
1274 eType = enumXFRubyBottom;
1276 pRubyStyle->SetPosition(eType);
1278 XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
1279 OUString rubyStyle = pXFStyleManager->AddStyle(pRubyStyle).m_pStyle->GetStyleName();
1280 pMarker->SetRubyStyleName(rubyStyle);
1282 LwpStory* pStory = GetContentStory();
1283 pStory->SetFoundry(m_pFoundry);
1284 OUString textStyle = pStory->RegisterFirstFribStyle();
1285 pMarker->SetTextStyleName(textStyle);
1288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */