125ea7f45SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
325ea7f45SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
425ea7f45SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
525ea7f45SAndrew Rist  * distributed with this work for additional information
625ea7f45SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
725ea7f45SAndrew Rist  * to you under the Apache License, Version 2.0 (the
825ea7f45SAndrew Rist  * "License"); you may not use this file except in compliance
925ea7f45SAndrew Rist  * with the License.  You may obtain a copy of the License at
1025ea7f45SAndrew Rist  *
1125ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1225ea7f45SAndrew Rist  *
1325ea7f45SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1425ea7f45SAndrew Rist  * software distributed under the License is distributed on an
1525ea7f45SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1625ea7f45SAndrew Rist  * KIND, either express or implied.  See the License for the
1725ea7f45SAndrew Rist  * specific language governing permissions and limitations
1825ea7f45SAndrew Rist  * under the License.
1925ea7f45SAndrew Rist  *
2025ea7f45SAndrew Rist  *************************************************************/
2125ea7f45SAndrew Rist 
2225ea7f45SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_canvas.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <boost/bind.hpp>
28cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
29cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontriangulator.hxx>
30cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
31cdf0e10cSrcweir #include "surfaceproxy.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace canvas
34cdf0e10cSrcweir {
35cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
36cdf0e10cSrcweir 	// SurfaceProxy::SurfaceProxy
37cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
38cdf0e10cSrcweir 
SurfaceProxy(const canvas::IColorBufferSharedPtr & pBuffer,const PageManagerSharedPtr & pPageManager)39cdf0e10cSrcweir 	SurfaceProxy::SurfaceProxy( const canvas::IColorBufferSharedPtr& pBuffer,
40cdf0e10cSrcweir 								const PageManagerSharedPtr&          pPageManager ) :
41cdf0e10cSrcweir 		mpPageManager( pPageManager ),
42cdf0e10cSrcweir         maSurfaceList(),
43cdf0e10cSrcweir         mpBuffer( pBuffer )
44cdf0e10cSrcweir     {
45cdf0e10cSrcweir 		const ::basegfx::B2ISize aImageSize(mpBuffer->getWidth(),mpBuffer->getHeight());
46cdf0e10cSrcweir 		const ::basegfx::B2ISize aPageSize(mpPageManager->getPageSize());
47cdf0e10cSrcweir 		const sal_Int32 aPageSizeX(aPageSize.getX());
48cdf0e10cSrcweir 		const sal_Int32 aPageSizeY(aPageSize.getY());
49cdf0e10cSrcweir 		const sal_Int32 aImageSizeX(aImageSize.getX());
50cdf0e10cSrcweir 		const sal_Int32 aImageSizeY(aImageSize.getY());
51cdf0e10cSrcweir 
52cdf0e10cSrcweir 		// see if the size of the colorbuffer is larger than the size
53cdf0e10cSrcweir 		// of a single page. if this is the case we divide the
54cdf0e10cSrcweir 		// colorbuffer into as many surfaces as we need to get the
55cdf0e10cSrcweir 		// whole area distributed.  otherwise (the colorbuffer is
56cdf0e10cSrcweir 		// smaller than the size of a single page) we search for free
57cdf0e10cSrcweir 		// pages or create a new one.
58cdf0e10cSrcweir 		// the incoming image is too large to fit into a single
59cdf0e10cSrcweir 		// page.  strategy: we split the image into rectangular
60cdf0e10cSrcweir 		// areas that are as large as the maximum page size
61cdf0e10cSrcweir 		// dictates and follow the strategy for fitting images.
62cdf0e10cSrcweir 		size_t dwNumSurfaces(0);
63cdf0e10cSrcweir 		for(sal_Int32 y=0; y<aImageSizeY; y+=aPageSizeY)
64cdf0e10cSrcweir 			for(sal_Int32 x=0; x<aImageSizeX; x+=aPageSizeX)
65cdf0e10cSrcweir 				++dwNumSurfaces;
66cdf0e10cSrcweir 		maSurfaceList.reserve(dwNumSurfaces);
67cdf0e10cSrcweir 
68cdf0e10cSrcweir 		for(sal_Int32 y=0; y<aImageSizeY; y+=aPageSizeY)
69cdf0e10cSrcweir 		{
70cdf0e10cSrcweir 			for(sal_Int32 x=0; x<aImageSizeX; x+=aPageSizeX)
71cdf0e10cSrcweir 			{
72cdf0e10cSrcweir 				// the current surface is located at the position [x,y]
73cdf0e10cSrcweir 				// and has the size [min(restx,pagesizex),min(resty,pagesizey)
74cdf0e10cSrcweir 				::basegfx::B2IPoint aOffset(x,y);
75cdf0e10cSrcweir 				::basegfx::B2ISize aSize( ::std::min( aImageSize.getX()-x,
76cdf0e10cSrcweir                                                       aPageSize.getX() ),
77cdf0e10cSrcweir                                           ::std::min( aImageSize.getY()-y,
78cdf0e10cSrcweir                                                       aPageSize.getY() ) );
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 				maSurfaceList.push_back(
81cdf0e10cSrcweir 					SurfaceSharedPtr(
82cdf0e10cSrcweir 						new Surface(
83cdf0e10cSrcweir 							mpPageManager,
84cdf0e10cSrcweir 							mpBuffer,
85cdf0e10cSrcweir 							aOffset,
86cdf0e10cSrcweir 							aSize)));
87cdf0e10cSrcweir 			}
88cdf0e10cSrcweir 		}
89cdf0e10cSrcweir     }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
92cdf0e10cSrcweir 	// SurfaceProxy::setColorBufferDirty
93cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
94cdf0e10cSrcweir 
setColorBufferDirty()95cdf0e10cSrcweir 	void SurfaceProxy::setColorBufferDirty()
96cdf0e10cSrcweir 	{
97cdf0e10cSrcweir 		::std::for_each( maSurfaceList.begin(),
98cdf0e10cSrcweir                          maSurfaceList.end(),
99cdf0e10cSrcweir 						 ::boost::mem_fn(&Surface::setColorBufferDirty));
100cdf0e10cSrcweir 	}
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
103cdf0e10cSrcweir 	// SurfaceProxy::draw
104cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
105cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DHomMatrix & rTransform)106cdf0e10cSrcweir 	bool SurfaceProxy::draw( double                         fAlpha,
107cdf0e10cSrcweir                              const ::basegfx::B2DPoint&     rPos,
108cdf0e10cSrcweir                              const ::basegfx::B2DHomMatrix& rTransform )
109cdf0e10cSrcweir 	{
110cdf0e10cSrcweir 		::std::for_each( maSurfaceList.begin(),
111cdf0e10cSrcweir                          maSurfaceList.end(),
112cdf0e10cSrcweir 						 ::boost::bind( &Surface::draw,
113cdf0e10cSrcweir                                         _1,
114cdf0e10cSrcweir                                         fAlpha,
115cdf0e10cSrcweir                                         ::boost::cref(rPos),
116cdf0e10cSrcweir                                         ::boost::cref(rTransform)));
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 		return true;
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
122cdf0e10cSrcweir 	// SurfaceProxy::draw
123cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
124cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DRange & rArea,const::basegfx::B2DHomMatrix & rTransform)125cdf0e10cSrcweir 	bool SurfaceProxy::draw( double                         fAlpha,
126cdf0e10cSrcweir                              const ::basegfx::B2DPoint&     rPos,
127cdf0e10cSrcweir                              const ::basegfx::B2DRange&		rArea,
128cdf0e10cSrcweir                              const ::basegfx::B2DHomMatrix& rTransform )
129cdf0e10cSrcweir 	{
130cdf0e10cSrcweir 		::std::for_each( maSurfaceList.begin(),
131cdf0e10cSrcweir                          maSurfaceList.end(),
132cdf0e10cSrcweir 						 ::boost::bind(&Surface::drawRectangularArea,
133cdf0e10cSrcweir                                        _1,
134cdf0e10cSrcweir                                        fAlpha,
135cdf0e10cSrcweir                                        ::boost::cref(rPos),
136cdf0e10cSrcweir                                        ::boost::cref(rArea),
137cdf0e10cSrcweir                                        ::boost::cref(rTransform)));
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 		return true;
140cdf0e10cSrcweir 	}
141cdf0e10cSrcweir 
142cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
143cdf0e10cSrcweir 	// SurfaceProxy::draw
144cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
145cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DPolyPolygon & rClipPoly,const::basegfx::B2DHomMatrix & rTransform)146cdf0e10cSrcweir 	bool SurfaceProxy::draw( double                           fAlpha,
147cdf0e10cSrcweir                              const ::basegfx::B2DPoint&       rPos,
148cdf0e10cSrcweir                              const ::basegfx::B2DPolyPolygon& rClipPoly,
149cdf0e10cSrcweir                              const ::basegfx::B2DHomMatrix&   rTransform )
150cdf0e10cSrcweir 	{
151cdf0e10cSrcweir 		const ::basegfx::B2DPolygon& rTriangulatedPolygon(
152cdf0e10cSrcweir             ::basegfx::triangulator::triangulate(rClipPoly));
153cdf0e10cSrcweir 
154cdf0e10cSrcweir #if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0
155cdf0e10cSrcweir         // dump polygons
156cdf0e10cSrcweir         OSL_TRACE( "Original clip polygon: %s\n"
157cdf0e10cSrcweir                    "Triangulated polygon: %s\n",
158cdf0e10cSrcweir                    rtl::OUStringToOString(
159*1f882ec4SArmin Le Grand                        basegfx::tools::exportToSvgD( rClipPoly, true, true, false ),
160cdf0e10cSrcweir                        RTL_TEXTENCODING_ASCII_US).getStr(),
161cdf0e10cSrcweir                    rtl::OUStringToOString(
162cdf0e10cSrcweir                        basegfx::tools::exportToSvgD(
163*1f882ec4SArmin Le Grand                            basegfx::B2DPolyPolygon(rTriangulatedPolygon), true, true, false ),
164cdf0e10cSrcweir                        RTL_TEXTENCODING_ASCII_US).getStr() );
165cdf0e10cSrcweir #endif
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 		::std::for_each( maSurfaceList.begin(),
168cdf0e10cSrcweir                          maSurfaceList.end(),
169cdf0e10cSrcweir 						 ::boost::bind(&Surface::drawWithClip,
170cdf0e10cSrcweir                                        _1,
171cdf0e10cSrcweir                                        fAlpha,
172cdf0e10cSrcweir                                        ::boost::cref(rPos),
173cdf0e10cSrcweir                                        ::boost::cref(rTriangulatedPolygon),
174cdf0e10cSrcweir                                        ::boost::cref(rTransform)));
175cdf0e10cSrcweir 
176cdf0e10cSrcweir 		return true;
177cdf0e10cSrcweir 	}
178cdf0e10cSrcweir }
179