xref: /trunk/main/canvas/source/tools/surfaceproxy.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_canvas.hxx"
30 
31 #include <boost/bind.hpp>
32 #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
33 #include <basegfx/polygon/b2dpolygontriangulator.hxx>
34 #include <basegfx/polygon/b2dpolypolygontools.hxx>
35 #include "surfaceproxy.hxx"
36 
37 namespace canvas
38 {
39     //////////////////////////////////////////////////////////////////////////////////
40     // SurfaceProxy::SurfaceProxy
41     //////////////////////////////////////////////////////////////////////////////////
42 
43     SurfaceProxy::SurfaceProxy( const canvas::IColorBufferSharedPtr& pBuffer,
44                                 const PageManagerSharedPtr&          pPageManager ) :
45         mpPageManager( pPageManager ),
46         maSurfaceList(),
47         mpBuffer( pBuffer )
48     {
49         const ::basegfx::B2ISize aImageSize(mpBuffer->getWidth(),mpBuffer->getHeight());
50         const ::basegfx::B2ISize aPageSize(mpPageManager->getPageSize());
51         const sal_Int32 aPageSizeX(aPageSize.getX());
52         const sal_Int32 aPageSizeY(aPageSize.getY());
53         const sal_Int32 aImageSizeX(aImageSize.getX());
54         const sal_Int32 aImageSizeY(aImageSize.getY());
55 
56         // see if the size of the colorbuffer is larger than the size
57         // of a single page. if this is the case we divide the
58         // colorbuffer into as many surfaces as we need to get the
59         // whole area distributed.  otherwise (the colorbuffer is
60         // smaller than the size of a single page) we search for free
61         // pages or create a new one.
62         // the incoming image is too large to fit into a single
63         // page.  strategy: we split the image into rectangular
64         // areas that are as large as the maximum page size
65         // dictates and follow the strategy for fitting images.
66         size_t dwNumSurfaces(0);
67         for(sal_Int32 y=0; y<aImageSizeY; y+=aPageSizeY)
68             for(sal_Int32 x=0; x<aImageSizeX; x+=aPageSizeX)
69                 ++dwNumSurfaces;
70         maSurfaceList.reserve(dwNumSurfaces);
71 
72         for(sal_Int32 y=0; y<aImageSizeY; y+=aPageSizeY)
73         {
74             for(sal_Int32 x=0; x<aImageSizeX; x+=aPageSizeX)
75             {
76                 // the current surface is located at the position [x,y]
77                 // and has the size [min(restx,pagesizex),min(resty,pagesizey)
78                 ::basegfx::B2IPoint aOffset(x,y);
79                 ::basegfx::B2ISize aSize( ::std::min( aImageSize.getX()-x,
80                                                       aPageSize.getX() ),
81                                           ::std::min( aImageSize.getY()-y,
82                                                       aPageSize.getY() ) );
83 
84                 maSurfaceList.push_back(
85                     SurfaceSharedPtr(
86                         new Surface(
87                             mpPageManager,
88                             mpBuffer,
89                             aOffset,
90                             aSize)));
91             }
92         }
93     }
94 
95     //////////////////////////////////////////////////////////////////////////////////
96     // SurfaceProxy::setColorBufferDirty
97     //////////////////////////////////////////////////////////////////////////////////
98 
99     void SurfaceProxy::setColorBufferDirty()
100     {
101         ::std::for_each( maSurfaceList.begin(),
102                          maSurfaceList.end(),
103                          ::boost::mem_fn(&Surface::setColorBufferDirty));
104     }
105 
106     //////////////////////////////////////////////////////////////////////////////////
107     // SurfaceProxy::draw
108     //////////////////////////////////////////////////////////////////////////////////
109 
110     bool SurfaceProxy::draw( double                         fAlpha,
111                              const ::basegfx::B2DPoint&     rPos,
112                              const ::basegfx::B2DHomMatrix& rTransform )
113     {
114         ::std::for_each( maSurfaceList.begin(),
115                          maSurfaceList.end(),
116                          ::boost::bind( &Surface::draw,
117                                         _1,
118                                         fAlpha,
119                                         ::boost::cref(rPos),
120                                         ::boost::cref(rTransform)));
121 
122         return true;
123     }
124 
125     //////////////////////////////////////////////////////////////////////////////////
126     // SurfaceProxy::draw
127     //////////////////////////////////////////////////////////////////////////////////
128 
129     bool SurfaceProxy::draw( double                         fAlpha,
130                              const ::basegfx::B2DPoint&     rPos,
131                              const ::basegfx::B2DRange&     rArea,
132                              const ::basegfx::B2DHomMatrix& rTransform )
133     {
134         ::std::for_each( maSurfaceList.begin(),
135                          maSurfaceList.end(),
136                          ::boost::bind(&Surface::drawRectangularArea,
137                                        _1,
138                                        fAlpha,
139                                        ::boost::cref(rPos),
140                                        ::boost::cref(rArea),
141                                        ::boost::cref(rTransform)));
142 
143         return true;
144     }
145 
146     //////////////////////////////////////////////////////////////////////////////////
147     // SurfaceProxy::draw
148     //////////////////////////////////////////////////////////////////////////////////
149 
150     bool SurfaceProxy::draw( double                           fAlpha,
151                              const ::basegfx::B2DPoint&       rPos,
152                              const ::basegfx::B2DPolyPolygon& rClipPoly,
153                              const ::basegfx::B2DHomMatrix&   rTransform )
154     {
155         const ::basegfx::B2DPolygon& rTriangulatedPolygon(
156             ::basegfx::triangulator::triangulate(rClipPoly));
157 
158 #if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0
159         // dump polygons
160         OSL_TRACE( "Original clip polygon: %s\n"
161                    "Triangulated polygon: %s\n",
162                    rtl::OUStringToOString(
163                        basegfx::tools::exportToSvgD( rClipPoly ),
164                        RTL_TEXTENCODING_ASCII_US).getStr(),
165                    rtl::OUStringToOString(
166                        basegfx::tools::exportToSvgD(
167                            basegfx::B2DPolyPolygon(rTriangulatedPolygon) ),
168                        RTL_TEXTENCODING_ASCII_US).getStr() );
169 #endif
170 
171         ::std::for_each( maSurfaceList.begin(),
172                          maSurfaceList.end(),
173                          ::boost::bind(&Surface::drawWithClip,
174                                        _1,
175                                        fAlpha,
176                                        ::boost::cref(rPos),
177                                        ::boost::cref(rTriangulatedPolygon),
178                                        ::boost::cref(rTransform)));
179 
180         return true;
181     }
182 }
183