Merge "Added new API to Property::Map to enable method chaining" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / events / hit-test-algorithm-impl.cpp
1 /*
2  * Copyright (c) 2016 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 <dali/internal/event/events/hit-test-algorithm-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/integration-api/system-overlay.h>
23 #include <dali/public-api/actors/layer.h>
24 #include <dali/public-api/math/vector2.h>
25 #include <dali/public-api/math/vector4.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/internal/event/actors/actor-impl.h>
28 #include <dali/internal/event/actors/camera-actor-impl.h>
29 #include <dali/internal/event/actors/image-actor-impl.h>
30 #include <dali/internal/event/actors/layer-impl.h>
31 #include <dali/internal/event/actors/layer-list.h>
32 #include <dali/internal/event/common/system-overlay-impl.h>
33 #include <dali/internal/event/common/stage-impl.h>
34 #include <dali/internal/event/common/projection.h>
35 #include <dali/internal/event/images/frame-buffer-image-impl.h>
36 #include <dali/internal/event/render-tasks/render-task-impl.h>
37 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
38
39 namespace Dali
40 {
41
42 namespace Internal
43 {
44
45 namespace HitTestAlgorithm
46 {
47
48 namespace
49 {
50
51 struct HitActor
52 {
53   HitActor()
54   : actor( NULL ),
55     distance( std::numeric_limits<float>::max() ),
56     depth( std::numeric_limits<int>::min() )
57   {
58   }
59
60   Actor *actor;                         ///< The actor hit (if actor is hit, then this is initialised).
61   Vector2 hitPosition;                  ///< Position of hit (only valid if actor valid).
62   float distance;                       ///< Distance from ray origin to hit actor.
63   int depth;                            ///< Depth index of this actor.
64 };
65
66 /**
67  * Creates an Actor handle so that a HitTestFunction provided via the public API can be called.
68  */
69 struct HitTestFunctionWrapper : public HitTestInterface
70 {
71   /**
72    * Constructor
73    *
74    * @param[in] func HitTestFunction to call with an Actor handle.
75    */
76   HitTestFunctionWrapper( Dali::HitTestAlgorithm::HitTestFunction func )
77   : mFunc( func )
78   {
79   }
80
81   virtual bool IsActorHittable( Actor* actor )
82   {
83     return mFunc( Dali::Actor( actor ), Dali::HitTestAlgorithm::CHECK_ACTOR );
84   }
85
86   virtual bool DescendActorHierarchy( Actor* actor )
87   {
88     return mFunc( Dali::Actor( actor ), Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE );
89   }
90
91   virtual bool DoesLayerConsumeHit( Layer* layer )
92   {
93     // Layer::IsTouchConsumed() focuses on touch only. Here we are a wrapper for the public-api
94     // where the caller may want to check for something completely different.
95     // TODO: Should provide a means to let caller decide. For now do not allow layers to consume
96     return false;
97   }
98
99   Dali::HitTestAlgorithm::HitTestFunction mFunc;
100 };
101
102 /**
103  * Used in the hit-test algorithm to check whether the actor is touchable.
104  * It is used by the touch event processor.
105  */
106 struct ActorTouchableCheck : public HitTestInterface
107 {
108   virtual bool IsActorHittable( Actor* actor )
109   {
110     return actor->GetTouchRequired() && // Does the Application or derived actor type require a touch event?
111            actor->IsHittable();         // Is actor sensitive, visible and on the scene?
112   }
113
114   virtual bool DescendActorHierarchy( Actor* actor )
115   {
116     return actor->IsVisible() && // Actor is visible, if not visible then none of its children are visible.
117            actor->IsSensitive(); // Actor is sensitive, if insensitive none of its children should be hittable either.
118   }
119
120   virtual bool DoesLayerConsumeHit( Layer* layer )
121   {
122     return layer->IsTouchConsumed();
123   }
124 };
125
126 /**
127  * Check to see if the actor we're about to hit test is exclusively owned by another rendertask?
128  */
129 bool IsActorExclusiveToAnotherRenderTask( const Actor& actor,
130                                           const RenderTask& renderTask,
131                                           const Vector< RenderTaskList::Exclusive >& exclusives )
132
133 {
134   if( exclusives.Size() )
135   {
136     for( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt )
137     {
138       if( ( exclusiveIt->renderTaskPtr != &renderTask ) && ( exclusiveIt->actorPtr == &actor ) )
139       {
140         return true;
141       }
142     }
143   }
144   return false;
145 }
146
147 /**
148  * Recursively hit test all the actors, without crossing into other layers.
149  * This algorithm performs a Depth-First-Search (DFS) on all Actors within Layer.
150  * Hit-Testing each Actor, noting the distance from the Ray-Origin (3D origin
151  * of touch vector). The closest Hit-Tested Actor is that which is returned.
152  * Exceptions to this rule are:
153  * - When comparing against renderable parents, if Actor is the same distance
154  * or closer than it's renderable parent, then it takes priority.
155  */
156 HitActor HitTestWithinLayer( Actor& actor,
157                              const RenderTask& renderTask,
158                              const Vector< RenderTaskList::Exclusive >& exclusives,
159                              const Vector4& rayOrigin,
160                              const Vector4& rayDir,
161                              float& nearClippingPlane,
162                              float& farClippingPlane,
163                              HitTestInterface& hitCheck,
164                              bool& overlayHit,
165                              bool layerIs3d,
166                              unsigned int clippingDepth,
167                              unsigned int clippingBitPlaneMask )
168 {
169   HitActor hit;
170
171   if( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) )
172   {
173     return hit;
174   }
175
176   // For clipping, regardless of whether we have hit this actor or not,
177   // we increase the clipping depth if we have hit a clipping actor.
178   // This is used later to ensure all nested clipped children have hit
179   // all clipping actors also for them to be counted as hit.
180   unsigned int newClippingDepth = clippingDepth;
181   bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED;
182   if( clippingActor )
183   {
184     ++newClippingDepth;
185   }
186
187   // If we are a clipping actor or hittable...
188   if( clippingActor || hitCheck.IsActorHittable( &actor ) )
189   {
190     Vector3 size( actor.GetCurrentSize() );
191
192     // Ensure the actor has a valid size.
193     // If so, perform a quick ray sphere test to see if our ray is close to the actor.
194     if( size.x > 0.0f && size.y > 0.0f && actor.RaySphereTest( rayOrigin, rayDir ) )
195     {
196       Vector2 hitPointLocal;
197       float distance;
198
199       // Finally, perform a more accurate ray test to see if our ray actually hits the actor.
200       if( actor.RayActorTest( rayOrigin, rayDir, hitPointLocal, distance ) )
201       {
202         if( distance >= nearClippingPlane && distance <= farClippingPlane )
203         {
204           // If the hit has happened on a clipping actor, then add this clipping depth to the mask of hit clipping depths.
205           // This mask shows all the actors that have been hit at different clipping depths.
206           if( clippingActor )
207           {
208             clippingBitPlaneMask |= 1u << clippingDepth;
209           }
210
211           if( overlayHit && !actor.IsOverlay() )
212           {
213             // If we have already hit an overlay and current actor is not an overlay ignore current actor.
214           }
215           else
216           {
217             if( actor.IsOverlay() )
218             {
219               overlayHit = true;
220             }
221
222             // At this point we have hit an actor.
223             // Now perform checks for clipping.
224             // Assume we have hit the actor first as if it is not clipped this would be the case.
225             bool haveHitActor = true;
226
227             // Check if we are performing clipping. IE. if any actors so far have clipping enabled - not necessarily this one.
228             // We can do this by checking the clipping depth has a value 1 or above.
229             if( newClippingDepth >= 1u )
230             {
231               // Now for us to count this actor as hit, we must have also hit
232               // all CLIPPING actors up to this point in the hierarchy as well.
233               // This information is stored in the clippingBitPlaneMask we updated above.
234               // Here we calculate a comparison mask by setting all the bits up to the current depth value.
235               // EG. a depth of 4 (10000 binary) = a mask of 1111 binary.
236               // This allows us a fast way of comparing all bits are set up to this depth.
237               unsigned int clippingDepthMask = ( 1u << clippingDepth ) - 1u;
238
239               // The two masks must be equal to be a hit, as we are already assuming a hit
240               // (for non-clipping mode) then they must be not-equal to disqualify the hit.
241               if( clippingBitPlaneMask != clippingDepthMask )
242               {
243                 haveHitActor = false;
244               }
245             }
246
247             if( haveHitActor )
248             {
249               hit.actor = &actor;
250               hit.hitPosition = hitPointLocal;
251               hit.distance = distance;
252               hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER;
253
254               if( actor.GetRendererCount() > 0 )
255               {
256                 //Get renderer with maximum depth
257                 int rendererMaxDepth(actor.GetRendererAt( 0 ).Get()->GetDepthIndex());
258                 for( unsigned int i(1); i < actor.GetRendererCount(); ++i )
259                 {
260                   int depth = actor.GetRendererAt( i ).Get()->GetDepthIndex();
261                   if( depth > rendererMaxDepth )
262                   {
263                     rendererMaxDepth = depth;
264                   }
265                 }
266                 hit.depth += rendererMaxDepth;
267               }
268             }
269           }
270         }
271       }
272     }
273   }
274
275   // Find a child hit, until we run out of actors in the current layer.
276   HitActor childHit;
277   if( actor.GetChildCount() > 0 )
278   {
279     childHit.distance = std::numeric_limits<float>::max();
280     childHit.depth = std::numeric_limits<int>::min();
281     ActorContainer& children = actor.GetChildrenInternal();
282
283     // Hit test ALL children and calculate their distance.
284     bool parentIsRenderable = actor.IsRenderable();
285
286     for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter )
287     {
288       // Descend tree only if...
289       if ( !( *iter )->IsLayer() &&                                 // Child is NOT a layer, hit testing current layer only
290             ( hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We can descend into child hierarchy
291       {
292         HitActor currentHit( HitTestWithinLayer( ( *iter->Get() ),
293                                                  renderTask,
294                                                  exclusives,
295                                                  rayOrigin,
296                                                  rayDir,
297                                                  nearClippingPlane,
298                                                  farClippingPlane,
299                                                  hitCheck,
300                                                  overlayHit,
301                                                  layerIs3d,
302                                                  newClippingDepth,
303                                                  clippingBitPlaneMask ) );
304
305         bool updateChildHit = false;
306         if( currentHit.distance >= 0.0f )
307         {
308           if( layerIs3d )
309           {
310             updateChildHit = ( ( currentHit.depth > childHit.depth ) ||
311                                ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) );
312           }
313           else
314           {
315             updateChildHit = currentHit.depth >= childHit.depth;
316           }
317         }
318
319         if( updateChildHit )
320         {
321           if( !parentIsRenderable || currentHit.depth > hit.depth ||
322             ( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) )
323           {
324             childHit = currentHit;
325           }
326         }
327       }
328     }
329   }
330
331   return ( childHit.actor ) ? childHit : hit;
332 }
333
334 /**
335  * Return true if actor is sourceActor or a descendent of sourceActor
336  */
337 bool IsWithinSourceActors( const Actor& sourceActor, const Actor& actor )
338 {
339   if ( &sourceActor == &actor )
340   {
341     return true;
342   }
343
344   Actor* parent = actor.GetParent();
345   if ( parent )
346   {
347     return IsWithinSourceActors( sourceActor, *parent );
348   }
349
350   // Not within source actors
351   return false;
352 }
353
354 /**
355  * Returns true if the layer and all of the layer's parents are visible and sensitive.
356  */
357 inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates, const Vector2& stageSize, HitTestInterface& hitCheck )
358 {
359   bool hittable( true );
360
361   if( layer.IsClipping() )
362   {
363     ClippingBox box = layer.GetClippingBox();
364
365     if( screenCoordinates.x < box.x ||
366         screenCoordinates.x > box.x + box.width ||
367         screenCoordinates.y < stageSize.y - (box.y + box.height) ||
368         screenCoordinates.y > stageSize.y - box.y)
369     {
370       // Not touchable if clipping is enabled in the layer and the screen coordinate is outside the clip region.
371       hittable = false;
372     }
373   }
374
375   if( hittable )
376   {
377     Actor* actor( &layer );
378
379     // Ensure that we can descend into the layer's (or any of its parent's) hierarchy.
380     while( actor && hittable )
381     {
382       if( ! hitCheck.DescendActorHierarchy( actor ) )
383       {
384         hittable = false;
385         break;
386       }
387       actor = actor->GetParent();
388     }
389   }
390
391   return hittable;
392 }
393
394 /**
395  * Gets the near and far clipping planes of the camera from which the scene is viewed in the render task.
396  */
397 void GetCameraClippingPlane( RenderTask& renderTask, float& nearClippingPlane, float& farClippingPlane )
398 {
399   CameraActor* cameraActor = renderTask.GetCameraActor();
400   nearClippingPlane = cameraActor->GetNearClippingPlane();
401   farClippingPlane = cameraActor->GetFarClippingPlane();
402 }
403
404 /**
405  * Hit test a RenderTask
406  */
407 bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives,
408                         Stage& stage,
409                         LayerList& layers,
410                         RenderTask& renderTask,
411                         Vector2 screenCoordinates,
412                         Results& results,
413                         HitTestInterface& hitCheck )
414 {
415   if ( renderTask.IsHittable( screenCoordinates ) )
416   {
417     Viewport viewport;
418     renderTask.GetViewport( viewport );
419     if( screenCoordinates.x < viewport.x ||
420         screenCoordinates.x > viewport.x + viewport.width ||
421         screenCoordinates.y < viewport.y ||
422         screenCoordinates.y > viewport.y + viewport.height )
423     {
424       // The screen coordinate is outside the viewport of render task. The viewport clips all layers.
425       return false;
426     }
427
428     float nearClippingPlane, farClippingPlane;
429     GetCameraClippingPlane( renderTask, nearClippingPlane, farClippingPlane );
430
431     // Determine the layer depth of the source actor
432     Actor* sourceActor( renderTask.GetSourceActor() );
433     if( sourceActor )
434     {
435       Dali::Layer layer( sourceActor->GetLayer() );
436       if( layer )
437       {
438         const unsigned int sourceActorDepth( layer.GetDepth() );
439
440         CameraActor* cameraActor = renderTask.GetCameraActor();
441         bool pickingPossible = cameraActor->BuildPickingRay(
442             screenCoordinates,
443             viewport,
444             results.rayOrigin,
445             results.rayDirection );
446         if( !pickingPossible )
447         {
448           return false;
449         }
450
451         // Hit test starting with the top layer, working towards the bottom layer.
452         HitActor hit;
453         bool overlayHit = false;
454         bool layerConsumesHit = false;
455         const Vector2& stageSize = stage.GetSize();
456
457         for( int i = layers.GetLayerCount() - 1; i >= 0 && !( hit.actor ); --i )
458         {
459           Layer* layer( layers.GetLayer( i ) );
460           overlayHit = false;
461
462           // Ensure layer is touchable (also checks whether ancestors are also touchable)
463           if( IsActuallyHittable( *layer, screenCoordinates, stageSize, hitCheck ) )
464           {
465             // Always hit-test the source actor; otherwise test whether the layer is below the source actor in the hierarchy
466             if( sourceActorDepth == static_cast<unsigned int>( i ) )
467             {
468               // Recursively hit test the source actor & children, without crossing into other layers.
469               hit = HitTestWithinLayer( *sourceActor,
470                                         renderTask,
471                                         exclusives,
472                                         results.rayOrigin,
473                                         results.rayDirection,
474                                         nearClippingPlane,
475                                         farClippingPlane,
476                                         hitCheck,
477                                         overlayHit,
478                                         layer->GetBehavior() == Dali::Layer::LAYER_3D,
479                                         0u,
480                                         0u );
481             }
482             else if( IsWithinSourceActors( *sourceActor, *layer ) )
483             {
484               // Recursively hit test all the actors, without crossing into other layers.
485               hit = HitTestWithinLayer( *layer,
486                                         renderTask,
487                                         exclusives,
488                                         results.rayOrigin,
489                                         results.rayDirection,
490                                         nearClippingPlane,
491                                         farClippingPlane,
492                                         hitCheck,
493                                         overlayHit,
494                                         layer->GetBehavior() == Dali::Layer::LAYER_3D,
495                                         0u,
496                                         0u );
497             }
498
499             // If this layer is set to consume the hit, then do not check any layers behind it
500             if( hitCheck.DoesLayerConsumeHit( layer ) )
501             {
502               layerConsumesHit = true;
503               break;
504             }
505           }
506         }
507
508         if( hit.actor )
509         {
510           results.renderTask = Dali::RenderTask( &renderTask );
511           results.actor = Dali::Actor( hit.actor );
512           results.actorCoordinates = hit.hitPosition;
513
514           return true; // Success
515         }
516
517         if( layerConsumesHit )
518         {
519           return true; // Also success if layer is consuming the hit
520         }
521       }
522     }
523   }
524   return false;
525 }
526
527 /**
528  * Iterate through the RenderTaskList and perform hit testing.
529  *
530  * @param[in] stage The stage the tests will be performed in
531  * @param[in] layers The list of layers to test
532  * @param[in] taskList The list of render tasks
533  * @param[out] results Ray information calculated by the camera
534  * @param[in] hitCheck The hit testing interface object to use
535  * @param[in] onScreen True to test on-screen, false to test off-screen
536  * @return True if we have a hit, false otherwise
537  */
538 bool HitTestRenderTaskList( Stage& stage,
539                             LayerList& layers,
540                             RenderTaskList& taskList,
541                             const Vector2& screenCoordinates,
542                             Results& results,
543                             HitTestInterface& hitCheck,
544                             bool onScreen )
545 {
546   RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
547   RenderTaskList::RenderTaskContainer::reverse_iterator endIter = tasks.rend();
548   const Vector< RenderTaskList::Exclusive >& exclusives = taskList.GetExclusivesList();
549
550   for( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter )
551   {
552     RenderTask& renderTask = GetImplementation( *iter );
553     Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer();
554
555     // Note that if frameBufferImage is NULL we are using the default (on screen) render target
556     if( frameBufferImage )
557     {
558       ResourceId id = GetImplementation( frameBufferImage ).GetResourceId();
559
560       // Change comparison depending on if on-screen or off-screen.
561       if( onScreen ? ( 0 != id ) : ( 0 == id ) )
562       {
563         // Skip to next task
564         continue;
565       }
566     }
567
568     if( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) )
569     {
570       // Return true when an actor is hit (or layer in our render-task consumes the hit)
571       return true; // don't bother checking off screen tasks
572     }
573   }
574
575   return false;
576 }
577
578 /**
579  * Iterate through the RenderTaskList and perform hit testing for both on-screen and off-screen.
580  *
581  * @param[in] stage The stage the tests will be performed in
582  * @param[in] layers The list of layers to test
583  * @param[in] taskList The list of render tasks
584  * @param[out] results Ray information calculated by the camera
585  * @param[in] hitCheck The hit testing interface object to use
586  * @param[in] onScreen True to test on-screen, false to test off-screen
587  * @return True if we have a hit, false otherwise
588  */
589 bool HitTestForEachRenderTask( Stage& stage,
590                                LayerList& layers,
591                                RenderTaskList& taskList,
592                                const Vector2& screenCoordinates,
593                                Results& results,
594                                HitTestInterface& hitCheck )
595 {
596   bool result = false;
597
598   // Check on-screen tasks before off-screen ones.
599   // Hit test order should be reverse of draw order (see ProcessRenderTasks() where off-screen tasks are drawn first).
600   if( HitTestRenderTaskList( stage, layers, taskList, screenCoordinates, results, hitCheck, true  ) ||
601       HitTestRenderTaskList( stage, layers, taskList, screenCoordinates, results, hitCheck, false ) )
602   {
603     // Found hit.
604     result = true;
605   }
606
607   return result;
608 }
609
610 } // unnamed namespace
611
612 bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func )
613 {
614   bool wasHit( false );
615   // Hit-test the regular on-stage actors
616   RenderTaskList& taskList = stage.GetRenderTaskList();
617   LayerList& layerList = stage.GetLayerList();
618
619   Results hitTestResults;
620   HitTestFunctionWrapper hitTestFunctionWrapper( func );
621   if( HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
622   {
623     results.actor = hitTestResults.actor;
624     results.actorCoordinates = hitTestResults.actorCoordinates;
625     wasHit = true;
626   }
627   return wasHit;
628 }
629
630 bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results, HitTestInterface& hitTestInterface )
631 {
632   bool wasHit( false );
633
634   // Hit-test the system-overlay actors first
635   SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal();
636
637   if( systemOverlay )
638   {
639     RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks();
640     LayerList& overlayLayerList = systemOverlay->GetLayerList();
641
642     wasHit = HitTestForEachRenderTask( stage, overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface );
643   }
644
645   // Hit-test the regular on-stage actors
646   if( !wasHit )
647   {
648     RenderTaskList& taskList = stage.GetRenderTaskList();
649     LayerList& layerList = stage.GetLayerList();
650
651     wasHit = HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, results, hitTestInterface );
652   }
653   return wasHit;
654 }
655
656 bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results )
657 {
658   ActorTouchableCheck actorTouchableCheck;
659   return HitTest( stage, screenCoordinates, results, actorTouchableCheck );
660 }
661
662 bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordinates,
663               Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func )
664 {
665   bool wasHit( false );
666   Results hitTestResults;
667
668   const Vector< RenderTaskList::Exclusive >& exclusives = stage.GetRenderTaskList().GetExclusivesList();
669   HitTestFunctionWrapper hitTestFunctionWrapper( func );
670   if( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) )
671   {
672     results.actor = hitTestResults.actor;
673     results.actorCoordinates = hitTestResults.actorCoordinates;
674     wasHit = true;
675   }
676   return wasHit;
677 }
678
679
680 } // namespace HitTestAlgorithm
681
682 } // namespace Internal
683
684 } // namespace Dali