| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #ifndef SkPath_DEFINED | 10 #ifndef SkPath_DEFINED |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 /** Returns true if the filltype is one of the Inverse variants */ | 86 /** Returns true if the filltype is one of the Inverse variants */ |
| 87 bool isInverseFillType() const { return IsInverseFillType((FillType)fFillTyp
e); } | 87 bool isInverseFillType() const { return IsInverseFillType((FillType)fFillTyp
e); } |
| 88 | 88 |
| 89 /** | 89 /** |
| 90 * Toggle between inverse and normal filltypes. This reverse the return | 90 * Toggle between inverse and normal filltypes. This reverse the return |
| 91 * value of isInverseFillType() | 91 * value of isInverseFillType() |
| 92 */ | 92 */ |
| 93 void toggleInverseFillType() { | 93 void toggleInverseFillType() { |
| 94 fFillType ^= 2; | 94 fFillType ^= 2; |
| 95 GEN_ID_INC; | 95 GEN_ID_INC; |
| 96 } | 96 } |
| 97 | 97 |
| 98 enum Convexity { | 98 enum Convexity { |
| 99 kUnknown_Convexity, | 99 kUnknown_Convexity, |
| 100 kConvex_Convexity, | 100 kConvex_Convexity, |
| 101 kConcave_Convexity | 101 kConcave_Convexity |
| 102 }; | 102 }; |
| 103 | 103 |
| 104 /** | 104 /** |
| 105 * Return the path's convexity, as stored in the path. If it is currently u
nknown, | 105 * Return the path's convexity, as stored in the path. If it is currently u
nknown, |
| 106 * then this function will attempt to compute the convexity (and cache the
result). | 106 * then this function will attempt to compute the convexity (and cache the
result). |
| 107 */ | 107 */ |
| 108 Convexity getConvexity() const { | 108 Convexity getConvexity() const { |
| 109 if (kUnknown_Convexity != fConvexity) { | 109 return static_cast<Convexity>(fPathRef->getConvexity()); |
| 110 return static_cast<Convexity>(fConvexity); | |
| 111 } else { | |
| 112 return this->internalGetConvexity(); | |
| 113 } | |
| 114 } | 110 } |
| 115 | 111 |
| 116 /** | 112 /** |
| 117 * Return the currently cached value for convexity, even if that is set to | 113 * Return the currently cached value for convexity, even if that is set to |
| 118 * kUnknown_Convexity. Note: getConvexity() will automatically call | 114 * kUnknown_Convexity. Note: getConvexity() will automatically call |
| 119 * ComputeConvexity and cache its return value if the current setting is | 115 * ComputeConvexity and cache its return value if the current setting is |
| 120 * kUnknown. | 116 * kUnknown. |
| 121 */ | 117 */ |
| 122 Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; } | 118 Convexity getConvexityOrUnknown() const { |
| 119 return static_cast<Convexity>(fPathRef->getConvexityOrUnknown()); |
| 120 } |
| 123 | 121 |
| 124 /** | 122 /** |
| 125 * Store a convexity setting in the path. There is no automatic check to | 123 * Store a convexity setting in the path. There is no automatic check to |
| 126 * see if this value actually agrees with the return value that would be | 124 * see if this value actually agrees with the return value that would be |
| 127 * computed by getConvexity(). | 125 * computed by getConvexity(). |
| 128 * | 126 * |
| 129 * Note: even if this is set to a "known" value, if the path is later | 127 * Note: even if this is set to a "known" value, if the path is later |
| 130 * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be | 128 * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be |
| 131 * reset to kUnknown_Convexity. | 129 * reset to kUnknown_Convexity. |
| 132 */ | 130 */ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 155 /** Returns true if the path is an oval. | 153 /** Returns true if the path is an oval. |
| 156 * | 154 * |
| 157 * @param rect returns the bounding rect of this oval. It's a circle | 155 * @param rect returns the bounding rect of this oval. It's a circle |
| 158 * if the height and width are the same. | 156 * if the height and width are the same. |
| 159 * | 157 * |
| 160 * @return true if this path is an oval. | 158 * @return true if this path is an oval. |
| 161 * Tracking whether a path is an oval is considered an | 159 * Tracking whether a path is an oval is considered an |
| 162 * optimization for performance and so some paths that are in | 160 * optimization for performance and so some paths that are in |
| 163 * fact ovals can report false. | 161 * fact ovals can report false. |
| 164 */ | 162 */ |
| 165 bool isOval(SkRect* rect) const; | 163 bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); } |
| 166 | 164 |
| 167 /** Clear any lines and curves from the path, making it empty. This frees up | 165 /** Clear any lines and curves from the path, making it empty. This frees up |
| 168 internal storage associated with those segments. | 166 internal storage associated with those segments. |
| 169 On Android, does not change fSourcePath. | 167 On Android, does not change fSourcePath. |
| 170 */ | 168 */ |
| 171 void reset(); | 169 void reset(); |
| 172 | 170 |
| 173 /** Similar to reset(), in that all lines and curves are removed from the | 171 /** Similar to reset(), in that all lines and curves are removed from the |
| 174 path. However, any internal storage for those lines/curves is retained, | 172 path. However, any internal storage for those lines/curves is retained, |
| 175 making reuse of the path potentially faster. | 173 making reuse of the path potentially faster. |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 this contour, to specify the 1st control point of a cubic curve | 448 this contour, to specify the 1st control point of a cubic curve |
| 451 @param dx2 The amount to add to the x-coordinate of the last point on | 449 @param dx2 The amount to add to the x-coordinate of the last point on |
| 452 this contour, to specify the 2nd control point of a cubic curve | 450 this contour, to specify the 2nd control point of a cubic curve |
| 453 @param dy2 The amount to add to the y-coordinate of the last point on | 451 @param dy2 The amount to add to the y-coordinate of the last point on |
| 454 this contour, to specify the 2nd control point of a cubic curve | 452 this contour, to specify the 2nd control point of a cubic curve |
| 455 @param dx3 The amount to add to the x-coordinate of the last point on | 453 @param dx3 The amount to add to the x-coordinate of the last point on |
| 456 this contour, to specify the end point of a cubic curve | 454 this contour, to specify the end point of a cubic curve |
| 457 @param dy3 The amount to add to the y-coordinate of the last point on | 455 @param dy3 The amount to add to the y-coordinate of the last point on |
| 458 this contour, to specify the end point of a cubic curve | 456 this contour, to specify the end point of a cubic curve |
| 459 */ | 457 */ |
| 460 void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, | 458 void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, |
| 461 SkScalar x3, SkScalar y3); | 459 SkScalar x3, SkScalar y3); |
| 462 | 460 |
| 463 /** Append the specified arc to the path as a new contour. If the start of | 461 /** Append the specified arc to the path as a new contour. If the start of |
| 464 the path is different from the path's current last point, then an | 462 the path is different from the path's current last point, then an |
| 465 automatic lineTo() is added to connect the current contour to the start | 463 automatic lineTo() is added to connect the current contour to the start |
| 466 of the arc. However, if the path is empty, then we call moveTo() with | 464 of the arc. However, if the path is empty, then we call moveTo() with |
| 467 the first point of the arc. The sweep angle is treated mod 360. | 465 the first point of the arc. The sweep angle is treated mod 360. |
| 468 | 466 |
| 469 @param oval The bounding oval defining the shape and size of the arc | 467 @param oval The bounding oval defining the shape and size of the arc |
| 470 @param startAngle Starting angle (in degrees) where the arc begins | 468 @param startAngle Starting angle (in degrees) where the arc begins |
| 471 @param sweepAngle Sweep angle (in degrees) measured clockwise. This is | 469 @param sweepAngle Sweep angle (in degrees) measured clockwise. This is |
| 472 treated mod 360. | 470 treated mod 360. |
| 473 @param forceMoveTo If true, always begin a new contour with the arc | 471 @param forceMoveTo If true, always begin a new contour with the arc |
| 474 */ | 472 */ |
| 475 void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, | 473 void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, |
| 476 bool forceMoveTo); | 474 bool forceMoveTo); |
| 477 | 475 |
| 478 /** Append a line and arc to the current path. This is the same as the | 476 /** Append a line and arc to the current path. This is the same as the |
| 479 PostScript call "arct". | 477 PostScript call "arct". |
| 480 */ | 478 */ |
| 481 void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, | 479 void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, |
| 482 SkScalar radius); | 480 SkScalar radius); |
| 483 | 481 |
| 484 /** Append a line and arc to the current path. This is the same as the | 482 /** Append a line and arc to the current path. This is the same as the |
| 485 PostScript call "arct". | 483 PostScript call "arct". |
| 486 */ | 484 */ |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 return (FillType)(fill & 1); | 543 return (FillType)(fill & 1); |
| 546 } | 544 } |
| 547 | 545 |
| 548 /** | 546 /** |
| 549 * Tries to quickly compute the direction of the first non-degenerate | 547 * Tries to quickly compute the direction of the first non-degenerate |
| 550 * contour. If it can be computed, return true and set dir to that | 548 * contour. If it can be computed, return true and set dir to that |
| 551 * direction. If it cannot be (quickly) determined, return false and ignore | 549 * direction. If it cannot be (quickly) determined, return false and ignore |
| 552 * the dir parameter. If the direction was determined, it is cached to make | 550 * the dir parameter. If the direction was determined, it is cached to make |
| 553 * subsequent calls return quickly. | 551 * subsequent calls return quickly. |
| 554 */ | 552 */ |
| 555 bool cheapComputeDirection(Direction* dir) const; | 553 bool cheapComputeDirection(Direction* dir) const { |
| 554 bool result; |
| 555 if (NULL != dir) { |
| 556 int intDir = *dir; |
| 557 result = fPathRef->cheapComputeDirection(&intDir); |
| 558 *dir = static_cast<Direction>(intDir); |
| 559 } else { |
| 560 result = fPathRef->cheapComputeDirection(NULL); |
| 561 } |
| 562 return result; |
| 563 } |
| 556 | 564 |
| 557 /** | 565 /** |
| 558 * Returns true if the path's direction can be computed via | 566 * Returns true if the path's direction can be computed via |
| 559 * cheapComputDirection() and if that computed direction matches the | 567 * cheapComputDirection() and if that computed direction matches the |
| 560 * specified direction. If dir is kUnknown, returns true if the direction | 568 * specified direction. If dir is kUnknown, returns true if the direction |
| 561 * cannot be computed. | 569 * cannot be computed. |
| 562 */ | 570 */ |
| 563 bool cheapIsDirection(Direction dir) const { | 571 bool cheapIsDirection(Direction dir) const { |
| 564 Direction computedDir = kUnknown_Direction; | 572 Direction computedDir = kUnknown_Direction; |
| 565 (void)this->cheapComputeDirection(&computedDir); | 573 (void)this->cheapComputeDirection(&computedDir); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 kQuad_SegmentMask = 1 << 1, | 790 kQuad_SegmentMask = 1 << 1, |
| 783 kConic_SegmentMask = 1 << 2, | 791 kConic_SegmentMask = 1 << 2, |
| 784 kCubic_SegmentMask = 1 << 3, | 792 kCubic_SegmentMask = 1 << 3, |
| 785 }; | 793 }; |
| 786 | 794 |
| 787 /** | 795 /** |
| 788 * Returns a mask, where each bit corresponding to a SegmentMask is | 796 * Returns a mask, where each bit corresponding to a SegmentMask is |
| 789 * set if the path contains 1 or more segments of that type. | 797 * set if the path contains 1 or more segments of that type. |
| 790 * Returns 0 for an empty path (no segments). | 798 * Returns 0 for an empty path (no segments). |
| 791 */ | 799 */ |
| 792 uint32_t getSegmentMasks() const { return fSegmentMask; } | 800 uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); } |
| 793 | 801 |
| 794 enum Verb { | 802 enum Verb { |
| 795 kMove_Verb, //!< iter.next returns 1 point | 803 kMove_Verb, //!< iter.next returns 1 point |
| 796 kLine_Verb, //!< iter.next returns 2 points | 804 kLine_Verb, //!< iter.next returns 2 points |
| 797 kQuad_Verb, //!< iter.next returns 3 points | 805 kQuad_Verb, //!< iter.next returns 3 points |
| 798 kConic_Verb, //!< iter.next returns 3 points + iter.conicWeight() | 806 kConic_Verb, //!< iter.next returns 3 points + iter.conicWeight() |
| 799 kCubic_Verb, //!< iter.next returns 4 points | 807 kCubic_Verb, //!< iter.next returns 4 points |
| 800 kClose_Verb, //!< iter.next returns 1 point (contour's moveTo pt) | 808 kClose_Verb, //!< iter.next returns 1 point (contour's moveTo pt) |
| 801 kDone_Verb, //!< iter.next returns 0 points | 809 kDone_Verb, //!< iter.next returns 0 points |
| 802 }; | 810 }; |
| 803 | 811 |
| 804 /** Iterate through all of the segments (lines, quadratics, cubics) of | 812 /** Iterate through all of the segments (lines, quadratics, cubics) of |
| 805 each contours in a path. | 813 each contours in a path. |
| 806 | 814 |
| 807 The iterator cleans up the segments along the way, removing degenerate | 815 The iterator cleans up the segments along the way, removing degenerate |
| 808 segments and adding close verbs where necessary. When the forceClose | 816 segments and adding close verbs where necessary. When the forceClose |
| 809 argument is provided, each contour (as defined by a new starting | 817 argument is provided, each contour (as defined by a new starting |
| 810 move command) will be completed with a close verb regardless of the | 818 move command) will be completed with a close verb regardless of the |
| 811 contour's contents. | 819 contour's contents. |
| 812 */ | 820 */ |
| 813 class SK_API Iter { | 821 class SK_API Iter { |
| 814 public: | 822 public: |
| 815 Iter(); | 823 Iter(); |
| 816 Iter(const SkPath&, bool forceClose); | 824 Iter(const SkPath&, bool forceClose); |
| 825 Iter(const SkPathRef*, bool forceClose); |
| 817 | 826 |
| 818 void setPath(const SkPath&, bool forceClose); | 827 void setPath(const SkPath&, bool forceClose); |
| 828 void setPathRef(const SkPathRef*, bool forceClose); |
| 819 | 829 |
| 820 /** Return the next verb in this iteration of the path. When all | 830 /** Return the next verb in this iteration of the path. When all |
| 821 segments have been visited, return kDone_Verb. | 831 segments have been visited, return kDone_Verb. |
| 822 | 832 |
| 823 @param pts The points representing the current verb and/or segment | 833 @param pts The points representing the current verb and/or segment |
| 824 @param doConsumeDegerates If true, first scan for segments that are | 834 @param doConsumeDegerates If true, first scan for segments that are |
| 825 deemed degenerate (too short) and skip those. | 835 deemed degenerate (too short) and skip those. |
| 826 @return The verb for the current segment | 836 @return The verb for the current segment |
| 827 */ | 837 */ |
| 828 Verb next(SkPoint pts[4], bool doConsumeDegerates = true) { | 838 Verb next(SkPoint pts[4], bool doConsumeDegerates = true) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 const SkPath* getSourcePath() const; | 935 const SkPath* getSourcePath() const; |
| 926 void setSourcePath(const SkPath* path); | 936 void setSourcePath(const SkPath* path); |
| 927 #endif | 937 #endif |
| 928 | 938 |
| 929 SkDEBUGCODE(void validate() const;) | 939 SkDEBUGCODE(void validate() const;) |
| 930 | 940 |
| 931 private: | 941 private: |
| 932 enum SerializationOffsets { | 942 enum SerializationOffsets { |
| 933 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 943 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O |
| 934 kNewFormat_SerializationShift = 28, // requires 1 bit | 944 kNewFormat_SerializationShift = 28, // requires 1 bit |
| 945 kOldDirection_SerializationShift = 26, // requires 2 bits |
| 946 kOldIsFinite_SerializationShift = 25, // 1 bit |
| 947 kOldIsOval_SerializationShift = 24, // requires 1 bit |
| 948 kOldConvexity_SerializationShift = 16, // requires 8 bits |
| 949 #endif |
| 950 // TODO: make this shift be 0 |
| 951 kFillType_SerializationShift = 8, // requires 8 bits |
| 952 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O |
| 953 kOldSegmentMask_SerializationShift = 0 // requires 4 bits |
| 935 #endif | 954 #endif |
| 936 kDirection_SerializationShift = 26, // requires 2 bits | |
| 937 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | |
| 938 // rename to kUnused_SerializationShift | |
| 939 kOldIsFinite_SerializationShift = 25, // 1 bit | |
| 940 #endif | |
| 941 kIsOval_SerializationShift = 24, // requires 1 bit | |
| 942 kConvexity_SerializationShift = 16, // requires 8 bits | |
| 943 kFillType_SerializationShift = 8, // requires 8 bits | |
| 944 kSegmentMask_SerializationShift = 0 // requires 4 bits | |
| 945 }; | 955 }; |
| 946 | 956 |
| 947 SkAutoTUnref<SkPathRef> fPathRef; | 957 SkAutoTUnref<SkPathRef> fPathRef; |
| 948 | 958 |
| 949 int fLastMoveToIndex; | |
| 950 uint8_t fFillType; | 959 uint8_t fFillType; |
| 951 uint8_t fSegmentMask; | |
| 952 mutable uint8_t fConvexity; | |
| 953 mutable uint8_t fDirection; | |
| 954 mutable SkBool8 fIsOval; | |
| 955 #ifdef SK_BUILD_FOR_ANDROID | 960 #ifdef SK_BUILD_FOR_ANDROID |
| 956 uint32_t fGenerationID; | 961 uint32_t fGenerationID; |
| 957 const SkPath* fSourcePath; | 962 const SkPath* fSourcePath; |
| 958 #endif | 963 #endif |
| 959 | 964 |
| 960 /** Resets all fields other than fPathRef to their initial 'empty' values. | 965 /** Resets all fields other than fPathRef to their initial 'empty' values. |
| 961 * Assumes the caller has already emptied fPathRef. | 966 * Assumes the caller has already emptied fPathRef. |
| 962 * On Android increments fGenerationID without reseting it. | 967 * On Android increments fGenerationID without reseting it. |
| 963 */ | 968 */ |
| 964 void resetFields(); | 969 void resetFields(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 977 automatically set to (0,0). | 982 automatically set to (0,0). |
| 978 */ | 983 */ |
| 979 void pathTo(const SkPath& path); | 984 void pathTo(const SkPath& path); |
| 980 | 985 |
| 981 /* Append, in reverse order, the first contour of path, ignoring path's | 986 /* Append, in reverse order, the first contour of path, ignoring path's |
| 982 last point. If no moveTo() call has been made for this contour, the | 987 last point. If no moveTo() call has been made for this contour, the |
| 983 first point is automatically set to (0,0). | 988 first point is automatically set to (0,0). |
| 984 */ | 989 */ |
| 985 void reversePathTo(const SkPath&); | 990 void reversePathTo(const SkPath&); |
| 986 | 991 |
| 987 // called before we add points for lineTo, quadTo, cubicTo, checking to see | |
| 988 // if we need to inject a leading moveTo first | |
| 989 // | |
| 990 // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0) | |
| 991 // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previou
s moveTo) | |
| 992 // | |
| 993 inline void injectMoveToIfNeeded(); | |
| 994 | |
| 995 inline bool hasOnlyMoveTos() const; | 992 inline bool hasOnlyMoveTos() const; |
| 996 | 993 |
| 997 Convexity internalGetConvexity() const; | |
| 998 | |
| 999 bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts, | 994 bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts, |
| 1000 bool* isClosed, Direction* direction) const; | 995 bool* isClosed, Direction* direction) const; |
| 1001 | 996 |
| 1002 /** Returns if the path can return a bound at no cost (true) or will have to | 997 /** Returns if the path can return a bound at no cost (true) or will have to |
| 1003 perform some computation (false). | 998 perform some computation (false). |
| 1004 */ | 999 */ |
| 1005 bool hasComputedBounds() const { | 1000 bool hasComputedBounds() const { |
| 1006 SkDEBUGCODE(this->validate();) | 1001 SkDEBUGCODE(this->validate();) |
| 1007 return fPathRef->hasComputedBounds(); | 1002 return fPathRef->hasComputedBounds(); |
| 1008 } | 1003 } |
| 1009 | 1004 |
| 1010 | |
| 1011 // 'rect' needs to be sorted | |
| 1012 void setBounds(const SkRect& rect) { | |
| 1013 fPathRef->setBounds(rect); | |
| 1014 } | |
| 1015 | |
| 1016 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 1005 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O |
| 1017 friend class SkPathRef; // just for SerializationOffsets | 1006 friend class SkPathRef; // just for SerializationOffsets |
| 1018 #endif | 1007 #endif |
| 1019 friend class SkAutoPathBoundsUpdate; | 1008 friend class SkAutoPathBoundsUpdate; |
| 1020 friend class SkAutoDisableOvalCheck; | |
| 1021 friend class SkAutoDisableDirectionCheck; | |
| 1022 friend class SkBench_AddPathTest; // perf test pathTo/reversePathTo | 1009 friend class SkBench_AddPathTest; // perf test pathTo/reversePathTo |
| 1023 }; | 1010 }; |
| 1024 | 1011 |
| 1025 #endif | 1012 #endif |
| OLD | NEW |