xref: /trunk/main/canvas/source/tools/surface.cxx (revision 25ea7f45)
1*25ea7f45SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*25ea7f45SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*25ea7f45SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*25ea7f45SAndrew Rist  * distributed with this work for additional information
6*25ea7f45SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*25ea7f45SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*25ea7f45SAndrew Rist  * "License"); you may not use this file except in compliance
9*25ea7f45SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*25ea7f45SAndrew Rist  *
11*25ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*25ea7f45SAndrew Rist  *
13*25ea7f45SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*25ea7f45SAndrew Rist  * software distributed under the License is distributed on an
15*25ea7f45SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*25ea7f45SAndrew Rist  * KIND, either express or implied.  See the License for the
17*25ea7f45SAndrew Rist  * specific language governing permissions and limitations
18*25ea7f45SAndrew Rist  * under the License.
19*25ea7f45SAndrew Rist  *
20*25ea7f45SAndrew Rist  *************************************************************/
21*25ea7f45SAndrew Rist 
22*25ea7f45SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_canvas.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "surface.hxx"
28cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygonclipper.hxx>
29cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
30cdf0e10cSrcweir #include <comphelper/scopeguard.hxx>
31cdf0e10cSrcweir #include <boost/bind.hpp>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace canvas
34cdf0e10cSrcweir {
35cdf0e10cSrcweir 
36cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
37cdf0e10cSrcweir 	// Surface::Surface
38cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
39cdf0e10cSrcweir 
Surface(const PageManagerSharedPtr & rPageManager,const IColorBufferSharedPtr & rColorBuffer,const::basegfx::B2IPoint & rPos,const::basegfx::B2ISize & rSize)40cdf0e10cSrcweir 	Surface::Surface( const PageManagerSharedPtr&  rPageManager,
41cdf0e10cSrcweir 					  const IColorBufferSharedPtr& rColorBuffer,
42cdf0e10cSrcweir 					  const ::basegfx::B2IPoint&   rPos,
43cdf0e10cSrcweir 					  const ::basegfx::B2ISize&    rSize ) :
44cdf0e10cSrcweir 		mpColorBuffer(rColorBuffer),
45cdf0e10cSrcweir 		mpPageManager(rPageManager),
46cdf0e10cSrcweir 		mpFragment(),
47cdf0e10cSrcweir 		maSourceOffset(rPos),
48cdf0e10cSrcweir 		maSize(rSize),
49cdf0e10cSrcweir 		mbIsDirty(true)
50cdf0e10cSrcweir 	{
51cdf0e10cSrcweir 	}
52cdf0e10cSrcweir 
53cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
54cdf0e10cSrcweir 	// Surface::~Surface
55cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
56cdf0e10cSrcweir 
~Surface()57cdf0e10cSrcweir 	Surface::~Surface()
58cdf0e10cSrcweir 	{
59cdf0e10cSrcweir 		if(mpFragment)
60cdf0e10cSrcweir 			mpPageManager->free(mpFragment);
61cdf0e10cSrcweir 	}
62cdf0e10cSrcweir 
63cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
64cdf0e10cSrcweir 	// Surface::getUVCoords
65cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
66cdf0e10cSrcweir 
setColorBufferDirty()67cdf0e10cSrcweir 	void Surface::setColorBufferDirty()
68cdf0e10cSrcweir 	{
69cdf0e10cSrcweir 		mbIsDirty=true;
70cdf0e10cSrcweir 	}
71cdf0e10cSrcweir 
72cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
73cdf0e10cSrcweir 	// Surface::getUVCoords
74cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
75cdf0e10cSrcweir 
getUVCoords() const76cdf0e10cSrcweir 	basegfx::B2DRectangle Surface::getUVCoords() const
77cdf0e10cSrcweir 	{
78cdf0e10cSrcweir 		::basegfx::B2ISize aPageSize(mpPageManager->getPageSize());
79cdf0e10cSrcweir 		::basegfx::B2IPoint aDestOffset;
80cdf0e10cSrcweir         if( mpFragment )
81cdf0e10cSrcweir             aDestOffset = mpFragment->getPos();
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 		const double pw( aPageSize.getX() );
84cdf0e10cSrcweir 		const double ph( aPageSize.getY() );
85cdf0e10cSrcweir 		const double ox( aDestOffset.getX() );
86cdf0e10cSrcweir 		const double oy( aDestOffset.getY() );
87cdf0e10cSrcweir 		const double sx( maSize.getX() );
88cdf0e10cSrcweir 		const double sy( maSize.getY() );
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 		return ::basegfx::B2DRectangle( ox/pw,
91cdf0e10cSrcweir                                         oy/ph,
92cdf0e10cSrcweir                                         (ox+sx)/pw,
93cdf0e10cSrcweir                                         (oy+sy)/ph );
94cdf0e10cSrcweir 	}
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
97cdf0e10cSrcweir 	// Surface::getUVCoords
98cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
99cdf0e10cSrcweir 
getUVCoords(const::basegfx::B2IPoint & rPos,const::basegfx::B2ISize & rSize) const100cdf0e10cSrcweir 	basegfx::B2DRectangle Surface::getUVCoords( const ::basegfx::B2IPoint& rPos,
101cdf0e10cSrcweir 												const ::basegfx::B2ISize&  rSize ) const
102cdf0e10cSrcweir 	{
103cdf0e10cSrcweir 		::basegfx::B2ISize aPageSize(mpPageManager->getPageSize());
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 		const double pw( aPageSize.getX() );
106cdf0e10cSrcweir 		const double ph( aPageSize.getY() );
107cdf0e10cSrcweir 		const double ox( rPos.getX() );
108cdf0e10cSrcweir 		const double oy( rPos.getY() );
109cdf0e10cSrcweir 		const double sx( rSize.getX() );
110cdf0e10cSrcweir 		const double sy( rSize.getY() );
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 		return ::basegfx::B2DRectangle( ox/pw,
113cdf0e10cSrcweir                                         oy/ph,
114cdf0e10cSrcweir                                         (ox+sx)/pw,
115cdf0e10cSrcweir                                         (oy+sy)/ph );
116cdf0e10cSrcweir 	}
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
119cdf0e10cSrcweir 	// Surface::draw
120cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
121cdf0e10cSrcweir 
draw(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DHomMatrix & rTransform)122cdf0e10cSrcweir 	bool Surface::draw( double                          fAlpha,
123cdf0e10cSrcweir 						const ::basegfx::B2DPoint&      rPos,
124cdf0e10cSrcweir 						const ::basegfx::B2DHomMatrix&  rTransform )
125cdf0e10cSrcweir 	{
126cdf0e10cSrcweir 		IRenderModuleSharedPtr pRenderModule(mpPageManager->getRenderModule());
127cdf0e10cSrcweir 
128cdf0e10cSrcweir         RenderModuleGuard aGuard( pRenderModule );
129cdf0e10cSrcweir 
130cdf0e10cSrcweir 		prepareRendering();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 		// convert size to normalized device coordinates
133cdf0e10cSrcweir 		const ::basegfx::B2DRectangle& rUV( getUVCoords() );
134cdf0e10cSrcweir 
135cdf0e10cSrcweir 		const double u1(rUV.getMinX());
136cdf0e10cSrcweir 		const double v1(rUV.getMinY());
137cdf0e10cSrcweir 		const double u2(rUV.getMaxX());
138cdf0e10cSrcweir 		const double v2(rUV.getMaxY());
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 		// concat transforms
141cdf0e10cSrcweir         // 1) offset of surface subarea
142cdf0e10cSrcweir         // 2) surface transform
143cdf0e10cSrcweir 		// 3) translation to output position [rPos]
144cdf0e10cSrcweir 		// 4) scale to normalized device coordinates
145cdf0e10cSrcweir 		// 5) flip y-axis
146cdf0e10cSrcweir 		// 6) translate to account for viewport transform
147cdf0e10cSrcweir         basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(
148cdf0e10cSrcweir             maSourceOffset.getX(), maSourceOffset.getY()));
149cdf0e10cSrcweir         aTransform = aTransform * rTransform;
150cdf0e10cSrcweir 		aTransform.translate(::basegfx::fround(rPos.getX()),
151cdf0e10cSrcweir                              ::basegfx::fround(rPos.getY()));
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 		/*
154cdf0e10cSrcweir 			######################################
155cdf0e10cSrcweir 			######################################
156cdf0e10cSrcweir 			######################################
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 			    		   Y
159cdf0e10cSrcweir 			    		   ^+1
160cdf0e10cSrcweir 			    		   |
161cdf0e10cSrcweir 			       2	   |	   3
162cdf0e10cSrcweir 			    	 x------------x
163cdf0e10cSrcweir 			    	 |	   |	  |
164cdf0e10cSrcweir 			 		 |	   |	  |
165cdf0e10cSrcweir 			   ------|-----O------|------>X
166cdf0e10cSrcweir 			   -1  	 |	   |	  |		+1
167cdf0e10cSrcweir 			    	 |	   |	  |
168cdf0e10cSrcweir 			    	 x------------x
169cdf0e10cSrcweir 			        1      |       0
170cdf0e10cSrcweir 			    	 	   |
171cdf0e10cSrcweir 			    		   |-1
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 			######################################
174cdf0e10cSrcweir 			######################################
175cdf0e10cSrcweir 			######################################
176cdf0e10cSrcweir 		*/
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p0(aTransform * ::basegfx::B2DPoint(maSize.getX(),maSize.getY()));
179cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p1(aTransform * ::basegfx::B2DPoint(0.0,maSize.getY()));
180cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p2(aTransform * ::basegfx::B2DPoint(0.0,0.0));
181cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p3(aTransform * ::basegfx::B2DPoint(maSize.getX(),0.0));
182cdf0e10cSrcweir 
183cdf0e10cSrcweir 		canvas::Vertex vertex;
184cdf0e10cSrcweir 		vertex.r = 1.0f;
185cdf0e10cSrcweir 		vertex.g = 1.0f;
186cdf0e10cSrcweir 		vertex.b = 1.0f;
187cdf0e10cSrcweir 		vertex.a = static_cast<float>(fAlpha);
188cdf0e10cSrcweir 		vertex.z = 0.0f;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir             pRenderModule->beginPrimitive( canvas::IRenderModule::PRIMITIVE_TYPE_QUAD );
192cdf0e10cSrcweir 
193cdf0e10cSrcweir             // issue an endPrimitive() when leaving the scope
194cdf0e10cSrcweir             const ::comphelper::ScopeGuard aScopeGuard(
195cdf0e10cSrcweir                 boost::bind( &::canvas::IRenderModule::endPrimitive,
196cdf0e10cSrcweir                              ::boost::ref(pRenderModule) ) );
197cdf0e10cSrcweir 
198cdf0e10cSrcweir             vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v2);
199cdf0e10cSrcweir             vertex.x=static_cast<float>(p0.getX()); vertex.y=static_cast<float>(p0.getY());
200cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
201cdf0e10cSrcweir 
202cdf0e10cSrcweir             vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v2);
203cdf0e10cSrcweir             vertex.x=static_cast<float>(p1.getX()); vertex.y=static_cast<float>(p1.getY());
204cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
205cdf0e10cSrcweir 
206cdf0e10cSrcweir             vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v1);
207cdf0e10cSrcweir             vertex.x=static_cast<float>(p2.getX()); vertex.y=static_cast<float>(p2.getY());
208cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
209cdf0e10cSrcweir 
210cdf0e10cSrcweir             vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v1);
211cdf0e10cSrcweir             vertex.x=static_cast<float>(p3.getX()); vertex.y=static_cast<float>(p3.getY());
212cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 		return !(pRenderModule->isError());
216cdf0e10cSrcweir 	}
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
219cdf0e10cSrcweir 	// Surface::drawRectangularArea
220cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
221cdf0e10cSrcweir 
drawRectangularArea(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DRectangle & rArea,const::basegfx::B2DHomMatrix & rTransform)222cdf0e10cSrcweir 	bool Surface::drawRectangularArea(
223cdf0e10cSrcweir 						double                         fAlpha,
224cdf0e10cSrcweir                         const ::basegfx::B2DPoint&     rPos,
225cdf0e10cSrcweir 						const ::basegfx::B2DRectangle& rArea,
226cdf0e10cSrcweir 						const ::basegfx::B2DHomMatrix& rTransform )
227cdf0e10cSrcweir 	{
228cdf0e10cSrcweir         if( rArea.isEmpty() )
229cdf0e10cSrcweir             return true; // immediate exit for empty area
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 		IRenderModuleSharedPtr pRenderModule(mpPageManager->getRenderModule());
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 		RenderModuleGuard aGuard( pRenderModule );
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 		prepareRendering();
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 		// these positions are relative to the texture
238cdf0e10cSrcweir 		::basegfx::B2IPoint aPos1(
239cdf0e10cSrcweir 			::basegfx::fround(rArea.getMinimum().getX()),
240cdf0e10cSrcweir 			::basegfx::fround(rArea.getMinimum().getY()));
241cdf0e10cSrcweir 		::basegfx::B2IPoint aPos2(
242cdf0e10cSrcweir 			::basegfx::fround(rArea.getMaximum().getX()),
243cdf0e10cSrcweir 			::basegfx::fround(rArea.getMaximum().getY()) );
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 		// clip the positions to the area this surface covers
246cdf0e10cSrcweir 		aPos1.setX(::std::max(aPos1.getX(),maSourceOffset.getX()));
247cdf0e10cSrcweir 		aPos1.setY(::std::max(aPos1.getY(),maSourceOffset.getY()));
248cdf0e10cSrcweir 		aPos2.setX(::std::min(aPos2.getX(),maSourceOffset.getX()+maSize.getX()));
249cdf0e10cSrcweir 		aPos2.setY(::std::min(aPos2.getY(),maSourceOffset.getY()+maSize.getY()));
250cdf0e10cSrcweir 
251cdf0e10cSrcweir 		// if the resulting area is empty, return immediately
252cdf0e10cSrcweir 		::basegfx::B2IVector aSize(aPos2 - aPos1);
253cdf0e10cSrcweir 		if(aSize.getX() <= 0 || aSize.getY() <= 0)
254cdf0e10cSrcweir 			return true;
255cdf0e10cSrcweir 
256cdf0e10cSrcweir         ::basegfx::B2IPoint aDestOffset;
257cdf0e10cSrcweir         if( mpFragment )
258cdf0e10cSrcweir             aDestOffset = mpFragment->getPos();
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 		// convert size to normalized device coordinates
261cdf0e10cSrcweir 		const ::basegfx::B2DRectangle& rUV(
262cdf0e10cSrcweir             getUVCoords(aPos1 - maSourceOffset + aDestOffset,
263cdf0e10cSrcweir                         aSize) );
264cdf0e10cSrcweir 		const double u1(rUV.getMinX());
265cdf0e10cSrcweir 		const double v1(rUV.getMinY());
266cdf0e10cSrcweir 		const double u2(rUV.getMaxX());
267cdf0e10cSrcweir 		const double v2(rUV.getMaxY());
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 		// concatenate transforms
270cdf0e10cSrcweir         // 1) offset of surface subarea
271cdf0e10cSrcweir         // 2) surface transform
272cdf0e10cSrcweir 		// 3) translation to output position [rPos]
273cdf0e10cSrcweir         basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix(aPos1.getX(), aPos1.getY()));
274cdf0e10cSrcweir         aTransform = aTransform * rTransform;
275cdf0e10cSrcweir 		aTransform.translate(::basegfx::fround(rPos.getX()),
276cdf0e10cSrcweir                              ::basegfx::fround(rPos.getY()));
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 		/*
280cdf0e10cSrcweir 			######################################
281cdf0e10cSrcweir 			######################################
282cdf0e10cSrcweir 			######################################
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 			    		   Y
285cdf0e10cSrcweir 			    		   ^+1
286cdf0e10cSrcweir 			    		   |
287cdf0e10cSrcweir 			       2	   |	   3
288cdf0e10cSrcweir 			    	 x------------x
289cdf0e10cSrcweir 			    	 |	   |	  |
290cdf0e10cSrcweir 			 		 |	   |	  |
291cdf0e10cSrcweir 			   ------|-----O------|------>X
292cdf0e10cSrcweir 			   -1  	 |	   |	  |		+1
293cdf0e10cSrcweir 			    	 |	   |	  |
294cdf0e10cSrcweir 			    	 x------------x
295cdf0e10cSrcweir 			        1      |       0
296cdf0e10cSrcweir 			    	 	   |
297cdf0e10cSrcweir 			    		   |-1
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 			######################################
300cdf0e10cSrcweir 			######################################
301cdf0e10cSrcweir 			######################################
302cdf0e10cSrcweir 		*/
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p0(aTransform * ::basegfx::B2DPoint(aSize.getX(),aSize.getY()));
305cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p1(aTransform * ::basegfx::B2DPoint(0.0,			aSize.getY()));
306cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p2(aTransform * ::basegfx::B2DPoint(0.0,			0.0));
307cdf0e10cSrcweir 		const ::basegfx::B2DPoint& p3(aTransform * ::basegfx::B2DPoint(aSize.getX(),0.0));
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 		canvas::Vertex vertex;
310cdf0e10cSrcweir 		vertex.r = 1.0f;
311cdf0e10cSrcweir 		vertex.g = 1.0f;
312cdf0e10cSrcweir 		vertex.b = 1.0f;
313cdf0e10cSrcweir 		vertex.a = static_cast<float>(fAlpha);
314cdf0e10cSrcweir 		vertex.z = 0.0f;
315cdf0e10cSrcweir 
316cdf0e10cSrcweir         {
317cdf0e10cSrcweir             pRenderModule->beginPrimitive( canvas::IRenderModule::PRIMITIVE_TYPE_QUAD );
318cdf0e10cSrcweir 
319cdf0e10cSrcweir             // issue an endPrimitive() when leaving the scope
320cdf0e10cSrcweir             const ::comphelper::ScopeGuard aScopeGuard(
321cdf0e10cSrcweir                 boost::bind( &::canvas::IRenderModule::endPrimitive,
322cdf0e10cSrcweir                              ::boost::ref(pRenderModule) ) );
323cdf0e10cSrcweir 
324cdf0e10cSrcweir             vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v2);
325cdf0e10cSrcweir             vertex.x=static_cast<float>(p0.getX()); vertex.y=static_cast<float>(p0.getY());
326cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
327cdf0e10cSrcweir 
328cdf0e10cSrcweir             vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v2);
329cdf0e10cSrcweir             vertex.x=static_cast<float>(p1.getX()); vertex.y=static_cast<float>(p1.getY());
330cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
331cdf0e10cSrcweir 
332cdf0e10cSrcweir             vertex.u=static_cast<float>(u1); vertex.v=static_cast<float>(v1);
333cdf0e10cSrcweir             vertex.x=static_cast<float>(p2.getX()); vertex.y=static_cast<float>(p2.getY());
334cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
335cdf0e10cSrcweir 
336cdf0e10cSrcweir             vertex.u=static_cast<float>(u2); vertex.v=static_cast<float>(v1);
337cdf0e10cSrcweir             vertex.x=static_cast<float>(p3.getX()); vertex.y=static_cast<float>(p3.getY());
338cdf0e10cSrcweir             pRenderModule->pushVertex(vertex);
339cdf0e10cSrcweir         }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 		return !(pRenderModule->isError());
342cdf0e10cSrcweir 	}
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
345cdf0e10cSrcweir 	// Surface::drawWithClip
346cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
347cdf0e10cSrcweir 
drawWithClip(double fAlpha,const::basegfx::B2DPoint & rPos,const::basegfx::B2DPolygon & rClipPoly,const::basegfx::B2DHomMatrix & rTransform)348cdf0e10cSrcweir 	bool Surface::drawWithClip( double                          fAlpha,
349cdf0e10cSrcweir 								const ::basegfx::B2DPoint&      rPos,
350cdf0e10cSrcweir 								const ::basegfx::B2DPolygon&    rClipPoly,
351cdf0e10cSrcweir 								const ::basegfx::B2DHomMatrix&  rTransform )
352cdf0e10cSrcweir 	{
353cdf0e10cSrcweir 		IRenderModuleSharedPtr pRenderModule(mpPageManager->getRenderModule());
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 		RenderModuleGuard aGuard( pRenderModule );
356cdf0e10cSrcweir 
357cdf0e10cSrcweir 		prepareRendering();
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 		// untransformed surface rectangle, relative to the whole
360cdf0e10cSrcweir 		// image (note: this surface might actually only be a tile of
361cdf0e10cSrcweir 		// the whole image, with non-zero maSourceOffset)
362cdf0e10cSrcweir 		const double x1(maSourceOffset.getX());
363cdf0e10cSrcweir 		const double y1(maSourceOffset.getY());
364cdf0e10cSrcweir 		const double w(maSize.getX());
365cdf0e10cSrcweir 		const double h(maSize.getY());
366cdf0e10cSrcweir 		const double x2(x1+w);
367cdf0e10cSrcweir 		const double y2(y1+h);
368cdf0e10cSrcweir 		const ::basegfx::B2DRectangle aSurfaceClipRect(x1,y1,x2,y2);
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 		// concatenate transforms
371cdf0e10cSrcweir 		// we use 'fround' here to avoid rounding errors. the vertices will
372cdf0e10cSrcweir 		// be transformed by the overall transform and uv coordinates will
373cdf0e10cSrcweir 		// be calculated from the result, and this is why we need to use
374cdf0e10cSrcweir 		// integer coordinates here...
375cdf0e10cSrcweir         basegfx::B2DHomMatrix aTransform;
376cdf0e10cSrcweir         aTransform = aTransform * rTransform;
377cdf0e10cSrcweir 		aTransform.translate(::basegfx::fround(rPos.getX()),
378cdf0e10cSrcweir                              ::basegfx::fround(rPos.getY()));
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 		/*
381cdf0e10cSrcweir 			######################################
382cdf0e10cSrcweir 			######################################
383cdf0e10cSrcweir 			######################################
384cdf0e10cSrcweir 
385cdf0e10cSrcweir 			    		   Y
386cdf0e10cSrcweir 			    		   ^+1
387cdf0e10cSrcweir 			    		   |
388cdf0e10cSrcweir 			       2	   |	   3
389cdf0e10cSrcweir 			    	 x------------x
390cdf0e10cSrcweir 			    	 |	   |	  |
391cdf0e10cSrcweir 			 		 |	   |	  |
392cdf0e10cSrcweir 			   ------|-----O------|------>X
393cdf0e10cSrcweir 			   -1  	 |	   |	  |		+1
394cdf0e10cSrcweir 			    	 |	   |	  |
395cdf0e10cSrcweir 			    	 x------------x
396cdf0e10cSrcweir 			        1      |       0
397cdf0e10cSrcweir 			    	 	   |
398cdf0e10cSrcweir 			    		   |-1
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 			######################################
401cdf0e10cSrcweir 			######################################
402cdf0e10cSrcweir 			######################################
403cdf0e10cSrcweir 		*/
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 		// uv coordinates that map the surface rectangle
406cdf0e10cSrcweir 		// to the destination rectangle.
407cdf0e10cSrcweir 		const ::basegfx::B2DRectangle& rUV( getUVCoords() );
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 		basegfx::B2DPolygon rTriangleList(basegfx::tools::clipTriangleListOnRange(rClipPoly,
410cdf0e10cSrcweir                                                                                   aSurfaceClipRect));
411cdf0e10cSrcweir 
412cdf0e10cSrcweir 		// Push vertices to backend renderer
413cdf0e10cSrcweir 		if(const sal_uInt32 nVertexCount = rTriangleList.count())
414cdf0e10cSrcweir 		{
415cdf0e10cSrcweir 			canvas::Vertex vertex;
416cdf0e10cSrcweir 			vertex.r = 1.0f;
417cdf0e10cSrcweir 			vertex.g = 1.0f;
418cdf0e10cSrcweir 			vertex.b = 1.0f;
419cdf0e10cSrcweir 			vertex.a = static_cast<float>(fAlpha);
420cdf0e10cSrcweir 			vertex.z = 0.0f;
421cdf0e10cSrcweir 
422cdf0e10cSrcweir #if defined(TRIANGLE_LOG) && defined(DBG_UTIL)
423cdf0e10cSrcweir 			OSL_TRACE( "Surface::draw(): numvertices %d numtriangles %d\n",
424cdf0e10cSrcweir 						nVertexCount,
425cdf0e10cSrcweir 						nVertexCount/3 );
426cdf0e10cSrcweir #endif
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 			pRenderModule->beginPrimitive( canvas::IRenderModule::PRIMITIVE_TYPE_TRIANGLE );
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 			// issue an endPrimitive() when leaving the scope
431cdf0e10cSrcweir 			const ::comphelper::ScopeGuard aScopeGuard(
432cdf0e10cSrcweir 				boost::bind( &::canvas::IRenderModule::endPrimitive,
433cdf0e10cSrcweir 								::boost::ref(pRenderModule) ) );
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 			for(sal_uInt32 nIndex=0; nIndex<nVertexCount; ++nIndex)
436cdf0e10cSrcweir 			{
437cdf0e10cSrcweir 				const basegfx::B2DPoint &aPoint = rTriangleList.getB2DPoint(nIndex);
438cdf0e10cSrcweir 				basegfx::B2DPoint aTransformedPoint(aTransform * aPoint);
439cdf0e10cSrcweir 				const double tu(((aPoint.getX()-aSurfaceClipRect.getMinX())*rUV.getWidth()/w)+rUV.getMinX());
440cdf0e10cSrcweir                 const double tv(((aPoint.getY()-aSurfaceClipRect.getMinY())*rUV.getHeight()/h)+rUV.getMinY());
441cdf0e10cSrcweir 				vertex.u=static_cast<float>(tu);
442cdf0e10cSrcweir 				vertex.v=static_cast<float>(tv);
443cdf0e10cSrcweir 				vertex.x=static_cast<float>(aTransformedPoint.getX());
444cdf0e10cSrcweir 				vertex.y=static_cast<float>(aTransformedPoint.getY());
445cdf0e10cSrcweir 				pRenderModule->pushVertex(vertex);
446cdf0e10cSrcweir 			}
447cdf0e10cSrcweir 		}
448cdf0e10cSrcweir 
449cdf0e10cSrcweir 		return !(pRenderModule->isError());
450cdf0e10cSrcweir 	}
451cdf0e10cSrcweir 
452cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
453cdf0e10cSrcweir 	// Surface::prepareRendering
454cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
455cdf0e10cSrcweir 
prepareRendering()456cdf0e10cSrcweir 	void Surface::prepareRendering()
457cdf0e10cSrcweir 	{
458cdf0e10cSrcweir 		mpPageManager->validatePages();
459cdf0e10cSrcweir 
460cdf0e10cSrcweir 		// clients requested to draw from this surface, therefore one
461cdf0e10cSrcweir 		// of the above implemented concrete rendering operations
462cdf0e10cSrcweir 		// was triggered. we therefore need to ask the pagemanager
463cdf0e10cSrcweir 		// to allocate some space for the fragment we're dedicated to.
464cdf0e10cSrcweir 		if(!(mpFragment))
465cdf0e10cSrcweir 		{
466cdf0e10cSrcweir 			mpFragment = mpPageManager->allocateSpace(maSize);
467cdf0e10cSrcweir             if( mpFragment )
468cdf0e10cSrcweir             {
469cdf0e10cSrcweir 			    mpFragment->setColorBuffer(mpColorBuffer);
470cdf0e10cSrcweir     			mpFragment->setSourceOffset(maSourceOffset);
471cdf0e10cSrcweir             }
472cdf0e10cSrcweir 		}
473cdf0e10cSrcweir 
474cdf0e10cSrcweir         if( mpFragment )
475cdf0e10cSrcweir         {
476cdf0e10cSrcweir 		    // now we need to 'select' the fragment, which will in turn
477cdf0e10cSrcweir 		    // pull informations from the image on demand.
478cdf0e10cSrcweir 		    // in case this fragment is still not located on any of the
479cdf0e10cSrcweir 		    // available pages ['naked'], we force the page manager to
480cdf0e10cSrcweir 		    // do it now, no way to defer this any longer...
481cdf0e10cSrcweir 		    if(!(mpFragment->select(mbIsDirty)))
482cdf0e10cSrcweir 			    mpPageManager->nakedFragment(mpFragment);
483cdf0e10cSrcweir 
484cdf0e10cSrcweir         }
485cdf0e10cSrcweir 	    mbIsDirty=false;
486cdf0e10cSrcweir 	}
487cdf0e10cSrcweir 
488cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
489cdf0e10cSrcweir 	// End of file
490cdf0e10cSrcweir 	//////////////////////////////////////////////////////////////////////////////////
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493