Fix visual defect during text scroll
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / graphics / shaders / glyphy-common-glsl-shader.def
1 /*
2  * Copyright 2012 Google, Inc. 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  * Google Author(s): Behdad Esfahbod, Maysum Panju
17  */
18
19
20 #ifndef GLYPHY_INFINITY
21 #define GLYPHY_INFINITY 1e9
22 #endif
23 #ifndef GLYPHY_EPSILON
24 #define GLYPHY_EPSILON  1e-5
25 #endif
26
27 #ifndef GLYPHY_RGBA
28 #ifdef GLYPHY_BGRA
29 #define GLYPHY_RGBA(v) glyphy_bgra (v)
30 #else
31 #define GLYPHY_RGBA(v) glyphy_rgba (v)
32 #endif
33 #endif
34
35 vec4 glyphy_rgba (const vec4 v)
36 {
37   return v.rgba;
38 }
39
40 vec4 glyphy_bgra (const vec4 v)
41 {
42   return v.bgra;
43 }
44
45 struct glyphy_arc_t
46 {
47   vec2  p0;
48   vec2  p1;
49   float d;
50 };
51
52 struct glyphy_arc_endpoint_t
53 {
54   /* Second arc endpoint */
55   vec2  p;
56   /* Infinity if this endpoint does not form an arc with the previous
57    * endpoint.  Ie. a \"move_to\".  Test with glyphy_isinf().
58    * Arc depth otherwise.  */
59   float d;
60 };
61
62 struct glyphy_arc_list_t
63 {
64   /* Number of endpoints in the list.
65    * Will be zero if we're far away inside or outside, in which case side is set.
66    * Will be -1 if this arc-list encodes a single line, in which case line_* are set. */
67   int num_endpoints;
68
69   /* If num_endpoints is zero, this specifies whether we are inside (-1)
70    * or outside (+1).  Otherwise we're unsure (0). */
71   int side;
72   /* Offset to the arc-endpoints from the beginning of the glyph blob */
73   int offset;
74
75   /* A single line is all we care about.  It's right here. */
76   float line_angle;
77   float line_distance; /* From nominal glyph center */
78 };
79
80 bool glyphy_isinf (const float v)
81 {
82   return abs (v) >= GLYPHY_INFINITY * .5;
83 }
84
85 bool glyphy_iszero (const float v)
86 {
87   return abs (v) <= GLYPHY_EPSILON * 2.;
88 }
89
90 vec2 glyphy_ortho (const vec2 v)
91 {
92   return vec2 (-v.y, v.x);
93 }
94
95 int glyphy_float_to_byte (const float v)
96 {
97   return int (v * (256. - GLYPHY_EPSILON));
98 }
99
100 ivec4 glyphy_vec4_to_bytes (const vec4 v)
101 {
102   return ivec4 (v * (256. - GLYPHY_EPSILON));
103 }
104
105 ivec2 glyphy_float_to_two_nimbles (const float v)
106 {
107   int f = glyphy_float_to_byte (v);
108   return ivec2 (f / 16, int(mod (float(f), 16.)));
109 }
110
111 /* returns tan (2 * atan (d)) */
112 float glyphy_tan2atan (const float d)
113 {
114   return 2. * d / (1. - d * d);
115 }
116
117 glyphy_arc_endpoint_t glyphy_arc_endpoint_decode(const vec4 v, const ivec2 nominal_size)
118 {
119   vec2 p = (vec2 (glyphy_float_to_two_nimbles (v.a)) + v.gb) / 16.;
120   float d = v.r;
121   if (d == 0.)
122     d = GLYPHY_INFINITY;
123   else
124 #define GLYPHY_MAX_D .5
125     d = float(glyphy_float_to_byte (d) - 128) * GLYPHY_MAX_D / 127.;
126 #undef GLYPHY_MAX_D
127   return glyphy_arc_endpoint_t (p * vec2(nominal_size), d);
128 }
129
130 vec2 glyphy_arc_center (const glyphy_arc_t a)
131 {
132   return mix (a.p0, a.p1, .5) +
133          glyphy_ortho (a.p1 - a.p0) / (2. * glyphy_tan2atan (a.d));
134 }
135
136 bool glyphy_arc_wedge_contains (const glyphy_arc_t a, const vec2 p)
137 {
138   float d2 = glyphy_tan2atan (a.d);
139   return dot (p - a.p0, (a.p1 - a.p0) * mat2(1,  d2, -d2, 1)) >= 0. &&
140          dot (p - a.p1, (a.p1 - a.p0) * mat2(1, -d2,  d2, 1)) <= 0.;
141 }
142
143 float glyphy_arc_wedge_signed_dist_shallow (const glyphy_arc_t a, const vec2 p)
144 {
145   vec2 v = normalize (a.p1 - a.p0);
146   float line_d = dot (p - a.p0, glyphy_ortho (v));
147   if (a.d == 0.)
148     return line_d;
149
150   float d0 = dot ((p - a.p0), v);
151   if (d0 < 0.)
152     return sign (line_d) * distance (p, a.p0);
153   float d1 = dot ((a.p1 - p), v);
154   if (d1 < 0.)
155     return sign (line_d) * distance (p, a.p1);
156   float r = 2. * a.d * (d0 * d1) / (d0 + d1);
157   if (r * line_d > 0.)
158     return sign (line_d) * min (abs (line_d + r), min (distance (p, a.p0), distance (p, a.p1)));
159   return line_d + r;
160 }
161
162 float glyphy_arc_wedge_signed_dist (const glyphy_arc_t a, const vec2 p)
163 {
164   if (abs (a.d) <= .03)
165     return glyphy_arc_wedge_signed_dist_shallow (a, p);
166   vec2 c = glyphy_arc_center (a);
167   return sign (a.d) * (distance (a.p0, c) - distance (p, c));
168 }
169
170 float glyphy_arc_extended_dist (const glyphy_arc_t a, const vec2 p)
171 {
172   /* Note: this doesn't handle points inside the wedge. */
173   vec2 m = mix (a.p0, a.p1, .5);
174   float d2 = glyphy_tan2atan (a.d);
175   if (dot (p - m, a.p1 - m) < 0.)
176     return dot (p - a.p0, normalize ((a.p1 - a.p0) * mat2(+d2, -1, +1, +d2)));
177   else
178     return dot (p - a.p1, normalize ((a.p1 - a.p0) * mat2(-d2, -1, +1, -d2)));
179 }
180
181 int glyphy_arc_list_offset (const vec2 p, const ivec2 nominal_size)
182 {
183   ivec2 cell = ivec2 (clamp (floor (p), vec2 (0.,0.), vec2(nominal_size - 1)));
184   return cell.y * nominal_size.x + cell.x;
185 }
186
187 glyphy_arc_list_t glyphy_arc_list_decode (const vec4 v, const ivec2 nominal_size)
188 {
189   glyphy_arc_list_t l;
190   ivec4 iv = glyphy_vec4_to_bytes (v);
191   l.side = 0; /* unsure */
192   if (iv.r == 0)
193   { /* arc-list encoded */
194     l.offset = (iv.g * 256) + iv.b;
195     l.num_endpoints = iv.a;
196     if (l.num_endpoints == 255)
197     {
198       l.num_endpoints = 0;
199       l.side = -1;
200     }
201     else if (l.num_endpoints == 0)
202       l.side = +1;
203   }
204   else
205   { /* single line encoded */
206     l.num_endpoints = -1;
207     l.line_distance = ( float(iv.r)/32. + 0.01*float(iv.g)/82.0 - 6.) * max (float (nominal_size.x), float (nominal_size.y));
208     l.line_angle = ( -float(iv.b)/40.74 - float( iv.a )*0.0001 )-3.142;
209   }
210   return l;
211 }