Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : // must be first
22 : : #include <canvas/debug.hxx>
23 : : #include <tools/diagnose_ex.h>
24 : :
25 : : #include <animatedsprite.hxx>
26 : :
27 : : #include <cppcanvas/canvas.hxx>
28 : : #include <canvas/canvastools.hxx>
29 : :
30 : : #include <basegfx/vector/b2dvector.hxx>
31 : : #include <basegfx/point/b2dpoint.hxx>
32 : : #include <basegfx/matrix/b2dhommatrix.hxx>
33 : : #include <basegfx/numeric/ftools.hxx>
34 : :
35 : :
36 : : using namespace ::com::sun::star;
37 : :
38 : : namespace slideshow
39 : : {
40 : : namespace internal
41 : : {
42 : 0 : AnimatedSprite::AnimatedSprite( const ViewLayerSharedPtr& rViewLayer,
43 : : const ::basegfx::B2DSize& rSpriteSizePixel,
44 : : double nSpritePrio ) :
45 : : mpViewLayer( rViewLayer ),
46 : : mpSprite(),
47 : : maEffectiveSpriteSizePixel( rSpriteSizePixel ),
48 : : maContentPixelOffset(),
49 : : mnSpritePrio(nSpritePrio),
50 : : mnAlpha(0.0),
51 : : maPosPixel(),
52 : : maClip(),
53 : : maTransform(),
54 : 0 : mbSpriteVisible( false )
55 : : {
56 : 0 : ENSURE_OR_THROW( mpViewLayer, "AnimatedSprite::AnimatedSprite(): Invalid view layer" );
57 : :
58 : : // Add half a pixel tolerance to sprite size, since we later on compare
59 : : // against it in resize(). And view transformations will almost never yield
60 : : // the same data bits when transforming to device coordinates
61 : 0 : maEffectiveSpriteSizePixel += ::basegfx::B2DSize(0.5, 0.5);
62 : :
63 : 0 : mpSprite = mpViewLayer->createSprite( maEffectiveSpriteSizePixel,
64 : 0 : mnSpritePrio );
65 : :
66 : 0 : ENSURE_OR_THROW( mpSprite, "AnimatedSprite::AnimatedSprite(): Could not create sprite" );
67 : 0 : }
68 : :
69 : 0 : ::cppcanvas::CanvasSharedPtr AnimatedSprite::getContentCanvas() const
70 : : {
71 : 0 : ENSURE_OR_THROW( mpViewLayer->getCanvas(), "AnimatedSprite::getContentCanvas(): No view layer canvas" );
72 : :
73 : 0 : const ::cppcanvas::CanvasSharedPtr pContentCanvas( mpSprite->getContentCanvas() );
74 : 0 : pContentCanvas->clear();
75 : :
76 : : // extract linear part of canvas view transformation
77 : : // (linear means: without translational components). The
78 : : // only translation that is imposed at the view transform
79 : : // is the local content pixel offset.
80 : : //
81 : : // We can apply that directly here, no need to call
82 : : // aLinearTransform.translate(), since, as said above, the
83 : : // last column of aLinearTransform is assumed [0 0 1]
84 : 0 : ::basegfx::B2DHomMatrix aLinearTransform( mpViewLayer->getTransformation() );
85 : 0 : aLinearTransform.set( 0, 2, maContentPixelOffset.getX() );
86 : 0 : aLinearTransform.set( 1, 2, maContentPixelOffset.getY() );
87 : :
88 : : // apply linear part of canvas view transformation to sprite canvas
89 : 0 : pContentCanvas->setTransformation( aLinearTransform );
90 : :
91 : 0 : return pContentCanvas;
92 : : }
93 : :
94 : 0 : bool AnimatedSprite::resize( const ::basegfx::B2DSize& rSpriteSizePixel )
95 : : {
96 : : // Enlarge or reduce the sprite size, if necessary. This
97 : : // method employs a strategy similar to container, when
98 : : // allocating memory: size is doubled or halved everytime
99 : : // the limit is reached. This makes for amortized constant
100 : : // time in runtime complexity. Note that we take exact
101 : : // powers of two here, since several HW-accelerated canvas
102 : : // implementations are limited to such sprite sizes
103 : : // (otherwise, those implementations would internally
104 : : // round up, too, wasting precious mem).
105 : 0 : ::basegfx::B2DSize aNewSize( maEffectiveSpriteSizePixel );
106 : 0 : bool bNeedResize( false );
107 : :
108 : 0 : if( rSpriteSizePixel.getX() > maEffectiveSpriteSizePixel.getX() ||
109 : 0 : rSpriteSizePixel.getX() < 0.5*maEffectiveSpriteSizePixel.getX() )
110 : : {
111 : : // enlarge or shrink width
112 : 0 : aNewSize.setX( ::canvas::tools::nextPow2( ::basegfx::fround(rSpriteSizePixel.getX()) ) );
113 : 0 : bNeedResize = true;
114 : : }
115 : :
116 : 0 : if( rSpriteSizePixel.getY() > maEffectiveSpriteSizePixel.getY() ||
117 : 0 : rSpriteSizePixel.getY() < 0.5*maEffectiveSpriteSizePixel.getY() )
118 : : {
119 : : // enlarge or shrink height, by doubling it
120 : 0 : aNewSize.setY( ::canvas::tools::nextPow2( ::basegfx::fround(rSpriteSizePixel.getY()) ) );
121 : 0 : bNeedResize = true;
122 : : }
123 : :
124 : 0 : if( bNeedResize )
125 : : {
126 : : // as the old sprite might have already been altered
127 : : // (and therefore been placed in the update list of
128 : : // the spritecanvas for this frame), must hide it
129 : : // here, to ensure it's not visible on screen any
130 : : // longer.
131 : 0 : mpSprite->hide();
132 : :
133 : 0 : maEffectiveSpriteSizePixel = aNewSize;
134 : 0 : mpSprite = mpViewLayer->createSprite( maEffectiveSpriteSizePixel,
135 : 0 : mnSpritePrio );
136 : :
137 : 0 : ENSURE_OR_THROW( mpSprite,
138 : : "AnimatedSprite::resize(): Could not create new sprite" );
139 : :
140 : : // set attributes similar to previous sprite
141 : 0 : if( mpSprite && mbSpriteVisible )
142 : : {
143 : 0 : mpSprite->show();
144 : 0 : mpSprite->setAlpha( mnAlpha );
145 : :
146 : 0 : if( maPosPixel )
147 : 0 : mpSprite->movePixel( *maPosPixel );
148 : :
149 : 0 : if( maClip )
150 : 0 : mpSprite->setClip( *maClip );
151 : : }
152 : : }
153 : :
154 : 0 : return mpSprite;
155 : : }
156 : :
157 : 0 : void AnimatedSprite::setPixelOffset( const ::basegfx::B2DSize& rPixelOffset )
158 : : {
159 : 0 : maContentPixelOffset = rPixelOffset;
160 : 0 : }
161 : :
162 : 0 : void AnimatedSprite::movePixel( const ::basegfx::B2DPoint& rNewPos )
163 : : {
164 : 0 : maPosPixel.reset( rNewPos );
165 : 0 : mpSprite->movePixel( rNewPos );
166 : 0 : }
167 : :
168 : 0 : void AnimatedSprite::setAlpha( double nAlpha )
169 : : {
170 : 0 : mnAlpha = nAlpha;
171 : 0 : mpSprite->setAlpha( nAlpha );
172 : 0 : }
173 : :
174 : 0 : void AnimatedSprite::clip( const ::basegfx::B2DPolyPolygon& rClip )
175 : : {
176 : 0 : maClip.reset( rClip );
177 : 0 : mpSprite->setClipPixel( rClip );
178 : 0 : }
179 : :
180 : 0 : void AnimatedSprite::clip()
181 : : {
182 : 0 : maClip.reset();
183 : 0 : mpSprite->setClip();
184 : 0 : }
185 : :
186 : 0 : void AnimatedSprite::transform( const ::basegfx::B2DHomMatrix& rTransform )
187 : : {
188 : 0 : maTransform.reset( rTransform );
189 : 0 : mpSprite->transform( rTransform );
190 : 0 : }
191 : :
192 : 0 : void AnimatedSprite::hide()
193 : : {
194 : 0 : mpSprite->hide();
195 : 0 : mbSpriteVisible = false;
196 : 0 : }
197 : :
198 : 0 : void AnimatedSprite::show()
199 : : {
200 : 0 : mbSpriteVisible = true;
201 : 0 : mpSprite->show();
202 : 0 : }
203 : :
204 : : }
205 : : }
206 : :
207 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|