Merge "Refactoring Button: remove painter" into tizen
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / image / image-wrapper.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 "image-wrapper.h"
20
21 // INTERNAL INCLUDES
22 #include <v8-utils.h>
23 #include <dali-wrapper.h>
24 #include <image/image-api.h>
25 #include <image/frame-buffer-image-api.h>
26 #include <image/resource-image-api.h>
27 #include <image/nine-patch-image-api.h>
28 #include <image/buffer-image-api.h>
29 #include <image/native-image-api.h>
30 #include <shared/api-function.h>
31 #include <shared/object-template-helper.h>
32
33 namespace Dali
34 {
35
36 namespace V8Plugin
37 {
38
39 v8::Persistent<v8::ObjectTemplate> ImageWrapper::mImageTemplate;
40 v8::Persistent<v8::ObjectTemplate> ImageWrapper::mResourceImageTemplate;
41 v8::Persistent<v8::ObjectTemplate> ImageWrapper::mNinePatchImageTemplate;
42 v8::Persistent<v8::ObjectTemplate> ImageWrapper::mBufferImageTemplate;
43 v8::Persistent<v8::ObjectTemplate> ImageWrapper::mFrameBufferImageTemplate;
44 v8::Persistent<v8::ObjectTemplate> ImageWrapper::mNativeImageTemplate;
45
46 /**
47  * pointer to a persistent template handle
48  */
49 struct ImageTemplate
50 {
51   v8::Persistent<v8::ObjectTemplate>* imageTemplate;
52 };
53
54 /**
55  * array of templates for each type of image
56  */
57 const ImageTemplate ImageTemplateLookup[]=
58 {
59     { &ImageWrapper::mImageTemplate },              // IMAGE
60     { &ImageWrapper::mResourceImageTemplate },      // RESOURCE_IMAGE
61     { &ImageWrapper::mNinePatchImageTemplate },     // NINE PATCH IMAGE
62     { &ImageWrapper::mBufferImageTemplate  },       // BITMAP_IMAGE
63     { &ImageWrapper::mFrameBufferImageTemplate },   // FRAME_BUFFER_IMAGE
64     { &ImageWrapper::mNativeImageTemplate },        // NATIVE_IMAGE
65
66 };
67
68
69 namespace // un-named name space
70 {
71
72 /**
73  * Bitmask of API's that an image can support
74  */
75 enum ImageApiBitMask
76 {
77   IMAGE_API              = 1 << 0,
78   BITMAP_IMAGE_API       = 1 << 1,
79   RESOURCE_IMAGE_API     = 1 << 2,
80   NINE_PATCH_IMAGE_API   = 1 << 3,
81   FRAME_BUFFER_IMAGE_API = 1 << 4,
82   NATIVE_IMAGE_API       = 1 << 5,
83
84 };
85
86 /**
87  * structure used for the ImageApiLookup.
88  */
89 struct ImageApiStruct
90 {
91   const char* imageName;                  ///< name of the image, used to find out what type of image to construct
92   ImageWrapper::ImageType imageType;      ///< image type
93   Image (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args); ///< constructor
94   int supportApis;                        ///< supported API's
95 };
96
97 /**
98  * Lookup table to match a image type with a constructor and supported API's.
99  */
100 const ImageApiStruct ImageApiLookup[]=
101 {
102   {"Image",           ImageWrapper::IMAGE,              ImageApi::New,            IMAGE_API },
103   {"ResourceImage",   ImageWrapper::RESOURCE_IMAGE,     ResourceImageApi::New,    IMAGE_API | RESOURCE_IMAGE_API },
104   {"NinePatchImage",  ImageWrapper::NINE_PATCH_IMAGE,   NinePatchImageApi::New,   IMAGE_API | RESOURCE_IMAGE_API | NINE_PATCH_IMAGE_API },
105   {"BufferImage",     ImageWrapper::BITMAP_IMAGE,       BufferImageApi::New,      IMAGE_API | BITMAP_IMAGE_API },
106   {"FrameBufferImage",ImageWrapper::FRAME_BUFFER_IMAGE, FrameBufferImageApi::New, IMAGE_API | FRAME_BUFFER_IMAGE_API },
107   {"NativeImage",     ImageWrapper::NATIVE_IMAGE,       NativeImageApi::New,      IMAGE_API | NATIVE_IMAGE_API },
108
109 };
110
111 const unsigned int ImageApiLookupCount = sizeof(ImageApiLookup)/sizeof(ImageApiLookup[0]);
112
113
114 /**
115  * given an image type return what api's it supports
116  */
117 int GetImageSupportedApis( ImageWrapper::ImageType type )
118 {
119   return ImageApiLookup[ type].supportApis;
120 }
121
122 /**
123  * Used for the ImageFunctionTable to map function names to functions
124  * with for a specific API
125  */
126 struct ImageFunctions
127 {
128   const char* name;               ///< function name
129   void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
130   ImageApiBitMask api;
131 };
132
133 /**
134  * Contains a list of all functions that can be called
135  */
136 const ImageFunctions ImageFunctionTable[]=
137 {
138     /**************************************
139     * Image API (in order of image.h)
140     **************************************/
141     { "GetWidth",                ImageApi::GetWidth , IMAGE_API },
142     { "GetHeight",               ImageApi::GetHeight, IMAGE_API },
143     { "GetReleasePolicy",        ImageApi::GetReleasePolicy, IMAGE_API },
144
145     // resource-image API
146     { "GetLoadingState",         ResourceImageApi::GetLoadingState,     RESOURCE_IMAGE_API },
147     { "GetUrl",                  ResourceImageApi::GetUrl,              RESOURCE_IMAGE_API },
148     { "GetLoadPolicy",           ResourceImageApi::GetLoadPolicy,       RESOURCE_IMAGE_API },
149     { "Reload",                  ResourceImageApi::Reload,              RESOURCE_IMAGE_API },
150
151     // nine-patch API
152     { "GetStretchBorders",       NinePatchImageApi::GetStretchBorders,        NINE_PATCH_IMAGE_API },
153     { "GetChildRectangle",       NinePatchImageApi::GetChildRectangle,        NINE_PATCH_IMAGE_API },
154     { "CreateCroppedBufferImage",NinePatchImageApi::CreateCroppedBufferImage, NINE_PATCH_IMAGE_API },
155
156     // buffer image API
157     { "GetBuffer",              BufferImageApi::GetBuffer,           BITMAP_IMAGE_API },
158     { "GetBufferSize",          BufferImageApi::GetBufferSize,       BITMAP_IMAGE_API },
159     { "GetBufferStride",        BufferImageApi::GetBufferStride,     BITMAP_IMAGE_API },
160     { "GetPixelFormat",         BufferImageApi::GetPixelFormat,      BITMAP_IMAGE_API },
161     { "Update",                 BufferImageApi::Update,              BITMAP_IMAGE_API },
162     { "IsDataExternal",         BufferImageApi::IsDataExternal,      BITMAP_IMAGE_API },
163
164     // Frame buffer image has no API
165     // Native image has no API
166
167 };
168
169 const unsigned int ImageFunctionTableCount = sizeof(ImageFunctionTable)/sizeof(ImageFunctionTable[0]);
170 } //un-named space
171
172
173 ImageWrapper::ImageWrapper( const Dali::Image& image, GarbageCollectorInterface& gc )
174 : BaseWrappedObject( BaseWrappedObject::IMAGE , gc )
175 {
176     mImage = image;
177 }
178
179 v8::Handle<v8::Object> ImageWrapper::WrapImage(v8::Isolate* isolate, const Dali::Image& image )
180 {
181   v8::EscapableHandleScope handleScope( isolate );
182
183   v8::Local<v8::Object> object = WrapImage( isolate, image, GetImageType( image.GetTypeName() ) );
184
185   return handleScope.Escape( object );
186 }
187 v8::Handle<v8::Object> ImageWrapper::WrapImage(v8::Isolate* isolate, const Dali::Image& image, ImageType imageType )
188 {
189   v8::EscapableHandleScope handleScope( isolate );
190   v8::Local<v8::ObjectTemplate> objectTemplate;
191
192   objectTemplate = GetImageTemplate( isolate, imageType);
193
194   // create an instance of the template
195   v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
196
197   // create the Image wrapper
198   ImageWrapper* pointer =  new ImageWrapper( image, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
199
200   // assign the JavaScript object to the wrapper.
201   // This also stores the Image object, in an internal field inside the JavaScript object.
202   pointer->SetJavascriptObject( isolate, localObject );
203
204   return handleScope.Escape( localObject );
205 }
206
207 v8::Local<v8::ObjectTemplate> ImageWrapper::GetImageTemplate( v8::Isolate* isolate, ImageType imageType )
208 {
209   v8::EscapableHandleScope handleScope( isolate );
210   v8::Local<v8::ObjectTemplate> objectTemplate;
211
212   if( ImageTemplateLookup[ imageType ].imageTemplate->IsEmpty() )
213   {
214     objectTemplate = MakeImageTemplate( isolate, imageType );
215     ImageTemplateLookup[ imageType ].imageTemplate->Reset( isolate, objectTemplate );
216   }
217   else
218   {
219     // get the object template
220     objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ImageTemplateLookup[ imageType ].imageTemplate );
221   }
222
223   return handleScope.Escape( objectTemplate );
224 }
225
226 v8::Handle<v8::ObjectTemplate> ImageWrapper::MakeImageTemplate( v8::Isolate* isolate, ImageType imageType )
227 {
228   v8::EscapableHandleScope handleScope( isolate );
229
230   v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
231
232   objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
233
234   // add intercepts for Signals on ResourceImage, we can't use HandleWrapper::AddIntercepts because Image doesn't inherit
235   // from Handle ( just baseHandle)
236   if (( imageType == RESOURCE_IMAGE ) ||
237       ( imageType == NINE_PATCH_IMAGE ))
238   {
239      ObjectTemplateHelper::AddSignalConnectAndDisconnect( isolate, objTemplate );
240   }
241
242   // find out what API's this image supports
243   int supportApis = GetImageSupportedApis( imageType );
244
245   // add our function properties
246   for( unsigned int i = 0; i < ImageFunctionTableCount; ++i )
247   {
248     const ImageFunctions property =  ImageFunctionTable[i];
249
250     // check to see if the image supports a certain type of API
251     // e.g. Bitmap will support IMAGE_API and BITMAP_IMAGE_API
252     if( supportApis &  property.api )
253     {
254       std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
255
256       objTemplate->Set( v8::String::NewFromUtf8(   isolate, funcName.c_str() ),
257                       v8::FunctionTemplate::New( isolate, property.function ) );
258     }
259   }
260
261   return handleScope.Escape( objTemplate );
262 }
263
264
265 void ImageWrapper::NewImage( const v8::FunctionCallbackInfo< v8::Value >& args)
266 {
267   v8::Isolate* isolate = args.GetIsolate();
268   v8::HandleScope handleScope( isolate);
269
270   if(!args.IsConstructCall())
271   {
272       DALI_SCRIPT_EXCEPTION( isolate, "Image constructor called without 'new'");
273       return;
274   }
275
276   // find out the callee function name...e.g. BufferImage, ResourceImage
277   v8::Local<v8::Function> callee = args.Callee();
278   v8::Local<v8::Value> v8String = callee->GetName();
279   std::string typeName = V8Utils::v8StringToStdString( v8String );
280
281   ImageType imageType = GetImageType( typeName );
282
283   if( imageType == UNKNOWN_IMAGE_TYPE )
284   {
285     DALI_SCRIPT_EXCEPTION( isolate, "unknown image type");
286     return;
287   }
288   Image image = (ImageApiLookup[imageType].constructor)( args );
289
290   if( ! image )
291   {
292     // a v8 exception will have been thrown by the constructor
293     return;
294   }
295
296   v8::Local<v8::Object> localObject = WrapImage( isolate, image, imageType );
297
298   args.GetReturnValue().Set( localObject );
299 }
300
301 Image ImageWrapper::GetImage()
302 {
303   return mImage;
304 }
305
306 /**
307  * given an image type name, e.g. returns the type, e.g. ImageWrapper::BITMAP_IMAGE
308  */
309 ImageWrapper::ImageType ImageWrapper::GetImageType( const std::string& name )
310 {
311   for( unsigned int i = 0 ; i < ImageApiLookupCount ; i++ )
312   {
313     if( strncmp( ImageApiLookup[i].imageName, name.c_str(), name.length() ) == 0 )
314     {
315       return ImageApiLookup[i].imageType;
316     }
317   }
318   return ImageWrapper::UNKNOWN_IMAGE_TYPE;
319 }
320
321
322
323 } // namespace V8Plugin
324
325 } // namespace Dali