LCOV - code coverage report
Current view: top level - layout/painting - DottedCornerFinder.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 4 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef mozilla_DottedCornerFinder_h_
       7             : #define mozilla_DottedCornerFinder_h_
       8             : 
       9             : #include "mozilla/gfx/2D.h"
      10             : #include "mozilla/gfx/BezierUtils.h"
      11             : #include "gfxRect.h"
      12             : 
      13             : namespace mozilla {
      14             : 
      15             : // Calculate C_i and r_i for each filled/unfilled circles in dotted corner.
      16             : // Returns circle with C_{2j} and r_{2j} where 0 < 2j < n.
      17             : //
      18             : //                            ____-----------+
      19             : //                      __----  *****     ###|
      20             : //                __----      *********  ####|
      21             : //           __---  #####    ***********#####|
      22             : //        _--     #########  *****+*****#####+ C_0
      23             : //      _-       ########### *** C_1****#####|
      24             : //     /         #####+#####  *********  ####|
      25             : //    /       .  ### C_2 ###    *****     ###|
      26             : //   |            #########       ____-------+
      27             : //   |     .        #####____-----
      28             : //  |              __----
      29             : //  |    .       /
      30             : // |           /
      31             : // |  *****   |
      32             : // | ******* |
      33             : // |*********|
      34             : // |****+****|
      35             : // | C_{n-1} |
      36             : // | ******* |
      37             : // |  *****  |
      38             : // |  #####  |
      39             : // | ####### |
      40             : // |#########|
      41             : // +----+----+
      42             : //     C_n
      43             : 
      44             : class DottedCornerFinder
      45             : {
      46             :   typedef mozilla::gfx::Bezier Bezier;
      47             :   typedef mozilla::gfx::Float Float;
      48             :   typedef mozilla::gfx::Point Point;
      49             :   typedef mozilla::gfx::Size Size;
      50             : 
      51             : public:
      52             :   struct Result
      53             :   {
      54             :     // Center point of dot and its radius.
      55             :     Point C;
      56             :     Float r;
      57             : 
      58           0 :     Result(const Point& aC, Float aR)
      59           0 :      : C(aC), r(aR)
      60             :     {
      61           0 :       MOZ_ASSERT(aR >= 0);
      62           0 :     }
      63             :   };
      64             : 
      65             :   //                        aBorderRadiusX
      66             :   //                       aCornerDim.width
      67             :   //                     |<----------------->|
      68             :   //                     |                   | v
      69             :   //                   --+-------------___---+--
      70             :   //                   ^ |         __--      | |
      71             :   //                   | |       _-          | | aR0
      72             :   //                   | |     /         aC0 +--
      73             :   //                   | |   /               | ^
      74             :   //                   | |  |                |
      75             :   //  aBorderRadiusY   | | |             __--+
      76             :   // aCornerDim.height | ||            _-
      77             :   //                   | ||           /
      78             :   //                   | |           /
      79             :   //                   | |          |
      80             :   //                   | |          |
      81             :   //                   | |         |
      82             :   //                   | |         |
      83             :   //                   v |    aCn  |
      84             :   //                   --+----+----+
      85             :   //                     |    |
      86             :   //                     |<-->|
      87             :   //                      aRn
      88             :   //
      89             :   // aCornerDim and (aBorderRadiusX, aBorderRadiusY) can be different when
      90             :   // aBorderRadiusX is smaller than aRn*2 or
      91             :   // aBorderRadiusY is smaller than aR0*2.
      92             :   //
      93             :   //                                        aCornerDim.width
      94             :   //                                      |<----------------->|
      95             :   //                                      |                   |
      96             :   //                                      | aBorderRadiusX    |
      97             :   //                                      |<--------->|       |
      98             :   //                                      |           |       |
      99             :   //                   -------------------+-------__--+-------+--
     100             :   //                   ^                ^ |     _-            | ^
     101             :   //                   |                | |   /               | |
     102             :   //                   |                | |  /                | |
     103             :   //                   | aBorderRadiusY | | |                 | | aR0
     104             :   //                   |                | ||                  | |
     105             :   //                   |                | |                   | |
     106             :   // aCornerDim.height |                v |                   | v
     107             :   //                   |                --+               aC0 +--
     108             :   //                   |                  |                   |
     109             :   //                   |                  |                   |
     110             :   //                   |                  |                   |
     111             :   //                   |                  |                   |
     112             :   //                   |                  |                   |
     113             :   //                   v                  |        aCn        |
     114             :   //                   -------------------+---------+---------+
     115             :   //                                      |         |
     116             :   //                                      |<------->|
     117             :   //                                          aRn
     118             :   DottedCornerFinder(const Bezier& aOuterBezier, const Bezier& aInnerBezier,
     119             :                      mozilla::Corner aCorner,
     120             :                      Float aBorderRadiusX, Float aBorderRadiusY,
     121             :                      const Point& aC0, Float aR0, const Point& aCn, Float aRn,
     122             :                      const Size& aCornerDim);
     123             : 
     124             :   bool HasMore(void) const;
     125             :   Result Next(void);
     126             : 
     127             : private:
     128             :   static const size_t MAX_LOOP = 32;
     129             : 
     130             :   // Bezier control points for the outer curve, the inner curve, and a curve
     131             :   // that center points of circles are on (center curve).
     132             :   //
     133             :   //               ___---+ outer curve
     134             :   //           __--      |
     135             :   //         _-          |
     136             :   //       /        __---+ center curve
     137             :   //     /      __--     |
     138             :   //    |     /          |
     139             :   //   |    /        __--+ inner curve
     140             :   //  |    |       _-
     141             :   //  |    |      /
     142             :   // |     |     /
     143             :   // |    |     |
     144             :   // |    |     |
     145             :   // |    |    |
     146             :   // |    |    |
     147             :   // |    |    |
     148             :   // +----+----+
     149             :   Bezier mOuterBezier;
     150             :   Bezier mInnerBezier;
     151             :   Bezier mCenterBezier;
     152             : 
     153             :   mozilla::Corner mCorner;
     154             : 
     155             :   // Sign of the normal vector used in radius calculation, flipped depends on
     156             :   // corner and start and end radii.
     157             :   Float mNormalSign;
     158             : 
     159             :   // Center points and raii for start and end circles, mR0 >= mRn.
     160             :   // mMaxR = max(mR0, mRn)
     161             :   //
     162             :   //                           v
     163             :   //               ___---+------
     164             :   //           __--     #|#    | mRn
     165             :   //         _-        ##|##   |
     166             :   //       /           ##+## ---
     167             :   //     /              mCn    ^
     168             :   //    |               #|#
     169             :   //   |             __--+
     170             :   //  |            _-
     171             :   //  |           /
     172             :   // |           /
     173             :   // |          |
     174             :   // |          |
     175             :   // |  #####  |
     176             :   // | ####### |
     177             :   // |#########|
     178             :   // +----+----+
     179             :   // |## mC0 ##|
     180             :   // | ####### |
     181             :   // |  #####  |
     182             :   // |    |
     183             :   // |<-->|
     184             :   //
     185             :   //  mR0
     186             :   //
     187             :   Point mC0;
     188             :   Point mCn;
     189             :   Float mR0;
     190             :   Float mRn;
     191             :   Float mMaxR;
     192             : 
     193             :   // Parameters for the center curve with perfect circle and the inner curve.
     194             :   // The center curve doesn't necessarily share the origin with others.
     195             :   //
     196             :   //               ___---+
     197             :   //           __--      |
     198             :   //         _-          |
     199             :   //       /        __-+ |
     200             :   //     /      __--     |
     201             :   //    |     /          |
     202             :   //   |    /        __--+--
     203             :   //  |    |       _-    | ^
     204             :   //  |    |      /      | |
     205             :   // |     |     /       | |
     206             :   // |    |     |        | |
     207             :   // |    |     |        | | mInnerHeight
     208             :   // |    |    |         | |
     209             :   // |    +    |         | |
     210             :   // |         |         | v
     211             :   // +---------+---------+
     212             :   //           |         | mInnerCurveOrigin
     213             :   //           |<------->|
     214             :   //           mInnerWidth
     215             :   //
     216             :   //               ___---+
     217             :   //           __--
     218             :   //         _-
     219             :   //       /        __-+
     220             :   //     /      __--   |
     221             :   //    |     /        |
     222             :   //   |    /        __--+
     223             :   //  |    |       _-  |
     224             :   //  |    |      /    |
     225             :   // |     |     /     |
     226             :   // |    |     |      |
     227             :   // |    |     |      |
     228             :   // |    |    |       |
     229             :   // |    +--- | ------+
     230             :   // |    |    |       | mCenterCurveOrigin
     231             :   // +    |    +       |
     232             :   //      |            |
     233             :   //      |            |
     234             :   //      |            |
     235             :   //      |            |
     236             :   //      |<---------->|
     237             :   //       mCenterCurveR
     238             :   //
     239             :   Point mCenterCurveOrigin;
     240             :   Float mCenterCurveR;
     241             :   Point mInnerCurveOrigin;
     242             :   Float mInnerWidth;
     243             :   Float mInnerHeight;
     244             : 
     245             :   Point mLastC;
     246             :   Float mLastR;
     247             :   Float mLastT;
     248             : 
     249             :   // Overlap between two circles.
     250             :   // It uses arc length on PERFECT, SINGLE_CURVE_AND_RADIUS, and SINGLE_CURVE,
     251             :   // and direct distance on OTHER.
     252             :   Float mBestOverlap;
     253             : 
     254             :   // If one of border-widths is 0, do not calculate overlap, and draw circles
     255             :   // until it reaches the other side or exceeds mMaxCount.
     256             :   bool mHasZeroBorderWidth;
     257             :   bool mHasMore;
     258             : 
     259             :   // The maximum number of filled/unfilled circles.
     260             :   size_t mMaxCount;
     261             : 
     262             :   enum {
     263             :     //                      radius.width
     264             :     //                 |<----------------->|
     265             :     //                 |                   |
     266             :     //               --+-------------___---+----
     267             :     //               ^ |         __--     #|#  ^
     268             :     //               | |       _-        ##|## |
     269             :     //               | |     /           ##+## | top-width
     270             :     //               | |   /             ##|## |
     271             :     //               | |  |               #|#  v
     272             :     //               | | |             __--+----
     273             :     // radius.height | ||            _-
     274             :     //               | ||           /
     275             :     //               | |           /
     276             :     //               | |          |
     277             :     //               | |          |
     278             :     //               | |  #####  |
     279             :     //               | | ####### |
     280             :     //               v |#########|
     281             :     //               --+----+----+
     282             :     //                 |#########|
     283             :     //                 | ####### |
     284             :     //                 |  #####  |
     285             :     //                 |         |
     286             :     //                 |<------->|
     287             :     //                  left-width
     288             : 
     289             :     // * top-width == left-width
     290             :     // * radius.width == radius.height
     291             :     // * top-width < radius.width * 2
     292             :     //
     293             :     // All circles has same radii and are on single perfect circle's arc.
     294             :     // Overlap is known.
     295             :     //
     296             :     // Split the perfect circle's arc into 2n segments, each segment's length is
     297             :     // top-width * (1 - overlap).  Place each circle's center point C_i on each
     298             :     // end of the segment, each circle's radius r_i is top-width / 2
     299             :     //
     300             :     //                       #####
     301             :     //                      #######
     302             :     // perfect             #########
     303             :     // circle's          ___---+####
     304             :     // arc     ##### __--  ## C_0 ##
     305             :     //   |    #####_-       ###|###
     306             :     //   |   ####+####       ##|##
     307             :     //   |   ##/C_i ##         |
     308             :     //   |    |######          |
     309             :     //   |   | #####           |
     310             :     //   +->|                  |
     311             :     //     |                   |
     312             :     //   ##|##                 |
     313             :     //  ###|###                |
     314             :     // ####|####               |
     315             :     // ####+-------------------+
     316             :     // ## C_n ##
     317             :     //  #######
     318             :     //   #####
     319             :     PERFECT,
     320             : 
     321             :     // * top-width == left-width
     322             :     // * 0.5 < radius.width / radius.height < 2.0
     323             :     // * top-width < min(radius.width, radius.height) * 2
     324             :     //
     325             :     // All circles has same radii and are on single elliptic arc.
     326             :     // Overlap is known.
     327             :     //
     328             :     // Split the elliptic arc into 2n segments, each segment's length is
     329             :     // top-width * (1 - overlap).  Place each circle's center point C_i on each
     330             :     // end of the segment, each circle's radius r_i is top-width / 2
     331             :     //
     332             :     //                            #####
     333             :     //                           #######
     334             :     //             #####        #########
     335             :     //            #######   ____----+####
     336             :     // elliptic  ######__---    ## C_0 ##
     337             :     // arc       ##__+-###       ###|###
     338             :     //   |      / # C_i #         ##|##
     339             :     //   +--> /    #####            |
     340             :     //       |                      |
     341             :     //   ###|#                      |
     342             :     //  ###|###                     |
     343             :     // ####|####                    |
     344             :     // ####+------------------------+
     345             :     // ## C_n ##
     346             :     //  #######
     347             :     //   #####
     348             :     SINGLE_CURVE_AND_RADIUS,
     349             : 
     350             :     // * top-width != left-width
     351             :     // * 0 < min(top-width, left-width)
     352             :     // * 0.5 < radius.width / radius.height < 2.0
     353             :     // * max(top-width, left-width) < min(radius.width, radius.height) * 2
     354             :     //
     355             :     // All circles are on single elliptic arc.
     356             :     // Overlap is unknown.
     357             :     //
     358             :     // Place each circle's center point C_i on elliptic arc, each circle's
     359             :     // radius r_i is the distance between the center point and the inner curve.
     360             :     // The arc segment's length between C_i and C_{i-1} is
     361             :     // (r_i + r_{i-1}) * (1 - overlap).
     362             :     //
     363             :     //  outer curve
     364             :     //           /
     365             :     //          /
     366             :     //         /         / center curve
     367             :     //        / ####### /
     368             :     //       /##       /#
     369             :     //      +#        /  #
     370             :     //     /#        /    #
     371             :     //    / #   C_i /     #
     372             :     //   /  #      +      #  /
     373             :     //  /   #     /  \    # / inner curve
     374             :     //      #    /     \  #/
     375             :     //       #  /   r_i  \+
     376             :     //        #/       ##/
     377             :     //        / ####### /
     378             :     //                 /
     379             :     SINGLE_CURVE,
     380             : 
     381             :     // Other cases.
     382             :     // Circles are not on single elliptic arc.
     383             :     // Overlap are unknown.
     384             :     //
     385             :     // Place tangent point innerTangent on the inner curve and find circle's
     386             :     // center point C_i and radius r_i where the circle is also tangent to the
     387             :     // outer curve.
     388             :     // Distance between C_i and C_{i-1} is (r_i + r_{i-1}) * (1 - overlap).
     389             :     //
     390             :     //  outer curve
     391             :     //           /
     392             :     //          /
     393             :     //         /
     394             :     //        / #######
     395             :     //       /##       ##
     396             :     //      +#           #
     397             :     //     /# \           #
     398             :     //    / #    \        #
     399             :     //   /  #      +      #  /
     400             :     //  /   #   C_i  \    # / inner curve
     401             :     //      #          \  #/
     402             :     //       #      r_i  \+
     403             :     //        ##       ##/ innerTangent
     404             :     //          ####### /
     405             :     //                 /
     406             :     OTHER
     407             :   } mType;
     408             : 
     409             :   size_t mI;
     410             :   size_t mCount;
     411             : 
     412             :   // Determine mType from parameters.
     413             :   void DetermineType(Float aBorderRadiusX, Float aBorderRadiusY);
     414             : 
     415             :   // Reset calculation.
     416             :   void Reset(void);
     417             : 
     418             :   // Find radius for the given tangent point on the inner curve such that the
     419             :   // circle is also tangent to the outer curve.
     420             :   void FindPointAndRadius(Point& C, Float& r, const Point& innerTangent,
     421             :                           const Point& normal, Float t);
     422             : 
     423             :   // Find next dot.
     424             :   Float FindNext(Float overlap);
     425             : 
     426             :   // Find mBestOverlap for parameters.
     427             :   void FindBestOverlap(Float aMinR,
     428             :                        Float aMinBorderRadius, Float aMaxBorderRadius);
     429             : 
     430             :   // Fill corner with dots with given overlap, and return the number of dots
     431             :   // and last two dots's overlap.
     432             :   bool GetCountAndLastOverlap(Float aOverlap,
     433             :                               size_t* aCount, Float* aActualOverlap);
     434             : };
     435             : 
     436             : } // namespace mozilla
     437             : 
     438             : #endif /* mozilla_DottedCornerFinder_h_ */

Generated by: LCOV version 1.13