/* AbiWord * Copyright (C) 1998 AbiSource, Inc. * Copyright (C) 2002 Martin Sevior * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include #include "fp_ContainerObject.h" #include "fl_SectionLayout.h" #include "fl_DocLayout.h" #include "ut_debugmsg.h" #include "ut_assert.h" #include "fp_Column.h" #include "fp_Line.h" #include "fp_TableContainer.h" #include "fl_TableLayout.h" #include "fp_FootnoteContainer.h" #include "fp_FrameContainer.h" #include "fl_FootnoteLayout.h" #include "fl_DocLayout.h" #include "fl_BlockLayout.h" #include "fp_Column.h" #include "fp_Run.h" #include "fv_View.h" #include "gr_Painter.h" /*! Create container \param iType Container type \param pSectionLayout Section layout type used for this container */ fp_ContainerObject::fp_ContainerObject(FP_ContainerType iType, fl_SectionLayout* pSectionLayout) : m_iConType(iType), m_pSectionLayout(pSectionLayout), m_iDirection(UT_BIDI_UNSET), m_iBreakTick(0), m_iRef(0), m_bCanDelete(true) { UT_ASSERT(pSectionLayout); } const char * fp_ContainerObject::getContainerString(void) { switch (getContainerType()) { case FP_CONTAINER_RUN: return "FP_CONTAINER_RUN"; case FP_CONTAINER_LINE: return "FP_CONTAINER_LINE"; case FP_CONTAINER_VERTICAL: return "FP_CONTAINER_VERTICAL"; case FP_CONTAINER_ROW: return "FP_CONTAINER_ROW"; case FP_CONTAINER_TABLE: return "FP_CONTAINER_TABLE"; case FP_CONTAINER_CELL: return "FP_CONTAINER_CELL"; case FP_CONTAINER_COLUMN: return "FP_CONTAINER_COLUMN"; case FP_CONTAINER_HDRFTR: return "FP_CONTAINER_HDRFTR"; case FP_CONTAINER_ENDNOTE: return "FP_CONTAINER_ENDNOTE"; case FP_CONTAINER_FOOTNOTE: return "FP_CONTAINER_FOOTNOTE"; case FP_CONTAINER_ANNOTATION: return "FP_CONTAINER_ANNOTATION"; case FP_CONTAINER_COLUMN_POSITIONED: return "FP_CONTAINER_COLUMN_POSITIONED"; case FP_CONTAINER_COLUMN_SHADOW: return "FP_CONTAINER_COLUMN_SHADOW"; case FP_CONTAINER_FRAME: return "FP_CONTAINER_FRAME"; case FP_CONTAINER_TOC: return "FP_CONTAINER_TOC"; default: return "unknown FP_CONTAINER object"; } } /*! Destruct container */ fp_ContainerObject::~fp_ContainerObject() { m_iConType = static_cast(-1); // UT_ASSERT(m_bCanDelete); } /*! * return true is this container is of column type */ bool fp_ContainerObject::isColumnType(void) const { bool b = (m_iConType == FP_CONTAINER_COLUMN) || (m_iConType == FP_CONTAINER_HDRFTR) || (m_iConType == FP_CONTAINER_COLUMN_SHADOW) || (m_iConType == FP_CONTAINER_FRAME) || (m_iConType == FP_CONTAINER_COLUMN_POSITIONED) || (m_iConType == FP_CONTAINER_FOOTNOTE) || (m_iConType == FP_CONTAINER_ANNOTATION) ; return b; } /*! * Return the DocSectionLayout that owns this */ fl_DocSectionLayout * fp_ContainerObject::getDocSectionLayout(void) { fl_ContainerLayout * pCL = static_cast(getSectionLayout()); while(pCL && (pCL->getContainerType() != FL_CONTAINER_DOCSECTION) && (pCL->getContainerType() != FL_CONTAINER_HDRFTR)) { xxx_UT_DEBUGMSG(("getDocSectionLayout: Container type %s \n",getContainerString())); pCL = pCL->myContainingLayout(); } if(pCL && (pCL->getContainerType() == FL_CONTAINER_HDRFTR)) { return static_cast(pCL)->getDocSectionLayout(); } else if(pCL) { return static_cast(pCL); } return NULL; } /*! * Return a pointer to the Graphics class for this object */ GR_Graphics * fp_ContainerObject::getGraphics(void) const { return getSectionLayout()->getDocLayout()->getGraphics(); } /* *---------------------------------------------------------------------- */ /*! Create container \param iType Container type \param pSectionLayout Section layout type used for this container */ fp_Container::fp_Container(FP_ContainerType iType, fl_SectionLayout* pSectionLayout) : fp_ContainerObject(iType, pSectionLayout), m_pContainer(NULL), m_pNext(NULL), m_pPrev(NULL), m_pMyBrokenContainer(NULL), m_cBrokenContainers(0), m_FillType(NULL,this,FG_FILL_TRANSPARENT) { m_vecContainers.clear(); m_FillType.setDocLayout(pSectionLayout->getDocLayout()); } /*! Destruct container */ fp_Container::~fp_Container() { // // The containers referenced in the m_vecContainers vector are owned by their // respective fl_Layout classes and so are not destructed here. // } /*! * This returns a pointer to a container broken across a page that * contains this container. This is used (in the first instance) by the * Table pagination code which breaks tables across pages. This returns * the pointer to the broken table this container is within. */ fp_Container * fp_Container::getMyBrokenContainer(void) const { return m_pMyBrokenContainer; } /*! * Sets the pointer to the broken table which contains this container. */ void fp_Container::setMyBrokenContainer(fp_Container * pMyBroken) { m_pMyBrokenContainer = pMyBroken; fp_Container * pc = this; while (NULL != pc) { pc->incBrokenCount(); pc = pc->getContainer(); } } void fp_Container::setNext(fp_ContainerObject * pNext) { m_pNext = pNext; if(pNext) pNext->ref(); } void fp_Container::setPrev(fp_ContainerObject * pPrev) { m_pPrev = pPrev; if(pPrev) pPrev->ref(); } /*! * Recursive clears all broken containers contained by this container */ void fp_Container::clearBrokenContainers(void) { if(m_pMyBrokenContainer) { fp_Container * pc = this; while (NULL != pc) { pc->decBrokenCount(); pc = pc->getContainer(); } m_pMyBrokenContainer = NULL; } if (0 != getBrokenCount()) { UT_sint32 i =0; for(i=0;(i(getNthCon(i)); if (pCon && (0 != pCon->getBrokenCount())) { pCon->clearBrokenContainers(); } } } m_cBrokenContainers = 0; } UT_uint32 fp_Container::binarysearchCons(const void* key, int (*compar)(const void *, const void *)) { UT_uint32 u = m_vecContainers.binarysearch(key, compar); return u; } /*! * The container that encloses this container. */ void fp_Container::setContainer(fp_Container * pCO) { UT_ASSERT(pCO != this); m_pContainer = pCO; if(pCO != NULL) { m_FillType.setParent(pCO->getFillType()); } else { m_FillType.setParent(NULL); } } /*! * Return the container that encloses this container. */ fp_Container * fp_Container::getContainer(void) const { return m_pContainer; } /*! * Return the column that encloses this container. */ fp_Container* fp_Container::getColumn(void) const { const fp_Container * pCon = this; while(pCon && ((!pCon->isColumnType())) ) { pCon = pCon->getContainer(); } return const_cast(pCon); } /*! * Get the page containing this container. */ fp_Page * fp_Container::getPage(void) const { fp_Container * pCon = getColumn(); if(pCon == NULL) { return NULL; } if(pCon->getContainerType() == FP_CONTAINER_COLUMN) { return static_cast(pCon)->getPage(); } if(pCon->getContainerType() == FP_CONTAINER_COLUMN_POSITIONED) { return static_cast(pCon)->getPage(); } if(pCon->getContainerType() == FP_CONTAINER_FRAME) { return static_cast(pCon)->getPage(); } if(pCon->getContainerType() == FP_CONTAINER_COLUMN_SHADOW) { return static_cast(pCon)->getPage(); } if(pCon->getContainerType() == FP_CONTAINER_HDRFTR) { return NULL; } if(pCon->getContainerType() == FP_CONTAINER_FOOTNOTE) { return static_cast(pCon)->getPage(); } if(pCon->getContainerType() == FP_CONTAINER_ANNOTATION) { return static_cast(pCon)->getPage(); } UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return NULL; } void fp_Container::insertConAt(fp_ContainerObject * pCon, UT_sint32 i) { #if 0 // DEBUG if(pCon->getContainerType() == FP_CONTAINER_LINE) { fp_Line * pLine = static_cast(pCon); UT_ASSERT(pLine->getBlock() != NULL); if(countCons() > 0) { fp_ContainerObject * pNext = m_vecContainers.getNthItem(i); if(pNext && pNext->getContainerType() == FP_CONTAINER_LINE) { fl_BlockLayout * pBL = pLine->getBlock(); fl_BlockLayout * pNextBL = static_cast(pNext)->getBlock(); if(pBL->canContainPoint() && pNextBL->canContainPoint()) UT_ASSERT(pNextBL->getPosition() >= pBL->getPosition()); } } } #endif UT_ASSERT(pCon != this); m_vecContainers.insertItemAt(pCon,i); pCon->ref(); } void fp_Container::addCon(fp_ContainerObject * pCon) { #if 0 // DEBUG if(pCon->getContainerType() == FP_CONTAINER_LINE) { fp_Line * pLine = static_cast(pCon); UT_ASSERT(pLine->getBlock() != NULL); UT_sint32 i = countCons(); if(i>0) { fp_ContainerObject * pPrev = m_vecContainers.getNthItem(i-1); if(pPrev && pPrev->getContainerType() == FP_CONTAINER_LINE) { fl_BlockLayout * pBL = pLine->getBlock(); fl_BlockLayout * pPrevBL = static_cast(pPrev)->getBlock(); UT_ASSERT(pPrevBL->getPosition() <= pBL->getPosition()); } } } #endif UT_ASSERT(pCon != this); m_vecContainers.addItem(pCon); pCon->ref(); } fp_ContainerObject * fp_Container:: getNthCon(UT_sint32 i) const { if(countCons() == 0) return NULL; return m_vecContainers.getNthItem(i); } UT_sint32 fp_Container::countCons(void) const { return m_vecContainers.getItemCount(); } UT_sint32 fp_Container::findCon(fp_ContainerObject * pCon) const { return m_vecContainers.findItem(pCon); } bool fp_Container::isEmpty(void) const { return m_vecContainers.getItemCount() == 0; } bool fp_Container::getPageRelativeOffsets(UT_Rect &r) const { // the X offset of a container is relative to page margin, what we // want is offset relative to the page edge fp_Container * pColumnC = getColumn(); UT_return_val_if_fail(pColumnC,false); fl_DocSectionLayout * pDSL = NULL; if(pColumnC->getContainerType() != FP_CONTAINER_FOOTNOTE || pColumnC->getContainerType() != FP_CONTAINER_ANNOTATION) { if(pColumnC->getContainerType() == FP_CONTAINER_FRAME) { fp_FrameContainer * pFC = static_cast(pColumnC); pDSL = pFC->getDocSectionLayout(); } else { fl_SectionLayout * pSL = static_cast(pColumnC->getSectionLayout()); if(pSL->getContainerType() == FL_CONTAINER_HDRFTR) { pDSL = static_cast(pSL)->getDocSectionLayout(); } else if(pSL->getContainerType() == FL_CONTAINER_SHADOW) { pDSL = static_cast(static_cast(pSL)->getSectionLayout()); } else { pDSL = pSL->getDocSectionLayout(); } } } else if (pColumnC->getContainerType() == FP_CONTAINER_FOOTNOTE) { fp_FootnoteContainer * pFC = static_cast(pColumnC); fl_FootnoteLayout * pFL = static_cast(pFC->getSectionLayout()); pDSL = static_cast(pFL->myContainingLayout()); } else if (pColumnC->getContainerType() == FP_CONTAINER_ANNOTATION) { fp_AnnotationContainer * pAC = static_cast(pColumnC); fl_AnnotationLayout * pAL = static_cast(pAC->getSectionLayout()); pDSL = static_cast(pAL->myContainingLayout()); } UT_return_val_if_fail(pDSL,false); UT_ASSERT(pDSL->getContainerType() == FL_CONTAINER_DOCSECTION); r.left = pDSL->getLeftMargin(); r.top = pDSL->getTopMargin(); r.width = getDrawingWidth(); r.height = getHeight(); r.left += getX(); r.top += getY(); return true; } void fp_Container::justRemoveNthCon(UT_sint32 i) { fp_ContainerObject * pCon = getNthCon(i); pCon->unref(); m_vecContainers.deleteNthItem(i); } void fp_Container::deleteNthCon(UT_sint32 i) { fp_Container * pCon = static_cast(getNthCon(i)); if(pCon->getContainer() == this) { pCon->setContainer(NULL); } pCon->unref(); m_vecContainers.deleteNthItem(i); xxx_UT_DEBUGMSG(("AFter deleting item %d in %x there are %d cons left \n",i,this,countCons())); } bool fp_Container::isOnScreen() const { UT_return_val_if_fail(getSectionLayout(),false); FV_View *pView = getSectionLayout()->getDocLayout()->getView(); if(!pView) { return false; } if(getPage()) { return getPage()->isOnScreen(); } return false; } /*! * Need to be able to fiddle with the fillType so don't do a const return; */ fg_FillType * fp_Container::getFillType(void) { return & m_FillType; } /*! * To draw the background under text. Basic idea is to draw the colour * or image defined here unless the fill type is transparent. If't transparent * we recursively call it's parents until it's not transparent. */ fg_FillType::fg_FillType(fg_FillType *pParent, fp_ContainerObject * pContainer, FG_Fill_Type iType): m_pParent(pParent), m_pContainer(pContainer), m_pDocLayout(NULL), m_FillType(iType), m_pImage(NULL), m_pGraphic(NULL), m_iGraphicTick(0), m_bTransparentForPrint(false), m_color(255,255,255), m_TransColor(255,255,255), m_bTransColorSet(false), m_bColorSet(false), m_iWidth(0), m_iHeight(0), m_pDocImage(NULL), m_pDocGraphic(NULL) { } fg_FillType::~fg_FillType(void) { DELETEP(m_pImage); DELETEP(m_pGraphic); } /*! * Set the parent of this fill class. */ void fg_FillType::setParent(fg_FillType * pParent) { m_pParent = pParent; } /*! * set this class to have a solid color fill */ void fg_FillType::setColor(UT_RGBColor & color) { xxx_UT_DEBUGMSG(("Fill type set to color class \n")); m_FillType = FG_FILL_COLOR; m_color = color; m_bColorSet = true; m_bTransparentForPrint = false; DELETEP(m_pImage); DELETEP(m_pGraphic); } /*! * set this class to have a solid color fill unless this is a NULL string * pointer. This is an on-screen color only. Don't print this. */ void fg_FillType::setColor(const char * pszColor) { if(pszColor) { if(strcmp(pszColor,"transparent") == 0) { if(!m_bTransColorSet) { m_FillType = FG_FILL_TRANSPARENT; } m_bColorSet = false; } else { m_FillType = FG_FILL_COLOR; m_bColorSet = true; DELETEP(m_pImage); DELETEP(m_pGraphic); } m_color.setColor(pszColor); m_bTransparentForPrint = false; } else { if(!m_bTransColorSet) { m_FillType = FG_FILL_TRANSPARENT; m_bColorSet = false; } } } /*! * Set a pointer to the Image pointer in fl_DocSectionLayout. This * enables many pages to share the same image without having to generate * a new image for every page. */ void fg_FillType::setImagePointer(FG_Graphic ** pDocGraphic,GR_Image ** pDocImage) { if(pDocImage != NULL) { DELETEP(m_pImage); DELETEP(m_pGraphic); } m_pDocImage = pDocImage; m_pDocGraphic = pDocGraphic; m_FillType = FG_FILL_IMAGE; } /*! * set this class to have a solid color fill but not print this color. */ void fg_FillType::setTransColor(UT_RGBColor & color) { UT_DEBUGMSG(("Fill type set to color class \n")); m_FillType = FG_FILL_COLOR; m_TransColor = color; DELETEP(m_pImage); DELETEP(m_pGraphic); m_bTransColorSet = true; } /*! * set this class to have a solid color fill unless this is a NULL string * pointer */ void fg_FillType::setTransColor(const char * pszColor) { if(pszColor) { if(strcmp(pszColor,"transparent") == 0) { if(!m_bColorSet) { m_FillType = FG_FILL_TRANSPARENT; } m_bTransColorSet = false; m_bTransparentForPrint = false; } else { m_FillType = FG_FILL_COLOR; m_bTransColorSet = true; m_bTransparentForPrint = true; } m_TransColor.setColor(pszColor); } else { if(!m_bColorSet) { m_FillType = FG_FILL_TRANSPARENT; m_bTransparentForPrint = false; } m_bTransparentForPrint = false; } DELETEP(m_pImage); DELETEP(m_pGraphic); } /*! * set this class to be transparent. */ void fg_FillType::setTransparent(void) { m_FillType = FG_FILL_TRANSPARENT; DELETEP(m_pImage); DELETEP(m_pGraphic); m_bTransparentForPrint = false; } /*! * set this class to have an image background for fills. */ void fg_FillType::setImage(FG_Graphic * pGraphic, GR_Image * pImage, GR_Graphics * pG, UT_sint32 iWidth, UT_sint32 iHeight) { m_FillType = FG_FILL_IMAGE; DELETEP(m_pImage); DELETEP(m_pGraphic); m_pImage = pImage; m_pGraphic = pGraphic; m_bTransparentForPrint = false; setWidthHeight(pG,iWidth,iHeight); m_pDocImage = NULL; } /*! * Set the doc layout for this class. */ void fg_FillType::setDocLayout(FL_DocLayout * pDocLayout) { m_pDocLayout = pDocLayout; if(m_pDocLayout) { m_iGraphicTick = m_pDocLayout->getGraphicTick(); } } /*! * Set that the fill should be transparent if we're printing. */ void fg_FillType::markTransparentForPrint(void) { m_bTransparentForPrint = true; } /*! * Return the parent of this class. */ fg_FillType * fg_FillType::getParent(void) const { return m_pParent; } /*! * Return the filltype of this class. */ FG_Fill_Type fg_FillType::getFillType(void) const { return m_FillType; } void fg_FillType::_regenerateImage(GR_Graphics * pG) { UT_return_if_fail(m_pGraphic); UT_return_if_fail(m_pDocLayout); DELETEP(m_pImage); m_pImage = m_pGraphic->regenerateImage(pG); setWidthHeight(pG,m_iWidth,m_iHeight); UT_Rect rec(0,0,m_iWidth,m_iHeight); m_pImage->scaleImageTo(pG,rec); m_iGraphicTick = m_pDocLayout->getGraphicTick(); } /*! * Return the most appropriate color. */ const UT_RGBColor * fg_FillType::getColor(void) const { if(m_bColorSet) { return & m_color; } if(m_bTransColorSet) { return &m_TransColor; } if(getParent()) { return getParent()->getColor(); } return &m_color; } void fg_FillType::setWidthHeight(GR_Graphics * pG, UT_sint32 iWidth, UT_sint32 iHeight, bool bDoImage) { if((m_iWidth == iWidth) && (m_iHeight == iHeight)) { return; } m_iWidth = iWidth; m_iHeight = iHeight; if((m_iHeight <= 0) || (m_iWidth <= 0)) { return; } if(m_pImage && bDoImage) { DELETEP(m_pImage); m_pImage = m_pGraphic->regenerateImage(pG); UT_Rect rec(0,0,iWidth,iHeight); m_pImage->scaleImageTo(pG,rec); } if(m_pDocImage && *m_pDocImage && bDoImage) { DELETEP(*m_pDocImage); *m_pDocImage = (*m_pDocGraphic)->regenerateImage(pG); UT_Rect rec(0,0,m_iWidth,m_iHeight); (*m_pDocImage)->scaleImageTo(pG,rec); } } void fg_FillType::setWidth(GR_Graphics * pG, UT_sint32 iWidth) { if(iWidth == m_iWidth) { return; } m_iWidth = iWidth; if((m_iHeight <= 0) || (m_iWidth <= 0)) { return; } if(m_pImage) { DELETEP(m_pImage); m_pImage = m_pGraphic->regenerateImage(pG); UT_Rect rec(0,0,m_iWidth,m_iHeight); m_pImage->scaleImageTo(pG,rec); } if(m_pDocImage && *m_pDocImage) { DELETEP(*m_pDocImage); *m_pDocImage = (*m_pDocGraphic)->regenerateImage(pG); UT_Rect rec(0,0,m_iWidth,m_iHeight); (*m_pDocImage)->scaleImageTo(pG,rec); } } void fg_FillType::setHeight(GR_Graphics * pG, UT_sint32 iHeight) { if(iHeight == m_iHeight) { return; } m_iHeight = iHeight; if((m_iHeight <= 0) || (m_iWidth <= 0)) { return; } if(m_pImage) { DELETEP(m_pImage); m_pImage = m_pGraphic->regenerateImage(pG); UT_Rect rec(0,0,m_iWidth,m_iHeight); m_pImage->scaleImageTo(pG,rec); } if(m_pDocImage && *m_pDocImage) { DELETEP(*m_pDocImage); *m_pDocImage = (*m_pDocGraphic)->regenerateImage(pG); UT_Rect rec(0,0,m_iWidth,m_iHeight); (*m_pDocImage)->scaleImageTo(pG,rec); } } /*! * Actually do the fill for this class. */ void fg_FillType::Fill(GR_Graphics * pG, UT_sint32 & srcX, UT_sint32 & srcY, UT_sint32 x, UT_sint32 y, UT_sint32 width, UT_sint32 height) { if(y < -9999999) { // Whoops! object is offscreen! // Bailout return; } // // Images appear to be 1 pixel narrower than rectangular // fills // UT_sint32 imageOffset = pG->tlu(1); // // Have to adjust for spacing between cells // GR_Painter painter(pG); UT_RGBColor white(255,255,255); bool bIsFrame = false; if(m_pContainer && (m_pContainer->getContainerType() == FP_CONTAINER_CELL)) { const fp_CellContainer * pCell = static_cast(m_pContainer); UT_sint32 xoff,yoff; pCell->getLeftTopOffsets(xoff,yoff); if(m_FillType == FG_FILL_IMAGE) { srcX -= xoff; srcY -= 2*yoff; } } if(m_pContainer && (m_pContainer->getContainerType() == FP_CONTAINER_FRAME)) { const fp_FrameContainer * pFrame = static_cast(m_pContainer); UT_sint32 xoff = pFrame->getXPad(); UT_sint32 yoff = pFrame->getYPad(); if(m_FillType == FG_FILL_IMAGE) { srcX += xoff; srcY += yoff; bIsFrame = true; } if(getParent() && ((m_FillType == FG_FILL_IMAGE) || (m_FillType == FG_FILL_TRANSPARENT) )) { m_color = getParent()->m_color; m_bColorSet = getParent()->m_bColorSet; m_TransColor = getParent()->m_TransColor; m_bTransColorSet = getParent()->m_bTransColorSet; if(m_pDocImage == NULL) m_pDocImage = getParent()->m_pDocImage; } } if(m_pContainer && (m_pContainer->getContainerType() == FP_CONTAINER_RUN)) { if(m_iGraphicTick != m_pDocLayout->getGraphicTick() ) { m_iGraphicTick = m_pDocLayout->getGraphicTick(); fp_Run * pRun = static_cast(m_pContainer); pRun->_setFont(NULL); pRun->lookupProperties(pG); if((m_FillType == FG_FILL_IMAGE) && (m_pDocImage == NULL)) { _regenerateImage(pG); } } } UT_Rect src; UT_Rect dest; xxx_UT_DEBUGMSG(("----Called fill -- Parent = %x Container %x FillType %d \n",m_pParent,m_pContainer,m_FillType)); if(!pG->queryProperties(GR_Graphics::DGP_SCREEN)) { if(m_bTransparentForPrint) { if(getParent() && m_pContainer) { UT_sint32 newX = x + (m_pContainer->getX()); UT_sint32 newY = y + (m_pContainer->getY()); getParent()->Fill(pG,newX,newY,x,y,width,height); return; } return; } if(m_FillType == FG_FILL_TRANSPARENT) { return; } if(m_FillType == FG_FILL_IMAGE) { if(m_pDocImage == NULL) { _regenerateImage(pG); } src.left = srcX; src.top = srcY; src.width = width; src.height = height; dest.left = x; dest.top = y; dest.width = width; dest.height = height; // // Overwrite With white first for alpha blended images // if(!pG->queryProperties(GR_Graphics::DGP_PAPER)) { painter.fillRect(white,dest); } if(m_pDocImage == NULL) { painter.fillRect(m_pImage,src,dest); } else if(*m_pDocImage) { if(!bIsFrame) { painter.fillRect(*m_pDocImage,src,dest); } else { painter.drawImage(*m_pDocImage, dest.left,dest.top); } } return; } if(m_FillType == FG_FILL_COLOR && m_bColorSet) { painter.fillRect(m_color,x,y,width,height); return; } return; } if(m_FillType == FG_FILL_TRANSPARENT) { xxx_UT_DEBUGMSG(("Fill type transparent ! \n")); if(getParent() && m_pContainer) { xxx_UT_DEBUGMSG(("Fill type transparent chaining up to parent %x ! \n",getParent())); UT_sint32 newX = srcX + (m_pContainer->getX()); UT_sint32 newY = srcY + (m_pContainer->getY()); getParent()->Fill(pG,newX,newY,x,y,width,height); return; } xxx_UT_DEBUGMSG(("Fill type transparent but no parent ! \n")); painter.fillRect(white,x,y,width,height); return; } if(m_FillType == FG_FILL_COLOR && m_bColorSet) { xxx_UT_DEBUGMSG(("Fill type Color ! \n")); painter.fillRect(m_color,x,y,width,height); return; } if(m_FillType == FG_FILL_IMAGE) { xxx_UT_DEBUGMSG(("Fill type Image ! srcX %d srcY %d x %d y %d width %d height %d \n",srcX,srcY,x,y,width,height)); if((m_pDocImage == NULL) && (m_pDocLayout->getGraphicTick() != m_iGraphicTick)) { _regenerateImage(pG); } if(srcX < 0) { UT_sint32 iX = -srcX; srcX = 0; painter.fillRect(white,x,y,iX,height); width -= iX; } if(srcY < 0) { UT_sint32 iY = -srcY; srcY = 0; painter.fillRect(white,x,y,width,iY); height -= iY; } if(m_pContainer) { xxx_UT_DEBUGMSG((" ContainerType %s \n ",m_pContainer->getContainerString())); } xxx_UT_DEBUGMSG(("m_pDocImage %p Trans col %d m_bColorSet %d \n ",m_pDocImage, m_bTransColorSet, m_bColorSet)); src.left = srcX; src.top = srcY; src.width = width+imageOffset; src.height = height+imageOffset; dest.left = x; dest.top = y; dest.width = width+imageOffset; dest.height = height+imageOffset; // // Only fill the bits exposed by the clip rect // const UT_Rect * pClip = pG->getClipRect(); if(pClip != NULL) { UT_sint32 leftDiff = 0; UT_sint32 widthDiff = 0; UT_sint32 topDiff = 0; UT_sint32 heightDiff = 0; if(pClip->left > dest.left) { leftDiff = pClip->left - dest.left - pG->tlu(2) -1; src.left += leftDiff; dest.left += leftDiff; src.width -= leftDiff; dest.width -= leftDiff; if(dest.width <= 0) { return; } } if(pClip->left + pClip->width < dest.left + dest.width) { widthDiff = dest.left + dest.width - pClip->left - pClip->width - pG->tlu(2) -1; src.width -= widthDiff; dest.width -= widthDiff; if(dest.width <= 0) { return; } } if(pClip->top > dest.top) { topDiff = pClip->top - dest.top - pG->tlu(2) -1; src.top += topDiff; dest.top += topDiff; src.height -= topDiff; dest.height -= topDiff; if(dest.height <= 0) { return; } } if(pClip->top + pClip->height < dest.top + dest.height) { heightDiff = dest.top + dest.height - pClip->top - pClip->height - pG->tlu(2) -1; src.height -= heightDiff; dest.height -= heightDiff; if(dest.height <= 0) { return; } } } if(m_pDocImage == NULL) { if(m_bTransColorSet) { painter.fillRect(m_TransColor,x,y,width,height); } else if(m_bColorSet) { painter.fillRect(m_color,x,y,width,height); } else { painter.fillRect(white,x,y,width,height); } painter.fillRect(m_pImage,src,dest); } else if(*m_pDocImage) { if(m_bTransColorSet) { painter.fillRect(m_TransColor,x,y,width,height); } else if(m_bColorSet) { painter.fillRect(m_color,x,y,width,height); } else if(getParent() && getParent()->m_pDocImage && *getParent()->m_pDocImage) { painter.fillRect(white,x,y,width,height); painter.fillRect(*getParent()->m_pDocImage,src,dest); } else { painter.fillRect(white,x,y,width,height); } painter.fillRect(*m_pDocImage,src,dest); } else { painter.fillRect(white,x,y,width,height); } } if(m_FillType == FG_FILL_COLOR && m_bTransColorSet) { xxx_UT_DEBUGMSG(("Fill type Trans Color ! \n")); painter.fillRect(m_TransColor,x,y,width,height); return; } return; }