Fix JavaScript plugin build break after rotation->orientation property change
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / text / font-api.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 "font-api.h"
20
21 // INTERNAL INCLUDES
22 #include <v8-utils.h>
23 #include <text/font-wrapper.h>
24 #include <object/property-value-wrapper.h>
25
26 namespace Dali
27 {
28
29 namespace V8Plugin
30 {
31
32 namespace // un named namespace
33 {
34
35
36
37
38 } //un named namespace
39
40 /***************************************
41  * IMAGE  FUNCTIONS
42  *
43  ****************************************/
44 Font FontApi::GetFont( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
45 {
46   v8::HandleScope handleScope( isolate );
47
48   v8::Local<v8::Object> object = args.This();
49   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
50   void* ptr = field->Value();
51
52   FontWrapper* wrapper = static_cast< FontWrapper *>(ptr);
53   return wrapper->GetFont();
54 }
55 Font FontApi::GetFont( v8::Isolate* isolate, v8::Local<v8::Value>& value )
56 {
57   v8::HandleScope handleScope( isolate );
58   v8::Local<v8::Object> object = value->ToObject();
59   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
60   void* ptr = field->Value();
61
62   FontWrapper* wrapper = static_cast< FontWrapper *>(ptr);
63   return wrapper->GetFont();
64 }
65
66 struct FontParams
67 {
68   typedef enum
69   {
70     NO_SIZE_SET,
71     USE_POINT_SIZE,
72     USE_PIXEL_SIZE,
73     USE_CAP_SIZE,
74   } SizeType;
75
76
77   FontParams()
78   :pointSize( 0 ),
79    pixelSize( 0 ),
80    capsSize( 0 ),
81    sizeType( FontParams::NO_SIZE_SET )
82   {
83   }
84
85   std::string family;
86   std::string style;
87   PointSize pointSize;
88   PixelSize pixelSize;
89   CapsHeight capsSize;
90   SizeType sizeType;
91
92
93 };
94
95
96 void ReadFontParameters( v8::Isolate* isolate,
97                          v8::Local<v8::Value > options,
98                          FontParams& fontParams )
99 {
100   // foont options is an optional parameter passed in which holds
101   // optional settings
102   // var fontOptions = {
103   //  family: "arial",
104   //  style:  "bold",
105   //  // one of the following
106   //  pixelSize: xx
107   //  pointSize: xx
108   //  capsHeight:xx // height of a capital letter above the baseline for a particular typeface.
109   //
110   // };
111   v8::HandleScope handleScope( isolate );
112   if( !options->IsObject() )
113   {
114     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 ( font parameters)" );
115     return;
116   }
117   v8::Local<v8::Object> obj = options->ToObject();
118
119   v8::Local<v8::Value> familyValue = obj->Get( v8::String::NewFromUtf8( isolate, "family" ) );
120   if( familyValue->IsString() )
121   {
122     fontParams.family =   V8Utils::v8StringToStdString( familyValue );
123   }
124
125   v8::Local<v8::Value> styleValue = obj->Get( v8::String::NewFromUtf8( isolate, "style" ) );
126   if( styleValue->IsString() )
127   {
128     fontParams.style =   V8Utils::v8StringToStdString( styleValue );
129   }
130
131   v8::Local<v8::Value> pixelSize = obj->Get( v8::String::NewFromUtf8( isolate, "pixelSize" ) );
132   v8::Local<v8::Value> pointSize = obj->Get( v8::String::NewFromUtf8( isolate, "pointSize" ) );
133   v8::Local<v8::Value> capsHeight = obj->Get( v8::String::NewFromUtf8( isolate, "capsHeight" ) );
134
135   if( pixelSize->IsUint32() )
136   {
137     fontParams.pixelSize.value =   pixelSize->ToUint32()->Value();
138     fontParams.sizeType = FontParams::USE_PIXEL_SIZE;
139   }
140   else if( pointSize->IsUint32() )
141   {
142     fontParams.pointSize.value =   pointSize->ToUint32()->Value();
143     fontParams.sizeType = FontParams::USE_POINT_SIZE;
144   }
145   else if( capsHeight->IsUint32() )
146   {
147     fontParams.capsSize.value = capsHeight->ToUint32()->Value();
148     fontParams.sizeType = FontParams::USE_CAP_SIZE;
149   }
150
151 }
152
153 Font FontApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
154 {
155   v8::Isolate* isolate = args.GetIsolate();
156   v8::HandleScope handleScope( isolate );
157
158   // if no parameters just create a default font
159   if ( args.Length() == 0)
160   {
161     return Font::New();
162   }
163   FontParams params;
164
165   ReadFontParameters( isolate, args[0], params );
166
167   FontParameters fontParams;
168   // construct a dali font parameters object
169   switch( params.sizeType)
170   {
171     case  FontParams::USE_PIXEL_SIZE:
172     {
173       fontParams = FontParameters( params.family, params.style, params.pixelSize  );
174       break;
175     }
176     case  FontParams::USE_POINT_SIZE:
177     {
178       fontParams = FontParameters( params.family, params.style, params.pointSize  );
179       break;
180     }
181     case  FontParams::USE_CAP_SIZE:
182     {
183       fontParams = FontParameters( params.family, params.style, params.capsSize  );
184       break;
185     }
186     default:
187     {
188       fontParams = FontParameters( params.family, params.style, PointSize(0.f));
189       break;
190     }
191   }
192   return Font::New( fontParams );
193
194 }
195
196
197 void FontApi::GetFamilyForText( const v8::FunctionCallbackInfo< v8::Value >& args )
198 {
199   v8::Isolate* isolate = args.GetIsolate();
200   v8::HandleScope handleScope( isolate );
201
202
203   bool foundString;
204   std::string text = V8Utils::GetStringParameter( PARAMETER_0, foundString, isolate, args );
205   if( !foundString )
206   {
207     DALI_SCRIPT_EXCEPTION( isolate, "bad parameter 0 ( text )" );
208     return;
209   }
210   std::string family = Font::GetFamilyForText( text );
211
212   args.GetReturnValue().Set( v8::String::NewFromUtf8( isolate, family.c_str()) );
213
214 }
215 void FontApi::GetLineHeightFromCapsHeight( const v8::FunctionCallbackInfo< v8::Value >& args )
216 {
217   v8::Isolate* isolate = args.GetIsolate();
218   v8::HandleScope handleScope( isolate );
219
220   FontParams params;
221   ReadFontParameters( isolate, args[0], params );
222   if( params.sizeType != FontParams::USE_CAP_SIZE )
223   {
224     DALI_SCRIPT_EXCEPTION( isolate, "caps height not found" );
225     return;
226   }
227
228   PixelSize size = Font::GetLineHeightFromCapsHeight( params.family, params.style, params.capsSize);
229   args.GetReturnValue().Set( v8::Integer::New( isolate, size.value ) );
230 }
231
232 void FontApi::GetInstalledFonts( const v8::FunctionCallbackInfo< v8::Value >& args )
233 {
234   v8::Isolate* isolate = args.GetIsolate();
235   v8::HandleScope handleScope( isolate );
236
237   bool found( false );
238   std::vector<std::string> fontList;
239
240   std::string mode = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
241
242   if( mode == "LIST_APPLICATION_FONTS" )
243   {
244     fontList = Font::GetInstalledFonts( Font::LIST_APPLICATION_FONTS );
245   }
246   else if( mode == "LIST_ALL_FONTS")
247   {
248     fontList = Font::GetInstalledFonts( Font::LIST_ALL_FONTS );
249   }
250   else  // default
251   {
252     fontList = Font::GetInstalledFonts( Font::LIST_SYSTEM_FONTS );
253   }
254   // create a javascript array
255   v8::Local<v8::Array> array = v8::Array::New(isolate, fontList.size() );
256   for( std::size_t i = 0; i < fontList.size(); i++)
257   {
258     const char* fontName = fontList[i].c_str();
259     array->Set(v8::Integer::New(args.GetIsolate(), i), v8::String::NewFromUtf8( isolate,fontName));
260   }
261
262   args.GetReturnValue().Set( array );
263 }
264
265 void FontApi::MeasureTextWidth( const v8::FunctionCallbackInfo< v8::Value >& args )
266 {
267   v8::Isolate* isolate = args.GetIsolate();
268   v8::HandleScope handleScope( isolate );
269   Font font = GetFont( isolate, args );
270
271   //float MeasureTextWidth(const std::string& text, float textHeightPx) const;
272
273   bool found( false );
274   std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
275   if(! found )
276   {
277     DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
278     return;
279   }
280   int height = V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 );
281   if( !found )
282   {
283      DALI_SCRIPT_EXCEPTION( isolate, "missing text height" );
284      return;
285   }
286   float width = font.MeasureTextWidth( text, height );
287
288   args.GetReturnValue().Set( v8::Integer::New( isolate, width ) );
289
290 }
291 void FontApi::MeasureTextHeight( const v8::FunctionCallbackInfo< v8::Value >& args )
292 {
293   v8::Isolate* isolate = args.GetIsolate();
294   v8::HandleScope handleScope( isolate );
295   Font font = GetFont( isolate, args );
296
297   //float MeasureTextHeight(const std::string& text, float textHeightPx) const;
298
299   bool found( false );
300   std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
301   if(! found )
302   {
303     DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
304     return;
305   }
306   int width= V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 );
307   if( !found )
308   {
309      DALI_SCRIPT_EXCEPTION( isolate, "missing text height" );
310      return;
311   }
312   float height = font.MeasureTextHeight( text, width );
313
314   args.GetReturnValue().Set( v8::Integer::New( isolate, height ) );
315 }
316 void FontApi::MeasureText( const v8::FunctionCallbackInfo< v8::Value >& args )
317 {
318   v8::Isolate* isolate = args.GetIsolate();
319   v8::HandleScope handleScope( isolate );
320   Font font = GetFont( isolate, args );
321
322   bool found( false );
323   std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
324   if(! found )
325   {
326     DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
327     return;
328   }
329
330   Vector3 vec3 = font.MeasureText( text );
331   Dali::Property::Value value( vec3 );
332   v8::Local <v8::Object> object = PropertyValueWrapper::WrapDaliProperty( isolate, value);
333   args.GetReturnValue().Set(  object );
334
335 }
336 void FontApi::AllGlyphsSupported( const v8::FunctionCallbackInfo< v8::Value >& args )
337 {
338   v8::Isolate* isolate = args.GetIsolate();
339   v8::HandleScope handleScope( isolate );
340   Font font = GetFont( isolate, args );
341
342   bool found( false );
343   std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
344   if(! found )
345   {
346     DALI_SCRIPT_EXCEPTION( isolate, "text not found" );
347     return;
348   }
349
350   bool supported = font.AllGlyphsSupported( text );
351   args.GetReturnValue().Set( v8::Boolean::New(  isolate, supported) );
352
353 }
354
355 // This one function is use to create a property map, instead of the many individual property
356 // getters used by the C++ Dali API.
357 // propertyMap
358 // {
359 //    name:
360 //    style:
361 //    pointSize:
362 //    pixelSize:
363 //    lineHeight:
364 //    ascender:
365 //    underlineThickness:
366 //    underlinePosition:
367 //    isDefaultSystemFont:
368 //    isDefaultSystemSize:
369 // }
370
371 void FontApi::GetProperties( const v8::FunctionCallbackInfo< v8::Value >& args )
372 {
373   v8::Isolate* isolate = args.GetIsolate();
374   v8::HandleScope handleScope( isolate );
375   Font font = GetFont( isolate, args );
376
377   v8::Local<v8::Object> keyObject = v8::Object::New( isolate );
378
379   keyObject->Set( v8::String::NewFromUtf8( isolate, "family" ), v8::String::NewFromUtf8( isolate, font.GetName().c_str() ) );
380   keyObject->Set( v8::String::NewFromUtf8( isolate, "style" ), v8::String::NewFromUtf8( isolate, font.GetStyle().c_str() ) );
381   keyObject->Set( v8::String::NewFromUtf8( isolate, "pointSize" ),  v8::Integer::New( isolate, font.GetPointSize() ) );
382   keyObject->Set( v8::String::NewFromUtf8( isolate, "pixelSize" ),  v8::Integer::New( isolate, font.GetPixelSize() ) );
383   keyObject->Set( v8::String::NewFromUtf8( isolate, "lineHeight" ),  v8::Integer::New( isolate, font.GetLineHeight() ) );
384   keyObject->Set( v8::String::NewFromUtf8( isolate, "ascender" ),  v8::Integer::New( isolate, font.GetAscender() ) );
385   keyObject->Set( v8::String::NewFromUtf8( isolate, "underlineThickness" ),  v8::Integer::New( isolate, font.GetUnderlineThickness() ) );
386   keyObject->Set( v8::String::NewFromUtf8( isolate, "underlinePosition" ),  v8::Integer::New( isolate, font.GetUnderlinePosition()) );
387   keyObject->Set( v8::String::NewFromUtf8( isolate, "isDefaultSystemFont" ),  v8::Boolean::New( isolate, font.IsDefaultSystemFont() ) );
388   keyObject->Set( v8::String::NewFromUtf8( isolate, "isDefaultSystemSize" ),  v8::Boolean::New( isolate,  font.IsDefaultSystemSize() ) );
389
390   args.GetReturnValue().Set( keyObject );
391
392 }
393
394 void FontApi::GetMetrics( const v8::FunctionCallbackInfo< v8::Value >& args )
395 {
396   v8::Isolate* isolate = args.GetIsolate();
397   v8::HandleScope handleScope( isolate );
398   Font font = GetFont( isolate, args );
399
400   bool found( false );
401   std::string text = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
402
403   if(! found )
404   {
405     DALI_SCRIPT_EXCEPTION( isolate, "character not found" );
406     return;
407   }
408
409   Text textObject( text );
410
411   Font::Metrics metric = font.GetMetrics( textObject[0] );
412
413   v8::Local<v8::Object> keyObject = v8::Object::New( isolate );
414   keyObject->Set( v8::String::NewFromUtf8( isolate, "advance" ), v8::Integer::New( isolate, metric.GetAdvance() ) );
415   keyObject->Set( v8::String::NewFromUtf8( isolate, "bearing" ), v8::Integer::New( isolate, metric.GetBearing() ) );
416   keyObject->Set( v8::String::NewFromUtf8( isolate, "width" ),   v8::Integer::New( isolate, metric.GetWidth() ) );
417   keyObject->Set( v8::String::NewFromUtf8( isolate, "height" ),  v8::Integer::New( isolate, metric.GetHeight() ) );
418
419   args.GetReturnValue().Set( keyObject );
420
421 }
422
423
424 void FontApi::PointsToPixels( const v8::FunctionCallbackInfo< v8::Value >& args )
425 {
426   v8::Isolate* isolate = args.GetIsolate();
427   v8::HandleScope handleScope( isolate );
428
429   bool found(false);
430   int pointSize= V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
431   if( !found )
432   {
433       DALI_SCRIPT_EXCEPTION( isolate, "missing pointSize" );
434       return;
435   }
436   args.GetReturnValue().Set( v8::Integer::New( isolate, Font::PointsToPixels(pointSize) ) );
437
438 }
439 void FontApi::PixelsToPoints( const v8::FunctionCallbackInfo< v8::Value >& args )
440 {
441   v8::Isolate* isolate = args.GetIsolate();
442   v8::HandleScope handleScope( isolate );
443
444   bool found(false);
445   int pixelSize= V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
446   if( !found )
447   {
448       DALI_SCRIPT_EXCEPTION( isolate, "missing pixelSize" );
449       return;
450   }
451   args.GetReturnValue().Set( v8::Integer::New( isolate, Font::PixelsToPoints(pixelSize) ) );
452 }
453
454
455
456 } // namespace V8Plugin
457
458 } // namespace Dali