1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pagemanager.cxx,v $
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"
40 //////////////////////////////////////////////////////////////////////////////////
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());
57 FragmentSharedPtr
pFragment((*it
)->allocateSpace(rSize
));
60 // the page created a new fragment, since we maybe want
61 // to consolidate sparse pages we keep a reference to
63 maFragments
.push_back(pFragment
);
70 // otherwise try to create a new page and allocate space there...
71 PageSharedPtr
pPage(new Page(mpRenderModule
));
74 maPages
.push_back(pPage
);
75 FragmentSharedPtr
pFragment(pPage
->allocateSpace(rSize
));
76 maFragments
.push_back(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
);
89 //////////////////////////////////////////////////////////////////////////////////
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(
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
)
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()))
135 const ::basegfx::B2ISize
& rSize((*candidate
)->getSize());
136 sal_uInt32
nMaxArea(rSize
.getX()*rSize
.getY());
138 FragmentContainer_t::const_iterator
it(candidate
);
141 if(!((*it
)->isNaked()))
143 const ::basegfx::B2ISize
& rCandidateSize((*it
)->getSize());
144 const sal_uInt32
nArea(rCandidateSize
.getX()*rCandidateSize
.getY());
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());
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);
191 //////////////////////////////////////////////////////////////////////////////////
192 // PageManager::validatePages
193 //////////////////////////////////////////////////////////////////////////////////
195 void PageManager::validatePages()
197 ::std::for_each( maPages
.begin(),
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
;