1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */
2 
3 /* AbiWord
4  * Copyright (C) 1998 AbiSource, Inc.
5  * Copyright (C) 2003 Martin Sevior (msevior@physics.unimelb.edu.au>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301 USA.
21  */
22 
23 #include <string.h>
24 #include <stdlib.h>
25 
26 #include "ut_types.h"
27 #include "ut_string.h"
28 
29 #include "ap_Prefs.h"
30 #include "fl_SectionLayout.h"
31 #include "fl_FrameLayout.h"
32 #include "fl_Layout.h"
33 #include "fl_DocLayout.h"
34 #include "fl_BlockLayout.h"
35 #include "fb_LineBreaker.h"
36 #include "fp_Page.h"
37 #include "fp_Line.h"
38 #include "fp_Column.h"
39 #include "fp_FrameContainer.h"
40 #include "fp_ContainerObject.h"
41 #include "pd_Document.h"
42 #include "pp_AttrProp.h"
43 #include "gr_Graphics.h"
44 #include "pp_Property.h"
45 #include "px_ChangeRecord.h"
46 #include "px_CR_Object.h"
47 #include "px_CR_ObjectChange.h"
48 #include "px_CR_Span.h"
49 #include "px_CR_SpanChange.h"
50 #include "px_CR_Strux.h"
51 #include "px_CR_StruxChange.h"
52 #include "px_CR_Glob.h"
53 #include "fp_Run.h"
54 #include "ut_debugmsg.h"
55 #include "ut_assert.h"
56 #include "ut_units.h"
57 #include "fv_FrameEdit.h"
58 #include "ut_png.h"
59 #include "ut_bytebuf.h"
60 #include "fg_GraphicRaster.h"
61 #include "fg_GraphicVector.h"
62 #include "fv_View.h"
63 
64 static void s_border_properties (const gchar * border_color, const gchar * border_style, const gchar * border_width,
65 								 const gchar * color, PP_PropertyMap::Line & line);
66 
67 static void s_background_properties (const gchar * pszBgStyle, const gchar * pszBgColor,
68 									 const gchar * pszBackgroundColor,
69 									 PP_PropertyMap::Background & background);
70 
71 
fl_FrameLayout(FL_DocLayout * pLayout,pf_Frag_Strux * sdh,PT_AttrPropIndex indexAP,fl_ContainerLayout * pMyContainerLayout)72 fl_FrameLayout::fl_FrameLayout(FL_DocLayout* pLayout,
73 							   pf_Frag_Strux* sdh,
74 							   PT_AttrPropIndex indexAP,
75 							   fl_ContainerLayout * pMyContainerLayout)
76  	: fl_SectionLayout(pLayout,
77 					   sdh,
78 					   indexAP,
79 					   FL_SECTION_FRAME,
80 					   FL_CONTAINER_FRAME,
81 					   PTX_SectionFrame,
82 					   pMyContainerLayout),
83 	  m_iFrameType(FL_FRAME_TEXTBOX_TYPE),
84 	  m_iFramePositionTo(FL_FRAME_POSITIONED_TO_BLOCK),
85 	  m_bNeedsRebuild(false),
86 	  m_bNeedsFormat(true),
87 	  m_bIsOnPage(false),
88 	  m_bHasEndFrame(false),
89 	  m_iWidth(0),
90 	  m_iHeight(0),
91 	  m_iXpos(0),
92 	  m_iYpos(0),
93 	  m_iXpad(0),
94 	  m_iYpad(0),
95 	  m_iXColumn(0),
96 	  m_iYColumn(0),
97 	  m_iXPage(0),
98 	  m_iYPage(0),
99 	  m_iBoundingSpace(0),
100 	  m_iFrameWrapMode(FL_FRAME_ABOVE_TEXT),
101 	  m_bIsTightWrap(false),
102 	  m_iPrefPage(-1),
103 	  m_iPrefColumn(0),
104 	  m_bExpandHeight(false),
105 	  m_iMinHeight(0),
106 	  m_pParentContainer(NULL)
107 {
108 }
109 
~fl_FrameLayout()110 fl_FrameLayout::~fl_FrameLayout()
111 {
112 	// NB: be careful about the order of these
113 	UT_DEBUGMSG(("Deleting Framelayout %p \n",this));
114 	_purgeLayout();
115 	fp_FrameContainer * pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
116 	while(pFC)
117 	{
118 		fp_FrameContainer * pNext = static_cast<fp_FrameContainer *>(pFC->getNext());
119 		if(pFC == static_cast<fp_FrameContainer *>(getLastContainer()))
120 		{
121 			pNext = NULL;
122 		}
123 		delete pFC;
124 		pFC = pNext;
125 	}
126 
127 	setFirstContainer(NULL);
128 	setLastContainer(NULL);
129 //
130 // Remove pointers to this if they exist
131 //
132 	if(getDocLayout() && getDocLayout()->getView())
133 	{
134 		FV_FrameEdit * pFE = getDocLayout()->getView()->getFrameEdit();
135 		if(pFE->getFrameLayout() == this)
136 		{
137 			pFE->setMode(FV_FrameEdit_NOT_ACTIVE);
138 		}
139 	}
140 }
141 
142 /*!
143  * This loads all the properties of the container found in the piecetable
144  * into the physical frame container
145  */
setContainerProperties(void)146 void 	fl_FrameLayout::setContainerProperties(void)
147 {
148 	fp_FrameContainer * pFrame = static_cast<fp_FrameContainer *>(getLastContainer());
149 	if(pFrame == NULL)
150 	{
151 		UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
152 		return;
153 	}
154 	pFrame->setBackground(m_background  );
155 	pFrame->setBottomStyle(m_lineBottom  );
156 	pFrame->setTopStyle(m_lineTop  );
157 	pFrame->setLeftStyle(m_lineLeft  );
158 	pFrame->setRightStyle(m_lineRight );
159 	pFrame->setXpad(m_iXpad);
160 	pFrame->setYpad(m_iYpad);
161 	pFrame->setTightWrapping(m_bIsTightWrap);
162 	if(FL_FRAME_BELOW_TEXT ==  m_iFrameWrapMode)
163         {
164 	        pFrame->setAbove(false);
165 	}
166 	else if(FL_FRAME_WRAPPED_TO_RIGHT == m_iFrameWrapMode)
167 	{
168 	        pFrame->setRightWrapped(true);
169 	}
170 	else if(FL_FRAME_WRAPPED_TO_LEFT == m_iFrameWrapMode)
171 	{
172 	  pFrame->setLeftWrapped(true);
173 	}
174 	else if(FL_FRAME_WRAPPED_TOPBOT == m_iFrameWrapMode)
175 	{
176 	        pFrame->setTopBot(true);
177 	}
178 //
179 // Now do the image for this frame.
180 //
181 	if(m_pGraphicImage)
182 	{
183 		if(m_pImageImage == NULL)
184 		{
185 			const PP_AttrProp * pAP = NULL;
186 			getAP(pAP);
187 			GR_Graphics * pG = getDocLayout()->getGraphics();
188 			UT_sint32 iWidth = pG->tlu(100);
189 			UT_sint32 iHeight = pG->tlu(100);
190 			if(m_pGraphicImage->getType() == FGT_Raster)
191 			{
192 				iWidth = pG->tlu(m_pGraphicImage->getWidth());
193 				iHeight = pG->tlu(m_pGraphicImage->getHeight());
194 			}
195 			GR_Image * pImage = m_pGraphicImage->generateImage(pG,pAP,iWidth,iHeight);
196 			m_iDocImageWidth = pFrame->getFullWidth();
197 			m_iDocImageHeight = pFrame->getFullHeight();
198 			m_iGraphicTick = getDocLayout()->getGraphicTick();
199 			UT_Rect rec(0,0,pFrame->getFullWidth(),pFrame->getFullHeight());
200 			if(rec.width < pG->tlu(3))
201 			{
202 				rec.width = pG->tlu(3);
203 			}
204 			if(rec.height < pG->tlu(3))
205 			{
206 				rec.height = pG->tlu(3);
207 			}
208 			if(pImage)
209 			{
210 				pImage->scaleImageTo(pG,rec);
211 			}
212 			m_pImageImage = pImage;
213 		}
214 		pFrame->getFillType().setImagePointer(&m_pGraphicImage,&m_pImageImage);
215 	}
216 	if(m_iFrameWrapMode >= FL_FRAME_WRAPPED_TO_RIGHT)
217 	{
218 //
219 // Set text wrapping around frame
220 //
221 		pFrame->setWrapping(true);
222 	}
223 	pFrame->setPreferedPageNo(m_iPrefPage);
224 	pFrame->setPreferedColumnNo(m_iPrefColumn);
225 }
226 
getBoundingSpace(void) const227 UT_sint32 fl_FrameLayout::getBoundingSpace(void) const
228 {
229 	return m_iBoundingSpace;
230 }
231 
232 /*!
233  * Returns the position in the document of the PTX_SectionFrame strux
234 */
getDocPosition(void)235 PT_DocPosition fl_FrameLayout::getDocPosition(void)
236 {
237 	pf_Frag_Strux* sdh = getStruxDocHandle();
238     return 	m_pLayout->getDocument()->getStruxPosition(sdh);
239 }
240 
241 /*!
242  * This method returns the length of the Frame. This is such that
243  * getDocPosition() + getLength() is one value beyond the the EndFrame
244  * strux
245  */
getLength(void)246 UT_uint32 fl_FrameLayout::getLength(void)
247 {
248 	PT_DocPosition startPos = getDocPosition();
249 	pf_Frag_Strux* sdhEnd = NULL;
250 	pf_Frag_Strux* sdhStart = getStruxDocHandle();
251 	UT_DebugOnly<bool> bres;
252 	bres = m_pLayout->getDocument()->getNextStruxOfType(sdhStart,PTX_EndFrame,&sdhEnd);
253 	UT_ASSERT(bres && sdhEnd);
254 	if(sdhEnd == NULL)
255 	{
256 	  return 1;
257 	}
258 	PT_DocPosition endPos = m_pLayout->getDocument()->getStruxPosition(sdhEnd);
259 	UT_uint32 length = static_cast<UT_uint32>(endPos - startPos + 1);
260 	return length;
261 }
262 
263 
264 /*!
265  * This code actually inserts a block AFTER the frame in the docsectionlayout
266  * Code copied from tablelayout
267  */
insertBlockAfter(fl_ContainerLayout *,const PX_ChangeRecord_Strux * pcrx,pf_Frag_Strux * sdh,PL_ListenerId lid,void (* pfnBindHandles)(pf_Frag_Strux * sdhNew,PL_ListenerId lid,fl_ContainerLayout * sfhNew))268 bool fl_FrameLayout::insertBlockAfter(fl_ContainerLayout* /*pLBlock*/,
269 											  const PX_ChangeRecord_Strux * pcrx,
270 											  pf_Frag_Strux* sdh,
271 											  PL_ListenerId lid,
272 											  void (* pfnBindHandles)(pf_Frag_Strux* sdhNew,
273 																	  PL_ListenerId lid,
274 																	  fl_ContainerLayout* sfhNew))
275 {
276 
277 	UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_InsertStrux);
278 	UT_ASSERT(pcrx->getStruxType()==PTX_Block);
279 
280 	fl_ContainerLayout * pNewCL = NULL;
281 	fl_ContainerLayout * pMyCL = myContainingLayout();
282 	pNewCL = pMyCL->insert(sdh,this,pcrx->getIndexAP(), FL_CONTAINER_BLOCK);
283 	fl_BlockLayout * pBlock = static_cast<fl_BlockLayout *>(pNewCL);
284 //
285 // Set the sectionlayout of this frame to that of the block since it is that scope
286 //
287 	pBlock->setSectionLayout(static_cast<fl_SectionLayout *>(myContainingLayout()));
288 	pNewCL->setContainingLayout(myContainingLayout());
289 
290 		// Must call the bind function to complete the exchange of handles
291 		// with the document (piece table) *** before *** anything tries
292 		// to call down into the document (like all of the view
293 		// listeners).
294 
295 	fl_ContainerLayout* sfhNew = pNewCL;
296 	pfnBindHandles(sdh,lid,sfhNew);
297 //
298 // increment the insertion point in the view.
299 //
300 	FV_View* pView = m_pLayout->getView();
301 	if (pView && (pView->isActive() || pView->isPreview()))
302 	{
303 		pView->setPoint(pcrx->getPosition() + fl_BLOCK_STRUX_OFFSET);
304 	}
305 	else if(pView && pView->getPoint() > pcrx->getPosition())
306 	{
307 		pView->setPoint(pView->getPoint() +  fl_BLOCK_STRUX_OFFSET);
308 	}
309 	if(pView)
310 		pView->updateCarets(pcrx->getPosition(),1);
311 	return true;
312 }
313 
bl_doclistener_insertEndFrame(fl_ContainerLayout *,const PX_ChangeRecord_Strux * pcrx,pf_Frag_Strux * sdh,PL_ListenerId lid,void (* pfnBindHandles)(pf_Frag_Strux * sdhNew,PL_ListenerId lid,fl_ContainerLayout * sfhNew))314 bool fl_FrameLayout::bl_doclistener_insertEndFrame(fl_ContainerLayout*,
315 											  const PX_ChangeRecord_Strux * pcrx,
316 											  pf_Frag_Strux* sdh,
317 											  PL_ListenerId lid,
318 											  void (* pfnBindHandles)(pf_Frag_Strux* sdhNew,
319 																	  PL_ListenerId lid,
320 																	  fl_ContainerLayout* sfhNew))
321 {
322 	// The endFrame strux actually needs a format handle to to this Frame layout.
323 	// so we bind to this layout. We also set a pointer to keep track of the endFrame strux.
324 
325 
326 	fl_ContainerLayout* sfhNew = this;
327 	pfnBindHandles(sdh,lid,sfhNew);
328 	setEndStruxDocHandle(sdh);
329 
330 
331 //
332 // increment the insertion point in the view.
333 //
334 	FV_View* pView = m_pLayout->getView();
335 	if (pView && (pView->isActive() || pView->isPreview()))
336 	{
337 		pView->setPoint(pcrx->getPosition() +  fl_BLOCK_STRUX_OFFSET);
338 	}
339 	else if(pView && pView->getPoint() > pcrx->getPosition())
340 	{
341 		pView->setPoint(pView->getPoint() +  fl_BLOCK_STRUX_OFFSET);
342 	}
343 	if(pView)
344 		pView->updateCarets(pcrx->getPosition(),1);
345 	m_bHasEndFrame = true;
346 	return true;
347 }
348 
349 
350 /*!
351  * This signals an incomplete frame section.
352  */
doclistener_deleteEndFrame(const PX_ChangeRecord_Strux *)353 bool fl_FrameLayout::doclistener_deleteEndFrame( const PX_ChangeRecord_Strux * /*pcrx*/)
354 {
355 	m_bHasEndFrame = false;
356 	return true;
357 }
358 
359 
getSectionLayout(void) const360 fl_SectionLayout * fl_FrameLayout::getSectionLayout(void) const
361 {
362 	fl_ContainerLayout * pDSL = myContainingLayout();
363 	while(pDSL)
364 	{
365 		if(pDSL->getContainerType() == FL_CONTAINER_DOCSECTION)
366 		{
367 			return static_cast<fl_SectionLayout *>(pDSL);
368 		}
369 		pDSL = pDSL->myContainingLayout();
370 	}
371 	return NULL;
372 }
373 
374 
doclistener_changeStrux(const PX_ChangeRecord_StruxChange * pcrxc)375 bool fl_FrameLayout::doclistener_changeStrux(const PX_ChangeRecord_StruxChange * pcrxc)
376 {
377 	UT_ASSERT(pcrxc->getType()==PX_ChangeRecord::PXT_ChangeStrux);
378 	fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer());
379 	UT_GenericVector<fl_ContainerLayout *> AllLayouts;
380 	AllLayouts.clear();
381 	fp_Page * pPage = NULL;
382 	UT_sint32 i = 0;
383 	if(pFrameC)
384 	{
385 	    pPage = pFrameC->getPage();
386 		if (pPage)
387 		{
388 			pPage->getAllLayouts(AllLayouts);
389 			for(i=0; i< AllLayouts.getItemCount();i++)
390 			{
391 				fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
392 				pCL->collapse();
393 			}
394 		}
395 	}
396 	setAttrPropIndex(pcrxc->getIndexAP());
397 	collapse();
398 	lookupProperties();
399 	format();
400 	for(i=0; i< AllLayouts.getItemCount();i++)
401 	{
402 	    fl_ContainerLayout * pCL = AllLayouts.getNthItem(i);
403 	    pCL->format();
404 	    xxx_UT_DEBUGMSG(("Format block %x \n",pBL));
405 	    pCL->markAllRunsDirty();
406 	}
407 	getDocSectionLayout()->markAllRunsDirty();
408 	return true;
409 }
410 
411 
recalculateFields(UT_uint32 iUpdateCount)412 bool fl_FrameLayout::recalculateFields(UT_uint32 iUpdateCount)
413 {
414 	// ingnore frames in normal view mode
415 	FV_View * pView = getDocLayout()->getView();
416 	GR_Graphics * pG = getDocLayout()->getGraphics();
417 	UT_return_val_if_fail( pView && pG, false );
418 
419 	bool bResult = false;
420 	fl_ContainerLayout*	pBL = getFirstLayout();
421 	while (pBL)
422 	{
423 		bResult = pBL->recalculateFields(iUpdateCount) || bResult;
424 		pBL = pBL->getNext();
425 	}
426 	return bResult;
427 }
428 
429 
markAllRunsDirty(void)430 void fl_FrameLayout::markAllRunsDirty(void)
431 {
432 	fl_ContainerLayout*	pCL = getFirstLayout();
433 	while (pCL)
434 	{
435 		pCL->markAllRunsDirty();
436 		pCL = pCL->getNext();
437 	}
438 }
439 
updateLayout(bool)440 void fl_FrameLayout::updateLayout(bool /*bDoAll*/)
441 {
442 	// ingnore frames in normal view mode
443 	FV_View * pView = getDocLayout()->getView();
444 	GR_Graphics * pG = getDocLayout()->getGraphics();
445 	UT_return_if_fail( pView && pG);
446 
447 	xxx_UT_DEBUGMSG(("UpdsateLayout in in framelayout \n"));
448 	if(needsReformat())
449 	{
450 		format();
451 	}
452 	m_vecFormatLayout.clear();
453 	fl_ContainerLayout*	pBL = getFirstLayout();
454 	while (pBL)
455 	{
456 		if (pBL->needsReformat())
457 		{
458 			pBL->format();
459 		}
460 
461 		pBL = pBL->getNext();
462 	}
463 }
464 
redrawUpdate(void)465 void fl_FrameLayout::redrawUpdate(void)
466 {
467 	fl_ContainerLayout*	pBL = getFirstLayout();
468 	while (pBL)
469 	{
470 		if (pBL->needsRedraw())
471 		{
472 			pBL->redrawUpdate();
473 		}
474 
475 		pBL = pBL->getNext();
476 	}
477 }
478 
479 
doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx)480 bool fl_FrameLayout::doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx)
481 {
482 	UT_UNUSED(pcrx);
483 	UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_DeleteStrux);
484 #if 0
485 	fp_FrameContainer * pFrameC = getFirstContainer();
486 	if(pFrameC && pFrameC->getPage())
487 	{
488 		pFrameC->getPage()->markDirtyOverlappingRuns(pFrameC);
489 	}
490 #endif
491 	fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer());
492 	UT_GenericVector<fl_BlockLayout *> vecBlocks;
493 	pFrameC->getBlocksAroundFrame(vecBlocks);
494 	UT_sint32 i = 0;
495 	for(i=0; i< vecBlocks.getItemCount();i++)
496 	{
497 	  fl_BlockLayout * pBL = vecBlocks.getNthItem(i);
498 	  pBL->collapse();
499 	  xxx_UT_DEBUGMSG(("Collapse block %x \n",pBL));
500 	}
501 
502 //
503 // Remove all remaining structures
504 //
505 	collapse();
506 	myContainingLayout()->remove(this);
507 	UT_DEBUGMSG(("Unlinking frame Layout %p \n",this));
508 //
509 // Remove from the list of frames in the previous block
510 //
511 	fl_ContainerLayout * pCL = getParentContainer();
512 	fl_BlockLayout * pBL = NULL;
513 	if(pCL)
514 	{
515 		if(!pCL->removeFrame(this))
516 		{
517 			UT_DEBUGMSG(("Whoops! Frame not found in container %p\n",pCL));
518 			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
519 		}
520 	}
521 	for(i=0; i< vecBlocks.getItemCount();i++)
522 	{
523 	  pBL = vecBlocks.getNthItem(i);
524 	  pBL->format();
525 	  xxx_UT_DEBUGMSG(("Format block %p\n",pBL));
526 	}
527 
528 	delete this;			// TODO whoa!  this construct is VERY dangerous.
529 
530 	return true;
531 }
532 
533 
534 /*!
535  * This method removes all layout structures contained by this layout
536  * structure.
537  */
_purgeLayout(void)538 void fl_FrameLayout::_purgeLayout(void)
539 {
540 	UT_DEBUGMSG(("FrameLayout: purge \n"));
541 	fl_ContainerLayout * pCL = getFirstLayout();
542 	while(pCL)
543 	{
544 		fl_ContainerLayout * pNext = pCL->getNext();
545 		delete pCL;
546 		pCL = pNext;
547 	}
548 }
549 
550 
551 /*!
552  * This method creates a new footnote with its properties initially set
553  * from the Attributes/properties of this Layout
554  */
_createFrameContainer(void)555 void fl_FrameLayout::_createFrameContainer(void)
556 {
557 	lookupProperties();
558 	fp_FrameContainer * pFrameContainer = new fp_FrameContainer(static_cast<fl_SectionLayout *>(this));
559 	setFirstContainer(pFrameContainer);
560 	setLastContainer(pFrameContainer);
561 	pFrameContainer->setWidth(m_iWidth);
562 	pFrameContainer->setHeight(m_iHeight);
563 	// Now do Frame image
564 
565 	const PP_AttrProp* pSectionAP = NULL;
566 	// This is a real NO-NO: must *always* call getAP()
567 	// m_pLayout->getDocument()->getAttrProp(m_apIndex, &pSectionAP);
568 	getAP(pSectionAP);
569 
570 	const gchar * pszDataID = NULL;
571 	pSectionAP->getAttribute(PT_STRUX_IMAGE_DATAID, (const gchar *&)pszDataID);
572 	DELETEP(m_pGraphicImage);
573 	DELETEP(m_pImageImage);
574 	//
575 	// Set the image size from the full width
576 	//
577 	setImageWidth(pFrameContainer->getFullWidth());
578 	setImageHeight(pFrameContainer->getFullHeight());
579 	if(pszDataID && *pszDataID)
580 	{
581 		UT_DEBUGMSG(("!!!Found image of file %s \n",pszDataID));
582 		m_pGraphicImage = FG_Graphic::createFromStrux(this);
583 	}
584 
585 	setContainerProperties();
586 }
587 
588 /*!
589   Create a new Frame container.
590   \param If pPrevFrame is non-null place the new cell after this in the linked
591           list, otherwise just append it to the end.
592   \return The newly created Frame container
593 */
getNewContainer(fp_Container *)594 fp_Container* fl_FrameLayout::getNewContainer(fp_Container *)
595 {
596 	UT_DEBUGMSG(("creating new Frame container\n"));
597 	_createFrameContainer();
598 	m_bIsOnPage = false;
599 	return static_cast<fp_Container *>(getLastContainer());
600 }
601 
_insertFrameContainer(fp_Container *)602 void fl_FrameLayout::_insertFrameContainer(fp_Container * /*pNewFC*/)
603 {
604 
605 // This is all done fl_BlockLayout::setFramesOnPage
606 
607 }
608 
609 
miniFormat(void)610 void fl_FrameLayout::miniFormat(void)
611 {
612 	// ingnore frames in normal view mode
613 	FV_View * pView = getDocLayout()->getView();
614 	GR_Graphics * pG = getDocLayout()->getGraphics();
615 	UT_return_if_fail( pView && pG );
616 
617 	fl_ContainerLayout*	pBL = getFirstLayout();
618 
619 	while (pBL)
620 	{
621 		pBL->format();
622 		pBL = pBL->getNext();
623 	}
624 	fp_FrameContainer * pFrame = static_cast<fp_FrameContainer *>(getFirstContainer());
625 	pFrame->layout();
626 	pFrame->getFillType().setWidthHeight(getDocLayout()->getGraphics(),pFrame->getFullWidth(),pFrame->getFullHeight(),false);
627 	m_bNeedsFormat = false;
628 	m_bNeedsReformat = false;
629 }
630 
format(void)631 void fl_FrameLayout::format(void)
632 {
633 	// ingnore frames in normal view mode
634 	FV_View * pView = getDocLayout()->getView();
635 	GR_Graphics * pG = getDocLayout()->getGraphics();
636 	UT_return_if_fail( pView && pG );
637 
638 	xxx_UT_DEBUGMSG(("SEVIOR: Formatting first container is %x \n",getFirstContainer()));
639 	if(isHidden() > FP_VISIBLE)
640 	{
641 		xxx_UT_DEBUGMSG(("Don't format FRAME coz I'm hidden! \n"));
642 		return;
643 	}
644 
645 	if(getFirstContainer() == NULL)
646 	{
647 		getNewContainer();
648 	}
649 	fl_ContainerLayout*	pBL2 = getFirstLayout();
650 	while (pBL2)
651 	{
652 		pBL2->format();
653 		UT_sint32 count = 0;
654 		while(pBL2->getLastContainer() == NULL || pBL2->getFirstContainer()==NULL)
655 		{
656 			UT_DEBUGMSG(("Error formatting a block try again \n"));
657 			count = count + 1;
658 			pBL2->format();
659 			if(count > 3)
660 			{
661 				UT_DEBUGMSG(("Give up trying to format. Hope for the best :-( \n"));
662 				break;
663 			}
664 		}
665 		pBL2 = pBL2->getNext();
666 	}
667 	static_cast<fp_FrameContainer *>(getFirstContainer())->layout();
668 	bool bPlacedOnPage = false;
669 	if(!m_bIsOnPage && !(getDocLayout()->isLayoutFilling()))
670 	{
671 //
672 // Place it on the correct page.
673 //
674 		fl_ContainerLayout * pCL = getParentContainer();
675 		if((!pCL) || pCL->getContainerType() != FL_CONTAINER_BLOCK)
676 		{
677 			UT_DEBUGMSG(("No BlockLayout or wrong layout associated with this frame! \n"));
678 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
679 			return;
680 		}
681 		fl_BlockLayout * pBL = NULL;
682 		pBL = static_cast<fl_BlockLayout *>(pCL);
683 		UT_sint32 count = pBL->getNumFrames();
684 		UT_sint32 i = 0;
685 		for(i=0; i<count; i++)
686 		{
687 			fl_FrameLayout * pFL = pBL->getNthFrameLayout(i);
688 			if(pFL == this)
689 			{
690 				break;
691 			}
692 		}
693 		if(count == i)
694 		{
695 			UT_DEBUGMSG(("BlockLayout does not contain this frame! \n"));
696 			UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
697 			return;
698 		}
699 		if(!pBL->isCollapsed())
700 		{
701 			m_bIsOnPage = pBL->setFramesOnPage(NULL);
702 			if(!m_bIsOnPage)
703 			{
704 				setNeedsReformat(this);
705 			}
706 		}
707 		if(m_bIsOnPage)
708 			bPlacedOnPage = true;
709 	}
710 	m_bNeedsFormat = m_bIsOnPage;
711 	m_bNeedsReformat = m_bIsOnPage;
712 	if(!m_bIsOnPage)
713 	{
714 		setNeedsReformat(this);
715 	}
716 	if(!m_bIsOnPage)
717 	{
718 		return;
719 	}
720 	if(bPlacedOnPage)
721 	{
722 		fl_DocSectionLayout * pDSL = getDocSectionLayout();
723 		fp_FrameContainer * pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
724 		if(pFC)
725 		{
726 			pDSL->setNeedsSectionBreak(true,pFC->getPage());
727 		}
728 	}
729 }
730 
setNeedsReformat(fl_ContainerLayout *,UT_uint32)731 void fl_FrameLayout::setNeedsReformat(fl_ContainerLayout * /*pCL*/,UT_uint32 /*offset*/)
732 {
733         m_bNeedsReformat = true;
734         myContainingLayout()->setNeedsReformat(this);
735 }
736 /*!
737     this function is only to be called by fl_ContainerLayout::lookupProperties()
738     all other code must call lookupProperties() instead
739 */
_lookupProperties(const PP_AttrProp * pSectionAP)740 void fl_FrameLayout::_lookupProperties(const PP_AttrProp* pSectionAP)
741 {
742 	UT_return_if_fail(pSectionAP);
743 
744 	FV_View * pView = getDocLayout()->getView();
745 	GR_Graphics * pG = getDocLayout()->getGraphics();
746 	UT_return_if_fail( pView && pG );
747 
748 	const gchar *pszFrameType = NULL;
749 	const gchar *pszPositionTo = NULL;
750 	const gchar *pszWrapMode = NULL;
751 	const gchar *pszXpos = NULL;
752 	const gchar *pszYpos = NULL;
753 	const gchar *pszColXpos = NULL;
754 	const gchar *pszColYpos = NULL;
755 	const gchar *pszPageXpos = NULL;
756 	const gchar *pszPageYpos = NULL;
757 	const gchar *pszWidth = NULL;
758 	const gchar *pszHeight = NULL;
759 	const gchar *pszXpad = NULL;
760 	const gchar *pszYpad = NULL;
761 
762 	const gchar * pszColor = NULL;
763 	const gchar * pszBorderColor = NULL;
764 	const gchar * pszBorderStyle = NULL;
765 	const gchar * pszBorderWidth = NULL;
766 
767 	const gchar * pszBoundingSpace = NULL;
768 	const gchar * pszTightWrapped = NULL;
769 	const gchar * pszPrefPage = NULL;
770 	const gchar * pszPrefColumn = NULL;
771 
772 	const gchar * pszExpandHeight = NULL;
773 	const gchar * pszPercentWidth = NULL;
774 	const gchar * pszMinHeight = NULL;
775 // Frame Type
776 
777 	if(!pSectionAP || !pSectionAP->getProperty("frame-type",pszFrameType))
778 	{
779 		m_iFrameType = FL_FRAME_TEXTBOX_TYPE;
780 	}
781 	else if(strcmp(pszFrameType,"textbox") == 0)
782 	{
783 		m_iFrameType = FL_FRAME_TEXTBOX_TYPE;
784 	}
785 	else if(strcmp(pszFrameType,"image") == 0)
786 	{
787 		m_iFrameType = FL_FRAME_WRAPPER_IMAGE;
788 	}
789 	else
790 	{
791 		UT_DEBUGMSG(("Unknown Frame Type %s \n",pszFrameType));
792 		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
793 		m_iFrameType = FL_FRAME_TEXTBOX_TYPE;
794 	}
795 
796 // Position-to
797 
798 	if((!pSectionAP || !pSectionAP->getProperty("position-to",pszPositionTo)))
799 	{
800 		m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
801 	}
802 	else if(strcmp(pszPositionTo,"block-above-text") == 0)
803 	{
804 		m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
805 	}
806 	else if(strcmp(pszPositionTo,"column-above-text") == 0)
807 	{
808 		m_iFramePositionTo = FL_FRAME_POSITIONED_TO_COLUMN;
809 	}
810 	else if(strcmp(pszPositionTo,"page-above-text") == 0)
811 	{
812 		m_iFramePositionTo = FL_FRAME_POSITIONED_TO_PAGE;
813 	}
814 	else
815 	{
816 		UT_DEBUGMSG(("Unknown Position to %s \n",pszPositionTo));
817 		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
818 		m_iFramePositionTo =  FL_FRAME_POSITIONED_TO_BLOCK;
819 	}
820 
821 
822 // wrap-mode
823 
824 	if(!pSectionAP || !pSectionAP->getProperty("wrap-mode",pszWrapMode))
825 	{
826 		m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
827 	}
828 	else if(strcmp(pszWrapMode,"above-text") == 0)
829 	{
830 		m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
831 	}
832 	else if(strcmp(pszWrapMode,"below-text") == 0)
833 	{
834 		m_iFrameWrapMode = FL_FRAME_BELOW_TEXT;
835 	}
836 	else if(strcmp(pszWrapMode,"wrapped-to-right") == 0)
837 	{
838 		m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_RIGHT;
839 	}
840 	else if(strcmp(pszWrapMode,"wrapped-to-left") == 0)
841 	{
842 		m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_LEFT;
843 	}
844 	else if(strcmp(pszWrapMode,"wrapped-both") == 0)
845 	{
846 		m_iFrameWrapMode = FL_FRAME_WRAPPED_BOTH_SIDES;
847 	}
848 	else if(strcmp(pszWrapMode,"wrapped-topbot") == 0)
849 	{
850 		m_iFrameWrapMode = FL_FRAME_WRAPPED_TOPBOT;
851 	}
852 	else
853 	{
854 		UT_DEBUGMSG(("Unknown wrap-mode %s \n",pszWrapMode));
855 		UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
856 		m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
857 	}
858 	//
859 	// Wrap type
860 	//
861 	if(!pSectionAP || !pSectionAP->getProperty("tight-wrap",pszTightWrapped))
862 	{
863 		m_bIsTightWrap = false;
864 	}
865 	else if(strcmp(pszTightWrapped,"1") == 0)
866 	{
867 		m_bIsTightWrap = true;
868 	}
869 	else
870 	{
871 		m_bIsTightWrap = false;
872 	}
873 
874 // Xpos
875 
876 	if(!pSectionAP || !pSectionAP->getProperty("xpos",pszXpos))
877 	{
878 		m_iXpos = 0;
879 	}
880 	else
881 	{
882 		m_iXpos = UT_convertToLogicalUnits(pszXpos);
883 	}
884 	UT_DEBUGMSG(("xpos for frame is %s \n",pszXpos));
885 // Ypos
886 
887 	if(!pSectionAP || !pSectionAP->getProperty("ypos",pszYpos))
888 	{
889 		m_iYpos = 0;
890 	}
891 	else
892 	{
893 		m_iYpos = UT_convertToLogicalUnits(pszYpos);
894 	}
895 	UT_DEBUGMSG(("ypos for frame is %s \n",pszYpos));
896 
897 // ColXpos
898 
899 	if(!pSectionAP || !pSectionAP->getProperty("frame-col-xpos",pszColXpos))
900 	{
901 		m_iXColumn = 0;
902 	}
903 	else
904 	{
905 		m_iXColumn = UT_convertToLogicalUnits(pszColXpos);
906 	}
907 	UT_DEBUGMSG(("ColXpos for frame is %s \n",pszColXpos));
908 // colYpos
909 
910 	if(!pSectionAP || !pSectionAP->getProperty("frame-col-ypos",pszColYpos))
911 	{
912 		m_iYColumn = 0;
913 	}
914 	else
915 	{
916 		m_iYColumn = UT_convertToLogicalUnits(pszColYpos);
917 	}
918 	UT_DEBUGMSG(("ColYpos for frame is %s units %d \n",pszColYpos,m_iYColumn));
919 
920 
921 // PageXpos
922 
923 	if(!pSectionAP || !pSectionAP->getProperty("frame-page-xpos",pszPageXpos))
924 	{
925 		m_iXPage = 0;
926 	}
927 	else
928 	{
929 		m_iXPage = UT_convertToLogicalUnits(pszPageXpos);
930 	}
931 	UT_DEBUGMSG(("PageXpos for frame is %s units %d \n",pszPageXpos,m_iXPage));
932 // PageYpos
933 
934 	if(!pSectionAP || !pSectionAP->getProperty("frame-page-ypos",pszPageYpos))
935 	{
936 		m_iYPage = 0;
937 	}
938 	else
939 	{
940 		m_iYPage = UT_convertToLogicalUnits(pszPageYpos);
941 	}
942 	UT_DEBUGMSG(("PageYpos for frame is %s units %d \n",pszPageYpos,m_iYPage));
943 
944 
945 // Width
946 
947 	if(!pSectionAP || !pSectionAP->getProperty("frame-width",pszWidth))
948 	{
949 		m_iWidth = UT_convertToLogicalUnits("1.0in");
950 	}
951 	else
952 	{
953 		m_iWidth = UT_convertToLogicalUnits(pszWidth);
954 	}
955 	if(m_iWidth < m_pLayout->getGraphics()->tlu(2))
956 	{
957 		m_iWidth = m_pLayout->getGraphics()->tlu(2);
958 	}
959 	UT_DEBUGMSG(("Width %s \n",pszWidth));
960 // Height
961 
962 	if(!pSectionAP || !pSectionAP->getProperty("frame-height",pszHeight))
963 	{
964 		m_iHeight = UT_convertToLogicalUnits("1.0in");
965 	}
966 	else
967 	{
968 		m_iHeight = UT_convertToLogicalUnits(pszHeight);
969 	}
970 	if(m_iHeight < m_pLayout->getGraphics()->tlu(2))
971 	{
972 		m_iHeight = m_pLayout->getGraphics()->tlu(2);
973 	}
974 	m_iMinHeight = m_iHeight;
975 	UT_DEBUGMSG(("Height %s \n",pszHeight));
976 
977 // Xpadding
978 
979 
980 	if(!pSectionAP || !pSectionAP->getProperty("xpad",pszXpad))
981 	{
982 		m_iXpad = UT_convertToLogicalUnits("0.03in");
983 	}
984 	else
985 	{
986 		m_iXpad = UT_convertToLogicalUnits(pszXpad);
987 	}
988 
989 
990 // Ypadding
991 
992 
993 	if(!pSectionAP || !pSectionAP->getProperty("ypad",pszYpad))
994 	{
995 		m_iYpad = UT_convertToLogicalUnits("0.03in");
996 	}
997 	else
998 	{
999 		m_iYpad = UT_convertToLogicalUnits(pszYpad);
1000 	}
1001 
1002 
1003 	/* Frame-border properties:
1004 	 */
1005 
1006 	pSectionAP->getProperty ("color", pszColor);
1007 
1008 	pSectionAP->getProperty ("bot-color",pszBorderColor);
1009 	pSectionAP->getProperty ("bot-style",pszBorderStyle);
1010 	pSectionAP->getProperty ("bot-thickness",pszBorderWidth);
1011 
1012 	s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineBottom);
1013 
1014 	pszBorderColor = NULL;
1015 	pszBorderStyle = NULL;
1016 	pszBorderWidth = NULL;
1017 
1018 	pSectionAP->getProperty ("left-color", pszBorderColor);
1019 	pSectionAP->getProperty ("left-style", pszBorderStyle);
1020 	pSectionAP->getProperty ("left-thickness", pszBorderWidth);
1021 
1022 	s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineLeft);
1023 
1024 	pszBorderColor = NULL;
1025 	pszBorderStyle = NULL;
1026 	pszBorderWidth = NULL;
1027 
1028 	pSectionAP->getProperty ("right-color",pszBorderColor);
1029 	pSectionAP->getProperty ("right-style",pszBorderStyle);
1030 	pSectionAP->getProperty ("right-thickness", pszBorderWidth);
1031 
1032 	s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineRight);
1033 
1034 	pszBorderColor = NULL;
1035 	pszBorderStyle = NULL;
1036 	pszBorderWidth = NULL;
1037 
1038 	pSectionAP->getProperty ("top-color",  pszBorderColor);
1039 	pSectionAP->getProperty ("top-style",  pszBorderStyle);
1040 	pSectionAP->getProperty ("top-thickness",pszBorderWidth);
1041 
1042 	s_border_properties (pszBorderColor, pszBorderStyle, pszBorderWidth, pszColor, m_lineTop);
1043 
1044 	/* Frame fill
1045 	 */
1046 	m_background.reset ();
1047 
1048 	const gchar * pszBgStyle = NULL;
1049 	const gchar * pszBgColor = NULL;
1050 	const gchar * pszBackgroundColor = NULL;
1051 
1052 	pSectionAP->getProperty ("bg-style",    pszBgStyle);
1053 	pSectionAP->getProperty ("bgcolor",     pszBgColor);
1054 	pSectionAP->getProperty ("background-color", pszBackgroundColor);
1055 
1056 	s_background_properties (pszBgStyle, pszBgColor, pszBackgroundColor, m_background);
1057 
1058 //
1059 // Bounding Space
1060 //
1061 	if(!pSectionAP || !pSectionAP->getProperty("bounding-space",pszBoundingSpace))
1062 	{
1063 		m_iBoundingSpace = UT_convertToLogicalUnits("0.05in");
1064 	}
1065 	else
1066 	{
1067 		m_iBoundingSpace = UT_convertToLogicalUnits(pszBoundingSpace);
1068 	}
1069 	//
1070 	// Preferred Page
1071 	//
1072 	if(!pSectionAP || !pSectionAP->getProperty("frame-pref-page",pszPrefPage))
1073 	{
1074 		m_iPrefPage = -1;
1075 	}
1076 	else
1077 	{
1078 		if(pszPrefPage && *pszPrefPage != 0)
1079 			m_iPrefPage = atoi(pszPrefPage);
1080 		else
1081 			m_iPrefPage = -1;
1082 	}
1083 	//
1084 	// Preferred column
1085 	//
1086 	if(!pSectionAP || !pSectionAP->getProperty("frame-pref-column",pszPrefColumn))
1087 	{
1088 		m_iPrefColumn = 0;
1089 	}
1090 	else
1091 	{
1092 		if(pszPrefColumn && *pszPrefColumn != 0)
1093 			m_iPrefColumn = atoi(pszPrefColumn);
1094 		else
1095 			m_iPrefColumn = -1;
1096 	}
1097 	//
1098 	// Percent Width
1099 	//
1100 	if(pSectionAP && pSectionAP->getProperty("frame-rel-width",pszPercentWidth))
1101 	{
1102 		if(pszPercentWidth && (m_iWidth <= (m_pLayout->getGraphics()->tlu(2)+3)))
1103 		{
1104 			double frac_width = UT_convertFraction(pszPercentWidth);
1105 			fl_DocSectionLayout * pDSL = getDocSectionLayout();
1106 			m_iWidth = frac_width*pDSL->getActualColumnWidth();
1107 		}
1108 	}
1109 
1110 	//
1111 	// Min Height
1112 	//
1113 	if(pSectionAP && pSectionAP->getProperty("frame-min-height",pszMinHeight))
1114 	{
1115 		if(pszMinHeight)
1116 		{
1117 			m_iMinHeight = UT_convertToLogicalUnits(pszMinHeight);
1118 			m_bExpandHeight = true;
1119 		}
1120 	}
1121 
1122 	//
1123 	// Expandable Height
1124 	//
1125 	if(pSectionAP && pSectionAP->getProperty("frame-expand-height",pszExpandHeight))
1126 	{
1127 		m_iMinHeight = m_iHeight;
1128 		m_bExpandHeight = true;
1129 	}
1130 
1131 	//
1132 	// left/right aligned
1133 	//
1134 	const char * pszAlign = NULL;
1135 	if(pSectionAP && pSectionAP->getProperty("frame-horiz-align",pszAlign))
1136 	{
1137 		if(pszAlign && (strcmp(pszAlign,"right") == 0) && (m_iXpos == 0))
1138 		{
1139 			fl_DocSectionLayout * pDSL = getDocSectionLayout();
1140 			m_iXpos =  pDSL->getActualColumnWidth() - m_iWidth;
1141 		}
1142 	}
1143 
1144 }
1145 
_lookupMarginProperties(const PP_AttrProp * pSectionAP)1146 void fl_FrameLayout::_lookupMarginProperties(const PP_AttrProp* pSectionAP)
1147 {
1148 
1149 	UT_return_if_fail(pSectionAP);
1150 	FV_View * pView = getDocLayout()->getView();
1151 	GR_Graphics * pG = getDocLayout()->getGraphics();
1152 	UT_return_if_fail( pView && pG );
1153 
1154 	UT_sint32 iFramePositionTo = m_iFramePositionTo;
1155 	FL_FrameWrapMode iFrameWrapMode = m_iFrameWrapMode;
1156 	bool bIsTightWrap = m_bIsTightWrap;
1157 	UT_sint32 iXpos = m_iXpos;
1158 	UT_sint32 iYpos = m_iYpos;
1159 	UT_sint32 iXColumn = m_iXColumn;
1160 	UT_sint32 iYColumn = m_iYColumn;
1161 	UT_sint32 iXPage = m_iXPage;
1162 	UT_sint32 iYPage = m_iYPage;
1163 
1164 
1165 	if(pView->getViewMode() == VIEW_NORMAL && !pG->queryProperties(GR_Graphics::DGP_PAPER))
1166 	{
1167 		m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1168 		m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_RIGHT;
1169 		m_bIsTightWrap = false;
1170 		m_iXpos = 0;
1171 		m_iYpos = 0;
1172 		m_iXColumn = 0;
1173 		m_iYColumn = 0;
1174 		m_iXPage = 0;
1175 		m_iYPage = 0;
1176 	}
1177 	else
1178 	{
1179 		const gchar *pszPositionTo = NULL;
1180 		const gchar *pszWrapMode = NULL;
1181 		const gchar *pszXpos = NULL;
1182 		const gchar *pszYpos = NULL;
1183 		const gchar *pszColXpos = NULL;
1184 		const gchar *pszColYpos = NULL;
1185 		const gchar *pszPageXpos = NULL;
1186 		const gchar *pszPageYpos = NULL;
1187 		const gchar * pszTightWrapped = NULL;
1188 
1189 
1190 		// Position-to
1191 
1192 		if(!pSectionAP || !pSectionAP->getProperty("position-to",pszPositionTo))
1193 		{
1194 			m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1195 		}
1196 		else if(strcmp(pszPositionTo,"block-above-text") == 0)
1197 		{
1198 			m_iFramePositionTo = FL_FRAME_POSITIONED_TO_BLOCK;
1199 		}
1200 		else if(strcmp(pszPositionTo,"column-above-text") == 0)
1201 		{
1202 			m_iFramePositionTo = FL_FRAME_POSITIONED_TO_COLUMN;
1203 		}
1204 		else if(strcmp(pszPositionTo,"page-above-text") == 0)
1205 		{
1206 			m_iFramePositionTo = FL_FRAME_POSITIONED_TO_PAGE;
1207 		}
1208 		else
1209 		{
1210 			UT_DEBUGMSG(("Unknown Position to %s \n",pszPositionTo));
1211 			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
1212 			m_iFramePositionTo =  FL_FRAME_POSITIONED_TO_BLOCK;
1213 		}
1214 
1215 
1216 		// wrap-mode
1217 
1218 		if(!pSectionAP || !pSectionAP->getProperty("wrap-mode",pszWrapMode))
1219 		{
1220 			m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
1221 		}
1222 		else if(strcmp(pszWrapMode,"above-text") == 0)
1223 		{
1224 			m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
1225 		}
1226 		else if(strcmp(pszWrapMode,"below-text") == 0)
1227 		{
1228 			m_iFrameWrapMode = FL_FRAME_BELOW_TEXT;
1229 		}
1230 		else if(strcmp(pszWrapMode,"wrapped-to-right") == 0)
1231 		{
1232 			m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_RIGHT;
1233 		}
1234 		else if(strcmp(pszWrapMode,"wrapped-to-left") == 0)
1235 		{
1236 			m_iFrameWrapMode = FL_FRAME_WRAPPED_TO_LEFT;
1237 		}
1238 		else if(strcmp(pszWrapMode,"wrapped-both") == 0)
1239 		{
1240 			m_iFrameWrapMode = FL_FRAME_WRAPPED_BOTH_SIDES;
1241 		}
1242 		else if(strcmp(pszWrapMode,"wrapped-topbot") == 0)
1243 		{
1244 			m_iFrameWrapMode = FL_FRAME_WRAPPED_TOPBOT;
1245 		}
1246 		else
1247 		{
1248 			UT_DEBUGMSG(("Unknown wrap-mode %s \n",pszWrapMode));
1249 			UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
1250 			m_iFrameWrapMode = FL_FRAME_ABOVE_TEXT;
1251 		}
1252 		//
1253 		// Wrap type
1254 		//
1255 		if(!pSectionAP || !pSectionAP->getProperty("tight-wrap",pszTightWrapped))
1256 		{
1257 			m_bIsTightWrap = false;
1258 		}
1259 		else if(strcmp(pszTightWrapped,"1") == 0)
1260 		{
1261 			m_bIsTightWrap = true;
1262 		}
1263 		else
1264 		{
1265 			m_bIsTightWrap = false;
1266 		}
1267 
1268 		// Xpos
1269 
1270 		if(!pSectionAP || !pSectionAP->getProperty("xpos",pszXpos))
1271 		{
1272 			m_iXpos = 0;
1273 		}
1274 		else
1275 		{
1276 			m_iXpos = UT_convertToLogicalUnits(pszXpos);
1277 		}
1278 		UT_DEBUGMSG(("xpos for frame is %s \n",pszXpos));
1279 		// Ypos
1280 
1281 		if(!pSectionAP || !pSectionAP->getProperty("ypos",pszYpos))
1282 		{
1283 			m_iYpos = 0;
1284 		}
1285 		else
1286 		{
1287 			m_iYpos = UT_convertToLogicalUnits(pszYpos);
1288 		}
1289 		UT_DEBUGMSG(("ypos for frame is %s \n",pszYpos));
1290 
1291 		// ColXpos
1292 
1293 		if(!pSectionAP || !pSectionAP->getProperty("frame-col-xpos",pszColXpos))
1294 		{
1295 			m_iXColumn = 0;
1296 		}
1297 		else
1298 		{
1299 			m_iXColumn = UT_convertToLogicalUnits(pszColXpos);
1300 		}
1301 		UT_DEBUGMSG(("ColXpos for frame is %s \n",pszColXpos));
1302 		// colYpos
1303 
1304 		if(!pSectionAP || !pSectionAP->getProperty("frame-col-ypos",pszColYpos))
1305 		{
1306 			m_iYColumn = 0;
1307 		}
1308 		else
1309 		{
1310 			m_iYColumn = UT_convertToLogicalUnits(pszColYpos);
1311 		}
1312 		UT_DEBUGMSG(("ColYpos for frame is %s units %d \n",pszColYpos,m_iYColumn));
1313 
1314 
1315 		// PageXpos
1316 
1317 		if(!pSectionAP || !pSectionAP->getProperty("frame-page-xpos",pszPageXpos))
1318 		{
1319 			m_iXPage = 0;
1320 		}
1321 		else
1322 		{
1323 			m_iXPage = UT_convertToLogicalUnits(pszPageXpos);
1324 		}
1325 		UT_DEBUGMSG(("PageXpos for frame is %s \n",pszPageXpos));
1326 		// PageYpos
1327 
1328 		if(!pSectionAP || !pSectionAP->getProperty("frame-page-ypos",pszPageYpos))
1329 		{
1330 			m_iYPage = 0;
1331 		}
1332 		else
1333 		{
1334 			m_iYPage = UT_convertToLogicalUnits(pszPageYpos);
1335 		}
1336 		UT_DEBUGMSG(("PageYpos for frame is %s units %d \n",pszColYpos,m_iYPage));
1337 
1338 	}
1339 
1340 	fl_ContainerLayout*	pCL = getFirstLayout();
1341 	while (pCL)
1342 	{
1343 		pCL->lookupMarginProperties();
1344 		pCL = pCL->getNext();
1345 	}
1346 
1347 	if(iFramePositionTo != m_iFramePositionTo || iFrameWrapMode != m_iFrameWrapMode ||
1348 	   bIsTightWrap != m_bIsTightWrap || iXpos != m_iXpos || iYpos != m_iYpos ||
1349 	   iXColumn != m_iXColumn || iYColumn != m_iYColumn || iXPage != m_iXPage ||
1350 	   iYPage != m_iYPage)
1351 	{
1352 		collapse();
1353 	}
1354 }
1355 
localCollapse(void)1356 void fl_FrameLayout::localCollapse(void)
1357 {
1358 	// ClearScreen on our Cell. One Cell per layout.
1359 	fp_FrameContainer *pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
1360 	if (pFC)
1361 	{
1362 		pFC->clearScreen();
1363 	}
1364 
1365 	// get rid of all the layout information for every containerLayout
1366 	fl_ContainerLayout*	pCL = getFirstLayout();
1367 	while (pCL)
1368 	{
1369 		pCL->collapse();
1370 		pCL = pCL->getNext();
1371 	}
1372 	m_bNeedsReformat = true;
1373 }
1374 
collapse(void)1375 void fl_FrameLayout::collapse(void)
1376 {
1377 	FV_View * pView = getDocLayout()->getView();
1378 	if(pView)
1379 	{
1380 		if(pView->getFrameEdit()->getFrameLayout() == this)
1381 		{
1382 			pView->getFrameEdit()->setMode(FV_FrameEdit_NOT_ACTIVE);
1383 		}
1384 	}
1385 	localCollapse();
1386 	fp_FrameContainer *pFC = static_cast<fp_FrameContainer *>(getFirstContainer());
1387 	if (pFC)
1388 	{
1389 //
1390 // Remove it from the page.
1391 //
1392 		if(pFC->getPage())
1393 		{
1394 			pFC->getPage()->removeFrameContainer(pFC);
1395 			pFC->setPage(NULL);
1396 		}
1397 //
1398 // remove it from the linked list.
1399 //
1400 		fp_FrameContainer * pPrev = static_cast<fp_FrameContainer *>(pFC->getPrev());
1401 		if(pPrev)
1402 		{
1403 			pPrev->setNext(pFC->getNext());
1404 		}
1405 		if(pFC->getNext())
1406 		{
1407 			pFC->getNext()->setPrev(pPrev);
1408 		}
1409 		delete pFC;
1410 	}
1411 	setFirstContainer(NULL);
1412 	setLastContainer(NULL);
1413 }
1414 
1415 // Frame Background
1416 
s_background_properties(const gchar * pszBgStyle,const gchar * pszBgColor,const gchar * pszBackgroundColor,PP_PropertyMap::Background & background)1417 static void s_background_properties (const gchar * pszBgStyle, const gchar * pszBgColor,
1418 									 const gchar * pszBackgroundColor,
1419 									 PP_PropertyMap::Background & background)
1420 {
1421 	if (pszBgStyle)
1422 		{
1423 			if (strcmp (pszBgStyle, "0") == 0)
1424 				{
1425 					background.m_t_background = PP_PropertyMap::background_none;
1426 				}
1427 			else if (strcmp (pszBgStyle, "1") == 0)
1428 				{
1429 					if (pszBgColor)
1430 						{
1431 							background.m_t_background = PP_PropertyMap::background_type (pszBgColor);
1432 							if (background.m_t_background == PP_PropertyMap::background_solid)
1433 								UT_parseColor (pszBgColor, background.m_color);
1434 						}
1435 
1436 				}
1437 		}
1438 
1439 	if (pszBackgroundColor)
1440 		{
1441 			background.m_t_background = PP_PropertyMap::background_type (pszBackgroundColor);
1442 			if (background.m_t_background == PP_PropertyMap::background_solid)
1443 				UT_parseColor (pszBackgroundColor, background.m_color);
1444 		}
1445 }
1446 
s_border_properties(const gchar * border_color,const gchar * border_style,const gchar * border_width,const gchar * color,PP_PropertyMap::Line & line)1447 static void s_border_properties (const gchar * border_color, const gchar * border_style, const gchar * border_width,
1448 								 const gchar * color, PP_PropertyMap::Line & line)
1449 {
1450 	/* frame-border properties:
1451 	 *
1452 	 * (1) color      - defaults to value of "color" property
1453 	 * (2) line-style - defaults to solid (in contrast to "none" in CSS)
1454 	 * (3) thickness  - defaults to 1 layout unit (??, vs "medium" in CSS)
1455 	 */
1456 	line.reset ();
1457 
1458 	PP_PropertyMap::TypeColor t_border_color = PP_PropertyMap::color_type (border_color);
1459 	if (t_border_color)
1460 		{
1461 			line.m_t_color = t_border_color;
1462 			if (t_border_color == PP_PropertyMap::color_color)
1463 				UT_parseColor (border_color, line.m_color);
1464 		}
1465 	else if (color)
1466 		{
1467 			PP_PropertyMap::TypeColor t_color = PP_PropertyMap::color_type (color);
1468 
1469 			line.m_t_color = t_color;
1470 			if (t_color == PP_PropertyMap::color_color)
1471 				UT_parseColor (color, line.m_color);
1472 		}
1473 
1474 	line.m_t_linestyle = PP_PropertyMap::linestyle_type (border_style);
1475 	if (!line.m_t_linestyle)
1476 		line.m_t_linestyle = PP_PropertyMap::linestyle_solid;
1477 
1478 	line.m_t_thickness = PP_PropertyMap::thickness_type (border_width);
1479 	if (line.m_t_thickness == PP_PropertyMap::thickness_length)
1480 		{
1481 			if (UT_determineDimension (border_width, (UT_Dimension)-1) == DIM_PX)
1482 				{
1483 					double thickness = UT_LAYOUT_RESOLUTION * UT_convertDimensionless (border_width);
1484 					line.m_thickness = static_cast<UT_sint32>(thickness / UT_PAPER_UNITS_PER_INCH);
1485 				}
1486 			else
1487 				line.m_thickness = UT_convertToLogicalUnits (border_width);
1488 
1489 			if (!line.m_thickness)
1490 				{
1491 					double thickness = UT_LAYOUT_RESOLUTION;
1492 					line.m_thickness = static_cast<UT_sint32>(thickness / UT_PAPER_UNITS_PER_INCH);
1493 				}
1494 		}
1495 	else // ??
1496 		{
1497 			double thickness = UT_LAYOUT_RESOLUTION;
1498 			line.m_thickness = static_cast<UT_sint32>(thickness / UT_PAPER_UNITS_PER_INCH);
1499 		}
1500 }
1501 
1502