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 |