LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkRecordPattern.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 49 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 660 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #ifndef SkRecordPattern_DEFINED
       9             : #define SkRecordPattern_DEFINED
      10             : 
      11             : #include "SkRecord.h"
      12             : #include "SkTLogic.h"
      13             : 
      14             : namespace SkRecords {
      15             : 
      16             : // First, some matchers.  These match a single command in the SkRecord,
      17             : // and may hang onto some data from it.  If so, you can get the data by calling .get().
      18             : 
      19             : // Matches a command of type T, and stores that command.
      20             : template <typename T>
      21             : class Is {
      22             : public:
      23           0 :     Is() : fPtr(nullptr) {}
      24             : 
      25             :     typedef T type;
      26           0 :     type* get() { return fPtr; }
      27             : 
      28           0 :     bool operator()(T* ptr) {
      29           0 :         fPtr = ptr;
      30           0 :         return true;
      31             :     }
      32             : 
      33             :     template <typename U>
      34           0 :     bool operator()(U*) {
      35           0 :         fPtr = nullptr;
      36           0 :         return false;
      37             :     }
      38             : 
      39             : private:
      40             :     type* fPtr;
      41             : };
      42             : 
      43             : // Matches any command that draws, and stores its paint.
      44             : class IsDraw {
      45             : public:
      46           0 :     IsDraw() : fPaint(nullptr) {}
      47             : 
      48             :     typedef SkPaint type;
      49           0 :     type* get() { return fPaint; }
      50             : 
      51             :     template <typename T>
      52           0 :     SK_WHEN(T::kTags & kDraw_Tag, bool) operator()(T* draw) {
      53           0 :         fPaint = AsPtr(draw->paint);
      54           0 :         return true;
      55             :     }
      56             : 
      57           0 :     bool operator()(DrawDrawable*) {
      58             :         static_assert(DrawDrawable::kTags & kDraw_Tag, "");
      59           0 :         fPaint = nullptr;
      60           0 :         return true;
      61             :     }
      62             : 
      63             :     template <typename T>
      64           0 :     SK_WHEN(!(T::kTags & kDraw_Tag), bool) operator()(T* draw) {
      65           0 :         fPaint = nullptr;
      66           0 :         return false;
      67             :     }
      68             : 
      69             : private:
      70             :     // Abstracts away whether the paint is always part of the command or optional.
      71           0 :     template <typename T> static T* AsPtr(SkRecords::Optional<T>& x) { return x; }
      72           0 :     template <typename T> static T* AsPtr(T& x) { return &x; }
      73             : 
      74             :     type* fPaint;
      75             : };
      76             : 
      77             : // Matches if Matcher doesn't.  Stores nothing.
      78             : template <typename Matcher>
      79             : struct Not {
      80             :     template <typename T>
      81           0 :     bool operator()(T* ptr) { return !Matcher()(ptr); }
      82             : };
      83             : 
      84             : // Matches if any of First or Rest... does.  Stores nothing.
      85             : template <typename First, typename... Rest>
      86             : struct Or {
      87             :     template <typename T>
      88           0 :     bool operator()(T* ptr) { return First()(ptr) || Or<Rest...>()(ptr); }
      89             : };
      90             : template <typename First>
      91             : struct Or<First> {
      92             :     template <typename T>
      93           0 :     bool operator()(T* ptr) { return First()(ptr); }
      94             : };
      95             : 
      96             : 
      97             : // Greedy is a special matcher that greedily matches Matcher 0 or more times.  Stores nothing.
      98             : template <typename Matcher>
      99             : struct Greedy {
     100             :     template <typename T>
     101           0 :     bool operator()(T* ptr) { return Matcher()(ptr); }
     102             : };
     103             : 
     104             : // Pattern matches each of its matchers in order.
     105             : //
     106             : // This is the main entry point to pattern matching, and so provides a couple of extra API bits:
     107             : //  - search scans through the record to look for matches;
     108             : //  - first, second, third, ... return the data stored by their respective matchers in the pattern.
     109             : 
     110             : template <typename... Matchers> class Pattern;
     111             : 
     112             : template <> class Pattern<> {
     113             : public:
     114             :     // Bottoms out recursion.  Just return whatever i the front decided on.
     115           0 :     int match(SkRecord*, int i) { return i; }
     116             : };
     117             : 
     118             : template <typename First, typename... Rest>
     119           0 : class Pattern<First, Rest...> {
     120             : public:
     121             :     // If this pattern matches the SkRecord starting from i,
     122             :     // return the index just past the end of the pattern, otherwise return 0.
     123             :     SK_ALWAYS_INLINE int match(SkRecord* record, int i) {
     124           0 :         i = this->matchFirst(&fFirst, record, i);
     125           0 :         return i > 0 ? fRest.match(record, i) : 0;
     126             :     }
     127             : 
     128             :     // Starting from *end, walk through the SkRecord to find the first span matching this pattern.
     129             :     // If there is no such span, return false.  If there is, return true and set [*begin, *end).
     130             :     SK_ALWAYS_INLINE bool search(SkRecord* record, int* begin, int* end) {
     131           0 :         for (*begin = *end; *begin < record->count(); ++(*begin)) {
     132           0 :             *end = this->match(record, *begin);
     133           0 :             if (*end != 0) {
     134           0 :                 return true;
     135             :             }
     136             :         }
     137           0 :         return false;
     138             :     }
     139             : 
     140             :     // TODO: some sort of smart get<i>()
     141           0 :     template <typename T> T* first()  { return fFirst.get();   }
     142           0 :     template <typename T> T* second() { return fRest.template first<T>();  }
     143           0 :     template <typename T> T* third()  { return fRest.template second<T>(); }
     144           0 :     template <typename T> T* fourth() { return fRest.template third<T>();  }
     145             : 
     146             : private:
     147             :     // If first isn't a Greedy, try to match at i once.
     148             :     template <typename T>
     149           0 :     int matchFirst(T* first, SkRecord* record, int i) {
     150           0 :         if (i < record->count()) {
     151           0 :             if (record->mutate(i, *first)) {
     152           0 :                 return i+1;
     153             :             }
     154             :         }
     155           0 :         return 0;
     156             :     }
     157             : 
     158             :     // If first is a Greedy, walk i until it doesn't match.
     159             :     template <typename T>
     160           0 :     int matchFirst(Greedy<T>* first, SkRecord* record, int i) {
     161           0 :         while (i < record->count()) {
     162           0 :             if (!record->mutate(i, *first)) {
     163           0 :                 return i;
     164             :             }
     165           0 :             i++;
     166             :         }
     167           0 :         return 0;
     168             :     }
     169             : 
     170             :     First            fFirst;
     171             :     Pattern<Rest...> fRest;
     172             : };
     173             : 
     174             : }  // namespace SkRecords
     175             : 
     176             : #endif//SkRecordPattern_DEFINED

Generated by: LCOV version 1.13