tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DashedCornerFinder.h (9710B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_DashedCornerFinder_h_
      8 #define mozilla_DashedCornerFinder_h_
      9 
     10 #include "mozilla/gfx/2D.h"
     11 #include "mozilla/gfx/BezierUtils.h"
     12 
     13 namespace mozilla {
     14 
     15 // Calculate {OuterT_i, InnerT_i} for each 1 < i < n, that
     16 //   (OuterL_i + InnerL_i) / 2 == dashLength * (W_i + W_{i-1}) / 2
     17 // where
     18 //   OuterP_i: OuterCurve(OuterT_i)
     19 //   InnerP_i: InnerCurve(OuterT_i)
     20 //   OuterL_i: Elliptic arc length between OuterP_i - OuterP_{i-1}
     21 //   InnerL_i: Elliptic arc length between InnerP_i - InnerP_{i-1}
     22 //   W_i = |OuterP_i - InnerP_i|
     23 //   1.0 < dashLength < 3.0
     24 //
     25 //                                         OuterP_1          OuterP_0
     26 //                                         _+__-----------+ OuterCurve
     27 //                          OuterP_2 __---- |   OuterL_1  |
     28 //                             __+---       |             |
     29 //                        __---  | OuterL_2 |             |
     30 //            OuterP_3 _--       |           | W_1        | W_0
     31 //                   _+           |          |            |
     32 //                  /  \       W_2 |         |            |
     33 //                 /    \          |          | InnerL_1  |
     34 //                |      \          | InnerL_2|____-------+ InnerCurve
     35 //                |       \          |____----+          InnerP_0
     36 //               |     .   \    __---+       InnerP_1
     37 //               |          \ /     InnerP_2
     38 //              |     .     /+ InnerP_3
     39 //              |          |
     40 //              |    .    |
     41 //              |         |
     42 //              |        |
     43 //              |        |
     44 // OuterP_{n-1} +--------+ InnerP_{n-1}
     45 //              |        |
     46 //              |        |
     47 //              |        |
     48 //              |        |
     49 //              |        |
     50 //     OuterP_n +--------+ InnerP_n
     51 //
     52 // Returns region with [OuterCurve((OuterT_{2j} + OuterT_{2j-1}) / 2),
     53 //                      OuterCurve((OuterT_{2j} + OuterT_{2j-1}) / 2),
     54 //                      InnerCurve((OuterT_{2j} + OuterT_{2j+1}) / 2),
     55 //                      InnerCurve((OuterT_{2j} + OuterT_{2j+1}) / 2)],
     56 // to start and end with half segment.
     57 //
     58 //                                     _+__----+------+ OuterCurve
     59 //                               _+---- |      |######|
     60 //                         __+---#|     |      |######|
     61 //                    _+---##|####|     |      |######|
     62 //                 _-- |#####|#####|     |      |#####|
     63 //               _+     |#####|#####|    |      |#####|
     64 //              /  \     |#####|####|    |      |#####|
     65 //             /    \     |####|#####|    |     |#####|
     66 //            |      \     |####|####|    |____-+-----+ InnerCurve
     67 //            |       \     |####|____+---+
     68 //           |     .   \   __+---+
     69 //           |          \ /
     70 //          |     .     /+
     71 //          |          |
     72 //          |    .    |
     73 //          |         |
     74 //          |        |
     75 //          |        |
     76 //          +--------+
     77 //          |        |
     78 //          |        |
     79 //          +--------+
     80 //          |########|
     81 //          |########|
     82 //          +--------+
     83 
     84 class DashedCornerFinder {
     85  typedef mozilla::gfx::Bezier Bezier;
     86  typedef mozilla::gfx::Float Float;
     87  typedef mozilla::gfx::Point Point;
     88  typedef mozilla::gfx::Size Size;
     89 
     90 public:
     91  struct Result {
     92    // Control points for the outer curve and the inner curve.
     93    //
     94    //   outerSectionBezier
     95    //        |
     96    //        v     _+ 3
     97    //        ___---#|
     98    //  0 +---#######|
     99    //    |###########|
    100    //     |###########|
    101    //      |##########|
    102    //       |##########|
    103    //        |#########|
    104    //         |#####____+ 3
    105    //        0 +----
    106    //              ^
    107    //              |
    108    //   innerSectionBezier
    109    Bezier outerSectionBezier;
    110    Bezier innerSectionBezier;
    111 
    112    Result(const Bezier& aOuterSectionBezier, const Bezier& aInnerSectionBezier)
    113        : outerSectionBezier(aOuterSectionBezier),
    114          innerSectionBezier(aInnerSectionBezier) {}
    115  };
    116 
    117  //                       aCornerDim.width
    118  //                     |<----------------->|
    119  //                     |                   |
    120  //                   --+-------------___---+--
    121  //                   ^ |         __--      | ^
    122  //                   | |       _-          | |
    123  //                   | |     /             | | aBorderWidthH
    124  //                   | |   /               | |
    125  //                   | |  |                | v
    126  //                   | | |             __--+--
    127  // aCornerDim.height | ||            _-
    128  //                   | ||           /
    129  //                   | |           /
    130  //                   | |          |
    131  //                   | |          |
    132  //                   | |         |
    133  //                   | |         |
    134  //                   v |         |
    135  //                   --+---------+
    136  //                     |         |
    137  //                     |<------->|
    138  //                     aBorderWidthV
    139  DashedCornerFinder(const Bezier& aOuterBezier, const Bezier& aInnerBezier,
    140                     Float aBorderWidthH, Float aBorderWidthV,
    141                     const Size& aCornerDim);
    142 
    143  bool HasMore(void) const;
    144  Result Next(void);
    145 
    146 private:
    147  static const size_t MAX_LOOP = 32;
    148 
    149  // Bezier control points for the outer curve and the inner curve.
    150  //
    151  //               ___---+ outer curve
    152  //           __--      |
    153  //         _-          |
    154  //       /             |
    155  //     /               |
    156  //    |                |
    157  //   |             __--+ inner curve
    158  //  |            _-
    159  //  |           /
    160  // |           /
    161  // |          |
    162  // |          |
    163  // |         |
    164  // |         |
    165  // |         |
    166  // +---------+
    167  Bezier mOuterBezier;
    168  Bezier mInnerBezier;
    169 
    170  Point mLastOuterP;
    171  Point mLastInnerP;
    172  Float mLastOuterT;
    173  Float mLastInnerT;
    174 
    175  // Length for each segment, ratio of the border width at that point.
    176  Float mBestDashLength;
    177 
    178  // If one of border-widths is 0, do not calculate mBestDashLength, and draw
    179  // segments until it reaches the other side or exceeds mMaxCount.
    180  bool mHasZeroBorderWidth;
    181  bool mHasMore;
    182 
    183  // The maximum number of segments.
    184  size_t mMaxCount;
    185 
    186  enum {
    187    //                      radius.width
    188    //                 |<----------------->|
    189    //                 |                   |
    190    //               --+-------------___---+--
    191    //               ^ |         __--      | ^
    192    //               | |       _-          | |
    193    //               | |     /             + | top-width
    194    //               | |   /               | |
    195    //               | |  |                | v
    196    //               | | |             __--+--
    197    // radius.height | ||            _-
    198    //               | ||           /
    199    //               | |           /
    200    //               | |          |
    201    //               | |          |
    202    //               | |         |
    203    //               | |         |
    204    //               v |         |
    205    //               --+----+----+
    206    //                 |         |
    207    //                 |<------->|
    208    //                  left-width
    209 
    210    // * top-width == left-width
    211    // * radius.width == radius.height
    212    // * top-width < radius.width * 2
    213    //
    214    // Split the perfect circle's arc into 2n segments, each segment's length is
    215    // top-width * dashLength. Then split the inner curve and the outer curve
    216    // with same angles.
    217    //
    218    //                        radius.width
    219    //                 |<---------------------->|
    220    //                 |                        | v
    221    //               --+------------------------+--
    222    //               ^ |                        | | top-width / 2
    223    //               | | perfect                | |
    224    //               | | circle's         ___---+--
    225    //               | | arc          __-+      | ^
    226    //               | |  |         _-   |      |
    227    // radius.height | |  |       +       |     +--
    228    //               | |  |     /  \      |     |
    229    //               | |  |    |     \     |    |
    230    //               | |  |   |       \     |   |
    231    //               | |  +->|          \   |   |
    232    //               | |    +---__       \   |  |
    233    //               | |    |     --__     \  | |
    234    //               | |    |         ---__ \ | |
    235    //               v |    |              --_\||
    236    //               --+----+----+--------------+
    237    //                 |    |    |
    238    //                 |<-->|    |
    239    //               left-width / 2
    240    PERFECT,
    241 
    242    // Other cases.
    243    //
    244    // Split the outer curve and the inner curve into 2n segments, each segment
    245    // satisfies following:
    246    //   (OuterL_i + InnerL_i) / 2 == dashLength * (W_i + W_{i-1}) / 2
    247    OTHER
    248  } mType;
    249 
    250  size_t mI;
    251  size_t mCount;
    252 
    253  // Determine mType from parameters.
    254  void DetermineType(Float aBorderWidthH, Float aBorderWidthV);
    255 
    256  // Reset calculation.
    257  void Reset(void);
    258 
    259  // Find next segment.
    260  Float FindNext(Float dashLength);
    261 
    262  // Find mBestDashLength for parameters.
    263  void FindBestDashLength(Float aMinBorderWidth, Float aMaxBorderWidth,
    264                          Float aMinBorderRadius, Float aMaxBorderRadius);
    265 
    266  // Fill corner with dashes with given dash length, and return the number of
    267  // segments and last segment's dash length.
    268  bool GetCountAndLastDashLength(Float aDashLength, size_t* aCount,
    269                                 Float* aActualDashLength);
    270 };
    271 
    272 }  // namespace mozilla
    273 
    274 #endif /* mozilla_DashedCornerFinder_h_ */