xref: /AOO42X/main/canvas/source/tools/surface.cxx (revision b1c5455db1639c48e26c568e4fa7ee78ca5d60ee)
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
10cdf0e10cSrcweir  *
11*25ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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 }
492