merge the formfield patch from ooo-build
[ooovba.git] / canvas / source / tools / pagemanager.cxx
blobf5c9760bc2793dc133600a8aaf53064600363a1b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pagemanager.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_canvas.hxx"
34 #include <boost/bind.hpp>
35 #include "pagemanager.hxx"
37 namespace canvas
40 //////////////////////////////////////////////////////////////////////////////////
41 // PageManager
42 //////////////////////////////////////////////////////////////////////////////////
44 //////////////////////////////////////////////////////////////////////////////////
45 // PageManager::allocateSpace
46 //////////////////////////////////////////////////////////////////////////////////
48 FragmentSharedPtr PageManager::allocateSpace( const ::basegfx::B2ISize& rSize )
50 // we are asked to find a location for the requested size.
51 // first we try to satisfy the request from the
52 // remaining space in the existing pages.
53 const PageContainer_t::iterator aEnd(maPages.end());
54 PageContainer_t::iterator it(maPages.begin());
55 while(it != aEnd)
57 FragmentSharedPtr pFragment((*it)->allocateSpace(rSize));
58 if(pFragment)
60 // the page created a new fragment, since we maybe want
61 // to consolidate sparse pages we keep a reference to
62 // the fragment.
63 maFragments.push_back(pFragment);
64 return pFragment;
67 ++it;
70 // otherwise try to create a new page and allocate space there...
71 PageSharedPtr pPage(new Page(mpRenderModule));
72 if(pPage->isValid())
74 maPages.push_back(pPage);
75 FragmentSharedPtr pFragment(pPage->allocateSpace(rSize));
76 maFragments.push_back(pFragment);
77 return pFragment;
80 // the rendermodule failed to create a new page [maybe out
81 // of videomemory], and all other pages could not take
82 // the new request. we decide to create a 'naked' fragment
83 // which will receive its location later.
84 FragmentSharedPtr pFragment(new PageFragment(rSize));
85 maFragments.push_back(pFragment);
86 return pFragment;
89 //////////////////////////////////////////////////////////////////////////////////
90 // PageManager::free
91 //////////////////////////////////////////////////////////////////////////////////
93 void PageManager::free( const FragmentSharedPtr& pFragment )
95 // erase the reference to the given fragment from our
96 // internal container.
97 FragmentContainer_t::iterator it(
98 std::remove(
99 maFragments.begin(),maFragments.end(),pFragment));
100 maFragments.erase(it,maFragments.end());
102 // let the fragment itself know about it...
103 // we need to pass 'this' as argument since the fragment
104 // needs to pass this to the page and can't create
105 // shared_ptr from itself...
106 pFragment->free(pFragment);
109 //////////////////////////////////////////////////////////////////////////////////
110 // PageManager::nakedFragment
111 //////////////////////////////////////////////////////////////////////////////////
113 void PageManager::nakedFragment( const FragmentSharedPtr& pFragment )
115 if(maPages.empty())
116 return;
118 // okay, one last chance is left, we try all available
119 // pages again. maybe some other fragment was deleted
120 // and we can exploit the space.
121 while(!(relocate(pFragment)))
123 // no way, we need to free up some space...
124 // TODO(F1): this is a heuristic, could
125 // be designed as a policy.
126 const FragmentContainer_t::const_iterator aEnd(maFragments.end());
127 FragmentContainer_t::const_iterator candidate(maFragments.begin());
128 while(candidate != aEnd)
130 if(!((*candidate)->isNaked()))
131 break;
132 ++candidate;
135 const ::basegfx::B2ISize& rSize((*candidate)->getSize());
136 sal_uInt32 nMaxArea(rSize.getX()*rSize.getY());
138 FragmentContainer_t::const_iterator it(candidate);
139 while(it != aEnd)
141 if(!((*it)->isNaked()))
143 const ::basegfx::B2ISize& rCandidateSize((*it)->getSize());
144 const sal_uInt32 nArea(rCandidateSize.getX()*rCandidateSize.getY());
145 if(nArea > nMaxArea)
147 candidate=it;
148 nMaxArea=nArea;
152 ++it;
155 // this does not erase the candidate,
156 // but makes it 'naked'...
157 (*candidate)->free(*candidate);
161 //////////////////////////////////////////////////////////////////////////////////
162 // PageManager::relocate
163 //////////////////////////////////////////////////////////////////////////////////
165 bool PageManager::relocate( const FragmentSharedPtr& pFragment )
167 // the fragment passed as argument is assumed to
168 // be naked, that is it is not located on any page.
169 // we try all available pages again, maybe some
170 // other fragment was deleted and we can exploit the space.
171 const PageContainer_t::iterator aEnd(maPages.end());
172 PageContainer_t::iterator it(maPages.begin());
173 while(it != aEnd)
175 // if the page at hand takes the fragment, we immediatelly
176 // call select() to pull the information from the associated
177 // image to the hardware surface.
178 if((*it)->nakedFragment(pFragment))
180 // dirty, since newly allocated.
181 pFragment->select(true);
182 return true;
185 ++it;
188 return false;
191 //////////////////////////////////////////////////////////////////////////////////
192 // PageManager::validatePages
193 //////////////////////////////////////////////////////////////////////////////////
195 void PageManager::validatePages()
197 ::std::for_each( maPages.begin(),
198 maPages.end(),
199 ::boost::mem_fn(&Page::validate));
202 //////////////////////////////////////////////////////////////////////////////////
203 // PageManager::getPageSize
204 //////////////////////////////////////////////////////////////////////////////////
206 ::basegfx::B2ISize PageManager::getPageSize() const
208 return mpRenderModule->getPageSize();
211 //////////////////////////////////////////////////////////////////////////////////
212 // PageManager::getRenderModule
213 //////////////////////////////////////////////////////////////////////////////////
215 canvas::IRenderModuleSharedPtr PageManager::getRenderModule() const
217 return mpRenderModule;