1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "ogl_canvascustomsprite.hxx"
11 #include "ogl_canvastools.hxx"
12 #include "ogl_tools.hxx"
14 #include <canvas/debug.hxx>
15 #include <canvas/verbosetrace.hxx>
16 #include <canvas/verifyinput.hxx>
17 #include <tools/diagnose_ex.h>
19 #include <canvas/canvastools.hxx>
21 #include <basegfx/matrix/b2dhommatrix.hxx>
22 #include <basegfx/point/b2dpoint.hxx>
23 #include <basegfx/tools/canvastools.hxx>
24 #include <basegfx/polygon/b2dpolygonclipper.hxx>
25 #include <basegfx/polygon/b2dpolygontriangulator.hxx>
26 #include <basegfx/polygon/b2dpolypolygontools.hxx>
30 using namespace ::com::sun::star
;
34 CanvasCustomSprite::CanvasCustomSprite( const ::com::sun::star::geometry::RealSize2D
& rSpriteSize
,
35 const SpriteCanvasRef
& rRefDevice
,
36 SpriteDeviceHelper
& rDeviceHelper
) :
37 mpSpriteCanvas( rRefDevice
),
45 ENSURE_OR_THROW( rRefDevice
.get(),
46 "CanvasCustomSprite::CanvasCustomSprite(): Invalid sprite canvas" );
48 ::canvas::tools::setIdentityAffineMatrix2D(maTransformation
);
49 maCanvasHelper
.init( *rRefDevice
.get(),
53 void CanvasCustomSprite::disposeThis()
55 ::osl::MutexGuard
aGuard( m_aMutex
);
57 mpSpriteCanvas
.clear();
60 CanvasCustomSpriteBaseT::disposeThis();
63 void SAL_CALL
CanvasCustomSprite::setAlpha( double alpha
) throw (lang::IllegalArgumentException
,
64 uno::RuntimeException
, std::exception
)
66 canvas::tools::verifyRange( alpha
, 0.0, 1.0 );
68 ::osl::MutexGuard
aGuard( m_aMutex
);
72 void SAL_CALL
CanvasCustomSprite::move( const geometry::RealPoint2D
& aNewPos
,
73 const rendering::ViewState
& viewState
,
74 const rendering::RenderState
& renderState
) throw (lang::IllegalArgumentException
,
75 uno::RuntimeException
, std::exception
)
77 canvas::tools::verifyArgs(aNewPos
, viewState
, renderState
,
78 BOOST_CURRENT_FUNCTION
,
79 static_cast< ::cppu::OWeakObject
* >(this));
81 ::osl::MutexGuard
aGuard( m_aMutex
);
82 ::basegfx::B2DHomMatrix aTransform
;
83 ::canvas::tools::mergeViewAndRenderTransform(aTransform
,
87 // convert position to device pixel
88 maPosition
= ::basegfx::unotools::b2DPointFromRealPoint2D(aNewPos
);
89 maPosition
*= aTransform
;
92 void SAL_CALL
CanvasCustomSprite::transform( const geometry::AffineMatrix2D
& aTransformation
) throw (lang::IllegalArgumentException
,
93 uno::RuntimeException
, std::exception
)
95 ::osl::MutexGuard
aGuard( m_aMutex
);
96 maTransformation
= aTransformation
;
99 void SAL_CALL
CanvasCustomSprite::clip( const uno::Reference
< rendering::XPolyPolygon2D
>& xClip
) throw (uno::RuntimeException
, std::exception
)
104 void SAL_CALL
CanvasCustomSprite::setPriority( double nPriority
) throw (uno::RuntimeException
, std::exception
)
106 ::osl::MutexGuard
aGuard( m_aMutex
);
107 mfPriority
= nPriority
;
110 void SAL_CALL
CanvasCustomSprite::show() throw (uno::RuntimeException
, std::exception
)
112 ::osl::MutexGuard
aGuard( m_aMutex
);
113 if( mpSpriteCanvas
.is() )
114 mpSpriteCanvas
->show(this);
117 void SAL_CALL
CanvasCustomSprite::hide() throw (uno::RuntimeException
, std::exception
)
119 ::osl::MutexGuard
aGuard( m_aMutex
);
120 if( mpSpriteCanvas
.is() )
121 mpSpriteCanvas
->hide(this);
124 uno::Reference
< rendering::XCanvas
> SAL_CALL
CanvasCustomSprite::getContentCanvas() throw (uno::RuntimeException
, std::exception
)
129 bool CanvasCustomSprite::renderSprite() const
131 if( ::basegfx::fTools::equalZero( mfAlpha
) )
134 TransformationPreserver aPreserver1
;
135 const ::basegfx::B2IVector
aSpriteSizePixel(
136 ::canvas::tools::roundUp( maSize
.Width
),
137 ::canvas::tools::roundUp( maSize
.Height
));
139 // translate sprite to output position
140 glTranslated(maPosition
.getX(), maPosition
.getY(), 0);
143 TransformationPreserver aPreserver2
;
145 // apply sprite content transformation matrix
146 double aGLTransform
[] =
148 maTransformation
.m00
, maTransformation
.m10
, 0, 0,
149 maTransformation
.m01
, maTransformation
.m11
, 0, 0,
151 maTransformation
.m02
, maTransformation
.m12
, 0, 1
153 glMultMatrixd(aGLTransform
);
155 IBufferContextSharedPtr pBufferContext
;
156 if( mfAlpha
!= 1.0 || mxClip
.is() )
158 // drats. need to render to temp surface before, and then
159 // composite that to screen
161 // TODO(P3): buffer texture
162 pBufferContext
= maCanvasHelper
.getDeviceHelper()->createBufferContext(aSpriteSizePixel
);
163 pBufferContext
->startBufferRendering();
166 // this ends up in pBufferContext, if that one's "current"
167 if( !maCanvasHelper
.renderRecordedActions() )
172 // content ended up in background buffer - compose to
173 // screen now. Calls below switches us back to window
174 // context, and binds to generated, dynamic texture
175 pBufferContext
->endBufferRendering();
176 GLuint nTexture
= pBufferContext
->getTextureId();
177 glBindTexture(GL_TEXTURE_2D
, nTexture
);
179 glEnable(GL_TEXTURE_2D
);
180 glTexParameteri(GL_TEXTURE_2D
,
181 GL_TEXTURE_MIN_FILTER
,
183 glTexParameteri(GL_TEXTURE_2D
,
184 GL_TEXTURE_MAG_FILTER
,
187 glBlendFunc(GL_SRC_ALPHA
,
188 GL_ONE_MINUS_SRC_ALPHA
);
190 // blend against fixed vertex color; texture alpha is multiplied in
191 glColor4f(1,1,1,mfAlpha
);
195 const double fWidth
=maSize
.Width
;
196 const double fHeight
=maSize
.Height
;
198 // TODO(P3): buffer triangulation
199 const ::basegfx::B2DPolygon
& rTriangulatedPolygon(
200 ::basegfx::triangulator::triangulate(
201 ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(mxClip
)));
203 basegfx::B2DPolygon
rTriangleList(
204 basegfx::tools::clipTriangleListOnRange(
205 rTriangulatedPolygon
,
208 aSpriteSizePixel
.getX(),
209 aSpriteSizePixel
.getY())));
211 glBegin(GL_TRIANGLES
);
212 for( sal_uInt32 i
=0; i
<rTriangulatedPolygon
.count(); i
++ )
214 const ::basegfx::B2DPoint
& rPt( rTriangulatedPolygon
.getB2DPoint(i
) );
215 const double s(rPt
.getX()/fWidth
);
216 const double t(rPt
.getY()/fHeight
);
217 glTexCoord2f(s
,t
); glVertex2d(rPt
.getX(), rPt
.getY());
223 const double fWidth
=maSize
.Width
/aSpriteSizePixel
.getX();
224 const double fHeight
=maSize
.Height
/aSpriteSizePixel
.getY();
226 glBegin(GL_TRIANGLE_STRIP
);
227 glTexCoord2f(0,0); glVertex2d(0,0);
228 glTexCoord2f(0,fHeight
); glVertex2d(0, aSpriteSizePixel
.getY());
229 glTexCoord2f(fWidth
,0); glVertex2d(aSpriteSizePixel
.getX(),0);
230 glTexCoord2f(fWidth
,fHeight
); glVertex2d(aSpriteSizePixel
.getX(),aSpriteSizePixel
.getY());
234 glBindTexture(GL_TEXTURE_2D
, 0);
235 glDisable(GL_TEXTURE_2D
);
240 glBegin(GL_LINE_STRIP
);
242 glVertex2d(-2,maSize
.Height
+4);
243 glVertex2d(maSize
.Width
+4,maSize
.Height
+4);
244 glVertex2d(maSize
.Width
+4,-2);
246 glVertex2d(maSize
.Width
+4,maSize
.Height
+4);
249 std::vector
<double> aVec
;
250 aVec
.push_back(mfAlpha
);
251 aVec
.push_back(mfPriority
);
252 aVec
.push_back(maCanvasHelper
.getRecordedActionCount());
253 renderOSD( aVec
, 10 );
259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */