1b3a38c948df55d4b8f6d67d95baeb554c929970
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / clipping / text-clipper.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/text/clipping/text-clipper.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/render-tasks/render-task-list.h>
25 #include <dali/integration-api/debug.h>
26
27 namespace
28 {
29
30 // Currently on desktop machines 2k x 2k is the maximum frame buffer size, on target is 4k x 4k.
31 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
32
33 } // namespace
34
35
36 namespace Dali
37 {
38
39 namespace Toolkit
40 {
41
42 namespace Text
43 {
44
45 ClipperPtr Clipper::New( const Vector2& size )
46 {
47   ClipperPtr clipper( new Clipper() );
48
49   // Second-phase init
50   clipper->Initialize( size );
51
52   return clipper;
53 }
54
55 Actor Clipper::GetRootActor() const
56 {
57   return mOffscreenRootActor;
58 }
59
60 ImageActor Clipper::GetImageActor() const
61 {
62   return mImageActor;
63 }
64
65 void Clipper::Refresh( const Vector2& size )
66 {
67   const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.width ),
68                             std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.height ) );
69
70   const bool sizeChanged = offscreenSize != mCurrentOffscreenSize;
71
72   if( sizeChanged )
73   {
74     // Reconfigure camera for current size.
75     mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
76
77     // Recreate frame buffer for offscreen rendering when the size changes.
78     FrameBufferImage frameBufferImage = FrameBufferImage::New( offscreenSize.width,
79                                                                offscreenSize.height,
80                                                                Pixel::RGBA8888 );
81     mImageActor.SetImage( frameBufferImage );
82     mRenderTask.SetTargetFrameBuffer( frameBufferImage );
83
84     // Stores current size to avoid create new Dali resources if text changes.
85     mCurrentOffscreenSize = offscreenSize;
86   }
87
88   mRenderTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
89 }
90
91 void Clipper::Initialize( const Vector2& size )
92 {
93   const Size offscreenSize( std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.width ),
94                             std::min( MAX_OFFSCREEN_RENDERING_SIZE, size.height ) );
95
96   // Create a root actor and an image actor for offscreen rendering.
97   mOffscreenRootActor = Layer::New();
98   mOffscreenRootActor.SetColorMode( USE_OWN_COLOR );
99   mOffscreenRootActor.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
100   mOffscreenRootActor.SetInheritRotation( false );
101   mOffscreenRootActor.SetInheritScale( false );
102   mOffscreenRootActor.SetDepthTestDisabled( true );
103   mOffscreenRootActor.SetSize( offscreenSize );
104   mOffscreenRootActor.SetPosition( 0.0f, 0.0f, 0.0f );
105
106   mImageActor = ImageActor::New();
107   mImageActor.SetAnchorPoint( ParentOrigin::CENTER );
108   mImageActor.SetParentOrigin( ParentOrigin::CENTER );
109   mImageActor.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
110                             BlendingFactor::ONE, BlendingFactor::ONE );
111   mImageActor.SetScale( Vector3( 1.0f, -1.0f, 1.0f ) );
112   mImageActor.SetSize( offscreenSize );
113
114   // Creates a new camera actor.
115   mOffscreenCameraActor = CameraActor::New();
116   mOffscreenCameraActor.SetParentOrigin( ParentOrigin::CENTER );
117   mOffscreenCameraActor.SetAnchorPoint( AnchorPoint::CENTER );
118   mOffscreenCameraActor.SetRotation(Degree(180.f), Vector3::YAXIS);
119   mOffscreenCameraActor.SetType( Dali::Camera::FREE_LOOK ); // Inherits position from the offscreen root actor.
120   mOffscreenCameraActor.SetOrthographicProjection( offscreenSize );
121   mOffscreenRootActor.Add( mOffscreenCameraActor ); // camera to shoot the offscreen text
122
123   // Creates a new render task.
124   mRenderTask = Stage::GetCurrent().GetRenderTaskList().CreateTask();
125   mRenderTask.SetSourceActor( mOffscreenRootActor );
126   mRenderTask.SetInputEnabled( false );
127   mRenderTask.SetClearColor( Color::TRANSPARENT );
128   mRenderTask.SetClearEnabled( true );
129   mRenderTask.SetExclusive( true );
130   mRenderTask.SetCameraActor( mOffscreenCameraActor );
131
132   // Creates a frame buffer for offscreen rendering
133   FrameBufferImage frameBufferImage = FrameBufferImage::New( offscreenSize.width,
134                                                              offscreenSize.height,
135                                                              Pixel::RGBA8888 );
136   mImageActor.SetImage( frameBufferImage );
137   mRenderTask.SetTargetFrameBuffer( frameBufferImage );
138
139   // Stores current size to avoid create new Dali resources if text changes.
140   mCurrentOffscreenSize = offscreenSize;
141 }
142
143 Clipper::Clipper()
144 {
145 }
146
147 Clipper::~Clipper()
148 {
149   if( Stage::IsInstalled() )
150   {
151     UnparentAndReset( mOffscreenRootActor );
152     UnparentAndReset( mImageActor );
153
154     Stage::GetCurrent().GetRenderTaskList().RemoveTask( mRenderTask );
155   }
156 }
157
158 } // namespace Text
159
160 } // namespace Toolkit
161
162 } // namespace Dali