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