Merge "TextSelectionToolbar and Style Properties added" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / shader-effects / soft-button-effect.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 // EXTERNAL INCLUDES
19 #include <dali/public-api/animation/constraint.h>
20 #include <dali/public-api/object/property-input.h>
21
22 // INTERNAL INCLUDES
23 #include <dali-toolkit/devel-api/shader-effects/soft-button-effect.h>
24
25 namespace Dali
26 {
27
28 namespace Toolkit
29 {
30
31 namespace
32 {
33
34 const std::string SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_PROPERTY_NAME( "uLightingIndentationAmount" );
35 const std::string SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_PROPERTY_NAME( "uTextureDistortAmount" );
36 const std::string SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_PROPERTY_NAME( "uAmbientLight" );
37 const std::string SOFT_BUTTON_DIFFUSE_LIGHT_PROPERTY_NAME( "uDiffuseLight" );
38 const std::string SOFT_BUTTON_LIGHTING_MULTIPLIER_PROPERTY_NAME( "uLightMultiplier" );
39 const std::string SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME( "uInsideCircleSizeScale" );
40 const std::string SOFT_BUTTON_RECIP_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME( "uRecipInsideCircleSizeScale" );
41 const std::string SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_PROPERTY_NAME( "uOutsideCircleDepth" );
42 const std::string SOFT_BUTTON_EFFECT_PIXEL_AREA_PROPERTY_NAME( "uEffectRegion" );
43 const std::string SOFT_BUTTON_RECTANGLE_SIZE_SCALE_PROPERTY_NAME( "uRectangleSizeScale" );
44
45
46 // factors that scale the look, defaults
47 const float SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_DEFAULT = 0.0f;
48 const float SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_DEFAULT = 0.0f;
49 const float SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_DEFAULT = 0.15f;
50 const Vector3 SOFT_BUTTON_DIFFUSE_LIGHT_DEFAULT = Vector3(0.0f, 0.7070168f, 0.7071068f);
51 const float SOFT_BUTTON_LIGHTING_MULTIPLIER_DEFAULT = 1.2f;
52 const float SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_DEFAULT = 0.75f;
53 const float SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_DEFAULT = Math::PI * 0.05f;
54 const Vector4 SOFT_BUTTON_EFFECT_PIXEL_AREA_DEFAULT = Vector4(0.0f, 0.0f, 1.0f, 1.0f);
55 const float SOFT_BUTTON_RECTANGLE_SIZE_SCALE_DEFAULT = 0.5f;
56
57 } // namespace
58
59 /**
60  * InverseConstraint
61  *
62  * f(current, property) = 1.0 / property
63  */
64 void InverseConstraint( float& current, const PropertyInputContainer& inputs )
65 {
66   current = 1.0f / inputs[0]->GetFloat();
67 }
68
69 ////////////////////////////////////////////////////
70 //
71 // Soft button shader / actor tweaking parameters
72 //
73
74
75 SoftButtonEffect::SoftButtonEffect()
76 {
77 }
78
79 //Call the Parent copy constructor to add reference to the implementation for this object
80 SoftButtonEffect::SoftButtonEffect(ShaderEffect handle)
81 :ShaderEffect(handle)
82 {
83 }
84
85 SoftButtonEffect::~SoftButtonEffect()
86 {
87 }
88
89 SoftButtonEffect SoftButtonEffect::New(Type type)
90 {
91   std::string vertexSource;
92   vertexSource =  "precision mediump float;\n"
93     "uniform vec3 uDiffuseLight;\n"
94     "uniform float uAmbientLight;\n"
95     "uniform float uLightMultiplier;\n"
96     "uniform vec4 uEffectRegion;\n"
97     "varying vec2 vCentredCoord;\n"
98
99     "const vec3 norm = vec3(0.0, 0.0, 1.0);\n"
100
101     "void main()\n"
102     "{\n"
103     "  vTexCoord = aTexCoord;\n"
104     // Get the rect coords of the effect region in -1..1 range, i.e. circle centred around the center of the rect
105     // Done in the vertex shader itself to make use of gl interpolation for varying.
106     "  vCentredCoord = vec2( ( (vTexCoord.x - uEffectRegion.x)/(uEffectRegion.z - uEffectRegion.x) * 2.0 - 1.0 ), ( (vTexCoord.y - uEffectRegion.y)/(uEffectRegion.w - uEffectRegion.y) * 2.0 - 1.0  ) );\n"
107     "  gl_Position = uMvpMatrix * vec4(aPosition, 1.0);\n"
108     "}\n";
109
110   std::string fragmentSourceFixed;
111   fragmentSourceFixed =  "precision mediump float;\n"
112
113     "uniform vec3 uDiffuseLight;\n"
114     "uniform float uAmbientLight;\n"
115     "uniform float uLightMultiplier;\n"
116     "varying vec2 vCentredCoord;\n"
117
118     "const vec3 norm = vec3(0.0, 0.0, 1.0);\n"
119
120     "void main()\n"
121     "{\n"
122     "   vec4 col = texture2D(sTexture, vTexCoord);\n"
123     // calc lighting
124     "   float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
125     // output col = image * light
126     // use the lighting value for colors only
127     "   gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
128     "}\n";
129
130   std::string fragmentSourceElliptical;
131   fragmentSourceElliptical =  "precision mediump float;\n"
132
133     "uniform float uLightingIndentationAmount;\n"
134     "uniform float uTextureDistortAmount;\n"
135     "uniform vec3 uDiffuseLight;\n"
136     "uniform float uAmbientLight;\n"
137     "uniform float uLightMultiplier;\n"
138     "uniform float uInsideCircleSizeScale;\n"
139     "uniform float uRecipInsideCircleSizeScale;\n"
140     "uniform float uOutsideCircleDepth;\n"
141     "uniform vec4 uEffectRegion;\n"
142     "varying vec2 vCentredCoord;\n"
143
144     "const float PI = 3.1415927;\n"
145
146     "void main()\n"
147     "{\n"
148       // Apply distortion only if the pixel is within the rect specified
149       "if( (vTexCoord.x > uEffectRegion.x) && (vTexCoord.x < uEffectRegion.z) && (vTexCoord.y > uEffectRegion.y) && (vTexCoord.y < uEffectRegion.w) )\n"
150       "{\n"
151       "   vec2 coord = vCentredCoord;\n"
152
153       // find a coordinate representing distance from circle centre, such that we split into inside / outside circles that can have different gradients / normals
154       "   float realDistFromCentre = length(coord);\n"
155       "   realDistFromCentre = min(1.0, realDistFromCentre);\n" // clamp corners of square to vertical normal
156       "   float distFromCentre;\n"
157       "   if(realDistFromCentre <= uInsideCircleSizeScale)\n"
158       "   {\n"
159       "     distFromCentre = realDistFromCentre * uRecipInsideCircleSizeScale * (1.0 - uOutsideCircleDepth);\n" // inside circle indent, up to outline depth
160       "   }\n"
161       "   else                                                                                                                      \n"
162       "   {\n"
163       "     distFromCentre = mix(1.0 - uOutsideCircleDepth, 1.0, (realDistFromCentre - ( uInsideCircleSizeScale)) / (1.0 - uInsideCircleSizeScale));\n" // outside circle
164       "   }\n"
165
166       // get coords in -PI..PI range, i.e. scale the circle for use by trig functions
167       "  coord *= PI;\n"
168
169       // get a z value for the distorted surface in 0..1 range, using cos for a smooth curve (note, we ignore inside / outside circles since the difference isn't noticeable visually)
170       "   vec2 cosThetaCoord = (cos(coord) * 0.5) + 0.5;\n"
171       "   float z = cosThetaCoord.x * cosThetaCoord.y;\n"
172
173       // get the normal for the distorted surface, using the fact that the derivative of cos is -sin, finding tangent vector from slope and then normal by cross product...
174       "   float sinThetaCoord = sin(distFromCentre*PI) * uLightingIndentationAmount;\n" // slope, so tangent vec is (1.0, -sin)
175       // ...2D normal vector along distFromCentre vec is (sin, 1.0), convert to components in 3D.
176       "   vec3 norm = normalize(vec3(coord.x * sinThetaCoord, coord.y * sinThetaCoord, 1.0));\n"
177
178       // form surface z and project texture onto it.
179       "   float indentAmount = 1.0 / (1.0 - (z * uTextureDistortAmount));\n"
180       "   vec2 distortedCoord = vCentredCoord * indentAmount;\n"
181
182       // Convert the rect coordinates in -1 to 1 range back to the original coordinates
183       "   vec2 texCoord = vec2( ( (distortedCoord.x + 1.0)*(0.5) * (uEffectRegion.z - uEffectRegion.x) + uEffectRegion.x ), ( (distortedCoord.y + 1.0)*(0.5) * (uEffectRegion.w - uEffectRegion.y) + uEffectRegion.y  ) );  \n"
184       "   vec4 col = texture2D(sTexture, texCoord);\n"
185
186       // calc lighting
187       "   float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
188       "  gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
189       "}\n"
190       "else\n"
191       "{\n"
192       "  vec4 col = texture2D(sTexture, vTexCoord);\n"
193       "  float lighting = (dot(uDiffuseLight, vec3(0.0, 0.0, 1.0)) + uAmbientLight) * uLightMultiplier;\n"
194       "  gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
195       "}\n"
196     "}\n";
197
198   std::string fragmentSourceRectangular;
199   fragmentSourceRectangular =  "precision mediump float;\n"
200
201     "uniform float uLightingIndentationAmount;\n"
202     "uniform float uTextureDistortAmount;\n"
203     "uniform vec3 uDiffuseLight;\n"
204     "uniform float uAmbientLight;\n"
205     "uniform float uLightMultiplier;\n"
206     "uniform float uInsideCircleSizeScale;\n"
207     "uniform float uRecipInsideCircleSizeScale;\n"
208     "uniform float uOutsideCircleDepth;\n"
209     "uniform float uRectangleSizeScale;\n"
210     "uniform vec4 uEffectRegion;\n"
211     "varying vec2 vCentredCoord;\n"
212
213     "const float PI = 3.1415927;\n"
214
215     "void main()\n"
216     "{\n"
217       // Apply distortion only if the pixel is within the rect specified
218       "if( (vTexCoord.x > uEffectRegion.x) && (vTexCoord.x < uEffectRegion.z) && (vTexCoord.y > uEffectRegion.y) && (vTexCoord.y < uEffectRegion.w) )\n"
219       "{ \n"
220         // get the rect coords to -1..1 range, i.e. circle centred around the center of the rect
221         "   vec2 centredCoord = vCentredCoord;\n"
222         // clamp coords such that the circle is split into 4 pieces that lie in the corners of the actor. uRectangleScale is the distance along each axis from the centre
223         // of the actor, e.g. 0.5 is half way along an axis from centre to actor edge.
224         "   vec2 clampedCoord;\n"
225         "   if(centredCoord.x > 0.0)\n"
226         "   {\n"
227         "     if(centredCoord.x < uRectangleSizeScale)\n"
228         "     {\n"
229                 // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
230         "       clampedCoord.x = 0.0;\n"
231         "     }\n"
232         "     else\n"
233         "     {\n"
234                 // we are outside rectangular region along this axis, so we want curvature.
235         "       clampedCoord.x = smoothstep(0.0, 1.0, (centredCoord.x - uRectangleSizeScale) / (1.0 - uRectangleSizeScale));\n"
236         "     }\n"
237         "   }\n"
238         "   else\n"
239         "   {\n"
240         "     if(centredCoord.x > -uRectangleSizeScale)\n"
241         "     {\n"
242                 // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
243         "       clampedCoord.x = 0.0;\n"
244         "     }\n"
245         "     else\n"
246         "     {\n"
247                 // we are outside rectangular region along this axis, so we want curvature.
248         "       clampedCoord.x = -smoothstep(0.0, 1.0, (centredCoord.x + uRectangleSizeScale) / (uRectangleSizeScale - 1.0));\n"
249         "     }\n"
250         "   }\n"
251         "   if(centredCoord.y > 0.0)\n"
252         "   {\n"
253         "     if(centredCoord.y < uRectangleSizeScale)\n"
254         "     {\n"
255                 // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
256         "       clampedCoord.y = 0.0;\n"
257         "     }\n"
258         "     else\n"
259         "     {\n"
260                 // we are outside rectangular region along this axis, so we want curvature.
261         "       clampedCoord.y = smoothstep(0.0, 1.0, (centredCoord.y - uRectangleSizeScale) / (1.0 - uRectangleSizeScale));\n"
262         "     }\n"
263         "   }\n"
264         "   else\n"
265         "   {\n"
266         "     if(centredCoord.y > -uRectangleSizeScale)\n"
267         "     {\n"
268                 // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
269         "       clampedCoord.y = 0.0;\n"
270         "     }\n"
271         "     else\n"
272         "     {\n"
273                 // we are outside rectangular region along this axis, so we want curvature.
274         "       clampedCoord.y = -smoothstep(0.0, 1.0, (centredCoord.y + uRectangleSizeScale) / (uRectangleSizeScale - 1.0));\n"
275         "     }\n"
276         "   }\n"
277         // get coords in -PI..PI range, i.e. scale above circle for use by trig functions
278         "   vec2 thetaCoord = clampedCoord * PI;\n"
279         // get a z value for the distorted surface in 0..1 range, using cos for a smooth curve (note, we ignore inside / outside circles since the difference isn't noticeable visually)
280         "   vec2 cosThetaCoord = (cos(thetaCoord) * 0.5) + 0.5;\n"
281         "   float z = cosThetaCoord.x * cosThetaCoord.y;\n"
282         // find a coordinate representing distance from circle centre, such that we split into inside / outside circles that can have different gradients / normals
283         "   float realDistFromCentre = length(thetaCoord);\n"
284         "   realDistFromCentre = min(PI, realDistFromCentre);\n" // clamp corners of square to vertical normal
285         "   float distFromCentre;\n"
286         "   if(realDistFromCentre <= PI * uInsideCircleSizeScale)\n"
287         "   {\n"
288         "     distFromCentre = realDistFromCentre * uRecipInsideCircleSizeScale * (PI - (uOutsideCircleDepth * PI)) / PI;\n" // inside circle indent, up to outline depth
289         "   }\n"
290         "   else\n"
291         "   {\n"
292         "     distFromCentre = mix(PI - (uOutsideCircleDepth * PI), PI, (realDistFromCentre - ( PI * uInsideCircleSizeScale)) / (PI - (PI * uInsideCircleSizeScale)));\n" // outside circle
293         "   }\n"
294         // get the normal for the distorted surface, using the fact that the derivative of cos is -sin, finding tangent vector from slope and then normal by cross product...
295         "   float sinThetaCoord = sin(distFromCentre) * uLightingIndentationAmount;\n" // slope, so tangent vec is (1.0, -sin)
296         // ...2D normal vector along distFromCentre vec is (sin, 1.0), convert to components in 3D.
297         "   vec3 norm = normalize(vec3(thetaCoord.x * sinThetaCoord, thetaCoord.y * sinThetaCoord, 1.0));\n"
298         // form surface z and project texture onto it.
299         "   float indentAmount = 1.0 / (1.0 - (z * uTextureDistortAmount));\n"
300         "   vec2 distortedCoord = centredCoord * indentAmount;\n"
301         // Convert the rect coordinates in -1 to 1 range back to the original coordinates
302         "   vec2 texCoord = vec2( ( (distortedCoord.x + 1.0)/(2.0) * (uEffectRegion.z - uEffectRegion.x) + uEffectRegion.x ), ( (distortedCoord.y + 1.0)/(2.0) * (uEffectRegion.w - uEffectRegion.y) + uEffectRegion.y  ) );\n"
303         "   vec4 col = texture2D(sTexture, texCoord);\n"
304         // calc lighting
305         "   float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
306         // output col = image * light
307         // use the lighting value for colors only
308         "   gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
309
310       "}\n"
311       "else\n"
312       "{\n"
313         "   vec4 col = texture2D(sTexture, vTexCoord);\n"
314         "   float lighting = (dot(uDiffuseLight, vec3(0.0, 0.0, 1.0)) + uAmbientLight) * uLightMultiplier;\n"
315         "   gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
316       "} \n"
317     "}\n";
318
319
320   //////////////////////////////////////
321   // Create shader effect
322   //
323   //
324
325   ShaderEffect shader;
326   switch(type)
327   {
328     case RECTANGULAR:
329       shader = ShaderEffect::New( vertexSource, fragmentSourceRectangular, GeometryType( GEOMETRY_TYPE_IMAGE ), ShaderEffect::GeometryHints( ShaderEffect::HINT_NONE ));
330       break;
331
332     case ELLIPTICAL:
333       shader = ShaderEffect::New( vertexSource, fragmentSourceElliptical, GeometryType( GEOMETRY_TYPE_IMAGE ), ShaderEffect::GeometryHints( ShaderEffect::HINT_NONE ));
334       break;
335
336     case FIXED:
337     default:
338       shader = ShaderEffect::New( vertexSource, fragmentSourceFixed, GeometryType( GEOMETRY_TYPE_IMAGE ), ShaderEffect::GeometryHints( ShaderEffect::HINT_NONE ));
339       break;
340   }
341   SoftButtonEffect handle( shader );
342
343
344   //////////////////////////////////////
345   // Register uniform properties
346   //
347   //
348
349   // factors that scale the look, defaults
350   handle.SetUniform(SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_PROPERTY_NAME, SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_DEFAULT);
351   handle.SetUniform(SOFT_BUTTON_DIFFUSE_LIGHT_PROPERTY_NAME, SOFT_BUTTON_DIFFUSE_LIGHT_DEFAULT);
352   handle.SetUniform(SOFT_BUTTON_LIGHTING_MULTIPLIER_PROPERTY_NAME, SOFT_BUTTON_LIGHTING_MULTIPLIER_DEFAULT);
353   if(FIXED != type)
354   {
355     handle.SetUniform(SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_PROPERTY_NAME, SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_DEFAULT);
356     handle.SetUniform(SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_PROPERTY_NAME, SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_DEFAULT);
357     handle.SetUniform(SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME, SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_DEFAULT);
358     handle.SetUniform(SOFT_BUTTON_RECIP_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME, 1.0f / SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_DEFAULT);
359     handle.SetUniform(SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_PROPERTY_NAME, SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_DEFAULT);
360     handle.SetUniform(SOFT_BUTTON_EFFECT_PIXEL_AREA_PROPERTY_NAME, SOFT_BUTTON_EFFECT_PIXEL_AREA_DEFAULT);
361     if(RECTANGULAR == type)
362     {
363       handle.SetUniform(SOFT_BUTTON_RECTANGLE_SIZE_SCALE_PROPERTY_NAME, SOFT_BUTTON_RECTANGLE_SIZE_SCALE_DEFAULT);
364     }
365
366     // precalc 1.0 / uInsideCircleSizeScale on CPU to save shader insns, using constraint to tie to the normal property
367     Dali::Property::Index insideCircleSizeScalePropertyIndex = handle.GetPropertyIndex(SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME);
368     Dali::Property::Index recipInsideCircleSizeScalePropertyIndex = handle.GetPropertyIndex(SOFT_BUTTON_RECIP_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME);
369     Constraint constraint = Constraint::New<float>( handle, recipInsideCircleSizeScalePropertyIndex, InverseConstraint );
370     constraint.AddSource( LocalSource(insideCircleSizeScalePropertyIndex) );
371     constraint.Apply();
372   }
373
374   return handle;
375 }
376
377 const std::string& SoftButtonEffect::GetLightingIndentationAmountPropertyName() const
378 {
379   return SOFT_BUTTON_LIGHTING_INDENTATION_AMOUNT_PROPERTY_NAME;
380 }
381
382 const std::string& SoftButtonEffect::GetTextureDistortionAmountPropertyName() const
383 {
384   return SOFT_BUTTON_TEXTURE_DISTORTION_AMOUNT_PROPERTY_NAME;
385 }
386
387 const std::string& SoftButtonEffect::GetAmbientLightAmountPropertyName() const
388 {
389   return SOFT_BUTTON_AMBIENT_LIGHT_AMOUNT_PROPERTY_NAME;
390 }
391
392 const std::string& SoftButtonEffect::GetDiffuseLightPropertyName() const
393 {
394   return SOFT_BUTTON_DIFFUSE_LIGHT_PROPERTY_NAME;
395 }
396
397 const std::string& SoftButtonEffect::GetLightingMultiplierPropertyName() const
398 {
399   return SOFT_BUTTON_LIGHTING_MULTIPLIER_PROPERTY_NAME;
400 }
401
402 const std::string& SoftButtonEffect::GetInsideShapeSizeScalePropertyName() const
403 {
404   return SOFT_BUTTON_INSIDE_SHAPE_SIZE_SCALE_PROPERTY_NAME;
405 }
406
407 const std::string& SoftButtonEffect::GetOutsideShapeDepthPropertyName() const
408 {
409   return SOFT_BUTTON_OUTSIDE_SHAPE_DEPTH_PROPERTY_NAME;
410 }
411
412 const std::string& SoftButtonEffect::GetEffectPixelAreaPropertyName() const
413 {
414   return SOFT_BUTTON_EFFECT_PIXEL_AREA_PROPERTY_NAME;
415 }
416
417 const std::string& SoftButtonEffect::GetRectangleSizeScalePropertyName() const
418 {
419   return SOFT_BUTTON_RECTANGLE_SIZE_SCALE_PROPERTY_NAME;
420 }
421
422 }
423
424 }