6206fe48c148fbf1f05ae8ba3ec921178e50cece
[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     { "GetChildRectangle",       NinePatchImageApi::GetChildRectangle,        NINE_PATCH_IMAGE_API },
153     { "CreateCroppedBufferImage",NinePatchImageApi::CreateCroppedBufferImage, NINE_PATCH_IMAGE_API },
154
155     // buffer image API
156     { "GetBuffer",              BufferImageApi::GetBuffer,           BITMAP_IMAGE_API },
157     { "GetBufferSize",          BufferImageApi::GetBufferSize,       BITMAP_IMAGE_API },
158     { "GetBufferStride",        BufferImageApi::GetBufferStride,     BITMAP_IMAGE_API },
159     { "GetPixelFormat",         BufferImageApi::GetPixelFormat,      BITMAP_IMAGE_API },
160     { "Update",                 BufferImageApi::Update,              BITMAP_IMAGE_API },
161     { "IsDataExternal",         BufferImageApi::IsDataExternal,      BITMAP_IMAGE_API },
162
163     // Frame buffer image has no API
164     // Native image has no API
165
166 };
167
168 const unsigned int ImageFunctionTableCount = sizeof(ImageFunctionTable)/sizeof(ImageFunctionTable[0]);
169 } //un-named space
170
171
172 ImageWrapper::ImageWrapper( const Dali::Image& image, GarbageCollectorInterface& gc )
173 : BaseWrappedObject( BaseWrappedObject::IMAGE , gc )
174 {
175     mImage = image;
176 }
177
178 v8::Handle<v8::Object> ImageWrapper::WrapImage(v8::Isolate* isolate, const Dali::Image& image )
179 {
180   v8::EscapableHandleScope handleScope( isolate );
181
182   v8::Local<v8::Object> object = WrapImage( isolate, image, GetImageType( image.GetTypeName() ) );
183
184   return handleScope.Escape( object );
185 }
186 v8::Handle<v8::Object> ImageWrapper::WrapImage(v8::Isolate* isolate, const Dali::Image& image, ImageType imageType )
187 {
188   v8::EscapableHandleScope handleScope( isolate );
189   v8::Local<v8::ObjectTemplate> objectTemplate;
190
191   objectTemplate = GetImageTemplate( isolate, imageType);
192
193   // create an instance of the template
194   v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
195
196   // create the Image wrapper
197   ImageWrapper* pointer =  new ImageWrapper( image, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
198
199   // assign the JavaScript object to the wrapper.
200   // This also stores the Image object, in an internal field inside the JavaScript object.
201   pointer->SetJavascriptObject( isolate, localObject );
202
203   return handleScope.Escape( localObject );
204 }
205
206 v8::Local<v8::ObjectTemplate> ImageWrapper::GetImageTemplate( v8::Isolate* isolate, ImageType imageType )
207 {
208   v8::EscapableHandleScope handleScope( isolate );
209   v8::Local<v8::ObjectTemplate> objectTemplate;
210
211   if( ImageTemplateLookup[ imageType ].imageTemplate->IsEmpty() )
212   {
213     objectTemplate = MakeImageTemplate( isolate, imageType );
214     ImageTemplateLookup[ imageType ].imageTemplate->Reset( isolate, objectTemplate );
215   }
216   else
217   {
218     // get the object template
219     objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ImageTemplateLookup[ imageType ].imageTemplate );
220   }
221
222   return handleScope.Escape( objectTemplate );
223 }
224
225 v8::Handle<v8::ObjectTemplate> ImageWrapper::MakeImageTemplate( v8::Isolate* isolate, ImageType imageType )
226 {
227   v8::EscapableHandleScope handleScope( isolate );
228
229   v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
230
231   objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
232
233   // add intercepts for Signals on ResourceImage, we can't use HandleWrapper::AddIntercepts because Image doesn't inherit
234   // from Handle ( just baseHandle)
235   if (( imageType == RESOURCE_IMAGE ) ||
236       ( imageType == NINE_PATCH_IMAGE ))
237   {
238      ObjectTemplateHelper::AddSignalConnectAndDisconnect( isolate, objTemplate );
239   }
240
241   // find out what API's this image supports
242   int supportApis = GetImageSupportedApis( imageType );
243
244   // add our function properties
245   for( unsigned int i = 0; i < ImageFunctionTableCount; ++i )
246   {
247     const ImageFunctions property =  ImageFunctionTable[i];
248
249     // check to see if the image supports a certain type of API
250     // e.g. Bitmap will support IMAGE_API and BITMAP_IMAGE_API
251     if( supportApis &  property.api )
252     {
253       std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
254
255       objTemplate->Set( v8::String::NewFromUtf8(   isolate, funcName.c_str() ),
256                       v8::FunctionTemplate::New( isolate, property.function ) );
257     }
258   }
259
260   return handleScope.Escape( objTemplate );
261 }
262
263
264 void ImageWrapper::NewImage( const v8::FunctionCallbackInfo< v8::Value >& args)
265 {
266   v8::Isolate* isolate = args.GetIsolate();
267   v8::HandleScope handleScope( isolate);
268
269   if(!args.IsConstructCall())
270   {
271       DALI_SCRIPT_EXCEPTION( isolate, "Image constructor called without 'new'");
272       return;
273   }
274
275   // find out the callee function name...e.g. BufferImage, ResourceImage
276   v8::Local<v8::Function> callee = args.Callee();
277   v8::Local<v8::Value> v8String = callee->GetName();
278   std::string typeName = V8Utils::v8StringToStdString( v8String );
279
280   ImageType imageType = GetImageType( typeName );
281
282   if( imageType == UNKNOWN_IMAGE_TYPE )
283   {
284     DALI_SCRIPT_EXCEPTION( isolate, "unknown image type");
285     return;
286   }
287   Image image = (ImageApiLookup[imageType].constructor)( args );
288
289   if( ! image )
290   {
291     // a v8 exception will have been thrown by the constructor
292     return;
293   }
294
295   v8::Local<v8::Object> localObject = WrapImage( isolate, image, imageType );
296
297   args.GetReturnValue().Set( localObject );
298 }
299
300 Image ImageWrapper::GetImage()
301 {
302   return mImage;
303 }
304
305 /**
306  * given an image type name, e.g. returns the type, e.g. ImageWrapper::BITMAP_IMAGE
307  */
308 ImageWrapper::ImageType ImageWrapper::GetImageType( const std::string& name )
309 {
310   for( unsigned int i = 0 ; i < ImageApiLookupCount ; i++ )
311   {
312     if( strncmp( ImageApiLookup[i].imageName, name.c_str(), name.length() ) == 0 )
313     {
314       return ImageApiLookup[i].imageType;
315     }
316   }
317   return ImageWrapper::UNKNOWN_IMAGE_TYPE;
318 }
319
320
321
322 } // namespace V8Plugin
323
324 } // namespace Dali