sw_engine: implement linear gradient feature
[platform/core/graphics/tizenvg.git] / src / lib / tvgCanvasImpl.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
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 #ifndef _TVG_CANVAS_IMPL_H_
18 #define _TVG_CANVAS_IMPL_H_
19
20 #include "tvgCommon.h"
21
22 /************************************************************************/
23 /* Internal Class Implementation                                        */
24 /************************************************************************/
25
26 struct Canvas::Impl
27 {
28     vector<Paint*> paints;
29     RenderMethod*  renderer;
30
31     Impl(RenderMethod* pRenderer):renderer(pRenderer)
32     {
33         renderer->ref();
34     }
35
36     ~Impl()
37     {
38         clear();
39         renderer->unref();
40     }
41
42     Result push(unique_ptr<Paint> paint)
43     {
44         auto p = paint.release();
45         assert(p);
46         paints.push_back(p);
47
48         return update(p);
49     }
50
51     Result clear()
52     {
53         assert(renderer);
54
55         for (auto paint : paints) {
56             if (paint->id() == PAINT_ID_SCENE) {
57                 //We know renderer type, avoid dynamic_cast for performance.
58                 auto scene = static_cast<Scene*>(paint);
59                 if (!SCENE_IMPL->clear(*renderer)) return Result::InsufficientCondition;
60             } else {
61                 auto shape = static_cast<Shape*>(paint);
62                 if (!SHAPE_IMPL->dispose(*shape, *renderer)) return Result::InsufficientCondition;
63             }
64             delete(paint);
65         }
66         paints.clear();
67
68         return Result::Success;
69     }
70
71     Result update()
72     {
73         assert(renderer);
74
75         for(auto paint: paints) {
76             if (paint->id() == PAINT_ID_SCENE) {
77                 //We know renderer type, avoid dynamic_cast for performance.
78                 auto scene = static_cast<Scene*>(paint);
79                 if (!SCENE_IMPL->update(*renderer, nullptr)) return Result::InsufficientCondition;
80             } else {
81                 auto shape = static_cast<Shape*>(paint);
82                 if (!SHAPE_IMPL->update(*shape, *renderer, nullptr)) return Result::InsufficientCondition;
83             }
84         }
85         return Result::Success;
86     }
87
88     Result update(Paint* paint)
89     {
90         assert(renderer);
91
92         if (paint->id() == PAINT_ID_SCENE) {
93             //We know renderer type, avoid dynamic_cast for performance.
94             auto scene = static_cast<Scene*>(paint);
95             if (!SCENE_IMPL->update(*renderer)) return Result::InsufficientCondition;
96         } else {
97             auto shape = static_cast<Shape*>(paint);
98             if (!SHAPE_IMPL->update(*shape, *renderer)) return Result::InsufficientCondition;
99         }
100         return Result::Success;
101     }
102
103     Result draw()
104     {
105         assert(renderer);
106
107         //Clear render target before drawing
108         if (!renderer->clear()) return Result::InsufficientCondition;
109
110         for(auto paint: paints) {
111            if (paint->id() == PAINT_ID_SCENE) {
112                 //We know renderer type, avoid dynamic_cast for performance.
113                 auto scene = static_cast<Scene*>(paint);
114                 if(!SCENE_IMPL->render(*renderer)) return Result::InsufficientCondition;
115             } else {
116                 auto shape = static_cast<Shape*>(paint);
117                 if(!SHAPE_IMPL->render(*shape, *renderer)) return Result::InsufficientCondition;
118             }
119         }
120         return Result::Success;
121     }
122 };
123
124 #endif /* _TVG_CANVAS_IMPL_H_ */