Flutter Engine
The Flutter Engine
Classes | Macros | Typedefs | Functions | Variables
PathTest.cpp File Reference
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkData.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkRegion.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkStrokeRec.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/core/SkVertices.h"
#include "include/pathops/SkPathOps.h"
#include "include/private/SkIDChangeListener.h"
#include "include/private/SkPathRef.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTo.h"
#include "include/utils/SkNullCanvas.h"
#include "include/utils/SkParse.h"
#include "include/utils/SkParsePath.h"
#include "src/base/SkAutoMalloc.h"
#include "src/base/SkFloatBits.h"
#include "src/base/SkRandom.h"
#include "src/core/SkGeometry.h"
#include "src/core/SkPathEnums.h"
#include "src/core/SkPathPriv.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "tests/Test.h"
#include "tools/fonts/FontToolUtils.h"
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <memory>
#include <vector>

Go to the source code of this file.

Classes

struct  SegmentInfo
 
class  PathRefTest_Private
 
class  PathTest_Private
 
struct  Xforms
 

Macros

#define SUPPRESS_VISIBILITY_WARNING   __attribute__((visibility("hidden")))
 
#define CONIC_PERSPECTIVE_BUG_FIXED   0
 
#define kCurveSegmentMask   (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)
 

Typedefs

typedef void(* PathProc) (SkPath *)
 

Functions

static void set_radii (SkVector radii[4], int index, float rad)
 
static void test_add_rrect (skiatest::Reporter *reporter, const SkRect &bounds, const SkVector radii[4])
 
static void test_skbug_3469 (skiatest::Reporter *reporter)
 
static void test_skbug_3239 (skiatest::Reporter *reporter)
 
static void make_path_crbug364224 (SkPath *path)
 
static void make_path_crbug364224_simplified (SkPath *path)
 
static void test_sect_with_horizontal_needs_pinning ()
 
static void test_iterative_intersect_line ()
 
static void test_path_crbug364224 ()
 
static void test_draw_AA_path (int width, int height, const SkPath &path)
 
static void test_fuzz_crbug_638223 ()
 
static void test_fuzz_crbug_643933 ()
 
static void test_fuzz_crbug_647922 ()
 
static void test_fuzz_crbug_662780 ()
 
static void test_mask_overflow ()
 
static void test_fuzz_crbug_668907 ()
 
static void make_path_crbugskia2820 (SkPath *path, skiatest::Reporter *reporter)
 
static void test_path_crbugskia2820 (skiatest::Reporter *reporter)
 
static void test_path_crbugskia5995 ()
 
static void make_path0 (SkPath *path)
 
static void make_path1 (SkPath *path)
 
static void test_path_to_region (skiatest::Reporter *reporter)
 
static void test_path_close_issue1474 (skiatest::Reporter *reporter)
 
static void test_gen_id (skiatest::Reporter *reporter)
 
static void test_bad_cubic_crbug234190 ()
 
static void test_bad_cubic_crbug229478 ()
 
static void build_path_170666 (SkPath &path)
 
static void build_path_simple_170666 (SkPath &path)
 
static void test_crbug_170666 ()
 
static void test_tiny_path_convexity (skiatest::Reporter *reporter, const char *pathBug, SkScalar tx, SkScalar ty, SkScalar scale)
 
static void test_crbug_493450 (skiatest::Reporter *reporter)
 
static void test_crbug_495894 (skiatest::Reporter *reporter)
 
static void test_crbug_613918 ()
 
static void test_addrect (skiatest::Reporter *reporter)
 
static void test_addrect_isfinite (skiatest::Reporter *reporter)
 
static void build_big_path (SkPath *path, bool reducedCase)
 
static void test_clipped_cubic ()
 
static void dump_if_ne (skiatest::Reporter *reporter, const SkRect &expected, const SkRect &bounds)
 
static void test_bounds_crbug_513799 (skiatest::Reporter *reporter)
 
static void test_fuzz_crbug_627414 (skiatest::Reporter *reporter)
 
static void test_tricky_cubic ()
 
static void test_isfinite_after_transform (skiatest::Reporter *reporter)
 
static void add_corner_arc (SkPath *path, const SkRect &rect, SkScalar xIn, SkScalar yIn, int startAngle)
 
static void make_arb_round_rect (SkPath *path, const SkRect &r, SkScalar xCorner, SkScalar yCorner)
 
static void test_arb_round_rect_is_convex (skiatest::Reporter *reporter)
 
static void test_arb_zero_rad_round_rect_is_rect (skiatest::Reporter *reporter)
 
static void test_rect_isfinite (skiatest::Reporter *reporter)
 
static void test_path_isfinite (skiatest::Reporter *reporter)
 
static void test_isfinite (skiatest::Reporter *reporter)
 
static void test_islastcontourclosed (skiatest::Reporter *reporter)
 
static void test_poly (skiatest::Reporter *reporter, const SkPath &path, const SkPoint srcPts[], bool expectClose)
 
static void test_addPoly (skiatest::Reporter *reporter)
 
static void test_strokerec (skiatest::Reporter *reporter)
 
static void check_direction (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection expected)
 
static void test_direction (skiatest::Reporter *reporter)
 
static void add_rect (SkPath *path, const SkRect &r)
 
static void test_bounds (skiatest::Reporter *reporter)
 
static void stroke_cubic (const SkPoint pts[4])
 
static void stroke_tiny_cubic ()
 
static void check_close (skiatest::Reporter *reporter, const SkPath &path)
 
static void test_close (skiatest::Reporter *reporter)
 
static void check_convexity (skiatest::Reporter *reporter, const SkPath &path, bool expectedConvexity)
 
static void test_path_crbug389050 (skiatest::Reporter *reporter)
 
static void test_convexity2 (skiatest::Reporter *reporter)
 
static void test_convexity_doubleback (skiatest::Reporter *reporter)
 
static void check_convex_bounds (skiatest::Reporter *reporter, const SkPath &p, const SkRect &bounds)
 
static void setFromString (SkPath *path, const char str[])
 
static void test_convexity (skiatest::Reporter *reporter)
 
static void test_isLine (skiatest::Reporter *reporter)
 
static void test_conservativelyContains (skiatest::Reporter *reporter)
 
static void test_isRect_open_close (skiatest::Reporter *reporter)
 
static void test_isRect (skiatest::Reporter *reporter)
 
static void check_simple_rect (skiatest::Reporter *reporter, const SkPath &path, bool isClosed, const SkRect &rect, SkPathDirection dir, unsigned start)
 
static void test_is_closed_rect (skiatest::Reporter *reporter)
 
static void test_isArc (skiatest::Reporter *reporter)
 
static void test_isNestedFillRects (skiatest::Reporter *reporter)
 
static void write_and_read_back (skiatest::Reporter *reporter, const SkPath &p)
 
static void test_flattening (skiatest::Reporter *reporter)
 
static void test_transform (skiatest::Reporter *reporter)
 
static void test_zero_length_paths (skiatest::Reporter *reporter)
 
static void test_segment_masks (skiatest::Reporter *reporter)
 
static void test_iter (skiatest::Reporter *reporter)
 
static void test_range_iter (skiatest::Reporter *reporter)
 
static void check_for_circle (skiatest::Reporter *reporter, const SkPath &path, bool expectedCircle, SkPathFirstDirection expectedDir)
 
static void test_circle_skew (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
 
static void test_circle_translate (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
 
static void test_circle_rotate (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
 
static void test_circle_mirror_x (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
 
static void test_circle_mirror_y (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
 
static void test_circle_mirror_xy (skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
 
static void test_circle_with_direction (skiatest::Reporter *reporter, SkPathDirection inDir)
 
static void test_circle_with_add_paths (skiatest::Reporter *reporter)
 
static void test_circle (skiatest::Reporter *reporter)
 
static void test_oval (skiatest::Reporter *reporter)
 
static void test_open_oval (skiatest::Reporter *reporter)
 
static void test_empty (skiatest::Reporter *reporter, const SkPath &p)
 
static void test_rrect_is_convex (skiatest::Reporter *reporter, SkPath *path, SkPathDirection dir)
 
static void test_rrect_convexity_is_unknown (skiatest::Reporter *reporter, SkPath *path, SkPathDirection dir)
 
static void test_rrect (skiatest::Reporter *reporter)
 
static void test_arc (skiatest::Reporter *reporter)
 
static SkScalar oval_start_index_to_angle (unsigned start)
 
static SkScalar canonical_start_angle (float angle)
 
static void check_oval_arc (skiatest::Reporter *reporter, SkScalar start, SkScalar sweep, const SkPath &path)
 
static void test_arc_ovals (skiatest::Reporter *reporter)
 
static void check_move (skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x0, SkScalar y0)
 
static void check_line (skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x1, SkScalar y1)
 
static void check_quad (skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
 
static void check_close (skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter)
 
static void check_done (skiatest::Reporter *reporter, SkPath *p, SkPathPriv::RangeIter *iter)
 
static void check_done_and_reset (skiatest::Reporter *reporter, SkPath *p, SkPathPriv::RangeIter *iter)
 
static void check_path_is_move_and_reset (skiatest::Reporter *reporter, SkPath *p, SkScalar x0, SkScalar y0)
 
static void check_path_is_line_and_reset (skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1)
 
static void check_path_is_line (skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1)
 
static void check_path_is_line_pair_and_reset (skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
 
static void check_path_is_quad_and_reset (skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
 
static bool nearly_equal (const SkRect &a, const SkRect &b)
 
static void test_rMoveTo (skiatest::Reporter *reporter)
 
static void test_arcTo (skiatest::Reporter *reporter)
 
static void test_addPath (skiatest::Reporter *reporter)
 
static void test_addPathMode (skiatest::Reporter *reporter, bool explicitMoveTo, bool extend)
 
static void test_extendClosedPath (skiatest::Reporter *reporter)
 
static void test_addEmptyPath (skiatest::Reporter *reporter, SkPath::AddPathMode mode)
 
static void test_conicTo_special_case (skiatest::Reporter *reporter)
 
static void test_get_point (skiatest::Reporter *reporter)
 
static void test_contains (skiatest::Reporter *reporter)
 
static void test_operatorEqual (skiatest::Reporter *reporter)
 
static void compare_dump (skiatest::Reporter *reporter, const SkPath &path, bool dumpAsHex, const char *str)
 
static void test_dump (skiatest::Reporter *reporter)
 
static void test_crbug_629455 (skiatest::Reporter *reporter)
 
static void test_fuzz_crbug_662952 (skiatest::Reporter *reporter)
 
static void test_path_crbugskia6003 ()
 
static void test_fuzz_crbug_662730 (skiatest::Reporter *reporter)
 
static void test_skbug_6947 ()
 
static void test_skbug_7015 ()
 
static void test_skbug_7051 ()
 
static void test_skbug_7435 ()
 
static void test_interp (skiatest::Reporter *reporter)
 
 DEF_TEST (PathInterp, reporter)
 
 DEF_TEST (PathBigCubic, reporter)
 
 DEF_TEST (PathContains, reporter)
 
 DEF_TEST (Paths, reporter)
 
 DEF_TEST (conservatively_contains_rect, reporter)
 
static void rand_path (SkPath *path, SkRandom &rand, SkPath::Verb verb, int n)
 
 DEF_TEST (path_tight_bounds, reporter)
 
 DEF_TEST (skbug_6450, r)
 
 DEF_TEST (PathRefSerialization, reporter)
 
 DEF_TEST (NonFinitePathIteration, reporter)
 
 DEF_TEST (AndroidArc, reporter)
 
 DEF_TEST (HugeGeometry, reporter)
 
 DEF_TEST (ClipPath_nonfinite, reporter)
 
 DEF_TEST (Path_isRect, reporter)
 
 DEF_TEST (Path_self_add, reporter)
 
static void draw_triangle (SkCanvas *canvas, const SkPoint pts[])
 
 DEF_TEST (triangle_onehalf, reporter)
 
 DEF_TEST (triangle_big, reporter)
 
static void add_verbs (SkPath *path, int count)
 
 DEF_TEST (Path_shrinkToFit, reporter)
 
 DEF_TEST (Path_setLastPt, r)
 
 DEF_TEST (Path_increserve_handle_neg_crbug_883666, r)
 
static bool conditional_convex (const SkPath &path, bool is_convex)
 
template<typename ISA >
void survive (SkPath *path, const Xforms &x, bool isAxisAligned, skiatest::Reporter *reporter, ISA isa_proc)
 
 DEF_TEST (Path_survive_transform, r)
 
 DEF_TEST (path_last_move_to_index, r)
 
static void test_edger (skiatest::Reporter *r, const std::initializer_list< SkPath::Verb > &in, const std::initializer_list< SkPath::Verb > &expected)
 
static void assert_points (skiatest::Reporter *reporter, const SkPath &path, const std::initializer_list< SkPoint > &list)
 
static void test_addRect_and_trailing_lineTo (skiatest::Reporter *reporter)
 
static void test_addPath_and_injected_moveTo (skiatest::Reporter *reporter)
 
 DEF_TEST (pathedger, r)
 
 DEF_TEST (path_addpath_crbug_1153516, r)
 
 DEF_TEST (path_convexity_scale_way_down, r)
 
 DEF_TEST (path_moveto_addrect, r)
 
 DEF_TEST (path_moveto_twopass_convexity, r)
 
 DEF_TEST (path_walk_simple_edges_1154864, r)
 

Variables

const SkPathFirstDirection kDontCheckDir = static_cast<SkPathFirstDirection>(3)
 

Macro Definition Documentation

◆ CONIC_PERSPECTIVE_BUG_FIXED

#define CONIC_PERSPECTIVE_BUG_FIXED   0

◆ kCurveSegmentMask

#define kCurveSegmentMask   (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)

Definition at line 3045 of file PathTest.cpp.

◆ SUPPRESS_VISIBILITY_WARNING

#define SUPPRESS_VISIBILITY_WARNING   __attribute__((visibility("hidden")))

Definition at line 356 of file PathTest.cpp.

Typedef Documentation

◆ PathProc

typedef void(* PathProc) (SkPath *)

Definition at line 324 of file PathTest.cpp.

Function Documentation

◆ add_corner_arc()

static void add_corner_arc ( SkPath path,
const SkRect rect,
SkScalar  xIn,
SkScalar  yIn,
int  startAngle 
)
static

Definition at line 836 of file PathTest.cpp.

839{
840
841 SkScalar rx = std::min(rect.width(), xIn);
842 SkScalar ry = std::min(rect.height(), yIn);
843
844 SkRect arcRect;
845 arcRect.setLTRB(-rx, -ry, rx, ry);
846 switch (startAngle) {
847 case 0:
848 arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
849 break;
850 case 90:
851 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
852 break;
853 case 180:
854 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
855 break;
856 case 270:
857 arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
858 break;
859 default:
860 break;
861 }
862
863 path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
864}
#define SkIntToScalar(x)
Definition: SkScalar.h:57
float SkScalar
Definition: extension.cpp:12
static float min(float r, float g, float b)
Definition: hsl.cpp:48
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SkScalar startAngle
Definition: SkRecords.h:250
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
SkScalar fBottom
larger y-axis bounds
Definition: extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition: extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition: extension.cpp:16
void offset(float dx, float dy)
Definition: SkRect.h:1016
void setLTRB(float left, float top, float right, float bottom)
Definition: SkRect.h:865
SkScalar fTop
smaller y-axis bounds
Definition: extension.cpp:15

◆ add_rect()

static void add_rect ( SkPath path,
const SkRect r 
)
static

Definition at line 1200 of file PathTest.cpp.

1200 {
1201 path->moveTo(r.fLeft, r.fTop);
1202 path->lineTo(r.fRight, r.fTop);
1203 path->lineTo(r.fRight, r.fBottom);
1204 path->lineTo(r.fLeft, r.fBottom);
1205 path->close();
1206}

◆ add_verbs()

static void add_verbs ( SkPath path,
int  count 
)
static

Definition at line 5677 of file PathTest.cpp.

5677 {
5678 path->moveTo(0, 0);
5679 for (int i = 0; i < count; ++i) {
5680 switch (i & 3) {
5681 case 0: path->lineTo(10, 20); break;
5682 case 1: path->quadTo(5, 6, 7, 8); break;
5683 case 2: path->conicTo(1, 2, 3, 4, 0.5f); break;
5684 case 3: path->cubicTo(2, 4, 6, 8, 10, 12); break;
5685 }
5686 }
5687}
int count
Definition: FontMgrTest.cpp:50

◆ assert_points()

static void assert_points ( skiatest::Reporter reporter,
const SkPath path,
const std::initializer_list< SkPoint > &  list 
)
static

Definition at line 5902 of file PathTest.cpp.

5903 {
5904 const SkPoint* expected = list.begin();
5905 SkPath::RawIter iter(path);
5906 for (size_t i = 0;;) {
5907 SkPoint pts[4];
5908 switch (iter.next(pts)) {
5909 case SkPath::kDone_Verb:
5910 REPORTER_ASSERT(reporter, i == list.size());
5911 return;
5912 case SkPath::kMove_Verb:
5913 REPORTER_ASSERT(reporter, pts[0] == expected[i]);
5914 i++;
5915 break;
5916 case SkPath::kLine_Verb:
5917 REPORTER_ASSERT(reporter, pts[1] == expected[i]);
5918 i++;
5919 break;
5920 case SkPath::kClose_Verb: break;
5921 default: SkASSERT(false);
5922 }
5923 }
5924}
reporter
Definition: FontMgrTest.cpp:39
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
@ kClose_Verb
Definition: SkPath.h:1471
@ kMove_Verb
Definition: SkPath.h:1466
@ kDone_Verb
Definition: SkPath.h:1472
@ kLine_Verb
Definition: SkPath.h:1467

◆ build_big_path()

static void build_big_path ( SkPath path,
bool  reducedCase 
)
static

Definition at line 707 of file PathTest.cpp.

707 {
708 if (reducedCase) {
709 path->moveTo(577330, 1971.72f);
710 path->cubicTo(10.7082f, -116.596f, 262.057f, 45.6468f, 294.694f, 1.96237f);
711 } else {
712 path->moveTo(60.1631f, 7.70567f);
713 path->quadTo(60.1631f, 7.70567f, 0.99474f, 0.901199f);
714 path->lineTo(577379, 1977.77f);
715 path->quadTo(577364, 1979.57f, 577325, 1980.26f);
716 path->quadTo(577286, 1980.95f, 577245, 1980.13f);
717 path->quadTo(577205, 1979.3f, 577187, 1977.45f);
718 path->quadTo(577168, 1975.6f, 577183, 1973.8f);
719 path->quadTo(577198, 1972, 577238, 1971.31f);
720 path->quadTo(577277, 1970.62f, 577317, 1971.45f);
721 path->quadTo(577330, 1971.72f, 577341, 1972.11f);
722 path->cubicTo(10.7082f, -116.596f, 262.057f, 45.6468f, 294.694f, 1.96237f);
723 path->moveTo(306.718f, -32.912f);
724 path->cubicTo(30.531f, 10.0005f, 1502.47f, 13.2804f, 84.3088f, 9.99601f);
725 }
726}

◆ build_path_170666()

static void build_path_170666 ( SkPath path)
static

Definition at line 489 of file PathTest.cpp.

489 {
490 path.moveTo(17.9459f, 21.6344f);
491 path.lineTo(139.545f, -47.8105f);
492 path.lineTo(139.545f, -47.8105f);
493 path.lineTo(131.07f, -47.3888f);
494 path.lineTo(131.07f, -47.3888f);
495 path.lineTo(122.586f, -46.9532f);
496 path.lineTo(122.586f, -46.9532f);
497 path.lineTo(18076.6f, 31390.9f);
498 path.lineTo(18076.6f, 31390.9f);
499 path.lineTo(18085.1f, 31390.5f);
500 path.lineTo(18085.1f, 31390.5f);
501 path.lineTo(18076.6f, 31390.9f);
502 path.lineTo(18076.6f, 31390.9f);
503 path.lineTo(17955, 31460.3f);
504 path.lineTo(17955, 31460.3f);
505 path.lineTo(17963.5f, 31459.9f);
506 path.lineTo(17963.5f, 31459.9f);
507 path.lineTo(17971.9f, 31459.5f);
508 path.lineTo(17971.9f, 31459.5f);
509 path.lineTo(17.9551f, 21.6205f);
510 path.lineTo(17.9551f, 21.6205f);
511 path.lineTo(9.47091f, 22.0561f);
512 path.lineTo(9.47091f, 22.0561f);
513 path.lineTo(17.9459f, 21.6344f);
514 path.lineTo(17.9459f, 21.6344f);
515 path.close();path.moveTo(0.995934f, 22.4779f);
516 path.lineTo(0.986725f, 22.4918f);
517 path.lineTo(0.986725f, 22.4918f);
518 path.lineTo(17955, 31460.4f);
519 path.lineTo(17955, 31460.4f);
520 path.lineTo(17971.9f, 31459.5f);
521 path.lineTo(17971.9f, 31459.5f);
522 path.lineTo(18093.6f, 31390.1f);
523 path.lineTo(18093.6f, 31390.1f);
524 path.lineTo(18093.6f, 31390);
525 path.lineTo(18093.6f, 31390);
526 path.lineTo(139.555f, -47.8244f);
527 path.lineTo(139.555f, -47.8244f);
528 path.lineTo(122.595f, -46.9671f);
529 path.lineTo(122.595f, -46.9671f);
530 path.lineTo(0.995934f, 22.4779f);
531 path.lineTo(0.995934f, 22.4779f);
532 path.close();
533 path.moveTo(5.43941f, 25.5223f);
534 path.lineTo(798267, -28871.1f);
535 path.lineTo(798267, -28871.1f);
536 path.lineTo(3.12512e+06f, -113102);
537 path.lineTo(3.12512e+06f, -113102);
538 path.cubicTo(5.16324e+06f, -186882, 8.15247e+06f, -295092, 1.1957e+07f, -432813);
539 path.cubicTo(1.95659e+07f, -708257, 3.04359e+07f, -1.10175e+06f, 4.34798e+07f, -1.57394e+06f);
540 path.cubicTo(6.95677e+07f, -2.51831e+06f, 1.04352e+08f, -3.77748e+06f, 1.39135e+08f, -5.03666e+06f);
541 path.cubicTo(1.73919e+08f, -6.29583e+06f, 2.08703e+08f, -7.555e+06f, 2.34791e+08f, -8.49938e+06f);
542 path.cubicTo(2.47835e+08f, -8.97157e+06f, 2.58705e+08f, -9.36506e+06f, 2.66314e+08f, -9.6405e+06f);
543 path.cubicTo(2.70118e+08f, -9.77823e+06f, 2.73108e+08f, -9.88644e+06f, 2.75146e+08f, -9.96022e+06f);
544 path.cubicTo(2.76165e+08f, -9.99711e+06f, 2.76946e+08f, -1.00254e+07f, 2.77473e+08f, -1.00444e+07f);
545 path.lineTo(2.78271e+08f, -1.00733e+07f);
546 path.lineTo(2.78271e+08f, -1.00733e+07f);
547 path.cubicTo(2.78271e+08f, -1.00733e+07f, 2.08703e+08f, -7.555e+06f, 135.238f, 23.3517f);
548 path.cubicTo(131.191f, 23.4981f, 125.995f, 23.7976f, 123.631f, 24.0206f);
549 path.cubicTo(121.267f, 24.2436f, 122.631f, 24.3056f, 126.677f, 24.1591f);
550 path.cubicTo(2.08703e+08f, -7.555e+06f, 2.78271e+08f, -1.00733e+07f, 2.78271e+08f, -1.00733e+07f);
551 path.lineTo(2.77473e+08f, -1.00444e+07f);
552 path.lineTo(2.77473e+08f, -1.00444e+07f);
553 path.cubicTo(2.76946e+08f, -1.00254e+07f, 2.76165e+08f, -9.99711e+06f, 2.75146e+08f, -9.96022e+06f);
554 path.cubicTo(2.73108e+08f, -9.88644e+06f, 2.70118e+08f, -9.77823e+06f, 2.66314e+08f, -9.6405e+06f);
555 path.cubicTo(2.58705e+08f, -9.36506e+06f, 2.47835e+08f, -8.97157e+06f, 2.34791e+08f, -8.49938e+06f);
556 path.cubicTo(2.08703e+08f, -7.555e+06f, 1.73919e+08f, -6.29583e+06f, 1.39135e+08f, -5.03666e+06f);
557 path.cubicTo(1.04352e+08f, -3.77749e+06f, 6.95677e+07f, -2.51831e+06f, 4.34798e+07f, -1.57394e+06f);
558 path.cubicTo(3.04359e+07f, -1.10175e+06f, 1.95659e+07f, -708258, 1.1957e+07f, -432814);
559 path.cubicTo(8.15248e+06f, -295092, 5.16324e+06f, -186883, 3.12513e+06f, -113103);
560 path.lineTo(798284, -28872);
561 path.lineTo(798284, -28872);
562 path.lineTo(22.4044f, 24.6677f);
563 path.lineTo(22.4044f, 24.6677f);
564 path.cubicTo(22.5186f, 24.5432f, 18.8134f, 24.6337f, 14.1287f, 24.8697f);
565 path.cubicTo(9.4439f, 25.1057f, 5.55359f, 25.3978f, 5.43941f, 25.5223f);
566 path.close();
567}

◆ build_path_simple_170666()

static void build_path_simple_170666 ( SkPath path)
static

Definition at line 569 of file PathTest.cpp.

569 {
570 path.moveTo(126.677f, 24.1591f);
571 path.cubicTo(2.08703e+08f, -7.555e+06f, 2.78271e+08f, -1.00733e+07f, 2.78271e+08f, -1.00733e+07f);
572}

◆ canonical_start_angle()

static SkScalar canonical_start_angle ( float  angle)
inlinestatic

Definition at line 3974 of file PathTest.cpp.

3974 {
3975 while (angle < 0.f) {
3976 angle += 360.f;
3977 }
3978 while (angle >= 360.f) {
3979 angle -= 360.f;
3980 }
3981 return angle;
3982}

◆ check_close() [1/2]

static void check_close ( skiatest::Reporter reporter,
const SkPath path 
)
static

Definition at line 1261 of file PathTest.cpp.

1261 {
1262 for (int i = 0; i < 2; ++i) {
1263 SkPath::Iter iter(path, SkToBool(i));
1264 SkPoint mv;
1265 SkPoint pts[4];
1266 SkPath::Verb v;
1267 int nMT = 0;
1268 int nCL = 0;
1269 mv.set(0, 0);
1270 while (SkPath::kDone_Verb != (v = iter.next(pts))) {
1271 switch (v) {
1272 case SkPath::kMove_Verb:
1273 mv = pts[0];
1274 ++nMT;
1275 break;
1277 REPORTER_ASSERT(reporter, mv == pts[0]);
1278 ++nCL;
1279 break;
1280 default:
1281 break;
1282 }
1283 }
1284 // if we force a close on the interator we should have a close
1285 // for every moveTo
1286 REPORTER_ASSERT(reporter, !i || nMT == nCL);
1287 }
1288}
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
void set(float x, float y)
Definition: SkPoint_impl.h:200

◆ check_close() [2/2]

static void check_close ( skiatest::Reporter reporter,
SkPathPriv::RangeIter iter 
)
static

Definition at line 4049 of file PathTest.cpp.

4049 {
4050 auto [v, pts, w] = *(*iter)++;
4052}
@ kClose
SkPath::RawIter returns 0 points.
SkScalar w

◆ check_convex_bounds()

static void check_convex_bounds ( skiatest::Reporter reporter,
const SkPath p,
const SkRect bounds 
)
static

Definition at line 1607 of file PathTest.cpp.

1608 {
1609 REPORTER_ASSERT(reporter, p.isConvex());
1610 REPORTER_ASSERT(reporter, p.getBounds() == bounds);
1611
1612 SkPath p2(p);
1613 REPORTER_ASSERT(reporter, p2.isConvex());
1614 REPORTER_ASSERT(reporter, p2.getBounds() == bounds);
1615
1616 SkPath other;
1617 other.swap(p2);
1620}
Definition: SkPath.h:59
bool isConvex() const
Definition: SkPath.cpp:426
const SkRect & getBounds() const
Definition: SkPath.cpp:430
void swap(SkPath &other)
Definition: SkPath.cpp:219
Optional< SkRect > bounds
Definition: SkRecords.h:189

◆ check_convexity()

static void check_convexity ( skiatest::Reporter reporter,
const SkPath path,
bool  expectedConvexity 
)
static

Definition at line 1357 of file PathTest.cpp.

1358 {
1359 // We make a copy so that we don't cache the result on the passed in path.
1360 SkPath copy(path); // NOLINT(performance-unnecessary-copy-initialization)
1361 bool convexity = copy.isConvex();
1362 REPORTER_ASSERT(reporter, convexity == expectedConvexity);
1363}
static void copy(void *dst, const uint8_t *src, int width, int bpp, int deltaSrc, int offset, const SkPMColor ctable[])
Definition: SkSwizzler.cpp:31
Definition: copy.py:1

◆ check_direction()

static void check_direction ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  expected 
)
static

Definition at line 1099 of file PathTest.cpp.

1100 {
1101 if (expected == kDontCheckDir) {
1102 return;
1103 }
1104 // We make a copy so that we don't cache the result on the passed in path.
1105 SkPath copy(path); // NOLINT(performance-unnecessary-copy-initialization)
1106
1109 REPORTER_ASSERT(reporter, dir == expected);
1110 }
1111}
const SkPathFirstDirection kDontCheckDir
Definition: PathTest.cpp:1097
SkPathFirstDirection
Definition: SkPathEnums.h:19
static SkPathFirstDirection ComputeFirstDirection(const SkPath &)
Definition: SkPath.cpp:2627
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition: switches.h:145

◆ check_done()

static void check_done ( skiatest::Reporter reporter,
SkPath p,
SkPathPriv::RangeIter iter 
)
static

Definition at line 4054 of file PathTest.cpp.

4054 {
4056}
SkPath::RangeIter end()
Definition: SkPathPriv.h:187

◆ check_done_and_reset()

static void check_done_and_reset ( skiatest::Reporter reporter,
SkPath p,
SkPathPriv::RangeIter iter 
)
static

Definition at line 4058 of file PathTest.cpp.

4059 {
4060 check_done(reporter, p, iter);
4061 p->reset();
4062}
static void check_done(skiatest::Reporter *reporter, SkPath *p, SkPathPriv::RangeIter *iter)
Definition: PathTest.cpp:4054

◆ check_for_circle()

static void check_for_circle ( skiatest::Reporter reporter,
const SkPath path,
bool  expectedCircle,
SkPathFirstDirection  expectedDir 
)
static

Definition at line 3468 of file PathTest.cpp.

3471 {
3473 REPORTER_ASSERT(reporter, path.isOval(&rect) == expectedCircle);
3474 SkPathDirection isOvalDir;
3475 unsigned isOvalStart;
3476 if (SkPathPriv::IsOval(path, &rect, &isOvalDir, &isOvalStart)) {
3477 REPORTER_ASSERT(reporter, rect.height() == rect.width());
3478 REPORTER_ASSERT(reporter, SkPathPriv::AsFirstDirection(isOvalDir) == expectedDir);
3479 SkPath tmpPath;
3480 tmpPath.addOval(rect, isOvalDir, isOvalStart);
3481 REPORTER_ASSERT(reporter, path == tmpPath);
3482 }
3484}
SkPathDirection
Definition: SkPathTypes.h:34
static bool IsOval(const SkPath &path, SkRect *rect, SkPathDirection *dir, unsigned *start)
Definition: SkPathPriv.h:245
static SkPathFirstDirection AsFirstDirection(SkPathDirection dir)
Definition: SkPathPriv.h:43
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1106
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595

◆ check_line()

static void check_line ( skiatest::Reporter reporter,
SkPathPriv::RangeIter iter,
SkScalar  x1,
SkScalar  y1 
)
static

Definition at line 4031 of file PathTest.cpp.

4032 {
4033 auto [v, pts, w] = *(*iter)++;
4035 REPORTER_ASSERT(reporter, pts[1].fX == x1);
4036 REPORTER_ASSERT(reporter, pts[1].fY == y1);
4037}
@ kLine
SkPath::RawIter returns 2 points.

◆ check_move()

static void check_move ( skiatest::Reporter reporter,
SkPathPriv::RangeIter iter,
SkScalar  x0,
SkScalar  y0 
)
static

Definition at line 4023 of file PathTest.cpp.

4024 {
4025 auto [v, pts, w] = *(*iter)++;
4027 REPORTER_ASSERT(reporter, pts[0].fX == x0);
4028 REPORTER_ASSERT(reporter, pts[0].fY == y0);
4029}
@ kMove
SkPath::RawIter returns 1 point.

◆ check_oval_arc()

static void check_oval_arc ( skiatest::Reporter reporter,
SkScalar  start,
SkScalar  sweep,
const SkPath path 
)
static

Definition at line 3984 of file PathTest.cpp.

3985 {
3988 unsigned s = ~0U;
3989 bool isOval = SkPathPriv::IsOval(path, &r, &d, &s);
3990 REPORTER_ASSERT(reporter, isOval);
3991 SkPath recreatedPath;
3992 recreatedPath.addOval(r, d, s);
3993 REPORTER_ASSERT(reporter, path == recreatedPath);
3995 REPORTER_ASSERT(reporter, (SkPathDirection::kCW == d) == (sweep > 0.f));
3996}
static SkScalar oval_start_index_to_angle(unsigned start)
Definition: PathTest.cpp:3959
static SkScalar canonical_start_angle(float angle)
Definition: PathTest.cpp:3974
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
struct MyStruct s

◆ check_path_is_line()

static void check_path_is_line ( skiatest::Reporter reporter,
SkPath p,
SkScalar  x1,
SkScalar  y1 
)
static

Definition at line 4079 of file PathTest.cpp.

4080 {
4082 check_move(reporter, &iter, 0, 0);
4083 check_line(reporter, &iter, x1, y1);
4084 check_done(reporter, p, &iter);
4085}
static void check_line(skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x1, SkScalar y1)
Definition: PathTest.cpp:4031
static void check_move(skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x0, SkScalar y0)
Definition: PathTest.cpp:4023
SkPath::RangeIter RangeIter
Definition: SkPathPriv.h:164
SkPath::RangeIter begin()
Definition: SkPathPriv.h:186

◆ check_path_is_line_and_reset()

static void check_path_is_line_and_reset ( skiatest::Reporter reporter,
SkPath p,
SkScalar  x1,
SkScalar  y1 
)
static

Definition at line 4071 of file PathTest.cpp.

4072 {
4074 check_move(reporter, &iter, 0, 0);
4075 check_line(reporter, &iter, x1, y1);
4077}
static void check_done_and_reset(skiatest::Reporter *reporter, SkPath *p, SkPathPriv::RangeIter *iter)
Definition: PathTest.cpp:4058

◆ check_path_is_line_pair_and_reset()

static void check_path_is_line_pair_and_reset ( skiatest::Reporter reporter,
SkPath p,
SkScalar  x1,
SkScalar  y1,
SkScalar  x2,
SkScalar  y2 
)
static

Definition at line 4087 of file PathTest.cpp.

4088 {
4090 check_move(reporter, &iter, 0, 0);
4091 check_line(reporter, &iter, x1, y1);
4092 check_line(reporter, &iter, x2, y2);
4094}

◆ check_path_is_move_and_reset()

static void check_path_is_move_and_reset ( skiatest::Reporter reporter,
SkPath p,
SkScalar  x0,
SkScalar  y0 
)
static

Definition at line 4064 of file PathTest.cpp.

4065 {
4067 check_move(reporter, &iter, x0, y0);
4069}

◆ check_path_is_quad_and_reset()

static void check_path_is_quad_and_reset ( skiatest::Reporter reporter,
SkPath p,
SkScalar  x1,
SkScalar  y1,
SkScalar  x2,
SkScalar  y2 
)
static

Definition at line 4096 of file PathTest.cpp.

4097 {
4099 check_move(reporter, &iter, 0, 0);
4100 check_quad(reporter, &iter, x1, y1, x2, y2);
4102}
static void check_quad(skiatest::Reporter *reporter, SkPathPriv::RangeIter *iter, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
Definition: PathTest.cpp:4039

◆ check_quad()

static void check_quad ( skiatest::Reporter reporter,
SkPathPriv::RangeIter iter,
SkScalar  x1,
SkScalar  y1,
SkScalar  x2,
SkScalar  y2 
)
static

Definition at line 4039 of file PathTest.cpp.

4040 {
4041 auto [v, pts, w] = *(*iter)++;
4043 REPORTER_ASSERT(reporter, pts[1].fX == x1);
4044 REPORTER_ASSERT(reporter, pts[1].fY == y1);
4045 REPORTER_ASSERT(reporter, pts[2].fX == x2);
4046 REPORTER_ASSERT(reporter, pts[2].fY == y2);
4047}
@ kQuad
SkPath::RawIter returns 3 points.

◆ check_simple_rect()

static void check_simple_rect ( skiatest::Reporter reporter,
const SkPath path,
bool  isClosed,
const SkRect rect,
SkPathDirection  dir,
unsigned  start 
)
static

Definition at line 2313 of file PathTest.cpp.

2314 {
2317 unsigned s = ~0U;
2318
2319 REPORTER_ASSERT(reporter, SkPathPriv::IsSimpleRect(path, false, &r, &d, &s) == isClosed);
2324}
static bool IsSimpleRect(const SkPath &path, bool isSimpleFill, SkRect *rect, SkPathDirection *direction, unsigned *start)
Definition: SkPath.cpp:3244

◆ compare_dump()

static void compare_dump ( skiatest::Reporter reporter,
const SkPath path,
bool  dumpAsHex,
const char *  str 
)
static

Definition at line 4562 of file PathTest.cpp.

4563 {
4564 SkDynamicMemoryWStream wStream;
4565 path.dump(&wStream, dumpAsHex);
4566 sk_sp<SkData> data = wStream.detachAsData();
4567 REPORTER_ASSERT(reporter, data->size() == strlen(str));
4568 if (strlen(str) > 0) {
4569 REPORTER_ASSERT(reporter, !memcmp(data->data(), str, strlen(str)));
4570 } else {
4571 REPORTER_ASSERT(reporter, data->data() == nullptr || !memcmp(data->data(), str, strlen(str)));
4572 }
4573}
sk_sp< SkData > detachAsData()
Definition: SkStream.cpp:707
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ conditional_convex()

static bool conditional_convex ( const SkPath path,
bool  is_convex 
)
static

Definition at line 5772 of file PathTest.cpp.

5772 {
5774 return is_convex ? (c == SkPathConvexity::kConvex) : (c != SkPathConvexity::kConvex);
5775}
SkPathConvexity
Definition: SkPathEnums.h:13
static SkPathConvexity GetConvexityOrUnknown(const SkPath &path)
Definition: SkPathPriv.h:410

◆ DEF_TEST() [1/27]

DEF_TEST ( AndroidArc  ,
reporter   
)

Definition at line 5364 of file PathTest.cpp.

5364 {
5365 const char* tests[] = {
5366 "M50,0A50,50,0,0 1 100,50 L100,85 A15,15,0,0 1 85,100 L50,100 A50,50,0,0 1 50,0z",
5367 ("M50,0L92,0 A8,8,0,0 1 100,8 L100,92 A8,8,0,0 1 92,100 L8,100"
5368 " A8,8,0,0 1 0,92 L 0,8 A8,8,0,0 1 8,0z"),
5369 "M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0"
5370 };
5371 for (auto test : tests) {
5372 SkPath aPath;
5374 SkASSERT(aPath.isConvex());
5375 for (SkScalar scale = 1; scale < 1000; scale *= 1.1f) {
5376 SkPath scalePath = aPath;
5378 matrix.setScale(scale, scale);
5379 scalePath.transform(matrix);
5380 SkASSERT(scalePath.isConvex());
5381 }
5382 for (SkScalar scale = 1; scale < .001; scale /= 1.1f) {
5383 SkPath scalePath = aPath;
5385 matrix.setScale(scale, scale);
5386 scalePath.transform(matrix);
5387 SkASSERT(scalePath.isConvex());
5388 }
5389 }
5390}
static BlurTest tests[]
Definition: BlurTest.cpp:84
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static bool FromSVGString(const char str[], SkPath *)
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkPath.cpp:1711
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
const Scalar scale

◆ DEF_TEST() [2/27]

DEF_TEST ( ClipPath_nonfinite  ,
reporter   
)

Definition at line 5427 of file PathTest.cpp.

5427 {
5429 SkCanvas* canvas = surf->getCanvas();
5430
5432 for (bool aa : {false, true}) {
5434 for (SkScalar bad : {SK_ScalarInfinity, SK_ScalarNaN}) {
5435 for (int bits = 1; bits <= 15; ++bits) {
5436 SkPoint p0 = { 0, 0 };
5437 SkPoint p1 = { 0, 0 };
5438 if (bits & 1) p0.fX = -bad;
5439 if (bits & 2) p0.fY = -bad;
5440 if (bits & 4) p1.fX = bad;
5441 if (bits & 8) p1.fY = bad;
5442
5443 SkPath path;
5444 path.moveTo(p0);
5445 path.lineTo(p1);
5446 path.setFillType(ft);
5447 canvas->save();
5448 canvas->clipPath(path, aa);
5449 REPORTER_ASSERT(reporter, canvas->isClipEmpty() == !path.isInverseFillType());
5450 canvas->restore();
5451 }
5452 }
5453 }
5454 }
5456}
#define SK_ScalarNaN
Definition: SkScalar.h:28
#define SK_ScalarInfinity
Definition: SkScalar.h:26
virtual bool isClipEmpty() const
Definition: SkCanvas.cpp:1549
void restore()
Definition: SkCanvas.cpp:461
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1456
int save()
Definition: SkCanvas.cpp:447
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
static SkImageInfo MakeN32Premul(int width, int height)
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ DEF_TEST() [3/27]

DEF_TEST ( conservatively_contains_rect  ,
reporter   
)

Definition at line 5239 of file PathTest.cpp.

5239 {
5240 SkPath path;
5241
5242 path.moveTo(SkBits2Float(0x44000000), SkBits2Float(0x373938b8)); // 512, 1.10401e-05f
5243 // 1.4013e-45f, -9.22346e+18f, 3.58732e-43f, 0, 3.58732e-43f, 0
5244 path.cubicTo(SkBits2Float(0x00000001), SkBits2Float(0xdf000052),
5245 SkBits2Float(0x00000100), SkBits2Float(0x00000000),
5246 SkBits2Float(0x00000100), SkBits2Float(0x00000000));
5247 path.moveTo(0, 0);
5248
5249 // this should not assert
5250 path.conservativelyContainsRect({ -211747, 12.1115f, -197893, 25.0321f });
5251}
static float SkBits2Float(uint32_t bits)
Definition: SkFloatBits.h:48

◆ DEF_TEST() [4/27]

DEF_TEST ( HugeGeometry  ,
reporter   
)

Definition at line 5395 of file PathTest.cpp.

5395 {
5396 auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(100, 100));
5397 auto canvas = surf->getCanvas();
5398
5399 const bool aas[] = { false, true };
5400 const SkPaint::Style styles[] = {
5402 };
5403 const SkScalar values[] = {
5404 0, 1, 1000, 1000 * 1000, 1000.f * 1000 * 10000, SK_ScalarMax / 2, SK_ScalarMax,
5406 };
5407
5408 SkPaint paint;
5409 for (auto x : values) {
5410 SkRect r = { -x, -x, x, x };
5411 for (auto width : values) {
5412 paint.setStrokeWidth(width);
5413 for (auto aa : aas) {
5414 paint.setAntiAlias(aa);
5415 for (auto style : styles) {
5416 paint.setStyle(style);
5417 canvas->drawRect(r, paint);
5418 canvas->drawOval(r, paint);
5419 }
5420 }
5421 }
5422 }
5423
5424}
#define SK_ScalarMax
Definition: SkScalar.h:24
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
@ kStrokeAndFill_Style
sets to stroke and fill geometry
Definition: SkPaint.h:195
const Paint & paint
Definition: color_source.cc:38
double x
int32_t width

◆ DEF_TEST() [5/27]

DEF_TEST ( NonFinitePathIteration  ,
reporter   
)

Definition at line 5357 of file PathTest.cpp.

5357 {
5358 SkPath path;
5360 SkPathPriv::Iterate iterate(path);
5361 REPORTER_ASSERT(reporter, iterate.begin() == iterate.end());
5362}

◆ DEF_TEST() [6/27]

DEF_TEST ( path_addpath_crbug_1153516  ,
 
)

Definition at line 6065 of file PathTest.cpp.

6065 {
6066 // When we add a closed path to another path, verify
6067 // that the result has the right value for last contour start point.
6068 SkPath p1, p2;
6069 p2.lineTo(10,20);
6070 p1.addRect({143,226,200,241});
6071 p2.addPath(p1);
6072 p2.lineTo(262,513); // this should not assert
6073 SkPoint rectangleStart = {143, 226};
6074 SkPoint lineEnd = {262, 513};
6075 SkPoint actualMoveTo = p2.getPoint(p2.countPoints() - 2);
6076 REPORTER_ASSERT(r, actualMoveTo == rectangleStart );
6077 SkPoint actualLineTo = p2.getPoint(p2.countPoints() - 1);
6078 REPORTER_ASSERT(r, actualLineTo == lineEnd);
6079
6080 // Verify adding a closed path to itself
6081 p1.addPath(p1);
6082 p1.lineTo(262,513);
6083 actualMoveTo = p1.getPoint(p1.countPoints() - 2);
6084 REPORTER_ASSERT(r, actualMoveTo == rectangleStart );
6085 actualLineTo = p1.getPoint(p1.countPoints() - 1);
6086 REPORTER_ASSERT(r, actualLineTo == lineEnd);
6087 }
int countPoints() const
Definition: SkPath.cpp:535
SkPoint getPoint(int index) const
Definition: SkPath.cpp:549
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
SkPath & addPath(const SkPath &src, SkScalar dx, SkScalar dy, AddPathMode mode=kAppend_AddPathMode)
Definition: SkPath.cpp:1506
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864

◆ DEF_TEST() [7/27]

DEF_TEST ( path_convexity_scale_way_down  ,
 
)

Definition at line 6089 of file PathTest.cpp.

6089 {
6090 SkPath path = SkPathBuilder().moveTo(0,0).lineTo(1, 0)
6091 .lineTo(1,1).lineTo(0,1)
6092 .detach();
6093
6094 REPORTER_ASSERT(r, path.isConvex());
6095 SkPath path2;
6096 const SkScalar scale = 1e-8f;
6097 path.transform(SkMatrix::Scale(scale, scale), &path2);
6100}
static SkPath path2()
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & moveTo(SkPoint pt)
static void ForceComputeConvexity(const SkPath &path)
Definition: SkPathPriv.h:416

◆ DEF_TEST() [8/27]

DEF_TEST ( Path_increserve_handle_neg_crbug_883666  ,
 
)

Definition at line 5740 of file PathTest.cpp.

5740 {
5741 SkPath path;
5742
5743 path.conicTo({0, 0}, {1, 1}, SK_FloatNegativeInfinity);
5744
5745 // <== use a copy path object to force SkPathRef::copy() and SkPathRef::resetToSize()
5746 SkPath shallowPath = path;
5747
5748 // make sure we don't assert/crash on this.
5749 shallowPath.incReserve(0xffffffff);
5750}
constexpr float SK_FloatNegativeInfinity
void incReserve(int extraPtCount, int extraVerbCount=0, int extraConicCount=0)
Definition: SkPath.cpp:678

◆ DEF_TEST() [9/27]

DEF_TEST ( Path_isRect  ,
reporter   
)

Definition at line 5459 of file PathTest.cpp.

5459 {
5460 auto makePath = [](const SkPoint* points, size_t count, bool close) -> SkPath {
5461 SkPath path;
5462 for (size_t index = 0; index < count; ++index) {
5463 index < 2 ? path.moveTo(points[index]) : path.lineTo(points[index]);
5464 }
5465 if (close) {
5466 path.close();
5467 }
5468 return path;
5469 };
5470 auto makePath2 = [](const SkPoint* points, const SkPath::Verb* verbs, size_t count) -> SkPath {
5471 SkPath path;
5472 for (size_t index = 0; index < count; ++index) {
5473 switch (verbs[index]) {
5474 case SkPath::kMove_Verb:
5475 path.moveTo(*points++);
5476 break;
5477 case SkPath::kLine_Verb:
5478 path.lineTo(*points++);
5479 break;
5481 path.close();
5482 break;
5483 default:
5484 SkASSERT(0);
5485 }
5486 }
5487 return path;
5488 };
5489 // isolated from skbug.com/7792 (bug description)
5490 SkRect rect;
5491 SkPoint points[] = { {10, 10}, {75, 75}, {150, 75}, {150, 150}, {75, 150} };
5492 SkPath path = makePath(points, std::size(points), false);
5493 REPORTER_ASSERT(reporter, path.isRect(&rect));
5495 compare.setBounds(&points[1], std::size(points) - 1);
5497 // isolated from skbug.com/7792#c3
5498 SkPoint points3[] = { {75, 50}, {100, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 50} };
5499 path = makePath(points3, std::size(points3), true);
5500 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5501 // isolated from skbug.com/7792#c9
5502 SkPoint points9[] = { {10, 10}, {75, 75}, {150, 75}, {150, 150}, {75, 150} };
5503 path = makePath(points9, std::size(points9), true);
5504 REPORTER_ASSERT(reporter, path.isRect(&rect));
5505 compare.setBounds(&points9[1], std::size(points9) - 1);
5507 // isolated from skbug.com/7792#c11
5510 SkPoint points11[] = { {75, 150}, {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 150} };
5511 path = makePath2(points11, verbs11, std::size(verbs11));
5512 REPORTER_ASSERT(reporter, path.isRect(&rect));
5513 compare.setBounds(&points11[0], std::size(points11));
5515 // isolated from skbug.com/7792#c14
5520 SkPoint points14[] = { {250, 75}, {250, 75}, {250, 75}, {100, 75},
5521 {150, 75}, {150, 150}, {75, 150}, {75, 75}, {0, 0} };
5522 path = makePath2(points14, verbs14, std::size(verbs14));
5523 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5524 // isolated from skbug.com/7792#c15
5527 SkPoint points15[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {250, 75} };
5528 path = makePath2(points15, verbs15, std::size(verbs15));
5529 REPORTER_ASSERT(reporter, path.isRect(&rect));
5530 compare.setBounds(&points15[0], std::size(points15) - 1);
5532 // isolated from skbug.com/7792#c17
5533 SkPoint points17[] = { {75, 10}, {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 10} };
5534 path = makePath(points17, std::size(points17), true);
5535 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5536 // isolated from skbug.com/7792#c19
5541 SkPoint points19[] = { {75, 75}, {75, 75}, {75, 75}, {75, 75}, {150, 75}, {150, 150},
5542 {75, 150}, {10, 10}, {30, 10}, {10, 30} };
5543 path = makePath2(points19, verbs19, std::size(verbs19));
5544 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5545 // isolated from skbug.com/7792#c23
5549 SkPoint points23[] = { {75, 75}, {75, 75}, {75, 75}, {75, 75}, {150, 75}, {150, 150},
5550 {75, 150} };
5551 path = makePath2(points23, verbs23, std::size(verbs23));
5552 REPORTER_ASSERT(reporter, path.isRect(&rect));
5553 compare.setBounds(&points23[0], std::size(points23));
5555 // isolated from skbug.com/7792#c29
5559 SkPoint points29[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 250}, {75, 75} };
5560 path = makePath2(points29, verbs29, std::size(verbs29));
5561 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5562 // isolated from skbug.com/7792#c31
5566 SkPoint points31[] = { {75, 75}, {150, 75}, {150, 150}, {75, 150}, {75, 10}, {75, 75} };
5567 path = makePath2(points31, verbs31, std::size(verbs31));
5568 REPORTER_ASSERT(reporter, path.isRect(&rect));
5569 compare.setBounds(&points31[0], 4);
5571 // isolated from skbug.com/7792#c36
5574 SkPoint points36[] = { {75, 75}, {150, 75}, {150, 150}, {10, 150}, {75, 75}, {75, 75} };
5575 path = makePath2(points36, verbs36, std::size(verbs36));
5576 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5577 // isolated from skbug.com/7792#c39
5580 SkPoint points39[] = { {150, 75}, {150, 150}, {75, 150}, {75, 100} };
5581 path = makePath2(points39, verbs39, std::size(verbs39));
5582 REPORTER_ASSERT(reporter, !path.isRect(&rect));
5583 // isolated from zero_length_paths_aa
5587 SkPoint pointsAA[] = { {32, 9.5f}, {32, 9.5f}, {32, 17}, {17, 17}, {17, 9.5f}, {17, 2},
5588 {32, 2} };
5589 path = makePath2(pointsAA, verbsAA, std::size(verbsAA));
5590 REPORTER_ASSERT(reporter, path.isRect(&rect));
5591 compare.setBounds(&pointsAA[0], std::size(pointsAA));
5593 // isolated from skbug.com/7792#c41
5597 SkPoint points41[] = { {75, 75}, {150, 75}, {150, 150}, {140, 150}, {140, 75}, {75, 75} };
5598 path = makePath2(points41, verbs41, std::size(verbs41));
5599 REPORTER_ASSERT(reporter, path.isRect(&rect));
5600 compare.setBounds(&points41[1], 4);
5602 // isolated from skbug.com/7792#c53
5606 SkPoint points53[] = { {75, 75}, {150, 75}, {150, 150}, {140, 150}, {140, 75}, {75, 75} };
5607 path = makePath2(points53, verbs53, std::size(verbs53));
5608 REPORTER_ASSERT(reporter, path.isRect(&rect));
5609 compare.setBounds(&points53[1], 4);
5611}
static const int points[]
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
int compare(const void *untyped_lhs, const void *untyped_rhs)
Definition: skdiff.h:161

◆ DEF_TEST() [10/27]

DEF_TEST ( path_last_move_to_index  ,
 
)

Definition at line 5852 of file PathTest.cpp.

5852 {
5853 // Make sure that copyPath is safe after the call to path.offset().
5854 // Previously, we would leave its fLastMoveToIndex alone after the copy, but now we should
5855 // set it to path's value inside SkPath::transform()
5856
5857 const char text[] = "hello";
5858 constexpr size_t len = sizeof(text) - 1;
5860
5862 font.textToGlyphs(text, len, SkTextEncoding::kUTF8, glyphs, len);
5863
5864 SkPath copyPath;
5865 font.getPaths(glyphs, len, [](const SkPath* src, const SkMatrix& mx, void* ctx) {
5866 if (src) {
5867 ((SkPath*)ctx)->addPath(*src, mx);
5868 }
5869 }, &copyPath);
5870
5871 SkScalar radii[] = { 80, 100, 0, 0, 40, 60, 0, 0 };
5872 SkPath path;
5873 path.addRoundRect({10, 10, 110, 110}, radii);
5874 path.offset(0, 5, &(copyPath)); // <== change buffer copyPath.fPathRef->fPoints but not reset copyPath.fLastMoveToIndex lead to out of bound
5875
5876 copyPath.rConicTo(1, 1, 3, 3, 0.707107f);
5877}
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
@ kUTF8
uses bytes to represent UTF-8 or ASCII
uint16_t SkGlyphID
Definition: SkTypes.h:179
Definition: SkFont.h:35
SkPath & rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2, SkScalar w)
Definition: SkPath.cpp:791
std::u16string text
SkFont DefaultFont()
font
Font Metadata and Metrics.

◆ DEF_TEST() [11/27]

DEF_TEST ( path_moveto_addrect  ,
 
)

Definition at line 6103 of file PathTest.cpp.

6103 {
6104 // Test both an empty and non-empty rect passed to SkPath::addRect
6105 SkRect rects[] = {{207.0f, 237.0f, 300.0f, 237.0f},
6106 {207.0f, 237.0f, 300.0f, 267.0f}};
6107
6108 for (SkRect rect: rects) {
6109 for (int numExtraMoveTos : {0, 1, 2, 3}) {
6110 SkPath path;
6111 // Convexity and contains functions treat the path as a simple fill, so consecutive
6112 // moveTos are collapsed together.
6113 for (int i = 0; i < numExtraMoveTos; ++i) {
6114 path.moveTo(i, i);
6115 }
6116 path.addRect(rect);
6117
6118 REPORTER_ASSERT(r, (numExtraMoveTos + 1) == SkPathPriv::LeadingMoveToCount(path));
6119
6120 // addRect should mark the path as known convex automatically (i.e. it wasn't set
6121 // to unknown after edits)
6123 REPORTER_ASSERT(r, origConvexity == SkPathConvexity::kConvex);
6124
6125 // but it should also agree with the regular convexity computation
6127 REPORTER_ASSERT(r, path.isConvex());
6128
6129 SkRect query = rect.makeInset(10.f, 0.f);
6130 REPORTER_ASSERT(r, path.conservativelyContainsRect(query));
6131 }
6132 }
6133}
static int LeadingMoveToCount(const SkPath &path)
Definition: SkPathPriv.h:95

◆ DEF_TEST() [12/27]

DEF_TEST ( path_moveto_twopass_convexity  ,
 
)

Definition at line 6136 of file PathTest.cpp.

6136 {
6137 // There had been a bug when the last moveTo index > 0, the calculated point count was incorrect
6138 // and the BySign convexity pass would not evaluate the entire path, effectively only using the
6139 // winding rule for determining convexity.
6140 SkPath path;
6141 path.setFillType(SkPathFillType::kWinding);
6142 path.moveTo(3.25f, 115.5f);
6143 path.conicTo(9.98099e+17f, 2.83874e+15f, 1.75098e-30f, 1.75097e-30f, 1.05385e+18f);
6144 path.conicTo(9.96938e+17f, 6.3804e+19f, 9.96934e+17f, 1.75096e-30f, 1.75096e-30f);
6145 path.quadTo(1.28886e+10f, 9.9647e+17f, 9.98101e+17f, 2.61006e+15f);
6146 REPORTER_ASSERT(r, !path.isConvex());
6147
6148 SkPath pathWithExtraMoveTo;
6149 pathWithExtraMoveTo.setFillType(SkPathFillType::kWinding);
6150 pathWithExtraMoveTo.moveTo(5.90043e-39f, 1.34525e-43f);
6151 pathWithExtraMoveTo.addPath(path);
6152 REPORTER_ASSERT(r, !pathWithExtraMoveTo.isConvex());
6153}
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
void setFillType(SkPathFillType ft)
Definition: SkPath.h:235

◆ DEF_TEST() [13/27]

DEF_TEST ( Path_self_add  ,
reporter   
)

Definition at line 5614 of file PathTest.cpp.

5614 {
5615 // The possible problem is that during path.add() we may have to grow the dst buffers as
5616 // we append the src pts/verbs, but all the while we are iterating over the src. If src == dst
5617 // we could realloc the buffer's (on behalf of dst) leaving the src iterator pointing at
5618 // garbage.
5619 //
5620 // The test runs though verious sized src paths, since its not defined publicly what the
5621 // reserve allocation strategy is for SkPath, therefore we can't know when an append operation
5622 // will trigger a realloc. At the time of this writing, these loops were sufficient to trigger
5623 // an ASAN error w/o the fix to SkPath::addPath().
5624 //
5625 for (int count = 0; count < 10; ++count) {
5626 SkPath path;
5627 for (int add = 0; add < count; ++add) {
5628 // just add some stuff, so we have something to copy/append in addPath()
5629 path.moveTo(1, 2).lineTo(3, 4).cubicTo(1,2,3,4,5,6).conicTo(1,2,3,4,5);
5630 }
5631 path.addPath(path, 1, 2);
5632 path.addPath(path, 3, 4);
5633 }
5634}

◆ DEF_TEST() [14/27]

DEF_TEST ( Path_setLastPt  ,
 
)

Definition at line 5725 of file PathTest.cpp.

5725 {
5726 // There was a time where SkPath::setLastPoint() didn't invalidate cached path bounds.
5727 SkPath p;
5728 p.moveTo(0,0);
5729 p.moveTo(20,01);
5730 p.moveTo(20,10);
5731 p.moveTo(20,61);
5732 REPORTER_ASSERT(r, p.getBounds() == SkRect::MakeLTRB(0,0, 20,61));
5733
5734 p.setLastPt(30,01);
5735 REPORTER_ASSERT(r, p.getBounds() == SkRect::MakeLTRB(0,0, 30,10)); // was {0,0, 20,61}
5736
5737 REPORTER_ASSERT(r, p.isValid());
5738}
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646

◆ DEF_TEST() [15/27]

DEF_TEST ( Path_shrinkToFit  ,
reporter   
)

Definition at line 5691 of file PathTest.cpp.

5691 {
5692 for (int verbs = 0; verbs < 100; ++verbs) {
5693 SkPath unique_path, shared_path;
5694 add_verbs(&unique_path, verbs);
5695 add_verbs(&shared_path, verbs);
5696
5697 const SkPath copy = shared_path;
5698
5699 REPORTER_ASSERT(reporter, shared_path == unique_path);
5700 REPORTER_ASSERT(reporter, shared_path == copy);
5701
5702 uint32_t uID = unique_path.getGenerationID();
5703 uint32_t sID = shared_path.getGenerationID();
5704 uint32_t cID = copy.getGenerationID();
5705 REPORTER_ASSERT(reporter, sID == cID);
5706
5707 SkPathPriv::ShrinkToFit(&unique_path);
5708 SkPathPriv::ShrinkToFit(&shared_path);
5709 REPORTER_ASSERT(reporter, shared_path == unique_path);
5710 REPORTER_ASSERT(reporter, shared_path == copy);
5711
5712 // since the unique_path is "unique", it's genID need not have changed even though
5713 // unique_path has changed (been shrunk)
5714 REPORTER_ASSERT(reporter, uID == unique_path.getGenerationID());
5715 // since the copy has not been changed, its ID should be the same
5716 REPORTER_ASSERT(reporter, cID == copy.getGenerationID());
5717 // but since shared_path has changed, and was not uniquely owned, it's gen ID needs to have
5718 // changed, breaking the "sharing" -- this is done defensively in case there were any
5719 // outstanding Iterators active on copy, which could have been invalidated during
5720 // shrinkToFit.
5721 REPORTER_ASSERT(reporter, sID != shared_path.getGenerationID());
5722 }
5723}
static void add_verbs(SkPath *path, int count)
Definition: PathTest.cpp:5677
static void ShrinkToFit(SkPath *path)
Definition: SkPathPriv.h:130
uint32_t getGenerationID() const
Definition: SkPath.cpp:366

◆ DEF_TEST() [16/27]

DEF_TEST ( Path_survive_transform  ,
 
)

Definition at line 5830 of file PathTest.cpp.

5830 {
5831 const Xforms x;
5832
5833 SkPath path;
5834 path.addRect({10, 10, 40, 50});
5835 survive(&path, x, true, r, [](const SkPath& p) { return p.isRect(nullptr); });
5836
5837 path.reset();
5838 path.addOval({10, 10, 40, 50});
5839 survive(&path, x, true, r, [](const SkPath& p) { return p.isOval(nullptr); });
5840
5841 path.reset();
5842 path.addRRect(SkRRect::MakeRectXY({10, 10, 40, 50}, 5, 5));
5843 survive(&path, x, true, r, [](const SkPath& p) { return p.isRRect(nullptr); });
5844
5845 // make a trapazoid; definitely convex, but not marked as axis-aligned (e.g. oval, rrect)
5846 path.reset();
5847 path.moveTo(0, 0).lineTo(100, 0).lineTo(70, 100).lineTo(30, 100);
5848 REPORTER_ASSERT(r, path.isConvex());
5849 survive(&path, x, false, r, [](const SkPath& p) { return true; });
5850}
void survive(SkPath *path, const Xforms &x, bool isAxisAligned, skiatest::Reporter *reporter, ISA isa_proc)
Definition: PathTest.cpp:5779
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180

◆ DEF_TEST() [17/27]

DEF_TEST ( path_tight_bounds  ,
reporter   
)

Definition at line 5280 of file PathTest.cpp.

5280 {
5281 SkRandom rand;
5282
5283 const SkPath::Verb verbs[] = {
5285 };
5286 for (int i = 0; i < 1000; ++i) {
5287 for (int n = 1; n <= 10; n += 9) {
5288 for (SkPath::Verb verb : verbs) {
5289 SkPath path;
5290 rand_path(&path, rand, verb, n);
5291 SkRect bounds = path.getBounds();
5292 SkRect tight = path.computeTightBounds();
5293 REPORTER_ASSERT(reporter, bounds.contains(tight));
5294
5295 SkRect tight2;
5296 TightBounds(path, &tight2);
5297 REPORTER_ASSERT(reporter, nearly_equal(tight, tight2));
5298 }
5299 }
5300 }
5301}
static bool nearly_equal(const SkRect &a, const SkRect &b)
Definition: PathTest.cpp:4104
static void rand_path(SkPath *path, SkRandom &rand, SkPath::Verb verb, int n)
Definition: PathTest.cpp:5255
bool SK_API TightBounds(const SkPath &path, SkRect *result)
@ kConic_Verb
Definition: SkPath.h:1469
@ kCubic_Verb
Definition: SkPath.h:1470
@ kQuad_Verb
Definition: SkPath.h:1468

◆ DEF_TEST() [18/27]

DEF_TEST ( path_walk_simple_edges_1154864  ,
 
)

Definition at line 6156 of file PathTest.cpp.

6156 {
6157 // Drawing this path triggered an assert in walk_simple_edges:
6159
6160 SkPath path;
6161 path.setFillType(SkPathFillType::kWinding);
6162 path.moveTo(0.00665998459f, 2);
6163 path.quadTo(0.00665998459f, 4, -1.99334002f, 4);
6164 path.quadTo(-3.99334002f, 4, -3.99334002f, 2);
6165 path.quadTo(-3.99334002f, 0, -1.99334002f, 0);
6166 path.quadTo(0.00665998459f, 0, 0.00665998459f, 2);
6167 path.close();
6168
6169 SkPaint paint;
6170 paint.setAntiAlias(true);
6171 surface->getCanvas()->drawPath(path, paint);
6172}
VkSurfaceKHR surface
Definition: main.cc:49

◆ DEF_TEST() [19/27]

DEF_TEST ( PathBigCubic  ,
reporter   
)

Definition at line 5043 of file PathTest.cpp.

5043 {
5044 SkPath path;
5045 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
5046 path.moveTo(SkBits2Float(0x44000000), SkBits2Float(0x373938b8)); // 512, 1.10401e-05f
5047 path.cubicTo(SkBits2Float(0x00000001), SkBits2Float(0xdf000052), SkBits2Float(0x00000100), SkBits2Float(0x00000000), SkBits2Float(0x00000100), SkBits2Float(0x00000000)); // 1.4013e-45f, -9.22346e+18f, 3.58732e-43f, 0, 3.58732e-43f, 0
5048 path.moveTo(0, 512);
5049
5050 // this call should not assert
5052 ->getCanvas()
5053 ->drawPath(path, SkPaint());
5054}
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
SkCanvas * getCanvas()
Definition: SkSurface.cpp:82

◆ DEF_TEST() [20/27]

DEF_TEST ( PathContains  ,
reporter   
)

Definition at line 5056 of file PathTest.cpp.

5056 {
5058}
static void test_contains(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4309

◆ DEF_TEST() [21/27]

DEF_TEST ( pathedger  ,
 
)

Definition at line 6045 of file PathTest.cpp.

6045 {
6046 auto M = SkPath::kMove_Verb;
6047 auto L = SkPath::kLine_Verb;
6048 auto C = SkPath::kClose_Verb;
6049
6050 test_edger(r, { M }, {});
6051 test_edger(r, { M, M }, {});
6052 test_edger(r, { M, C }, {});
6053 test_edger(r, { M, M, C }, {});
6054 test_edger(r, { M, L }, { L, L });
6055 test_edger(r, { M, L, C }, { L, L });
6056 test_edger(r, { M, L, L }, { L, L, L });
6057 test_edger(r, { M, L, L, C }, { L, L, L });
6058
6059 test_edger(r, { M, L, L, M, L, L }, { L, L, L, L, L, L });
6060
6063}
static void test_addPath_and_injected_moveTo(skiatest::Reporter *reporter)
Definition: PathTest.cpp:5988
static void test_edger(skiatest::Reporter *r, const std::initializer_list< SkPath::Verb > &in, const std::initializer_list< SkPath::Verb > &expected)
Definition: PathTest.cpp:5879
static void test_addRect_and_trailing_lineTo(skiatest::Reporter *reporter)
Definition: PathTest.cpp:5926
#define M(PROC, DITHER)

◆ DEF_TEST() [22/27]

DEF_TEST ( PathInterp  ,
reporter   
)

Definition at line 5039 of file PathTest.cpp.

5039 {
5041}
static void test_interp(skiatest::Reporter *reporter)
Definition: PathTest.cpp:5000

◆ DEF_TEST() [23/27]

DEF_TEST ( PathRefSerialization  ,
reporter   
)

Definition at line 5325 of file PathTest.cpp.

5325 {
5326 SkPath path;
5327 const size_t numMoves = 5;
5328 const size_t numConics = 7;
5329 const size_t numPoints = numMoves + 2 * numConics;
5330 const size_t numVerbs = numMoves + numConics;
5331 for (size_t i = 0; i < numMoves; ++i) path.moveTo(1, 2);
5332 for (size_t i = 0; i < numConics; ++i) path.conicTo(1, 2, 3, 4, 5);
5333 REPORTER_ASSERT(reporter, path.countPoints() == numPoints);
5334 REPORTER_ASSERT(reporter, path.countVerbs() == numVerbs);
5335
5336 // Verify that path serializes/deserializes properly.
5337 sk_sp<SkData> data = path.serialize();
5338 size_t bytesWritten = data->size();
5339
5340 {
5341 SkPath readBack;
5342 REPORTER_ASSERT(reporter, readBack != path);
5343 size_t bytesRead = readBack.readFromMemory(data->data(), bytesWritten);
5344 REPORTER_ASSERT(reporter, bytesRead == bytesWritten);
5345 REPORTER_ASSERT(reporter, readBack == path);
5346 }
5347
5348 // One less byte (rounded down to alignment) than was written will also
5349 // fail to be deserialized.
5350 {
5351 SkPath readBack;
5352 size_t bytesRead = readBack.readFromMemory(data->data(), bytesWritten - 4);
5353 REPORTER_ASSERT(reporter, !bytesRead);
5354 }
5355}
size_t readFromMemory(const void *buffer, size_t length)

◆ DEF_TEST() [24/27]

DEF_TEST ( Paths  ,
reporter   
)

Definition at line 5060 of file PathTest.cpp.

5060 {
5078
5079 SkSize::Make(3, 4);
5080
5081 SkPath p, empty;
5082 SkRect bounds, bounds2;
5084
5085 REPORTER_ASSERT(reporter, p.getBounds().isEmpty());
5086
5087 // this triggers a code path in SkPath::operator= which is otherwise unexercised
5088 SkPath& self = p;
5089 p = self;
5090
5091 // this triggers a code path in SkPath::swap which is otherwise unexercised
5092 p.swap(self);
5093
5094 bounds.setLTRB(0, 0, SK_Scalar1, SK_Scalar1);
5095
5096 p.addRoundRect(bounds, SK_Scalar1, SK_Scalar1);
5098 // we have quads or cubics
5100 p.getSegmentMasks() & (kCurveSegmentMask | SkPath::kConic_SegmentMask));
5101 REPORTER_ASSERT(reporter, !p.isEmpty());
5102
5103 p.reset();
5105
5106 p.addOval(bounds);
5108 REPORTER_ASSERT(reporter, !p.isEmpty());
5109
5110 p.rewind();
5112
5113 p.addRect(bounds);
5115 // we have only lines
5116 REPORTER_ASSERT(reporter, SkPath::kLine_SegmentMask == p.getSegmentMasks());
5117 REPORTER_ASSERT(reporter, !p.isEmpty());
5118
5121
5122 // do getPoints and getVerbs return the right result
5123 REPORTER_ASSERT(reporter, p.getPoints(nullptr, 0) == 4);
5124 REPORTER_ASSERT(reporter, p.getVerbs(nullptr, 0) == 5);
5125 SkPoint pts[4];
5126 int count = p.getPoints(pts, 4);
5128 uint8_t verbs[6];
5129 verbs[5] = 0xff;
5130 p.getVerbs(verbs, 5);
5136 REPORTER_ASSERT(reporter, 0xff == verbs[5]);
5137 bounds2.setBounds(pts, 4);
5138 REPORTER_ASSERT(reporter, bounds == bounds2);
5139
5140 bounds.offset(SK_Scalar1*3, SK_Scalar1*4);
5141 p.offset(SK_Scalar1*3, SK_Scalar1*4);
5142 REPORTER_ASSERT(reporter, bounds == p.getBounds());
5143
5144 REPORTER_ASSERT(reporter, p.isRect(nullptr));
5145 bounds2.setEmpty();
5146 REPORTER_ASSERT(reporter, p.isRect(&bounds2));
5147 REPORTER_ASSERT(reporter, bounds == bounds2);
5148
5149 // now force p to not be a rect
5150 bounds.setWH(SK_Scalar1/2, SK_Scalar1/2);
5151 p.addRect(bounds);
5152 REPORTER_ASSERT(reporter, !p.isRect(nullptr));
5153
5154 // Test an edge case w.r.t. the bound returned by isRect (i.e., the
5155 // path has a trailing moveTo. Please see crbug.com\445368)
5156 {
5157 SkRect r;
5158 p.reset();
5159 p.addRect(bounds);
5160 REPORTER_ASSERT(reporter, p.isRect(&r));
5162 // add a moveTo outside of our bounds
5163 p.moveTo(bounds.fLeft + 10, bounds.fBottom + 10);
5164 REPORTER_ASSERT(reporter, p.isRect(&r));
5166 }
5167
5216 test_addPathMode(reporter, false, false);
5217 test_addPathMode(reporter, true, false);
5218 test_addPathMode(reporter, false, true);
5219 test_addPathMode(reporter, true, true);
5237}
static void test_arb_round_rect_is_convex(skiatest::Reporter *reporter)
Definition: PathTest.cpp:880
static void test_transform(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2848
static void test_fuzz_crbug_638223()
Definition: PathTest.cpp:189
static void test_arc_ovals(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3998
static void check_convex_bounds(skiatest::Reporter *reporter, const SkPath &p, const SkRect &bounds)
Definition: PathTest.cpp:1607
static void test_bad_cubic_crbug229478()
Definition: PathTest.cpp:467
static void test_skbug_6947()
Definition: PathTest.cpp:4775
static void test_arcTo(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4139
static void test_conicTo_special_case(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4285
static void test_isNestedFillRects(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2533
static void test_arb_zero_rad_round_rect_is_rect(skiatest::Reporter *reporter)
Definition: PathTest.cpp:907
static void test_range_iter(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3217
static void test_path_crbug389050(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1365
static void test_rMoveTo(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4111
static void test_iterative_intersect_line()
Definition: PathTest.cpp:149
static void test_get_point(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4295
#define kCurveSegmentMask
Definition: PathTest.cpp:3045
static void test_is_closed_rect(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2326
static void test_circle(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3671
static void test_direction(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1113
static void test_addPathMode(skiatest::Reporter *reporter, bool explicitMoveTo, bool extend)
Definition: PathTest.cpp:4223
static void test_bad_cubic_crbug234190()
Definition: PathTest.cpp:458
static void test_bounds_crbug_513799(skiatest::Reporter *reporter)
Definition: PathTest.cpp:754
static void test_convexity(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1641
static void test_dump(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4575
static void test_fuzz_crbug_627414(skiatest::Reporter *reporter)
Definition: PathTest.cpp:783
static void test_zero_length_paths(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2969
static void test_isLine(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1822
static void test_fuzz_crbug_643933()
Definition: PathTest.cpp:198
static void test_mask_overflow()
Definition: PathTest.cpp:250
static void test_path_crbugskia5995()
Definition: PathTest.cpp:300
static void test_open_oval(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3764
static void test_empty(skiatest::Reporter *reporter, const SkPath &p)
Definition: PathTest.cpp:3828
static void test_addrect_isfinite(skiatest::Reporter *reporter)
Definition: PathTest.cpp:687
static void test_convexity2(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1392
static void test_iter(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3072
static void test_fuzz_crbug_668907()
Definition: PathTest.cpp:264
static void test_fuzz_crbug_662780()
Definition: PathTest.cpp:222
static void test_close(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1290
static void test_isArc(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2455
static void test_arc(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3928
static void test_skbug_7435()
Definition: PathTest.cpp:4834
static void test_isRect(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2129
static void test_crbug_629455(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4715
static void test_clipped_cubic()
Definition: PathTest.cpp:728
static void test_extendClosedPath(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4243
static void test_isfinite_after_transform(skiatest::Reporter *reporter)
Definition: PathTest.cpp:810
static void test_skbug_3469(skiatest::Reporter *reporter)
Definition: PathTest.cpp:79
static void test_crbug_493450(skiatest::Reporter *reporter)
Definition: PathTest.cpp:603
static void test_operatorEqual(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4541
static void test_islastcontourclosed(skiatest::Reporter *reporter)
Definition: PathTest.cpp:995
static void test_addrect(skiatest::Reporter *reporter)
Definition: PathTest.cpp:659
static void test_bounds(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1208
static void test_skbug_7015()
Definition: PathTest.cpp:4811
static void test_tricky_cubic()
Definition: PathTest.cpp:794
static void test_addPoly(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1056
static void test_segment_masks(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3047
static void test_strokerec(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1074
static void test_isfinite(skiatest::Reporter *reporter)
Definition: PathTest.cpp:990
static void test_fuzz_crbug_662730(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4765
static void test_skbug_7051()
Definition: PathTest.cpp:4824
static void test_fuzz_crbug_662952(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4726
static void test_convexity_doubleback(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1545
static void test_skbug_3239(skiatest::Reporter *reporter)
Definition: PathTest.cpp:87
static void test_path_crbugskia2820(skiatest::Reporter *reporter)
Definition: PathTest.cpp:291
static void test_oval(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3701
static void test_path_close_issue1474(skiatest::Reporter *reporter)
Definition: PathTest.cpp:359
static void test_rrect(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3862
static void test_crbug_613918()
Definition: PathTest.cpp:648
static void test_crbug_170666()
Definition: PathTest.cpp:577
static void test_fuzz_crbug_647922()
Definition: PathTest.cpp:213
static void test_addEmptyPath(skiatest::Reporter *reporter, SkPath::AddPathMode mode)
Definition: PathTest.cpp:4269
static void test_crbug_495894(skiatest::Reporter *reporter)
Definition: PathTest.cpp:622
static void test_gen_id(skiatest::Reporter *reporter)
Definition: PathTest.cpp:409
static void test_flattening(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2798
static void test_addPath(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4205
static void test_path_to_region(skiatest::Reporter *reporter)
Definition: PathTest.cpp:333
static void test_path_crbugskia6003()
Definition: PathTest.cpp:4742
static void test_sect_with_horizontal_needs_pinning()
Definition: PathTest.cpp:135
static void test_path_crbug364224()
Definition: PathTest.cpp:167
static void test_conservativelyContains(skiatest::Reporter *reporter)
Definition: PathTest.cpp:1872
#define SK_Scalar1
Definition: SkScalar.h:18
static void TestPathRef(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4474
static void TestPathTo(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4640
static void TestPathrefListeners(skiatest::Reporter *reporter)
Definition: PathTest.cpp:4658
@ kLine_SegmentMask
Definition: SkPath.h:1445
@ kConic_SegmentMask
Definition: SkPath.h:1447
@ kExtend_AddPathMode
Definition: SkPath.h:1293
@ kAppend_AddPathMode
Definition: SkPath.h:1286
EMSCRIPTEN_KEEPALIVE void empty()
void setBounds(const SkPoint pts[], int count)
Definition: SkRect.h:881
void setEmpty()
Definition: SkRect.h:842
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition: SkSize.h:56

◆ DEF_TEST() [25/27]

DEF_TEST ( skbug_6450  ,
 
)

Definition at line 5303 of file PathTest.cpp.

5303 {
5304 SkRect ri = { 0.18554693f, 195.26283f, 0.185784385f, 752.644409f };
5305 SkVector rdi[4] = {
5306 { 1.81159976e-09f, 7.58768801e-05f },
5307 { 0.000118725002f, 0.000118725002f },
5308 { 0.000118725002f, 0.000118725002f },
5309 { 0.000118725002f, 0.486297607f }
5310 };
5311 SkRRect irr;
5312 irr.setRectRadii(ri, rdi);
5313 SkRect ro = { 9.18354821e-39f, 2.1710848e+9f, 2.16945843e+9f, 3.47808128e+9f };
5314 SkVector rdo[4] = {
5315 { 0, 0 },
5316 { 0.0103298295f, 0.185887396f },
5317 { 2.52999727e-29f, 169.001938f },
5318 { 195.262741f, 195.161255f }
5319 };
5320 SkRRect orr;
5321 orr.setRectRadii(ro, rdo);
5322 SkMakeNullCanvas()->drawDRRect(orr, irr, SkPaint());
5323}
SK_API std::unique_ptr< SkCanvas > SkMakeNullCanvas()
void setRectRadii(const SkRect &rect, const SkVector radii[4])
Definition: SkRRect.cpp:189

◆ DEF_TEST() [26/27]

DEF_TEST ( triangle_big  ,
reporter   
)

Definition at line 5661 of file PathTest.cpp.

5661 {
5663
5664 // The first two points, when sent through our fixed-point SkEdge, can walk negative beyond
5665 // -0.5 due to accumulated += error of the slope. We have since make the bounds calculation
5666 // be conservative, so we invoke clipping if we get in this situation.
5667 // This test was added to demonstrate the need for this conservative bounds calc.
5668 // (found by a fuzzer)
5669 const SkPoint pts[] = {
5670 { 0.327190518f, -114.945152f },
5671 { -0.5f, 1.00003874f },
5672 { 0.666425824f, 4304.26172f },
5673 };
5674 draw_triangle(surface->getCanvas(), pts);
5675}
static void draw_triangle(SkCanvas *canvas, const SkPoint pts[])
Definition: PathTest.cpp:5636

◆ DEF_TEST() [27/27]

DEF_TEST ( triangle_onehalf  ,
reporter   
)

Definition at line 5650 of file PathTest.cpp.

5650 {
5652
5653 const SkPoint pts[] = {
5654 { 0.499069244f, 9.63295173f },
5655 { 0.499402374f, 7.88207579f },
5656 { 10.2363272f, 0.49999997f }
5657 };
5658 draw_triangle(surface->getCanvas(), pts);
5659}

◆ draw_triangle()

static void draw_triangle ( SkCanvas canvas,
const SkPoint  pts[] 
)
static

Definition at line 5636 of file PathTest.cpp.

5636 {
5637 // draw in different ways, looking for an assert
5638
5639 {
5640 SkPath path;
5641 path.addPoly(pts, 3, false);
5642 canvas->drawPath(path, SkPaint());
5643 }
5644
5648}
@ kSrcOver
r = s + (1-sa)*d
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
Definition: SkCanvas.cpp:1720
static sk_sp< SkVertices > MakeCopy(VertexMode mode, int vertexCount, const SkPoint positions[], const SkPoint texs[], const SkColor colors[], int indexCount, const uint16_t indices[])
Definition: SkVertices.cpp:200
@ kTriangles_VertexMode
Definition: SkVertices.h:31
PODArray< SkColor > colors
Definition: SkRecords.h:276

◆ dump_if_ne()

static void dump_if_ne ( skiatest::Reporter reporter,
const SkRect expected,
const SkRect bounds 
)
static

Definition at line 746 of file PathTest.cpp.

746 {
747 if (expected != bounds) {
748 ERRORF(reporter, "path.getBounds() returned [%g %g %g %g], but expected [%g %g %g %g]",
749 bounds.left(), bounds.top(), bounds.right(), bounds.bottom(),
750 expected.left(), expected.top(), expected.right(), expected.bottom());
751 }
752}
#define ERRORF(r,...)
Definition: Test.h:293
constexpr float left() const
Definition: SkRect.h:734
constexpr float top() const
Definition: SkRect.h:741
constexpr float right() const
Definition: SkRect.h:748
constexpr float bottom() const
Definition: SkRect.h:755

◆ make_arb_round_rect()

static void make_arb_round_rect ( SkPath path,
const SkRect r,
SkScalar  xCorner,
SkScalar  yCorner 
)
static

Definition at line 866 of file PathTest.cpp.

867 {
868 // we are lazy here and use the same x & y for each corner
869 add_corner_arc(path, r, xCorner, yCorner, 270);
870 add_corner_arc(path, r, xCorner, yCorner, 0);
871 add_corner_arc(path, r, xCorner, yCorner, 90);
872 add_corner_arc(path, r, xCorner, yCorner, 180);
873 path->close();
874}
static void add_corner_arc(SkPath *path, const SkRect &rect, SkScalar xIn, SkScalar yIn, int startAngle)
Definition: PathTest.cpp:836

◆ make_path0()

static void make_path0 ( SkPath path)
static

Definition at line 309 of file PathTest.cpp.

309 {
310 // from * https://code.google.com/p/skia/issues/detail?id=1706
311
312 path->moveTo(146.939f, 1012.84f);
313 path->lineTo(181.747f, 1009.18f);
314 path->lineTo(182.165f, 1013.16f);
315 path->lineTo(147.357f, 1016.82f);
316 path->lineTo(146.939f, 1012.84f);
317 path->close();
318}

◆ make_path1()

static void make_path1 ( SkPath path)
static

Definition at line 320 of file PathTest.cpp.

320 {
321 path->addRect(SkRect::MakeXYWH(10, 10, 10, 1));
322}
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659

◆ make_path_crbug364224()

static void make_path_crbug364224 ( SkPath path)
static

Definition at line 105 of file PathTest.cpp.

105 {
106 path->reset();
107 path->moveTo(3.747501373f, 2.724499941f);
108 path->lineTo(3.747501373f, 3.75f);
109 path->cubicTo(3.747501373f, 3.88774991f, 3.635501385f, 4.0f, 3.497501373f, 4.0f);
110 path->lineTo(0.7475013733f, 4.0f);
111 path->cubicTo(0.6095013618f, 4.0f, 0.4975013733f, 3.88774991f, 0.4975013733f, 3.75f);
112 path->lineTo(0.4975013733f, 1.0f);
113 path->cubicTo(0.4975013733f, 0.8622499704f, 0.6095013618f, 0.75f, 0.7475013733f,0.75f);
114 path->lineTo(3.497501373f, 0.75f);
115 path->cubicTo(3.50275135f, 0.75f, 3.5070014f, 0.7527500391f, 3.513001442f, 0.753000021f);
116 path->lineTo(3.715001345f, 0.5512499809f);
117 path->cubicTo(3.648251295f, 0.5194999576f, 3.575501442f, 0.4999999702f, 3.497501373f, 0.4999999702f);
118 path->lineTo(0.7475013733f, 0.4999999702f);
119 path->cubicTo(0.4715013802f, 0.4999999702f, 0.2475013733f, 0.7239999771f, 0.2475013733f, 1.0f);
120 path->lineTo(0.2475013733f, 3.75f);
121 path->cubicTo(0.2475013733f, 4.026000023f, 0.4715013504f, 4.25f, 0.7475013733f, 4.25f);
122 path->lineTo(3.497501373f, 4.25f);
123 path->cubicTo(3.773501396f, 4.25f, 3.997501373f, 4.026000023f, 3.997501373f, 3.75f);
124 path->lineTo(3.997501373f, 2.474750042f);
125 path->lineTo(3.747501373f, 2.724499941f);
126 path->close();
127}

◆ make_path_crbug364224_simplified()

static void make_path_crbug364224_simplified ( SkPath path)
static

Definition at line 129 of file PathTest.cpp.

129 {
130 path->moveTo(3.747501373f, 2.724499941f);
131 path->cubicTo(3.648251295f, 0.5194999576f, 3.575501442f, 0.4999999702f, 3.497501373f, 0.4999999702f);
132 path->close();
133}

◆ make_path_crbugskia2820()

static void make_path_crbugskia2820 ( SkPath path,
skiatest::Reporter reporter 
)
static

In debug mode, this path was causing an assertion to fail in SkPathStroker::preJoinTo() and, in Release, the use of an unitialized value.

Definition at line 278 of file PathTest.cpp.

278 {
279 SkPoint orig, p1, p2, p3;
280 orig = SkPoint::Make(1.f, 1.f);
281 p1 = SkPoint::Make(1.f - SK_ScalarNearlyZero, 1.f);
282 p2 = SkPoint::Make(1.f, 1.f + SK_ScalarNearlyZero);
283 p3 = SkPoint::Make(2.f, 2.f);
284
285 path->reset();
286 path->moveTo(orig);
287 path->cubicTo(p1, p2, p3);
288 path->close();
289}
#define SK_ScalarNearlyZero
Definition: SkScalar.h:99
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173

◆ nearly_equal()

static bool nearly_equal ( const SkRect a,
const SkRect b 
)
static

Definition at line 4104 of file PathTest.cpp.

4104 {
4105 return SkScalarNearlyEqual(a.fLeft, b.fLeft) &&
4106 SkScalarNearlyEqual(a.fTop, b.fTop) &&
4107 SkScalarNearlyEqual(a.fRight, b.fRight) &&
4108 SkScalarNearlyEqual(a.fBottom, b.fBottom);
4109}
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
static bool b
struct MyStruct a[10]

◆ oval_start_index_to_angle()

static SkScalar oval_start_index_to_angle ( unsigned  start)
inlinestatic

Definition at line 3959 of file PathTest.cpp.

3959 {
3960 switch (start) {
3961 case 0:
3962 return 270.f;
3963 case 1:
3964 return 0.f;
3965 case 2:
3966 return 90.f;
3967 case 3:
3968 return 180.f;
3969 default:
3970 return -1.f;
3971 }
3972}

◆ rand_path()

static void rand_path ( SkPath path,
SkRandom rand,
SkPath::Verb  verb,
int  n 
)
static

Definition at line 5255 of file PathTest.cpp.

5255 {
5256 for (int i = 0; i < n; ++i) {
5257 switch (verb) {
5258 case SkPath::kLine_Verb:
5259 path->lineTo(rand.nextF()*100, rand.nextF()*100);
5260 break;
5261 case SkPath::kQuad_Verb:
5262 path->quadTo(rand.nextF()*100, rand.nextF()*100,
5263 rand.nextF()*100, rand.nextF()*100);
5264 break;
5266 path->conicTo(rand.nextF()*100, rand.nextF()*100,
5267 rand.nextF()*100, rand.nextF()*100, rand.nextF()*10);
5268 break;
5270 path->cubicTo(rand.nextF()*100, rand.nextF()*100,
5271 rand.nextF()*100, rand.nextF()*100,
5272 rand.nextF()*100, rand.nextF()*100);
5273 break;
5274 default:
5275 SkASSERT(false);
5276 }
5277 }
5278}
float nextF()
Definition: SkRandom.h:55

◆ set_radii()

static void set_radii ( SkVector  radii[4],
int  index,
float  rad 
)
static

Definition at line 62 of file PathTest.cpp.

62 {
63 sk_bzero(radii, sizeof(SkVector) * 4);
64 radii[index].set(rad, rad);
65}
sk_bzero(glyphs, sizeof(glyphs))

◆ setFromString()

static void setFromString ( SkPath path,
const char  str[] 
)
static

Definition at line 1622 of file PathTest.cpp.

1622 {
1623 bool first = true;
1624 while (str) {
1625 SkScalar x, y;
1626 str = SkParse::FindScalar(str, &x);
1627 if (nullptr == str) {
1628 break;
1629 }
1630 str = SkParse::FindScalar(str, &y);
1631 SkASSERT(str);
1632 if (first) {
1633 path->moveTo(x, y);
1634 first = false;
1635 } else {
1636 path->lineTo(x, y);
1637 }
1638 }
1639}
static const char * FindScalar(const char str[], SkScalar *value)
Definition: SkParse.cpp:216
double y

◆ stroke_cubic()

static void stroke_cubic ( const SkPoint  pts[4])
static

Definition at line 1225 of file PathTest.cpp.

1225 {
1226 SkPath path;
1227 path.moveTo(pts[0]);
1228 path.cubicTo(pts[1], pts[2], pts[3]);
1229
1230 SkPaint paint;
1231 paint.setStyle(SkPaint::kStroke_Style);
1232 paint.setStrokeWidth(SK_Scalar1 * 2);
1233
1234 SkPath fill;
1236}
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23

◆ stroke_tiny_cubic()

static void stroke_tiny_cubic ( )
static

Definition at line 1241 of file PathTest.cpp.

1241 {
1242 SkPoint p0[] = {
1243 { 372.0f, 92.0f },
1244 { 372.0f, 92.0f },
1245 { 372.0f, 92.0f },
1246 { 372.0f, 92.0f },
1247 };
1248
1249 stroke_cubic(p0);
1250
1251 SkPoint p1[] = {
1252 { 372.0f, 92.0f },
1253 { 372.0007f, 92.000755f },
1254 { 371.99927f, 92.003922f },
1255 { 371.99826f, 92.003899f },
1256 };
1257
1258 stroke_cubic(p1);
1259}
static void stroke_cubic(const SkPoint pts[4])
Definition: PathTest.cpp:1225

◆ survive()

template<typename ISA >
void survive ( SkPath path,
const Xforms x,
bool  isAxisAligned,
skiatest::Reporter reporter,
ISA  isa_proc 
)

Definition at line 5779 of file PathTest.cpp.

5780 {
5781 REPORTER_ASSERT(reporter, isa_proc(*path));
5782 // force the issue (computing convexity) the first time.
5783 REPORTER_ASSERT(reporter, path->isConvex());
5784
5785 SkPath path2;
5786
5787 // a path's isa and convexity should survive assignment
5788 path2 = *path;
5789 REPORTER_ASSERT(reporter, isa_proc(path2));
5791
5792 // a path's isa and convexity should identity transform
5793 path->transform(x.fIM, &path2);
5794 path->transform(x.fIM);
5795 REPORTER_ASSERT(reporter, isa_proc(path2));
5797 REPORTER_ASSERT(reporter, isa_proc(*path));
5799
5800 // a path's isa should survive translation, convexity depends on axis alignment
5801 path->transform(x.fTM, &path2);
5802 path->transform(x.fTM);
5803 REPORTER_ASSERT(reporter, isa_proc(path2));
5804 REPORTER_ASSERT(reporter, isa_proc(*path));
5807
5808 // a path's isa should survive scaling, convexity depends on axis alignment
5809 path->transform(x.fSM, &path2);
5810 path->transform(x.fSM);
5811 REPORTER_ASSERT(reporter, isa_proc(path2));
5812 REPORTER_ASSERT(reporter, isa_proc(*path));
5815
5816 // For security, post-rotation, we can't assume we're still convex. It might prove to be,
5817 // in fact, still be convex, be we can't have cached that setting, hence the call to
5818 // getConvexityOrUnknown() instead of getConvexity().
5819 path->transform(x.fRM, &path2);
5820 path->transform(x.fRM);
5823
5824 if (isAxisAligned) {
5825 REPORTER_ASSERT(reporter, !isa_proc(path2));
5826 REPORTER_ASSERT(reporter, !isa_proc(*path));
5827 }
5828}
static bool conditional_convex(const SkPath &path, bool is_convex)
Definition: PathTest.cpp:5772
static bool isAxisAligned(const SkScalerContextRec &rec)

◆ test_add_rrect()

static void test_add_rrect ( skiatest::Reporter reporter,
const SkRect bounds,
const SkVector  radii[4] 
)
static

Definition at line 67 of file PathTest.cpp.

68 {
72
74 // this line should not assert in the debug build (from validate)
75 path.addRRect(rrect);
76 REPORTER_ASSERT(reporter, bounds == path.getBounds());
77}
const SkRect & rect() const
Definition: SkRRect.h:264
SkRRect rrect
Definition: SkRecords.h:232

◆ test_addEmptyPath()

static void test_addEmptyPath ( skiatest::Reporter reporter,
SkPath::AddPathMode  mode 
)
static

Definition at line 4269 of file PathTest.cpp.

4269 {
4270 SkPath p, q, r;
4271 // case 1: dst is empty
4272 p.moveTo(2, 1);
4273 p.lineTo(2, 3);
4274 q.addPath(p, mode);
4275 REPORTER_ASSERT(reporter, q == p);
4276 // case 2: src is empty
4277 p.addPath(r, mode);
4278 REPORTER_ASSERT(reporter, q == p);
4279 // case 3: src and dst are empty
4280 q.reset();
4281 q.addPath(r, mode);
4283}
bool isEmpty() const
Definition: SkPath.cpp:416
SkPath & reset()
Definition: SkPath.cpp:370
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228

◆ test_addPath()

static void test_addPath ( skiatest::Reporter reporter)
static

Definition at line 4205 of file PathTest.cpp.

4205 {
4206 SkPath p, q;
4207 p.lineTo(1, 2);
4208 q.moveTo(4, 4);
4209 q.lineTo(7, 8);
4210 q.conicTo(8, 7, 6, 5, 0.5f);
4211 q.quadTo(6, 7, 8, 6);
4212 q.cubicTo(5, 6, 7, 8, 7, 5);
4213 q.close();
4214 p.addPath(q, -4, -4);
4215 SkRect expected = {0, 0, 4, 4};
4216 REPORTER_ASSERT(reporter, p.getBounds() == expected);
4217 p.reset();
4218 p.reverseAddPath(q);
4219 SkRect reverseExpected = {4, 4, 8, 8};
4220 REPORTER_ASSERT(reporter, p.getBounds() == reverseExpected);
4221}
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
Definition: SkPath.cpp:746
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
Definition: SkPath.cpp:799
SkPath & conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar w)
Definition: SkPath.cpp:766
SkPath & close()
Definition: SkPath.cpp:823

◆ test_addPath_and_injected_moveTo()

static void test_addPath_and_injected_moveTo ( skiatest::Reporter reporter)
static

Definition at line 5988 of file PathTest.cpp.

5988 {
5989 /*
5990 * Given a path, and the expected last-point and last-move-to in it,
5991 * assert that, after a lineTo(), that the injected moveTo corresponds
5992 * to the expected value.
5993 */
5994 auto test_before_after_lineto = [reporter](SkPath& path,
5995 SkPoint expectedLastPt,
5996 SkPoint expectedMoveTo) {
5997 SkPoint p = path.getPoint(path.countPoints() - 1);
5998 REPORTER_ASSERT(reporter, p == expectedLastPt);
5999
6000 const SkPoint newLineTo = {1234, 5678};
6001 path.lineTo(newLineTo);
6002
6003 p = path.getPoint(path.countPoints() - 2);
6004 REPORTER_ASSERT(reporter, p == expectedMoveTo); // this was injected by lineTo()
6005
6006 p = path.getPoint(path.countPoints() - 1);
6007 REPORTER_ASSERT(reporter, p == newLineTo);
6008 };
6009
6010 SkPath path1;
6011 path1.moveTo(230, 230); // Needed to show the bug: a moveTo before the addRect
6012 path1.moveTo(20,30).lineTo(40,30).lineTo(40,50).lineTo(20,50);
6013 SkPath path1c(path1);
6014 path1c.close();
6015
6016 SkPath path2;
6017 // If path2 contains zero points, the update calculation isn't tested.
6018 path2.moveTo(144, 72);
6019 path2.lineTo(146, 72);
6020 SkPath path2c(path2);
6021 path2c.close();
6023 SkPath path3c(path2c);
6024
6025 // Test addPath, adding a path that ends with close.
6026 // The start point of the last contour added,
6027 // and the internal flag tracking whether it is closed,
6028 // must be updated correctly.
6029 path2.addPath(path1c);
6030 path2c.addPath(path1c);
6031 // At this point, path1c, path2, and path2c should end the same way.
6032 test_before_after_lineto(path1c, {20,50}, {20,30});
6033 test_before_after_lineto(path2, {20,50}, {20,30});
6034 test_before_after_lineto(path2c, {20,50}, {20,30});
6035
6036 // Test addPath, adding a path not ending in close.
6038 path3c.addPath(path1);
6039 // At this point, path1, path3, and path3c should end the same way.
6040 test_before_after_lineto(path1, {20,50}, {20,50});
6041 test_before_after_lineto(path3, {20,50}, {20,50});
6042 test_before_after_lineto(path3c, {20,50}, {20,50});
6043}
static SkPath path1()
static SkPath path3()

◆ test_addPathMode()

static void test_addPathMode ( skiatest::Reporter reporter,
bool  explicitMoveTo,
bool  extend 
)
static

Definition at line 4223 of file PathTest.cpp.

4223 {
4224 SkPath p, q;
4225 if (explicitMoveTo) {
4226 p.moveTo(1, 1);
4227 }
4228 p.lineTo(1, 2);
4229 if (explicitMoveTo) {
4230 q.moveTo(2, 1);
4231 }
4232 q.lineTo(2, 2);
4234 uint8_t verbs[4];
4235 int verbcount = p.getVerbs(verbs, 4);
4236 REPORTER_ASSERT(reporter, verbcount == 4);
4241}

◆ test_addPoly()

static void test_addPoly ( skiatest::Reporter reporter)
static

Definition at line 1056 of file PathTest.cpp.

1056 {
1057 SkPoint pts[32];
1058 SkRandom rand;
1059
1060 for (size_t i = 0; i < std::size(pts); ++i) {
1061 pts[i].fX = rand.nextSScalar1();
1062 pts[i].fY = rand.nextSScalar1();
1063 }
1064
1065 for (int doClose = 0; doClose <= 1; ++doClose) {
1066 for (size_t count = 1; count <= std::size(pts); ++count) {
1067 SkPath path;
1068 path.addPoly(pts, SkToInt(count), SkToBool(doClose));
1069 test_poly(reporter, path, pts, SkToBool(doClose));
1070 }
1071 }
1072}
static void test_poly(skiatest::Reporter *reporter, const SkPath &path, const SkPoint srcPts[], bool expectClose)
Definition: PathTest.cpp:1019
constexpr int SkToInt(S x)
Definition: SkTo.h:29
SkScalar nextSScalar1()
Definition: SkRandom.h:113

◆ test_addrect()

static void test_addrect ( skiatest::Reporter reporter)
static

Definition at line 659 of file PathTest.cpp.

659 {
660 SkPath path;
661 path.lineTo(0, 0);
662 path.addRect(SkRect::MakeWH(50, 100));
663 REPORTER_ASSERT(reporter, path.isRect(nullptr));
664
665 path.reset();
666 path.lineTo(FLT_EPSILON, FLT_EPSILON);
667 path.addRect(SkRect::MakeWH(50, 100));
668 REPORTER_ASSERT(reporter, !path.isRect(nullptr));
669
670 path.reset();
671 path.quadTo(0, 0, 0, 0);
672 path.addRect(SkRect::MakeWH(50, 100));
673 REPORTER_ASSERT(reporter, !path.isRect(nullptr));
674
675 path.reset();
676 path.conicTo(0, 0, 0, 0, 0.5f);
677 path.addRect(SkRect::MakeWH(50, 100));
678 REPORTER_ASSERT(reporter, !path.isRect(nullptr));
679
680 path.reset();
681 path.cubicTo(0, 0, 0, 0, 0, 0);
682 path.addRect(SkRect::MakeWH(50, 100));
683 REPORTER_ASSERT(reporter, !path.isRect(nullptr));
684}
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609

◆ test_addRect_and_trailing_lineTo()

static void test_addRect_and_trailing_lineTo ( skiatest::Reporter reporter)
static

Definition at line 5926 of file PathTest.cpp.

5926 {
5927 SkPath path;
5928 const SkRect r = {1, 2, 3, 4};
5929 // build our default p-array clockwise
5930 const SkPoint p[] = {
5931 {r.fLeft, r.fTop}, {r.fRight, r.fTop},
5932 {r.fRight, r.fBottom}, {r.fLeft, r.fBottom},
5933 };
5934
5936 int increment = dir == SkPathDirection::kCW ? 1 : 3;
5937 for (int i = 0; i < 4; ++i) {
5938 path.reset();
5939 path.addRect(r, dir, i);
5940
5941 // check that we return the 4 ponts in the expected order
5942 SkPoint e[4];
5943 for (int j = 0; j < 4; ++j) {
5944 int index = (i + j*increment) % 4;
5945 e[j] = p[index];
5946 }
5948 e[0], e[1], e[2], e[3]
5949 });
5950
5951 // check that the new line begins where the rect began
5952 path.lineTo(7,8);
5954 e[0], e[1], e[2], e[3],
5955 e[0], {7,8},
5956 });
5957 }
5958 }
5959
5960 // now add a moveTo before the rect, just to be sure we don't always look at
5961 // the "first" point in the path when we handle the trailing lineTo
5962 path.reset();
5963 path.moveTo(7, 8);
5964 path.addRect(r, SkPathDirection::kCW, 2);
5965 path.lineTo(5, 6);
5966
5968 {7,8}, // initial moveTo
5969 p[2], p[3], p[0], p[1], // rect
5970 p[2], {5, 6}, // trailing line
5971 });
5972}
static void assert_points(skiatest::Reporter *reporter, const SkPath &path, const std::initializer_list< SkPoint > &list)
Definition: PathTest.cpp:5902

◆ test_addrect_isfinite()

static void test_addrect_isfinite ( skiatest::Reporter reporter)
static

Definition at line 687 of file PathTest.cpp.

687 {
688 SkPath path;
689
690 path.addRect(SkRect::MakeWH(50, 100));
691 REPORTER_ASSERT(reporter, path.isFinite());
692
693 path.moveTo(0, 0);
694 path.lineTo(SK_ScalarInfinity, 42);
695 REPORTER_ASSERT(reporter, !path.isFinite());
696
697 path.addRect(SkRect::MakeWH(50, 100));
698 REPORTER_ASSERT(reporter, !path.isFinite());
699
700 path.reset();
701 REPORTER_ASSERT(reporter, path.isFinite());
702
703 path.addRect(SkRect::MakeWH(50, 100));
704 REPORTER_ASSERT(reporter, path.isFinite());
705}

◆ test_arb_round_rect_is_convex()

static void test_arb_round_rect_is_convex ( skiatest::Reporter reporter)
static

Definition at line 880 of file PathTest.cpp.

880 {
881 SkRandom rand;
882 SkRect r;
883
884 for (int i = 0; i < 5000; ++i) {
885
886 SkScalar size = rand.nextUScalar1() * 30;
887 if (size < SK_Scalar1) {
888 continue;
889 }
890 r.fLeft = rand.nextUScalar1() * 300;
891 r.fTop = rand.nextUScalar1() * 300;
892 r.fRight = r.fLeft + 2 * size;
893 r.fBottom = r.fTop + 2 * size;
894
895 SkPath temp;
896
897 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
898
900 }
901}
static void make_arb_round_rect(SkPath *path, const SkRect &r, SkScalar xCorner, SkScalar yCorner)
Definition: PathTest.cpp:866
SkScalar nextUScalar1()
Definition: SkRandom.h:101
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762

◆ test_arb_zero_rad_round_rect_is_rect()

static void test_arb_zero_rad_round_rect_is_rect ( skiatest::Reporter reporter)
static

Definition at line 907 of file PathTest.cpp.

907 {
908 SkRandom rand;
909 SkRect r;
910
911 for (int i = 0; i < 5000; ++i) {
912
913 SkScalar size = rand.nextUScalar1() * 30;
914 if (size < SK_Scalar1) {
915 continue;
916 }
917 r.fLeft = rand.nextUScalar1() * 300;
918 r.fTop = rand.nextUScalar1() * 300;
919 r.fRight = r.fLeft + 2 * size;
920 r.fBottom = r.fTop + 2 * size;
921
922 SkPath temp;
923
924 make_arb_round_rect(&temp, r, 0, 0);
925
929 }
930}
bool isRect(SkRect *rect, bool *isClosed=nullptr, SkPathDirection *direction=nullptr) const
Definition: SkPath.cpp:516
GAsyncResult * result

◆ test_arc()

static void test_arc ( skiatest::Reporter reporter)
static

Definition at line 3928 of file PathTest.cpp.

3928 {
3929 SkPath p;
3930 SkRect emptyOval = {10, 20, 30, 20};
3931 REPORTER_ASSERT(reporter, emptyOval.isEmpty());
3932 p.addArc(emptyOval, 1, 2);
3933 REPORTER_ASSERT(reporter, p.isEmpty());
3934 p.reset();
3935 SkRect oval = {10, 20, 30, 40};
3936 p.addArc(oval, 1, 0);
3937 REPORTER_ASSERT(reporter, p.isEmpty());
3938 p.reset();
3939 SkPath cwOval;
3940 cwOval.addOval(oval);
3941 p.addArc(oval, 0, 360);
3942 REPORTER_ASSERT(reporter, p == cwOval);
3943 p.reset();
3944 SkPath ccwOval;
3946 p.addArc(oval, 0, -360);
3947 REPORTER_ASSERT(reporter, p == ccwOval);
3948 p.reset();
3949 p.addArc(oval, 1, 180);
3950 // diagonal colinear points make arc convex
3951 // TODO: one way to keep it concave would be to introduce interpolated on curve points
3952 // between control points and computing the on curve point at scan conversion time
3953 REPORTER_ASSERT(reporter, p.isConvex());
3956 REPORTER_ASSERT(reporter, p.isConvex());
3957}
SkRect oval
Definition: SkRecords.h:249
bool isEmpty() const
Definition: SkRect.h:693

◆ test_arc_ovals()

static void test_arc_ovals ( skiatest::Reporter reporter)
static

Definition at line 3998 of file PathTest.cpp.

3998 {
3999 SkRect oval = SkRect::MakeWH(10, 20);
4000 for (SkScalar sweep : {-720.f, -540.f, -360.f, 360.f, 432.f, 720.f}) {
4001 for (SkScalar start = -360.f; start <= 360.f; start += 1.f) {
4002 SkPath path;
4003 path.addArc(oval, start, sweep);
4004 // SkPath's interfaces for inserting and extracting ovals only allow contours
4005 // to start at multiples of 90 degrees.
4006 if (std::fmod(start, 90.f) == 0) {
4008 } else {
4009 REPORTER_ASSERT(reporter, !path.isOval(nullptr));
4010 }
4011 }
4012 // Test start angles that are nearly at valid oval start angles.
4013 for (float start : {-180.f, -90.f, 90.f, 180.f}) {
4015 SkPath path;
4016 path.addArc(oval, start + delta, sweep);
4018 }
4019 }
4020 }
4021}
static void check_oval_arc(skiatest::Reporter *reporter, SkScalar start, SkScalar sweep, const SkPath &path)
Definition: PathTest.cpp:3984

◆ test_arcTo()

static void test_arcTo ( skiatest::Reporter reporter)
static

Definition at line 4139 of file PathTest.cpp.

4139 {
4140 SkPath p;
4141 p.arcTo(0, 0, 1, 2, 1);
4143 p.arcTo(1, 2, 1, 2, 1);
4145 p.arcTo(1, 2, 3, 4, 0);
4147 p.arcTo(1, 2, 0, 0, 1);
4149 p.arcTo(1, 0, 1, 1, 1);
4150 SkPoint pt;
4151 REPORTER_ASSERT(reporter, p.getLastPt(&pt) && pt.fX == 1 && pt.fY == 1);
4152 p.reset();
4153 p.arcTo(1, 0, 1, -1, 1);
4154 REPORTER_ASSERT(reporter, p.getLastPt(&pt) && pt.fX == 1 && pt.fY == -1);
4155 p.reset();
4156 SkRect oval = {1, 2, 3, 4};
4157 p.arcTo(oval, 0, 0, true);
4159 p.arcTo(oval, 0, 0, false);
4161 p.arcTo(oval, 360, 0, true);
4163 p.arcTo(oval, 360, 0, false);
4165
4166 for (float sweep = 359, delta = 0.5f; sweep != (float) (sweep + delta); ) {
4167 p.arcTo(oval, 0, sweep, false);
4168 REPORTER_ASSERT(reporter, nearly_equal(p.getBounds(), oval));
4169 sweep += delta;
4170 delta /= 2;
4171 }
4172 for (float sweep = 361, delta = 0.5f; sweep != (float) (sweep - delta);) {
4173 p.arcTo(oval, 0, sweep, false);
4174 REPORTER_ASSERT(reporter, nearly_equal(p.getBounds(), oval));
4175 sweep -= delta;
4176 delta /= 2;
4177 }
4178 SkRect noOvalWidth = {1, 2, 0, 3};
4179 p.reset();
4180 p.arcTo(noOvalWidth, 0, 360, false);
4181 REPORTER_ASSERT(reporter, p.isEmpty());
4182
4183 SkRect noOvalHeight = {1, 2, 3, 1};
4184 p.reset();
4185 p.arcTo(noOvalHeight, 0, 360, false);
4186 REPORTER_ASSERT(reporter, p.isEmpty());
4187
4188 // Inspired by http://code.google.com/p/chromium/issues/detail?id=1001768
4189 {
4190 p.reset();
4191 p.moveTo(216, 216);
4192 p.arcTo(216, 108, 0, SkPath::ArcSize::kLarge_ArcSize, SkPathDirection::kCW, 216, 0);
4193 p.arcTo(270, 135, 0, SkPath::ArcSize::kLarge_ArcSize, SkPathDirection::kCCW, 216, 216);
4194
4195 // The 'arcTo' call should end up exactly at the starting location.
4196 int n = p.countPoints();
4197 REPORTER_ASSERT(reporter, p.getPoint(0) == p.getPoint(n - 1));
4198 }
4199
4200 // This test, if improperly handled, can create an infinite loop in angles_to_unit_vectors
4201 p.reset();
4202 p.arcTo(SkRect::MakeXYWH(0, 0, 10, 10), -2.61488527e+33f, 359.992157f, false);
4203}
static void check_path_is_move_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x0, SkScalar y0)
Definition: PathTest.cpp:4064
static void check_path_is_line_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1)
Definition: PathTest.cpp:4071
constexpr float centerY() const
Definition: SkRect.h:785

◆ test_bad_cubic_crbug229478()

static void test_bad_cubic_crbug229478 ( )
static

Definition at line 467 of file PathTest.cpp.

467 {
468 const SkPoint pts[] = {
469 { 4595.91064f, -11596.9873f },
470 { 4597.2168f, -11595.9414f },
471 { 4598.52344f, -11594.8955f },
472 { 4599.83008f, -11593.8496f },
473 };
474
475 SkPath path;
476 path.moveTo(pts[0]);
477 path.cubicTo(pts[1], pts[2], pts[3]);
478
481 paint.setStrokeWidth(20);
482
483 SkPath dst;
484 // Before the fix, this would infinite-recurse, and run out of stack
485 // because we would keep trying to subdivide a degenerate cubic segment.
487}
dst
Definition: cp.py:12

◆ test_bad_cubic_crbug234190()

static void test_bad_cubic_crbug234190 ( )
static

Definition at line 458 of file PathTest.cpp.

458 {
459 SkPath path;
460 path.moveTo(13.8509f, 3.16858f);
461 path.cubicTo(-2.35893e+08f, -4.21044e+08f,
462 -2.38991e+08f, -4.26573e+08f,
463 -2.41016e+08f, -4.30188e+08f);
464 test_draw_AA_path(84, 88, path);
465}
static void test_draw_AA_path(int width, int height, const SkPath &path)
Definition: PathTest.cpp:180

◆ test_bounds()

static void test_bounds ( skiatest::Reporter reporter)
static

Definition at line 1208 of file PathTest.cpp.

1208 {
1209 static const SkRect rects[] = {
1210 { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(160) },
1211 { SkIntToScalar(610), SkIntToScalar(160), SkIntToScalar(610), SkIntToScalar(199) },
1212 { SkIntToScalar(10), SkIntToScalar(198), SkIntToScalar(610), SkIntToScalar(199) },
1213 { SkIntToScalar(10), SkIntToScalar(160), SkIntToScalar(10), SkIntToScalar(199) },
1214 };
1215
1216 SkPath path0, path1;
1217 for (size_t i = 0; i < std::size(rects); ++i) {
1218 path0.addRect(rects[i]);
1219 add_rect(&path1, rects[i]);
1220 }
1221
1223}
static void add_rect(SkPath *path, const SkRect &r)
Definition: PathTest.cpp:1200

◆ test_bounds_crbug_513799()

static void test_bounds_crbug_513799 ( skiatest::Reporter reporter)
static

Definition at line 754 of file PathTest.cpp.

754 {
755 SkPath path;
756#if 0
757 // As written these tests were failing on LLVM 4.2 MacMini Release mysteriously, so we've
758 // rewritten them to avoid this (compiler-bug?).
759 REPORTER_ASSERT(reporter, SkRect::MakeLTRB(0, 0, 0, 0) == path.getBounds());
760
761 path.moveTo(-5, -8);
762 REPORTER_ASSERT(reporter, SkRect::MakeLTRB(-5, -8, -5, -8) == path.getBounds());
763
764 path.addRect(SkRect::MakeLTRB(1, 2, 3, 4));
765 REPORTER_ASSERT(reporter, SkRect::MakeLTRB(-5, -8, 3, 4) == path.getBounds());
766
767 path.moveTo(1, 2);
768 REPORTER_ASSERT(reporter, SkRect::MakeLTRB(-5, -8, 3, 4) == path.getBounds());
769#else
770 dump_if_ne(reporter, SkRect::MakeLTRB(0, 0, 0, 0), path.getBounds());
771
772 path.moveTo(-5, -8); // should set the bounds
773 dump_if_ne(reporter, SkRect::MakeLTRB(-5, -8, -5, -8), path.getBounds());
774
775 path.addRect(SkRect::MakeLTRB(1, 2, 3, 4)); // should extend the bounds
776 dump_if_ne(reporter, SkRect::MakeLTRB(-5, -8, 3, 4), path.getBounds());
777
778 path.moveTo(1, 2); // don't expect this to have changed the bounds
779 dump_if_ne(reporter, SkRect::MakeLTRB(-5, -8, 3, 4), path.getBounds());
780#endif
781}
static void dump_if_ne(skiatest::Reporter *reporter, const SkRect &expected, const SkRect &bounds)
Definition: PathTest.cpp:746

◆ test_circle()

static void test_circle ( skiatest::Reporter reporter)
static

Definition at line 3671 of file PathTest.cpp.

3671 {
3674
3675 // multiple addCircle()
3676 SkPath path;
3677 path.addCircle(0, 0, SkIntToScalar(10), SkPathDirection::kCW);
3678 path.addCircle(0, 0, SkIntToScalar(20), SkPathDirection::kCW);
3680
3681 // some extra lineTo() would make isOval() fail
3682 path.reset();
3683 path.addCircle(0, 0, SkIntToScalar(10), SkPathDirection::kCW);
3684 path.lineTo(0, 0);
3686
3687 // not back to the original point
3688 path.reset();
3689 path.addCircle(0, 0, SkIntToScalar(10), SkPathDirection::kCW);
3690 path.setLastPt(SkIntToScalar(5), SkIntToScalar(5));
3692
3694
3695 // test negative radius
3696 path.reset();
3697 path.addCircle(0, 0, -1, SkPathDirection::kCW);
3698 REPORTER_ASSERT(reporter, path.isEmpty());
3699}
static void test_circle_with_add_paths(skiatest::Reporter *reporter)
Definition: PathTest.cpp:3635
static void check_for_circle(skiatest::Reporter *reporter, const SkPath &path, bool expectedCircle, SkPathFirstDirection expectedDir)
Definition: PathTest.cpp:3468
static void test_circle_with_direction(skiatest::Reporter *reporter, SkPathDirection inDir)
Definition: PathTest.cpp:3593

◆ test_circle_mirror_x()

static void test_circle_mirror_x ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  dir 
)
static

Definition at line 3544 of file PathTest.cpp.

3546 {
3547 SkPath tmp;
3548 SkMatrix m;
3549 m.reset();
3550 m.setScaleX(-SK_Scalar1);
3551 path.transform(m, &tmp);
3554 } else {
3557 }
3558 check_for_circle(reporter, tmp, true, dir);
3559}

◆ test_circle_mirror_xy()

static void test_circle_mirror_xy ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  dir 
)
static

Definition at line 3580 of file PathTest.cpp.

3582 {
3583 SkPath tmp;
3584 SkMatrix m;
3585 m.reset();
3586 m.setScaleX(-SK_Scalar1);
3587 m.setScaleY(-SK_Scalar1);
3588 path.transform(m, &tmp);
3589
3590 check_for_circle(reporter, tmp, true, dir);
3591}

◆ test_circle_mirror_y()

static void test_circle_mirror_y ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  dir 
)
static

Definition at line 3561 of file PathTest.cpp.

3563 {
3564 SkPath tmp;
3565 SkMatrix m;
3566 m.reset();
3567 m.setScaleY(-SK_Scalar1);
3568 path.transform(m, &tmp);
3569
3572 } else {
3575 }
3576
3577 check_for_circle(reporter, tmp, true, dir);
3578}

◆ test_circle_rotate()

static void test_circle_rotate ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  dir 
)
static

Definition at line 3524 of file PathTest.cpp.

3526 {
3527 for (int angle = 0; angle < 360; ++angle) {
3528 SkPath tmp;
3529 SkMatrix m;
3530 m.setRotate(SkIntToScalar(angle));
3531 path.transform(m, &tmp);
3532
3533 // TODO: a rotated circle whose rotated angle is not a multiple of 90
3534 // degrees is not an oval anymore, this can be improved. we made this
3535 // for the simplicity of our implementation.
3536 if (angle % 90 == 0) {
3537 check_for_circle(reporter, tmp, true, dir);
3538 } else {
3539 check_for_circle(reporter, tmp, false, dir);
3540 }
3541 }
3542}

◆ test_circle_skew()

static void test_circle_skew ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  dir 
)
static

Definition at line 3486 of file PathTest.cpp.

3488 {
3489 SkPath tmp;
3490
3491 SkMatrix m;
3492 m.setSkew(SkIntToScalar(3), SkIntToScalar(5));
3493 path.transform(m, &tmp);
3494 // this matrix reverses the direction.
3497 } else {
3500 }
3501 check_for_circle(reporter, tmp, false, dir);
3502}

◆ test_circle_translate()

static void test_circle_translate ( skiatest::Reporter reporter,
const SkPath path,
SkPathFirstDirection  dir 
)
static

Definition at line 3504 of file PathTest.cpp.

3506 {
3507 SkPath tmp;
3508
3509 // translate at small offset
3510 SkMatrix m;
3511 m.setTranslate(SkIntToScalar(15), SkIntToScalar(15));
3512 path.transform(m, &tmp);
3513 check_for_circle(reporter, tmp, true, dir);
3514
3515 tmp.reset();
3516 m.reset();
3517
3518 // translate at a relatively big offset
3519 m.setTranslate(SkIntToScalar(1000), SkIntToScalar(1000));
3520 path.transform(m, &tmp);
3521 check_for_circle(reporter, tmp, true, dir);
3522}

◆ test_circle_with_add_paths()

static void test_circle_with_add_paths ( skiatest::Reporter reporter)
static

Definition at line 3635 of file PathTest.cpp.

3635 {
3636 SkPath path;
3637 SkPath circle;
3638 SkPath rect;
3639 SkPath empty;
3640
3641 const SkPathDirection kCircleDir = SkPathDirection::kCW;
3642 const SkPathDirection kCircleDirOpposite = SkPathDirection::kCCW;
3643
3644 circle.addCircle(0, 0, SkIntToScalar(10), kCircleDir);
3645 rect.addRect(SkIntToScalar(5), SkIntToScalar(5),
3647
3648 SkMatrix translate;
3649 translate.setTranslate(SkIntToScalar(12), SkIntToScalar(12));
3650
3651 // Although all the path concatenation related operations leave
3652 // the path a circle, most mark it as a non-circle for simplicity
3653
3654 // empty + circle (translate)
3655 path = empty;
3656 path.addPath(circle, translate);
3658
3659 // circle + empty (translate)
3660 path = circle;
3661 path.addPath(empty, translate);
3662
3664
3665 // test reverseAddPath
3666 path = circle;
3667 path.reverseAddPath(rect);
3668 check_for_circle(reporter, path, false, SkPathPriv::AsFirstDirection(kCircleDirOpposite));
3669}
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:254
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1213

◆ test_circle_with_direction()

static void test_circle_with_direction ( skiatest::Reporter reporter,
SkPathDirection  inDir 
)
static

Definition at line 3593 of file PathTest.cpp.

3594 {
3596 SkPath path;
3597
3598 // circle at origin
3599 path.addCircle(0, 0, SkIntToScalar(20), inDir);
3600
3608
3609 // circle at an offset at (10, 10)
3610 path.reset();
3611 path.addCircle(SkIntToScalar(10), SkIntToScalar(10),
3612 SkIntToScalar(20), inDir);
3613
3621
3622 // Try different starting points for the contour.
3623 for (unsigned start = 0; start < 4; ++start) {
3624 path.reset();
3625 path.addOval(SkRect::MakeXYWH(20, 10, 5, 5), inDir, start);
3632 }
3633}
static void test_circle_translate(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
Definition: PathTest.cpp:3504
static void test_circle_rotate(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
Definition: PathTest.cpp:3524
static void test_circle_mirror_x(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
Definition: PathTest.cpp:3544
static void test_circle_mirror_xy(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
Definition: PathTest.cpp:3580
static void test_circle_mirror_y(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
Definition: PathTest.cpp:3561
static void test_circle_skew(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection dir)
Definition: PathTest.cpp:3486

◆ test_clipped_cubic()

static void test_clipped_cubic ( )
static

Definition at line 728 of file PathTest.cpp.

728 {
730
731 // This path used to assert, because our cubic-chopping code incorrectly
732 // moved control points after the chop. This test should be run in SK_DEBUG
733 // mode to ensure that we no long assert.
734 SkPath path;
735 for (int doReducedCase = 0; doReducedCase <= 1; ++doReducedCase) {
736 build_big_path(&path, SkToBool(doReducedCase));
737
739 for (int doAA = 0; doAA <= 1; ++doAA) {
740 paint.setAntiAlias(SkToBool(doAA));
741 surface->getCanvas()->drawPath(path, paint);
742 }
743 }
744}
static void build_big_path(SkPath *path, bool reducedCase)
Definition: PathTest.cpp:707

◆ test_close()

static void test_close ( skiatest::Reporter reporter)
static

Definition at line 1290 of file PathTest.cpp.

1290 {
1291 SkPath closePt;
1292 closePt.moveTo(0, 0);
1293 closePt.close();
1294 check_close(reporter, closePt);
1295
1296 SkPath openPt;
1297 openPt.moveTo(0, 0);
1298 check_close(reporter, openPt);
1299
1300 SkPath empty;
1302 empty.close();
1304
1305 SkPath rect;
1306 rect.addRect(SK_Scalar1, SK_Scalar1, 10 * SK_Scalar1, 10*SK_Scalar1);
1308 rect.close();
1310
1311 SkPath quad;
1313 check_close(reporter, quad);
1314 quad.close();
1315 check_close(reporter, quad);
1316
1317 SkPath cubic;
1319 10*SK_Scalar1, 20 * SK_Scalar1, 20*SK_Scalar1);
1321 cubic.close();
1323
1324 SkPath line;
1325 line.moveTo(SK_Scalar1, SK_Scalar1);
1326 line.lineTo(10 * SK_Scalar1, 10*SK_Scalar1);
1328 line.close();
1330
1331 SkPath rect2;
1333 rect2.close();
1335 check_close(reporter, rect2);
1336 rect2.close();
1337 check_close(reporter, rect2);
1338
1339 SkPath oval3;
1341 oval3.close();
1343 check_close(reporter, oval3);
1344 oval3.close();
1345 check_close(reporter, oval3);
1346
1347 SkPath moves;
1349 moves.moveTo(5 * SK_Scalar1, SK_Scalar1);
1350 moves.moveTo(SK_Scalar1, 10 * SK_Scalar1);
1351 moves.moveTo(10 *SK_Scalar1, SK_Scalar1);
1352 check_close(reporter, moves);
1353
1355}
static void stroke_tiny_cubic()
Definition: PathTest.cpp:1241
static void check_close(skiatest::Reporter *reporter, const SkPath &path)
Definition: PathTest.cpp:1261
AI float cubic(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:195

◆ test_conicTo_special_case()

static void test_conicTo_special_case ( skiatest::Reporter reporter)
static

Definition at line 4285 of file PathTest.cpp.

4285 {
4286 SkPath p;
4287 p.conicTo(1, 2, 3, 4, -1);
4289 p.conicTo(1, 2, 3, 4, SK_ScalarInfinity);
4291 p.conicTo(1, 2, 3, 4, 1);
4293}
static void check_path_is_line_pair_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
Definition: PathTest.cpp:4087
static void check_path_is_quad_and_reset(skiatest::Reporter *reporter, SkPath *p, SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
Definition: PathTest.cpp:4096

◆ test_conservativelyContains()

static void test_conservativelyContains ( skiatest::Reporter reporter)
static

Definition at line 1872 of file PathTest.cpp.

1872 {
1873 SkPath path;
1874
1875 // kBaseRect is used to construct most our test paths: a rect, a circle, and a round-rect.
1876 static const SkRect kBaseRect = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
1877
1878 // A circle that bounds kBaseRect (with a significant amount of slop)
1879 SkScalar circleR = std::max(kBaseRect.width(), kBaseRect.height());
1880 circleR *= 1.75f / 2;
1881 static const SkPoint kCircleC = {kBaseRect.centerX(), kBaseRect.centerY()};
1882
1883 // round-rect radii
1884 static const SkScalar kRRRadii[] = {SkIntToScalar(5), SkIntToScalar(3)};
1885
1886 static const struct SUPPRESS_VISIBILITY_WARNING {
1887 SkRect fQueryRect;
1888 bool fInRect;
1889 bool fInCircle;
1890 bool fInRR;
1891 bool fInCubicRR;
1892 } kQueries[] = {
1893 {kBaseRect, true, true, false, false},
1894
1895 // rect well inside of kBaseRect
1896 {SkRect::MakeLTRB(kBaseRect.fLeft + 0.25f*kBaseRect.width(),
1897 kBaseRect.fTop + 0.25f*kBaseRect.height(),
1898 kBaseRect.fRight - 0.25f*kBaseRect.width(),
1899 kBaseRect.fBottom - 0.25f*kBaseRect.height()),
1900 true, true, true, true},
1901
1902 // rects with edges off by one from kBaseRect's edges
1903 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
1904 kBaseRect.width(), kBaseRect.height() + 1),
1905 false, true, false, false},
1906 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
1907 kBaseRect.width() + 1, kBaseRect.height()),
1908 false, true, false, false},
1909 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop,
1910 kBaseRect.width() + 1, kBaseRect.height() + 1),
1911 false, true, false, false},
1912 {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop,
1913 kBaseRect.width(), kBaseRect.height()),
1914 false, true, false, false},
1915 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1,
1916 kBaseRect.width(), kBaseRect.height()),
1917 false, true, false, false},
1918 {SkRect::MakeXYWH(kBaseRect.fLeft - 1, kBaseRect.fTop,
1919 kBaseRect.width() + 2, kBaseRect.height()),
1920 false, true, false, false},
1921 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop - 1,
1922 kBaseRect.width() + 2, kBaseRect.height()),
1923 false, true, false, false},
1924
1925 // zero-w/h rects at each corner of kBaseRect
1926 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fTop, 0, 0), true, true, false, false},
1927 {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fTop, 0, 0), true, true, false, true},
1928 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.fBottom, 0, 0), true, true, false, true},
1929 {SkRect::MakeXYWH(kBaseRect.fRight, kBaseRect.fBottom, 0, 0), true, true, false, true},
1930
1931 // far away rect
1932 {SkRect::MakeXYWH(10 * kBaseRect.fRight, 10 * kBaseRect.fBottom,
1933 SkIntToScalar(10), SkIntToScalar(10)),
1934 false, false, false, false},
1935
1936 // very large rect containing kBaseRect
1937 {SkRect::MakeXYWH(kBaseRect.fLeft - 5 * kBaseRect.width(),
1938 kBaseRect.fTop - 5 * kBaseRect.height(),
1939 11 * kBaseRect.width(), 11 * kBaseRect.height()),
1940 false, false, false, false},
1941
1942 // skinny rect that spans same y-range as kBaseRect
1943 {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop,
1944 SkIntToScalar(1), kBaseRect.height()),
1945 true, true, true, true},
1946
1947 // short rect that spans same x-range as kBaseRect
1948 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(), kBaseRect.width(), SkScalar(1)),
1949 true, true, true, true},
1950
1951 // skinny rect that spans slightly larger y-range than kBaseRect
1952 {SkRect::MakeXYWH(kBaseRect.centerX(), kBaseRect.fTop,
1953 SkIntToScalar(1), kBaseRect.height() + 1),
1954 false, true, false, false},
1955
1956 // short rect that spans slightly larger x-range than kBaseRect
1957 {SkRect::MakeXYWH(kBaseRect.fLeft, kBaseRect.centerY(),
1958 kBaseRect.width() + 1, SkScalar(1)),
1959 false, true, false, false},
1960 };
1961
1962 for (int inv = 0; inv < 4; ++inv) {
1963 for (size_t q = 0; q < std::size(kQueries); ++q) {
1964 SkRect qRect = kQueries[q].fQueryRect;
1965 if (inv & 0x1) {
1966 using std::swap;
1967 swap(qRect.fLeft, qRect.fRight);
1968 }
1969 if (inv & 0x2) {
1970 using std::swap;
1971 swap(qRect.fTop, qRect.fBottom);
1972 }
1973 for (int d = 0; d < 2; ++d) {
1975 path.reset();
1976 path.addRect(kBaseRect, dir);
1977 REPORTER_ASSERT(reporter, kQueries[q].fInRect ==
1978 path.conservativelyContainsRect(qRect));
1979
1980 path.reset();
1981 path.addCircle(kCircleC.fX, kCircleC.fY, circleR, dir);
1982 REPORTER_ASSERT(reporter, kQueries[q].fInCircle ==
1983 path.conservativelyContainsRect(qRect));
1984
1985 path.reset();
1986 path.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1], dir);
1987 REPORTER_ASSERT(reporter, kQueries[q].fInRR ==
1988 path.conservativelyContainsRect(qRect));
1989
1990 path.reset();
1991 path.moveTo(kBaseRect.fLeft + kRRRadii[0], kBaseRect.fTop);
1992 path.cubicTo(kBaseRect.fLeft + kRRRadii[0] / 2, kBaseRect.fTop,
1993 kBaseRect.fLeft, kBaseRect.fTop + kRRRadii[1] / 2,
1994 kBaseRect.fLeft, kBaseRect.fTop + kRRRadii[1]);
1995 path.lineTo(kBaseRect.fLeft, kBaseRect.fBottom);
1996 path.lineTo(kBaseRect.fRight, kBaseRect.fBottom);
1997 path.lineTo(kBaseRect.fRight, kBaseRect.fTop);
1998 path.close();
1999 REPORTER_ASSERT(reporter, kQueries[q].fInCubicRR ==
2000 path.conservativelyContainsRect(qRect));
2001
2002 }
2003 // Slightly non-convex shape, shouldn't contain any rects.
2004 path.reset();
2005 path.moveTo(0, 0);
2006 path.lineTo(SkIntToScalar(50), 0.05f);
2007 path.lineTo(SkIntToScalar(100), 0);
2008 path.lineTo(SkIntToScalar(100), SkIntToScalar(100));
2009 path.lineTo(0, SkIntToScalar(100));
2010 path.close();
2011 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(qRect));
2012 }
2013 }
2014
2015 // make sure a minimal convex shape works, a right tri with edges along pos x and y axes.
2016 path.reset();
2017 path.moveTo(0, 0);
2018 path.lineTo(SkIntToScalar(100), 0);
2019 path.lineTo(0, SkIntToScalar(100));
2020
2021 // inside, on along top edge
2022 REPORTER_ASSERT(reporter, path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(50), 0,
2023 SkIntToScalar(10),
2024 SkIntToScalar(10))));
2025 // above
2026 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(
2028 SkIntToScalar(-10),
2029 SkIntToScalar(10),
2030 SkIntToScalar(10))));
2031 // to the left
2032 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(-10),
2033 SkIntToScalar(5),
2034 SkIntToScalar(5),
2035 SkIntToScalar(5))));
2036
2037 // outside the diagonal edge
2038 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(10),
2039 SkIntToScalar(200),
2040 SkIntToScalar(20),
2041 SkIntToScalar(5))));
2042
2043
2044 // Test that multiple move commands do not cause asserts.
2045 path.moveTo(SkIntToScalar(100), SkIntToScalar(100));
2046 REPORTER_ASSERT(reporter, path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(50), 0,
2047 SkIntToScalar(10),
2048 SkIntToScalar(10))));
2049
2050 // Same as above path and first test but with an extra moveTo.
2051 path.reset();
2052 path.moveTo(100, 100);
2053 path.moveTo(0, 0);
2054 path.lineTo(SkIntToScalar(100), 0);
2055 path.lineTo(0, SkIntToScalar(100));
2056 // Convexity logic treats a path as filled and closed, so that multiple (non-trailing) moveTos
2057 // have no effect on convexity
2058 REPORTER_ASSERT(reporter, path.conservativelyContainsRect(
2060 SkIntToScalar(10),
2061 SkIntToScalar(10))));
2062
2063 // Same as above path and first test but with the extra moveTo making a degenerate sub-path
2064 // following the non-empty sub-path. Verifies that this does not trigger assertions.
2065 path.reset();
2066 path.moveTo(0, 0);
2067 path.lineTo(SkIntToScalar(100), 0);
2068 path.lineTo(0, SkIntToScalar(100));
2069 path.moveTo(100, 100);
2070
2071 REPORTER_ASSERT(reporter, path.conservativelyContainsRect(SkRect::MakeXYWH(SkIntToScalar(50), 0,
2072 SkIntToScalar(10),
2073 SkIntToScalar(10))));
2074
2075 // Test that multiple move commands do not cause asserts and that the function
2076 // is not confused by the multiple moves.
2077 path.reset();
2078 path.moveTo(0, 0);
2079 path.lineTo(SkIntToScalar(100), 0);
2080 path.lineTo(0, SkIntToScalar(100));
2081 path.moveTo(0, SkIntToScalar(200));
2082 path.lineTo(SkIntToScalar(100), SkIntToScalar(200));
2083 path.lineTo(0, SkIntToScalar(300));
2084
2085 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(
2087 SkIntToScalar(10),
2088 SkIntToScalar(10))));
2089
2090 path.reset();
2091 path.lineTo(100, 100);
2092 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeXYWH(0, 0, 1, 1)));
2093
2094 // An empty path should not contain any rectangle. It's questionable whether an empty path
2095 // contains an empty rectangle. However, since it is a conservative test it is ok to
2096 // return false.
2097 path.reset();
2098 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(1,1)));
2099 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(0,0)));
2100
2101 path.reset();
2102 path.moveTo(50, 50);
2103 path.cubicTo(0, 0, 100, 0, 50, 50);
2104 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(100, 100)));
2105 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(30, 30)));
2106 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(1,1)));
2107 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(0,0)));
2108
2109 path.reset();
2110 path.moveTo(50, 50);
2111 path.quadTo(100, 100, 50, 50);
2112 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(1,1)));
2113 REPORTER_ASSERT(reporter, !path.conservativelyContainsRect(SkRect::MakeWH(0,0)));
2114}
static SkM44 inv(const SkM44 &m)
Definition: 3d.cpp:26
#define SUPPRESS_VISIBILITY_WARNING
Definition: PathTest.cpp:356
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
static float max(float r, float g, float b)
Definition: hsl.cpp:49
constexpr float centerX() const
Definition: SkRect.h:776

◆ test_contains()

static void test_contains ( skiatest::Reporter reporter)
static

Definition at line 4309 of file PathTest.cpp.

4309 {
4310 SkPath p;
4311 p.moveTo(SkBits2Float(0xe085e7b1), SkBits2Float(0x5f512c00)); // -7.7191e+19f, 1.50724e+19f
4312 p.conicTo(SkBits2Float(0xdfdaa221), SkBits2Float(0x5eaac338), SkBits2Float(0x60342f13), SkBits2Float(0xdf0cbb58), SkBits2Float(0x3f3504f3)); // -3.15084e+19f, 6.15237e+18f, 5.19345e+19f, -1.01408e+19f, 0.707107f
4313 p.conicTo(SkBits2Float(0x60ead799), SkBits2Float(0xdfb76c24), SkBits2Float(0x609b9872), SkBits2Float(0xdf730de8), SkBits2Float(0x3f3504f4)); // 1.35377e+20f, -2.6434e+19f, 8.96947e+19f, -1.75139e+19f, 0.707107f
4314 p.lineTo(SkBits2Float(0x609b9872), SkBits2Float(0xdf730de8)); // 8.96947e+19f, -1.75139e+19f
4315 p.conicTo(SkBits2Float(0x6018b296), SkBits2Float(0xdeee870d), SkBits2Float(0xe008cd8e), SkBits2Float(0x5ed5b2db), SkBits2Float(0x3f3504f3)); // 4.40121e+19f, -8.59386e+18f, -3.94308e+19f, 7.69931e+18f, 0.707107f
4316 p.conicTo(SkBits2Float(0xe0d526d9), SkBits2Float(0x5fa67b31), SkBits2Float(0xe085e7b2), SkBits2Float(0x5f512c01), SkBits2Float(0x3f3504f3)); // -1.22874e+20f, 2.39925e+19f, -7.7191e+19f, 1.50724e+19f, 0.707107f
4317 // this may return true or false, depending on the platform's numerics, but it should not crash
4318 (void) p.contains(-77.2027664f, 15.3066053f);
4319
4320 p.reset();
4322 REPORTER_ASSERT(reporter, p.contains(0, 0));
4323 p.setFillType(SkPathFillType::kWinding);
4324 REPORTER_ASSERT(reporter, !p.contains(0, 0));
4325 p.moveTo(4, 4);
4326 p.lineTo(6, 8);
4327 p.lineTo(8, 4);
4328 // test on edge
4329 REPORTER_ASSERT(reporter, p.contains(6, 4));
4330 REPORTER_ASSERT(reporter, p.contains(5, 6));
4331 REPORTER_ASSERT(reporter, p.contains(7, 6));
4332 // test quick reject
4333 REPORTER_ASSERT(reporter, !p.contains(4, 0));
4334 REPORTER_ASSERT(reporter, !p.contains(0, 4));
4335 REPORTER_ASSERT(reporter, !p.contains(4, 10));
4336 REPORTER_ASSERT(reporter, !p.contains(10, 4));
4337 // test various crossings in x
4338 REPORTER_ASSERT(reporter, !p.contains(5, 7));
4339 REPORTER_ASSERT(reporter, p.contains(6, 7));
4340 REPORTER_ASSERT(reporter, !p.contains(7, 7));
4341 p.reset();
4342 p.moveTo(4, 4);
4343 p.lineTo(8, 6);
4344 p.lineTo(4, 8);
4345 // test on edge
4346 REPORTER_ASSERT(reporter, p.contains(4, 6));
4347 REPORTER_ASSERT(reporter, p.contains(6, 5));
4348 REPORTER_ASSERT(reporter, p.contains(6, 7));
4349 // test various crossings in y
4350 REPORTER_ASSERT(reporter, !p.contains(7, 5));
4351 REPORTER_ASSERT(reporter, p.contains(7, 6));
4352 REPORTER_ASSERT(reporter, !p.contains(7, 7));
4353 p.reset();
4354 p.moveTo(4, 4);
4355 p.lineTo(8, 4);
4356 p.lineTo(8, 8);
4357 p.lineTo(4, 8);
4358 // test on vertices
4359 REPORTER_ASSERT(reporter, p.contains(4, 4));
4360 REPORTER_ASSERT(reporter, p.contains(8, 4));
4361 REPORTER_ASSERT(reporter, p.contains(8, 8));
4362 REPORTER_ASSERT(reporter, p.contains(4, 8));
4363 p.reset();
4364 p.moveTo(4, 4);
4365 p.lineTo(6, 8);
4366 p.lineTo(2, 8);
4367 // test on edge
4368 REPORTER_ASSERT(reporter, p.contains(5, 6));
4369 REPORTER_ASSERT(reporter, p.contains(4, 8));
4370 REPORTER_ASSERT(reporter, p.contains(3, 6));
4371 p.reset();
4372 p.moveTo(4, 4);
4373 p.lineTo(0, 6);
4374 p.lineTo(4, 8);
4375 // test on edge
4376 REPORTER_ASSERT(reporter, p.contains(2, 5));
4377 REPORTER_ASSERT(reporter, p.contains(2, 7));
4378 REPORTER_ASSERT(reporter, p.contains(4, 6));
4379 // test canceling coincident edge (a smaller triangle is coincident with a larger one)
4380 p.reset();
4381 p.moveTo(4, 0);
4382 p.lineTo(6, 4);
4383 p.lineTo(2, 4);
4384 p.moveTo(4, 0);
4385 p.lineTo(0, 8);
4386 p.lineTo(8, 8);
4387 REPORTER_ASSERT(reporter, !p.contains(1, 2));
4388 REPORTER_ASSERT(reporter, !p.contains(3, 2));
4389 REPORTER_ASSERT(reporter, !p.contains(4, 0));
4390 REPORTER_ASSERT(reporter, p.contains(4, 4));
4391
4392 // test quads
4393 p.reset();
4394 p.moveTo(4, 4);
4395 p.quadTo(6, 6, 8, 8);
4396 p.quadTo(6, 8, 4, 8);
4397 p.quadTo(4, 6, 4, 4);
4398 REPORTER_ASSERT(reporter, p.contains(5, 6));
4399 REPORTER_ASSERT(reporter, !p.contains(6, 5));
4400 // test quad edge
4401 REPORTER_ASSERT(reporter, p.contains(5, 5));
4402 REPORTER_ASSERT(reporter, p.contains(5, 8));
4403 REPORTER_ASSERT(reporter, p.contains(4, 5));
4404 // test quad endpoints
4405 REPORTER_ASSERT(reporter, p.contains(4, 4));
4406 REPORTER_ASSERT(reporter, p.contains(8, 8));
4407 REPORTER_ASSERT(reporter, p.contains(4, 8));
4408
4409 p.reset();
4410 const SkPoint qPts[] = {{6, 6}, {8, 8}, {6, 8}, {4, 8}, {4, 6}, {4, 4}, {6, 6}};
4411 p.moveTo(qPts[0]);
4412 for (int index = 1; index < (int) std::size(qPts); index += 2) {
4413 p.quadTo(qPts[index], qPts[index + 1]);
4414 }
4415 REPORTER_ASSERT(reporter, p.contains(5, 6));
4416 REPORTER_ASSERT(reporter, !p.contains(6, 5));
4417 // test quad edge
4418 SkPoint halfway;
4419 for (int index = 0; index < (int) std::size(qPts) - 2; index += 2) {
4420 SkEvalQuadAt(&qPts[index], 0.5f, &halfway, nullptr);
4421 REPORTER_ASSERT(reporter, p.contains(halfway.fX, halfway.fY));
4422 }
4423
4424 // test conics
4425 p.reset();
4426 const SkPoint kPts[] = {{4, 4}, {6, 6}, {8, 8}, {6, 8}, {4, 8}, {4, 6}, {4, 4}};
4427 p.moveTo(kPts[0]);
4428 for (int index = 1; index < (int) std::size(kPts); index += 2) {
4429 p.conicTo(kPts[index], kPts[index + 1], 0.5f);
4430 }
4431 REPORTER_ASSERT(reporter, p.contains(5, 6));
4432 REPORTER_ASSERT(reporter, !p.contains(6, 5));
4433 // test conic edge
4434 for (int index = 0; index < (int) std::size(kPts) - 2; index += 2) {
4435 SkConic conic(&kPts[index], 0.5f);
4436 halfway = conic.evalAt(0.5f);
4437 REPORTER_ASSERT(reporter, p.contains(halfway.fX, halfway.fY));
4438 }
4439 // test conic end points
4440 REPORTER_ASSERT(reporter, p.contains(4, 4));
4441 REPORTER_ASSERT(reporter, p.contains(8, 8));
4442 REPORTER_ASSERT(reporter, p.contains(4, 8));
4443
4444 // test cubics
4445 SkPoint pts[] = {{5, 4}, {6, 5}, {7, 6}, {6, 6}, {4, 6}, {5, 7}, {5, 5}, {5, 4}, {6, 5}, {7, 6}};
4446 for (int i = 0; i < 3; ++i) {
4447 p.reset();
4448 p.setFillType(SkPathFillType::kEvenOdd);
4449 p.moveTo(pts[i].fX, pts[i].fY);
4450 p.cubicTo(pts[i + 1].fX, pts[i + 1].fY, pts[i + 2].fX, pts[i + 2].fY, pts[i + 3].fX, pts[i + 3].fY);
4451 p.cubicTo(pts[i + 4].fX, pts[i + 4].fY, pts[i + 5].fX, pts[i + 5].fY, pts[i + 6].fX, pts[i + 6].fY);
4452 p.close();
4453 REPORTER_ASSERT(reporter, p.contains(5.5f, 5.5f));
4454 REPORTER_ASSERT(reporter, !p.contains(4.5f, 5.5f));
4455 // test cubic edge
4456 SkEvalCubicAt(&pts[i], 0.5f, &halfway, nullptr, nullptr);
4457 REPORTER_ASSERT(reporter, p.contains(halfway.fX, halfway.fY));
4458 SkEvalCubicAt(&pts[i + 3], 0.5f, &halfway, nullptr, nullptr);
4459 REPORTER_ASSERT(reporter, p.contains(halfway.fX, halfway.fY));
4460 // test cubic end points
4461 REPORTER_ASSERT(reporter, p.contains(pts[i].fX, pts[i].fY));
4462 REPORTER_ASSERT(reporter, p.contains(pts[i + 3].fX, pts[i + 3].fY));
4463 REPORTER_ASSERT(reporter, p.contains(pts[i + 6].fX, pts[i + 6].fY));
4464 }
4465}
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
Definition: SkGeometry.cpp:418
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
Definition: SkGeometry.cpp:132
AI float conic(float tolerance, const SkPoint pts[], float w, const VectorXform &vectorXform=VectorXform())
Definition: WangsFormula.h:287
static constexpr SkPoint kPts[kPtsCount]
Definition: emptypath.cpp:123

◆ test_convexity()

static void test_convexity ( skiatest::Reporter reporter)
static

Definition at line 1641 of file PathTest.cpp.

1641 {
1642 SkPath path;
1643
1645 path.addCircle(0, 0, SkIntToScalar(10));
1647 path.addCircle(0, 0, SkIntToScalar(10)); // 2nd circle
1648 check_convexity(reporter, path, false);
1649
1650 path.reset();
1651 path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPathDirection::kCCW);
1654
1655 path.reset();
1656 path.addRect(0, 0, SkIntToScalar(10), SkIntToScalar(10), SkPathDirection::kCW);
1659
1660 path.reset();
1661 path.quadTo(100, 100, 50, 50); // This from GM:convexpaths
1663
1664 static const struct {
1665 const char* fPathStr;
1666 bool fExpectedIsConvex;
1667 SkPathFirstDirection fExpectedDirection;
1668 } gRec[] = {
1669 { "", true, SkPathFirstDirection::kUnknown },
1670 { "0 0", true, SkPathFirstDirection::kUnknown },
1671 { "0 0 10 10", true, SkPathFirstDirection::kUnknown },
1672 { "0 0 10 10 20 20 0 0 10 10", false, SkPathFirstDirection::kUnknown },
1673 { "0 0 10 10 10 20", true, SkPathFirstDirection::kCW },
1674 { "0 0 10 10 10 0", true, SkPathFirstDirection::kCCW },
1675 { "0 0 10 10 10 0 0 10", false, kDontCheckDir },
1676 { "0 0 10 0 0 10 -10 -10", false, SkPathFirstDirection::kCW },
1677 };
1678
1679 for (size_t i = 0; i < std::size(gRec); ++i) {
1680 path.reset();
1681 setFromString(&path, gRec[i].fPathStr);
1682 check_convexity(reporter, path, gRec[i].fExpectedIsConvex);
1683 check_direction(reporter, path, gRec[i].fExpectedDirection);
1684 // check after setting the initial convex and direction
1685 if (kDontCheckDir != gRec[i].fExpectedDirection) {
1686 // We make a copy so that we don't cache the result on the passed in path.
1687 SkPath copy(path); // NOLINT(performance-unnecessary-copy-initialization)
1689 bool foundDir = dir != SkPathFirstDirection::kUnknown;
1691 ^ foundDir);
1692 REPORTER_ASSERT(reporter, !foundDir || gRec[i].fExpectedDirection == dir);
1693 check_convexity(reporter, copy, gRec[i].fExpectedIsConvex);
1694 }
1695 REPORTER_ASSERT(reporter, gRec[i].fExpectedIsConvex == path.isConvex());
1696 check_direction(reporter, path, gRec[i].fExpectedDirection);
1697 }
1698
1699 static const SkPoint nonFinitePts[] = {
1700 { SK_ScalarInfinity, 0 },
1701 { 0, SK_ScalarInfinity },
1708 { SK_ScalarNaN, 0 },
1709 { 0, SK_ScalarNaN },
1711 };
1712
1713 const size_t nonFinitePtsCount = sizeof(nonFinitePts) / sizeof(nonFinitePts[0]);
1714
1715 static const SkPoint axisAlignedPts[] = {
1716 { SK_ScalarMax, 0 },
1717 { 0, SK_ScalarMax },
1718 { SK_ScalarMin, 0 },
1719 { 0, SK_ScalarMin },
1720 };
1721
1722 const size_t axisAlignedPtsCount = sizeof(axisAlignedPts) / sizeof(axisAlignedPts[0]);
1723
1724 for (int index = 0; index < (int) (13 * nonFinitePtsCount * axisAlignedPtsCount); ++index) {
1725 int i = (int) (index % nonFinitePtsCount);
1726 int f = (int) (index % axisAlignedPtsCount);
1727 int g = (int) ((f + 1) % axisAlignedPtsCount);
1728 path.reset();
1729 switch (index % 13) {
1730 case 0: path.lineTo(nonFinitePts[i]); break;
1731 case 1: path.quadTo(nonFinitePts[i], nonFinitePts[i]); break;
1732 case 2: path.quadTo(nonFinitePts[i], axisAlignedPts[f]); break;
1733 case 3: path.quadTo(axisAlignedPts[f], nonFinitePts[i]); break;
1734 case 4: path.cubicTo(nonFinitePts[i], axisAlignedPts[f], axisAlignedPts[f]); break;
1735 case 5: path.cubicTo(axisAlignedPts[f], nonFinitePts[i], axisAlignedPts[f]); break;
1736 case 6: path.cubicTo(axisAlignedPts[f], axisAlignedPts[f], nonFinitePts[i]); break;
1737 case 7: path.cubicTo(nonFinitePts[i], nonFinitePts[i], axisAlignedPts[f]); break;
1738 case 8: path.cubicTo(nonFinitePts[i], axisAlignedPts[f], nonFinitePts[i]); break;
1739 case 9: path.cubicTo(axisAlignedPts[f], nonFinitePts[i], nonFinitePts[i]); break;
1740 case 10: path.cubicTo(nonFinitePts[i], nonFinitePts[i], nonFinitePts[i]); break;
1741 case 11: path.cubicTo(nonFinitePts[i], axisAlignedPts[f], axisAlignedPts[g]); break;
1742 case 12: path.moveTo(nonFinitePts[i]); break;
1743 }
1746 }
1747
1748 for (int index = 0; index < (int) (11 * axisAlignedPtsCount); ++index) {
1749 int f = (int) (index % axisAlignedPtsCount);
1750 int g = (int) ((f + 1) % axisAlignedPtsCount);
1751 path.reset();
1752 int curveSelect = index % 11;
1753 switch (curveSelect) {
1754 case 0: path.moveTo(axisAlignedPts[f]); break;
1755 case 1: path.lineTo(axisAlignedPts[f]); break;
1756 case 2: path.quadTo(axisAlignedPts[f], axisAlignedPts[f]); break;
1757 case 3: path.quadTo(axisAlignedPts[f], axisAlignedPts[g]); break;
1758 case 4: path.quadTo(axisAlignedPts[g], axisAlignedPts[f]); break;
1759 case 5: path.cubicTo(axisAlignedPts[f], axisAlignedPts[f], axisAlignedPts[f]); break;
1760 case 6: path.cubicTo(axisAlignedPts[f], axisAlignedPts[f], axisAlignedPts[g]); break;
1761 case 7: path.cubicTo(axisAlignedPts[f], axisAlignedPts[g], axisAlignedPts[f]); break;
1762 case 8: path.cubicTo(axisAlignedPts[f], axisAlignedPts[g], axisAlignedPts[g]); break;
1763 case 9: path.cubicTo(axisAlignedPts[g], axisAlignedPts[f], axisAlignedPts[f]); break;
1764 case 10: path.cubicTo(axisAlignedPts[g], axisAlignedPts[f], axisAlignedPts[g]); break;
1765 }
1766 if (curveSelect == 0 || curveSelect == 1 || curveSelect == 2 || curveSelect == 5) {
1768 } else {
1769 // We make a copy so that we don't cache the result on the passed in path.
1770 SkPath copy(path); // NOLINT(performance-unnecessary-copy-initialization)
1771 REPORTER_ASSERT(reporter, !copy.isConvex());
1772 }
1773 }
1774
1775 static const SkPoint diagonalPts[] = {
1778 };
1779
1780 const size_t diagonalPtsCount = sizeof(diagonalPts) / sizeof(diagonalPts[0]);
1781
1782 for (int index = 0; index < (int) (7 * diagonalPtsCount); ++index) {
1783 int f = (int) (index % diagonalPtsCount);
1784 int g = (int) ((f + 1) % diagonalPtsCount);
1785 path.reset();
1786 int curveSelect = index % 11;
1787 switch (curveSelect) {
1788 case 0: path.moveTo(diagonalPts[f]); break;
1789 case 1: path.lineTo(diagonalPts[f]); break;
1790 case 2: path.quadTo(diagonalPts[f], diagonalPts[f]); break;
1791 case 3: path.quadTo(axisAlignedPts[f], diagonalPts[g]); break;
1792 case 4: path.quadTo(diagonalPts[g], axisAlignedPts[f]); break;
1793 case 5: path.cubicTo(diagonalPts[f], diagonalPts[f], diagonalPts[f]); break;
1794 case 6: path.cubicTo(diagonalPts[f], diagonalPts[f], axisAlignedPts[g]); break;
1795 case 7: path.cubicTo(diagonalPts[f], axisAlignedPts[g], diagonalPts[f]); break;
1796 case 8: path.cubicTo(axisAlignedPts[f], diagonalPts[g], diagonalPts[g]); break;
1797 case 9: path.cubicTo(diagonalPts[g], diagonalPts[f], axisAlignedPts[f]); break;
1798 case 10: path.cubicTo(diagonalPts[g], axisAlignedPts[f], diagonalPts[g]); break;
1799 }
1800 if (curveSelect == 0) {
1802 } else {
1803 // We make a copy so that we don't cache the result on the passed in path.
1804 SkPath copy(path); // NOLINT(performance-unnecessary-copy-initialization)
1805 REPORTER_ASSERT(reporter, !copy.isConvex());
1806 }
1807 }
1808
1809
1810 path.reset();
1811 path.moveTo(SkBits2Float(0xbe9171db), SkBits2Float(0xbd7eeb5d)); // -0.284072f, -0.0622362f
1812 path.lineTo(SkBits2Float(0xbe9171db), SkBits2Float(0xbd7eea38)); // -0.284072f, -0.0622351f
1813 path.lineTo(SkBits2Float(0xbe9171a0), SkBits2Float(0xbd7ee5a7)); // -0.28407f, -0.0622307f
1814 path.lineTo(SkBits2Float(0xbe917147), SkBits2Float(0xbd7ed886)); // -0.284067f, -0.0622182f
1815 path.lineTo(SkBits2Float(0xbe917378), SkBits2Float(0xbd7ee1a9)); // -0.284084f, -0.0622269f
1816 path.lineTo(SkBits2Float(0xbe9171db), SkBits2Float(0xbd7eeb5d)); // -0.284072f, -0.0622362f
1817 path.close();
1818 check_convexity(reporter, path, false);
1819
1820}
static const struct @223 gRec[]
static const SkPoint nonFinitePts[]
const size_t nonFinitePtsCount
static void check_convexity(skiatest::Reporter *reporter, const SkPath &path, bool expectedConvexity)
Definition: PathTest.cpp:1357
static void check_direction(skiatest::Reporter *reporter, const SkPath &path, SkPathFirstDirection expected)
Definition: PathTest.cpp:1099
static void setFromString(SkPath *path, const char str[])
Definition: PathTest.cpp:1622
#define SK_ScalarMin
Definition: SkScalar.h:25
#define SK_ScalarNegativeInfinity
Definition: SkScalar.h:27

◆ test_convexity2()

static void test_convexity2 ( skiatest::Reporter reporter)
static

Definition at line 1392 of file PathTest.cpp.

1392 {
1393 SkPath pt;
1394 pt.moveTo(0, 0);
1395 pt.close();
1396 check_convexity(reporter, pt, true);
1398
1399 SkPath line;
1400 line.moveTo(12*SK_Scalar1, 20*SK_Scalar1);
1401 line.lineTo(-12*SK_Scalar1, -20*SK_Scalar1);
1402 line.close();
1405
1406 SkPath triLeft;
1407 triLeft.moveTo(0, 0);
1408 triLeft.lineTo(SK_Scalar1, 0);
1409 triLeft.lineTo(SK_Scalar1, SK_Scalar1);
1410 triLeft.close();
1411 check_convexity(reporter, triLeft, true);
1413
1414 SkPath triRight;
1415 triRight.moveTo(0, 0);
1416 triRight.lineTo(-SK_Scalar1, 0);
1417 triRight.lineTo(SK_Scalar1, SK_Scalar1);
1418 triRight.close();
1419 check_convexity(reporter, triRight, true);
1421
1422 SkPath square;
1423 square.moveTo(0, 0);
1424 square.lineTo(SK_Scalar1, 0);
1425 square.lineTo(SK_Scalar1, SK_Scalar1);
1426 square.lineTo(0, SK_Scalar1);
1427 square.close();
1430
1431 SkPath redundantSquare;
1432 redundantSquare.moveTo(0, 0);
1433 redundantSquare.lineTo(0, 0);
1434 redundantSquare.lineTo(0, 0);
1435 redundantSquare.lineTo(SK_Scalar1, 0);
1436 redundantSquare.lineTo(SK_Scalar1, 0);
1437 redundantSquare.lineTo(SK_Scalar1, 0);
1438 redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
1439 redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
1440 redundantSquare.lineTo(SK_Scalar1, SK_Scalar1);
1441 redundantSquare.lineTo(0, SK_Scalar1);
1442 redundantSquare.lineTo(0, SK_Scalar1);
1443 redundantSquare.lineTo(0, SK_Scalar1);
1444 redundantSquare.close();
1445 check_convexity(reporter, redundantSquare, true);
1447
1448 SkPath bowTie;
1449 bowTie.moveTo(0, 0);
1450 bowTie.lineTo(0, 0);
1451 bowTie.lineTo(0, 0);
1452 bowTie.lineTo(SK_Scalar1, SK_Scalar1);
1453 bowTie.lineTo(SK_Scalar1, SK_Scalar1);
1454 bowTie.lineTo(SK_Scalar1, SK_Scalar1);
1455 bowTie.lineTo(SK_Scalar1, 0);
1456 bowTie.lineTo(SK_Scalar1, 0);
1457 bowTie.lineTo(SK_Scalar1, 0);
1458 bowTie.lineTo(0, SK_Scalar1);
1459 bowTie.lineTo(0, SK_Scalar1);
1460 bowTie.lineTo(0, SK_Scalar1);
1461 bowTie.close();
1462 check_convexity(reporter, bowTie, false);
1464
1465 SkPath spiral;
1466 spiral.moveTo(0, 0);
1467 spiral.lineTo(100*SK_Scalar1, 0);
1468 spiral.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
1469 spiral.lineTo(0, 100*SK_Scalar1);
1470 spiral.lineTo(0, 50*SK_Scalar1);
1471 spiral.lineTo(50*SK_Scalar1, 50*SK_Scalar1);
1472 spiral.lineTo(50*SK_Scalar1, 75*SK_Scalar1);
1473 spiral.close();
1474 check_convexity(reporter, spiral, false);
1476
1477 SkPath dent;
1478 dent.moveTo(0, 0);
1479 dent.lineTo(100*SK_Scalar1, 100*SK_Scalar1);
1480 dent.lineTo(0, 100*SK_Scalar1);
1481 dent.lineTo(-50*SK_Scalar1, 200*SK_Scalar1);
1482 dent.lineTo(-200*SK_Scalar1, 100*SK_Scalar1);
1483 dent.close();
1484 check_convexity(reporter, dent, false);
1486
1487 // https://bug.skia.org/2235
1488 SkPath strokedSin;
1489 for (int i = 0; i < 2000; i++) {
1490 SkScalar x = SkIntToScalar(i) / 2;
1491 SkScalar y = 500 - (x + SkScalarSin(x / 100) * 40) / 3;
1492 if (0 == i) {
1493 strokedSin.moveTo(x, y);
1494 } else {
1495 strokedSin.lineTo(x, y);
1496 }
1497 }
1499 stroke.setStrokeStyle(2 * SK_Scalar1);
1500 stroke.applyToPath(&strokedSin, strokedSin);
1501 check_convexity(reporter, strokedSin, false);
1503
1504 // http://crbug.com/412640
1505 SkPath degenerateConcave;
1506 degenerateConcave.moveTo(148.67912f, 191.875f);
1507 degenerateConcave.lineTo(470.37695f, 7.5f);
1508 degenerateConcave.lineTo(148.67912f, 191.875f);
1509 degenerateConcave.lineTo(41.446522f, 376.25f);
1510 degenerateConcave.lineTo(-55.971577f, 460.0f);
1511 degenerateConcave.lineTo(41.446522f, 376.25f);
1512 check_convexity(reporter, degenerateConcave, false);
1514
1515 // http://crbug.com/433683
1516 SkPath badFirstVector;
1517 badFirstVector.moveTo(501.087708f, 319.610352f);
1518 badFirstVector.lineTo(501.087708f, 319.610352f);
1519 badFirstVector.cubicTo(501.087677f, 319.610321f, 449.271606f, 258.078674f, 395.084564f, 198.711182f);
1520 badFirstVector.cubicTo(358.967072f, 159.140717f, 321.910553f, 120.650436f, 298.442322f, 101.955399f);
1521 badFirstVector.lineTo(301.557678f, 98.044601f);
1522 badFirstVector.cubicTo(325.283844f, 116.945084f, 362.615204f, 155.720825f, 398.777557f, 195.340454f);
1523 badFirstVector.cubicTo(453.031860f, 254.781662f, 504.912262f, 316.389618f, 504.912292f, 316.389648f);
1524 badFirstVector.lineTo(504.912292f, 316.389648f);
1525 badFirstVector.lineTo(501.087708f, 319.610352f);
1526 badFirstVector.close();
1527 check_convexity(reporter, badFirstVector, false);
1528
1529 // http://crbug.com/993330
1530 SkPath falseBackEdge;
1531 falseBackEdge.moveTo(-217.83430557928145f, -382.14948768484857f);
1532 falseBackEdge.lineTo(-227.73867866614847f, -399.52485512718323f);
1533 falseBackEdge.cubicTo(-158.3541047666846f, -439.0757140459542f,
1534 -79.8654464485281f, -459.875f,
1535 -1.1368683772161603e-13f, -459.875f);
1536 falseBackEdge.lineTo(-8.08037266162413e-14f, -439.875f);
1537 falseBackEdge.lineTo(-8.526512829121202e-14f, -439.87499999999994f);
1538 falseBackEdge.cubicTo(-76.39209188702645f, -439.87499999999994f,
1539 -151.46727226799754f, -419.98027663161537f,
1540 -217.83430557928145f, -382.14948768484857f);
1541 falseBackEdge.close();
1542 check_convexity(reporter, falseBackEdge, false);
1543}
#define SkScalarSin(radians)
Definition: SkScalar.h:45
static int square(int x)
Definition: etc1.cpp:302

◆ test_convexity_doubleback()

static void test_convexity_doubleback ( skiatest::Reporter reporter)
static

Definition at line 1545 of file PathTest.cpp.

1545 {
1546 SkPath doubleback;
1547 doubleback.lineTo(1, 1);
1548 check_convexity(reporter, doubleback, true);
1549 doubleback.lineTo(2, 2);
1550 check_convexity(reporter, doubleback, true);
1551 doubleback.reset();
1552 doubleback.lineTo(1, 0);
1553 check_convexity(reporter, doubleback, true);
1554 doubleback.lineTo(2, 0);
1555 check_convexity(reporter, doubleback, true);
1556 doubleback.lineTo(1, 0);
1557 check_convexity(reporter, doubleback, true);
1558 doubleback.reset();
1559 doubleback.quadTo(1, 1, 2, 2);
1560 check_convexity(reporter, doubleback, true);
1561 doubleback.reset();
1562 doubleback.quadTo(1, 0, 2, 0);
1563 check_convexity(reporter, doubleback, true);
1564 doubleback.quadTo(1, 0, 0, 0);
1565 check_convexity(reporter, doubleback, true);
1566
1567 doubleback.reset();
1568 doubleback.lineTo(1, 0);
1569 doubleback.lineTo(1, 0);
1570 doubleback.lineTo(1, 1);
1571 doubleback.lineTo(1, 1);
1572 doubleback.lineTo(1, 0);
1573 check_convexity(reporter, doubleback, false);
1574
1575 doubleback.reset();
1576 doubleback.lineTo(-1, 0);
1577 doubleback.lineTo(-1, 1);
1578 doubleback.lineTo(-1, 0);
1579 check_convexity(reporter, doubleback, false);
1580
1581 for (int i = 0; i < 4; ++i) {
1582 doubleback.reset();
1583 doubleback.moveTo(0, 0);
1584 if (i == 0) {
1585 doubleback.lineTo(-1, -1);
1586 doubleback.lineTo(0, 0);
1587 }
1588 doubleback.lineTo(0, 1);
1589 if (i == 1) {
1590 doubleback.lineTo(0, 2);
1591 doubleback.lineTo(0, 1);
1592 }
1593 doubleback.lineTo(1, 1);
1594 if (i == 2) {
1595 doubleback.lineTo(2, 2);
1596 doubleback.lineTo(1, 1);
1597 }
1598 doubleback.lineTo(0, 0);
1599 if (i == 3) {
1600 doubleback.lineTo(-1, -1);
1601 doubleback.lineTo(0, 0);
1602 }
1603 check_convexity(reporter, doubleback, false);
1604 }
1605}

◆ test_crbug_170666()

static void test_crbug_170666 ( )
static

Definition at line 577 of file PathTest.cpp.

577 {
578 SkPath path;
580 test_draw_AA_path(1000, 1000, path);
581
583 test_draw_AA_path(1000, 1000, path);
584}
static void build_path_170666(SkPath &path)
Definition: PathTest.cpp:489
static void build_path_simple_170666(SkPath &path)
Definition: PathTest.cpp:569

◆ test_crbug_493450()

static void test_crbug_493450 ( skiatest::Reporter reporter)
static

Definition at line 603 of file PathTest.cpp.

603 {
604 const char reducedCase[] =
605 "M0,0"
606 "L0.0002, 0"
607 "L0.0002, 0.0002"
608 "L0.0001, 0.0001"
609 "L0,0.0002"
610 "Z";
611 test_tiny_path_convexity(reporter, reducedCase, 100, 100, 100000);
612 const char originalFiddleData[] =
613 "M-0.3383152268862998,-0.11217565719203619L-0.33846085183212765,-0.11212264406895281"
614 "L-0.338509393480737,-0.11210607966681395L-0.33857792286700894,-0.1121889121487573"
615 "L-0.3383866116636664,-0.11228834570924921L-0.33842087635680235,-0.11246078673250548"
616 "L-0.33809536177201055,-0.11245415228342878L-0.33797257995493996,-0.11216571641452182"
617 "L-0.33802112160354925,-0.11201996164188659L-0.33819815585141844,-0.11218559834671019Z";
618 test_tiny_path_convexity(reporter, originalFiddleData, 280081.4116670522f, 93268.04618493588f,
619 826357.3384828606f);
620}
static void test_tiny_path_convexity(skiatest::Reporter *reporter, const char *pathBug, SkScalar tx, SkScalar ty, SkScalar scale)
Definition: PathTest.cpp:587

◆ test_crbug_495894()

static void test_crbug_495894 ( skiatest::Reporter reporter)
static

Definition at line 622 of file PathTest.cpp.

622 {
623 const char originalFiddleData[] =
624 "M-0.34004273849857214,-0.11332803232216355L-0.34008271397389744,-0.11324483772714951"
625 "L-0.3401940742265893,-0.11324483772714951L-0.34017694188002134,-0.11329807920275889"
626 "L-0.3402026403998733,-0.11333468903941245L-0.34029972369709194,-0.11334134592705701"
627 "L-0.3403054344792813,-0.11344121970007795L-0.3403140006525653,-0.11351115418399343"
628 "L-0.34024261587519866,-0.11353446986281181L-0.3402197727464413,-0.11360442946144192"
629 "L-0.34013696640469604,-0.11359110237029302L-0.34009128014718143,-0.1135877707043939"
630 "L-0.3400598708451401,-0.11360776134112742L-0.34004273849857214,-0.11355112520064405"
631 "L-0.3400113291965308,-0.11355112520064405L-0.3399970522410575,-0.11359110237029302"
632 "L-0.33997135372120546,-0.11355112520064405L-0.3399627875479215,-0.11353780084493197"
633 "L-0.3399485105924481,-0.11350782354357004L-0.3400027630232468,-0.11346452910331437"
634 "L-0.3399485105924481,-0.11340126558629839L-0.33993994441916414,-0.11340126558629839"
635 "L-0.33988283659727087,-0.11331804756574679L-0.33989140277055485,-0.11324483772714951"
636 "L-0.33997991989448945,-0.11324483772714951L-0.3399856306766788,-0.11324483772714951"
637 "L-0.34002560615200417,-0.11334467443478255ZM-0.3400684370184241,-0.11338461985124307"
638 "L-0.340154098751264,-0.11341791238732665L-0.340162664924548,-0.1134378899559977"
639 "L-0.34017979727111597,-0.11340126558629839L-0.3401655203156427,-0.11338129083212668"
640 "L-0.34012268944922275,-0.11332137577529414L-0.34007414780061346,-0.11334467443478255Z"
641 "M-0.3400027630232468,-0.11290567901106024L-0.3400113291965308,-0.11298876531245433"
642 "L-0.33997991989448945,-0.11301535852306784L-0.33990282433493346,-0.11296217481488612"
643 "L-0.33993994441916414,-0.11288906492739594Z";
644 test_tiny_path_convexity(reporter, originalFiddleData, 22682.240000000005f,7819.72220766405f,
645 65536);
646}

◆ test_crbug_613918()

static void test_crbug_613918 ( )
static

Definition at line 648 of file PathTest.cpp.

648 {
649 SkPath path;
650 path.conicTo(-6.62478e-08f, 4.13885e-08f, -6.36935e-08f, 3.97927e-08f, 0.729058f);
651 path.quadTo(2.28206e-09f, -1.42572e-09f, 3.91919e-09f, -2.44852e-09f);
652 path.cubicTo(-16752.2f, -26792.9f, -21.4673f, 10.9347f, -8.57322f, -7.22739f);
653
654 // This call could lead to an assert or uninitialized read due to a failure
655 // to check the return value from SkCubicClipper::ChopMonoAtY.
656 path.contains(-1.84817e-08f, 1.15465e-08f);
657}

◆ test_crbug_629455()

static void test_crbug_629455 ( skiatest::Reporter reporter)
static

Definition at line 4715 of file PathTest.cpp.

4715 {
4716 SkPath path;
4717 path.moveTo(0, 0);
4718 path.cubicTo(SkBits2Float(0xcdcdcd00), SkBits2Float(0xcdcdcdcd),
4719 SkBits2Float(0xcdcdcdcd), SkBits2Float(0xcdcdcdcd),
4720 SkBits2Float(0x423fcdcd), SkBits2Float(0x40ed9341));
4721// AKA: cubicTo(-4.31596e+08f, -4.31602e+08f, -4.31602e+08f, -4.31602e+08f, 47.951f, 7.42423f);
4722 path.lineTo(0, 0);
4723 test_draw_AA_path(100, 100, path);
4724}

◆ test_direction()

static void test_direction ( skiatest::Reporter reporter)
static

Definition at line 1113 of file PathTest.cpp.

1113 {
1114 size_t i;
1115 SkPath path;
1118
1119 static const char* gDegen[] = {
1120 "M 10 10",
1121 "M 10 10 M 20 20",
1122 "M 10 10 L 20 20",
1123 "M 10 10 L 10 10 L 10 10",
1124 "M 10 10 Q 10 10 10 10",
1125 "M 10 10 C 10 10 10 10 10 10",
1126 };
1127 for (i = 0; i < std::size(gDegen); ++i) {
1128 path.reset();
1129 bool valid = SkParsePath::FromSVGString(gDegen[i], &path);
1130 REPORTER_ASSERT(reporter, valid);
1133 }
1134
1135 static const char* gCW[] = {
1136 "M 10 10 L 10 10 Q 20 10 20 20",
1137 "M 10 10 C 20 10 20 20 20 20",
1138 "M 20 10 Q 20 20 30 20 L 10 20", // test double-back at y-max
1139 // rect with top two corners replaced by cubics with identical middle
1140 // control points
1141 "M 10 10 C 10 0 10 0 20 0 L 40 0 C 50 0 50 0 50 10",
1142 "M 20 10 L 0 10 Q 10 10 20 0", // left, degenerate serif
1143 };
1144 for (i = 0; i < std::size(gCW); ++i) {
1145 path.reset();
1146 bool valid = SkParsePath::FromSVGString(gCW[i], &path);
1147 REPORTER_ASSERT(reporter, valid);
1149 }
1150
1151 static const char* gCCW[] = {
1152 "M 10 10 L 10 10 Q 20 10 20 -20",
1153 "M 10 10 C 20 10 20 -20 20 -20",
1154 "M 20 10 Q 20 20 10 20 L 30 20", // test double-back at y-max
1155 // rect with top two corners replaced by cubics with identical middle
1156 // control points
1157 "M 50 10 C 50 0 50 0 40 0 L 20 0 C 10 0 10 0 10 10",
1158 "M 10 10 L 30 10 Q 20 10 10 0", // right, degenerate serif
1159 };
1160 for (i = 0; i < std::size(gCCW); ++i) {
1161 path.reset();
1162 bool valid = SkParsePath::FromSVGString(gCCW[i], &path);
1163 REPORTER_ASSERT(reporter, valid);
1165 }
1166
1167 // Test two donuts, each wound a different direction. Only the outer contour
1168 // determines the cheap direction
1169 path.reset();
1170 path.addCircle(0, 0, SkIntToScalar(2), SkPathDirection::kCW);
1171 path.addCircle(0, 0, SkIntToScalar(1), SkPathDirection::kCCW);
1173
1174 path.reset();
1175 path.addCircle(0, 0, SkIntToScalar(1), SkPathDirection::kCW);
1176 path.addCircle(0, 0, SkIntToScalar(2), SkPathDirection::kCCW);
1178
1179 // triangle with one point really far from the origin.
1180 path.reset();
1181 // the first point is roughly 1.05e10, 1.05e10
1182 path.moveTo(SkBits2Float(0x501c7652), SkBits2Float(0x501c7652));
1183 path.lineTo(110 * SK_Scalar1, -10 * SK_Scalar1);
1184 path.lineTo(-10 * SK_Scalar1, 60 * SK_Scalar1);
1186
1187 path.reset();
1188 path.conicTo(20, 0, 20, 20, 0.5f);
1189 path.close();
1191
1192 path.reset();
1193 path.lineTo(1, 1e7f);
1194 path.lineTo(1e7f, 2e7f);
1195 path.close();
1196 REPORTER_ASSERT(reporter, path.isConvex());
1198}

◆ test_draw_AA_path()

static void test_draw_AA_path ( int  width,
int  height,
const SkPath path 
)
static

Definition at line 180 of file PathTest.cpp.

180 {
182 SkCanvas* canvas = surface->getCanvas();
184 paint.setAntiAlias(true);
185 canvas->drawPath(path, paint);
186}
int32_t height

◆ test_dump()

static void test_dump ( skiatest::Reporter reporter)
static

Definition at line 4575 of file PathTest.cpp.

4575 {
4576 SkPath p;
4577 compare_dump(reporter, p, false, "path.setFillType(SkPathFillType::kWinding);\n");
4578 p.moveTo(1, 2);
4579 p.lineTo(3, 4);
4580 compare_dump(reporter, p, false, "path.setFillType(SkPathFillType::kWinding);\n"
4581 "path.moveTo(1, 2);\n"
4582 "path.lineTo(3, 4);\n");
4583 p.reset();
4584 p.setFillType(SkPathFillType::kEvenOdd);
4585 p.moveTo(1, 2);
4586 p.quadTo(3, 4, 5, 6);
4587 compare_dump(reporter, p, false, "path.setFillType(SkPathFillType::kEvenOdd);\n"
4588 "path.moveTo(1, 2);\n"
4589 "path.quadTo(3, 4, 5, 6);\n");
4590 p.reset();
4592 p.moveTo(1, 2);
4593 p.conicTo(3, 4, 5, 6, 0.5f);
4594 compare_dump(reporter, p, false, "path.setFillType(SkPathFillType::kInverseWinding);\n"
4595 "path.moveTo(1, 2);\n"
4596 "path.conicTo(3, 4, 5, 6, 0.5f);\n");
4597 p.reset();
4599 p.moveTo(1, 2);
4600 p.cubicTo(3, 4, 5, 6, 7, 8);
4601 compare_dump(reporter, p, false, "path.setFillType(SkPathFillType::kInverseEvenOdd);\n"
4602 "path.moveTo(1, 2);\n"
4603 "path.cubicTo(3, 4, 5, 6, 7, 8);\n");
4604 p.reset();
4605 p.setFillType(SkPathFillType::kWinding);
4606 p.moveTo(1, 2);
4607 p.lineTo(3, 4);
4608 compare_dump(reporter, p, true,
4609 "path.setFillType(SkPathFillType::kWinding);\n"
4610 "path.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000)); // 1, 2\n"
4611 "path.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000)); // 3, 4\n");
4612 p.reset();
4613 p.moveTo(SkBits2Float(0x3f800000), SkBits2Float(0x40000000));
4614 p.lineTo(SkBits2Float(0x40400000), SkBits2Float(0x40800000));
4615 compare_dump(reporter, p, false, "path.setFillType(SkPathFillType::kWinding);\n"
4616 "path.moveTo(1, 2);\n"
4617 "path.lineTo(3, 4);\n");
4618}
static void compare_dump(skiatest::Reporter *reporter, const SkPath &path, bool dumpAsHex, const char *str)
Definition: PathTest.cpp:4562

◆ test_edger()

static void test_edger ( skiatest::Reporter r,
const std::initializer_list< SkPath::Verb > &  in,
const std::initializer_list< SkPath::Verb > &  expected 
)
static

Definition at line 5879 of file PathTest.cpp.

5881 {
5882 SkPath path;
5883 SkScalar x = 0, y = 0;
5884 for (auto v : in) {
5885 switch (v) {
5886 case SkPath::kMove_Verb: path.moveTo(x++, y++); break;
5887 case SkPath::kLine_Verb: path.lineTo(x++, y++); break;
5888 case SkPath::kClose_Verb: path.close(); break;
5889 default: SkASSERT(false);
5890 }
5891 }
5892
5893 SkPathEdgeIter iter(path);
5894 for (auto v : expected) {
5895 auto e = iter.next();
5896 REPORTER_ASSERT(r, e);
5898 }
5899 REPORTER_ASSERT(r, !iter.next());
5900}
static SkPath::Verb EdgeToVerb(Edge e)
Definition: SkPathPriv.h:472

◆ test_empty()

static void test_empty ( skiatest::Reporter reporter,
const SkPath p 
)
static

Definition at line 3828 of file PathTest.cpp.

3828 {
3829 SkPath empty;
3830
3831 REPORTER_ASSERT(reporter, p.isEmpty());
3832 REPORTER_ASSERT(reporter, 0 == p.countPoints());
3833 REPORTER_ASSERT(reporter, 0 == p.countVerbs());
3834 REPORTER_ASSERT(reporter, 0 == p.getSegmentMasks());
3835 REPORTER_ASSERT(reporter, p.isConvex());
3837 REPORTER_ASSERT(reporter, !p.isInverseFillType());
3840}

◆ test_extendClosedPath()

static void test_extendClosedPath ( skiatest::Reporter reporter)
static

Definition at line 4243 of file PathTest.cpp.

4243 {
4244 SkPath p, q;
4245 p.moveTo(1, 1);
4246 p.lineTo(1, 2);
4247 p.lineTo(2, 2);
4248 p.close();
4249 q.moveTo(2, 1);
4250 q.lineTo(2, 3);
4251 p.addPath(q, SkPath::kExtend_AddPathMode);
4252 uint8_t verbs[7];
4253 int verbcount = p.getVerbs(verbs, 7);
4254 REPORTER_ASSERT(reporter, verbcount == 7);
4262
4263 SkPoint pt;
4264 REPORTER_ASSERT(reporter, p.getLastPt(&pt));
4266 REPORTER_ASSERT(reporter, p.getPoint(3) == SkPoint::Make(1, 1));
4267}

◆ test_flattening()

static void test_flattening ( skiatest::Reporter reporter)
static

Definition at line 2798 of file PathTest.cpp.

2798 {
2799 SkPath p;
2800
2801 static const SkPoint pts[] = {
2802 { 0, 0 },
2803 { SkIntToScalar(10), SkIntToScalar(10) },
2804 { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 },
2805 { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }
2806 };
2807 p.moveTo(pts[0]);
2808 p.lineTo(pts[1]);
2809 p.quadTo(pts[2], pts[3]);
2810 p.cubicTo(pts[4], pts[5], pts[6]);
2811
2813
2814 // create a buffer that should be much larger than the path so we don't
2815 // kill our stack if writer goes too far.
2816 char buffer[1024];
2817 size_t size1 = p.writeToMemory(nullptr);
2818 size_t size2 = p.writeToMemory(buffer);
2819 REPORTER_ASSERT(reporter, size1 == size2);
2820
2821 SkPath p2;
2822 size_t size3 = p2.readFromMemory(buffer, 1024);
2823 REPORTER_ASSERT(reporter, size1 == size3);
2824 REPORTER_ASSERT(reporter, p == p2);
2825
2826 size3 = p2.readFromMemory(buffer, 0);
2827 REPORTER_ASSERT(reporter, !size3);
2828
2829 SkPath tooShort;
2830 size3 = tooShort.readFromMemory(buffer, size1 - 1);
2831 REPORTER_ASSERT(reporter, tooShort.isEmpty());
2832
2833 char buffer2[1024];
2834 size3 = p2.writeToMemory(buffer2);
2835 REPORTER_ASSERT(reporter, size1 == size3);
2836 REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
2837
2838 // test persistence of the oval flag & convexity
2839 {
2840 SkPath oval;
2841 SkRect rect = SkRect::MakeWH(10, 10);
2842 oval.addOval(rect);
2843
2845 }
2846}
static void write_and_read_back(skiatest::Reporter *reporter, const SkPath &p)
Definition: PathTest.cpp:2757
size_t writeToMemory(void *buffer) const
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126

◆ test_fuzz_crbug_627414()

static void test_fuzz_crbug_627414 ( skiatest::Reporter reporter)
static

Definition at line 783 of file PathTest.cpp.

783 {
784 SkPath path;
785 path.moveTo(0, 0);
786 path.conicTo(3.58732e-43f, 2.72084f, 3.00392f, 3.00392f, 8.46e+37f);
787 test_draw_AA_path(100, 100, path);
788}

◆ test_fuzz_crbug_638223()

static void test_fuzz_crbug_638223 ( )
static

Definition at line 189 of file PathTest.cpp.

189 {
190 SkPath path;
191 path.moveTo(SkBits2Float(0x47452a00), SkBits2Float(0x43211d01)); // 50474, 161.113f
192 path.conicTo(SkBits2Float(0x401c0000), SkBits2Float(0x40680000),
193 SkBits2Float(0x02c25a81), SkBits2Float(0x981a1fa0),
194 SkBits2Float(0x6bf9abea)); // 2.4375f, 3.625f, 2.85577e-37f, -1.992e-24f, 6.03669e+26f
195 test_draw_AA_path(250, 250, path);
196}

◆ test_fuzz_crbug_643933()

static void test_fuzz_crbug_643933 ( )
static

Definition at line 198 of file PathTest.cpp.

198 {
199 SkPath path;
200 path.moveTo(0, 0);
201 path.conicTo(SkBits2Float(0x002001f2), SkBits2Float(0x4161ffff), // 2.93943e-39f, 14.125f
202 SkBits2Float(0x49f7224d), SkBits2Float(0x45eec8df), // 2.02452e+06f, 7641.11f
203 SkBits2Float(0x721aee0c)); // 3.0687e+30f
204 test_draw_AA_path(250, 250, path);
205 path.reset();
206 path.moveTo(0, 0);
207 path.conicTo(SkBits2Float(0x00007ff2), SkBits2Float(0x4169ffff), // 4.58981e-41f, 14.625f
208 SkBits2Float(0x43ff2261), SkBits2Float(0x41eeea04), // 510.269f, 29.8643f
209 SkBits2Float(0x5d06eff8)); // 6.07704e+17f
210 test_draw_AA_path(250, 250, path);
211}

◆ test_fuzz_crbug_647922()

static void test_fuzz_crbug_647922 ( )
static

Definition at line 213 of file PathTest.cpp.

213 {
214 SkPath path;
215 path.moveTo(0, 0);
216 path.conicTo(SkBits2Float(0x00003939), SkBits2Float(0x42487fff), // 2.05276e-41f, 50.125f
217 SkBits2Float(0x48082361), SkBits2Float(0x4408e8e9), // 139406, 547.639f
218 SkBits2Float(0x4d1ade0f)); // 1.6239e+08f
219 test_draw_AA_path(250, 250, path);
220}

◆ test_fuzz_crbug_662730()

static void test_fuzz_crbug_662730 ( skiatest::Reporter reporter)
static

Definition at line 4765 of file PathTest.cpp.

4765 {
4766 SkPath path;
4767 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
4768 path.lineTo(SkBits2Float(0xd5394437), SkBits2Float(0x37373737)); // -1.2731e+13f, 1.09205e-05f
4769 path.lineTo(SkBits2Float(0x37373737), SkBits2Float(0x37373737)); // 1.09205e-05f, 1.09205e-05f
4770 path.lineTo(SkBits2Float(0x37373745), SkBits2Float(0x0001b800)); // 1.09205e-05f, 1.57842e-40f
4771 path.close();
4772 test_draw_AA_path(100, 100, path);
4773}

◆ test_fuzz_crbug_662780()

static void test_fuzz_crbug_662780 ( )
static

Definition at line 222 of file PathTest.cpp.

222 {
224 SkCanvas* canvas = surface->getCanvas();
226 paint.setAntiAlias(true);
227 SkPath path;
228 path.moveTo(SkBits2Float(0x41000000), SkBits2Float(0x431e0000)); // 8, 158
229 path.lineTo(SkBits2Float(0x41000000), SkBits2Float(0x42f00000)); // 8, 120
230 // 8, 8, 8.00002f, 8, 0.707107f
231 path.conicTo(SkBits2Float(0x41000000), SkBits2Float(0x41000000),
232 SkBits2Float(0x41000010), SkBits2Float(0x41000000), SkBits2Float(0x3f3504f3));
233 path.lineTo(SkBits2Float(0x439a0000), SkBits2Float(0x41000000)); // 308, 8
234 // 308, 8, 308, 8, 0.707107f
235 path.conicTo(SkBits2Float(0x439a0000), SkBits2Float(0x41000000),
236 SkBits2Float(0x439a0000), SkBits2Float(0x41000000), SkBits2Float(0x3f3504f3));
237 path.lineTo(SkBits2Float(0x439a0000), SkBits2Float(0x431e0000)); // 308, 158
238 // 308, 158, 308, 158, 0.707107f
239 path.conicTo(SkBits2Float(0x439a0000), SkBits2Float(0x431e0000),
240 SkBits2Float(0x439a0000), SkBits2Float(0x431e0000), SkBits2Float(0x3f3504f3));
241 path.lineTo(SkBits2Float(0x41000000), SkBits2Float(0x431e0000)); // 8, 158
242 // 8, 158, 8, 158, 0.707107f
243 path.conicTo(SkBits2Float(0x41000000), SkBits2Float(0x431e0000),
244 SkBits2Float(0x41000000), SkBits2Float(0x431e0000), SkBits2Float(0x3f3504f3));
245 path.close();
246 canvas->clipPath(path, true);
247 canvas->drawRect(SkRect::MakeWH(250, 250), paint);
248}
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673

◆ test_fuzz_crbug_662952()

static void test_fuzz_crbug_662952 ( skiatest::Reporter reporter)
static

Definition at line 4726 of file PathTest.cpp.

4726 {
4727 SkPath path;
4728 path.moveTo(SkBits2Float(0x4109999a), SkBits2Float(0x411c0000)); // 8.6f, 9.75f
4729 path.lineTo(SkBits2Float(0x410a6666), SkBits2Float(0x411c0000)); // 8.65f, 9.75f
4730 path.lineTo(SkBits2Float(0x410a6666), SkBits2Float(0x411e6666)); // 8.65f, 9.9f
4731 path.lineTo(SkBits2Float(0x4109999a), SkBits2Float(0x411e6666)); // 8.6f, 9.9f
4732 path.lineTo(SkBits2Float(0x4109999a), SkBits2Float(0x411c0000)); // 8.6f, 9.75f
4733 path.close();
4734
4736 SkPaint paint;
4737 paint.setAntiAlias(true);
4738 surface->getCanvas()->clipPath(path, true);
4739 surface->getCanvas()->drawRect(SkRect::MakeWH(100, 100), paint);
4740}

◆ test_fuzz_crbug_668907()

static void test_fuzz_crbug_668907 ( )
static

Definition at line 264 of file PathTest.cpp.

264 {
265 SkPath path;
266 path.moveTo(SkBits2Float(0x46313741), SkBits2Float(0x3b00e540)); // 11341.8f, 0.00196679f
267 path.quadTo(SkBits2Float(0x41410041), SkBits2Float(0xc1414141), SkBits2Float(0x41414141),
268 SkBits2Float(0x414100ff)); // 12.0626f, -12.0784f, 12.0784f, 12.0627f
269 path.lineTo(SkBits2Float(0x46313741), SkBits2Float(0x3b00e540)); // 11341.8f, 0.00196679f
270 path.close();
271 test_draw_AA_path(400, 500, path);
272}

◆ test_gen_id()

static void test_gen_id ( skiatest::Reporter reporter)
static

Definition at line 409 of file PathTest.cpp.

409 {
410 SkPath a, b;
411 REPORTER_ASSERT(reporter, a.getGenerationID() == b.getGenerationID());
412
413 a.moveTo(0, 0);
414 const uint32_t z = a.getGenerationID();
415 REPORTER_ASSERT(reporter, z != b.getGenerationID());
416
417 a.reset();
418 REPORTER_ASSERT(reporter, a.getGenerationID() == b.getGenerationID());
419
420 a.moveTo(1, 1);
421 const uint32_t y = a.getGenerationID();
423
424 b.moveTo(2, 2);
425 const uint32_t x = b.getGenerationID();
426 REPORTER_ASSERT(reporter, x != y && x != z);
427
428 a.swap(b);
429 REPORTER_ASSERT(reporter, b.getGenerationID() == y && a.getGenerationID() == x);
430
431 b = a;
432 REPORTER_ASSERT(reporter, b.getGenerationID() == x);
433
434 SkPath c(a);
435 REPORTER_ASSERT(reporter, c.getGenerationID() == x);
436
437 c.lineTo(3, 3);
438 const uint32_t w = c.getGenerationID();
439 REPORTER_ASSERT(reporter, b.getGenerationID() == x);
440 REPORTER_ASSERT(reporter, a.getGenerationID() == x);
442
443#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
444 static bool kExpectGenIDToIgnoreFill = false;
445#else
446 static bool kExpectGenIDToIgnoreFill = true;
447#endif
448
449 c.toggleInverseFillType();
450 const uint32_t v = c.getGenerationID();
451 REPORTER_ASSERT(reporter, (v == w) == kExpectGenIDToIgnoreFill);
452
453 c.rewind();
454 REPORTER_ASSERT(reporter, v != c.getGenerationID());
455}

◆ test_get_point()

static void test_get_point ( skiatest::Reporter reporter)
static

Definition at line 4295 of file PathTest.cpp.

4295 {
4296 SkPath p;
4297 SkPoint pt = p.getPoint(0);
4299 REPORTER_ASSERT(reporter, !p.getLastPt(nullptr));
4300 REPORTER_ASSERT(reporter, !p.getLastPt(&pt) && pt == SkPoint::Make(0, 0));
4301 p.setLastPt(10, 10);
4302 pt = p.getPoint(0);
4303 REPORTER_ASSERT(reporter, pt == SkPoint::Make(10, 10));
4304 REPORTER_ASSERT(reporter, p.getLastPt(nullptr));
4305 p.rMoveTo(10, 10);
4306 REPORTER_ASSERT(reporter, p.getLastPt(&pt) && pt == SkPoint::Make(20, 20));
4307}

◆ test_interp()

static void test_interp ( skiatest::Reporter reporter)
static

Definition at line 5000 of file PathTest.cpp.

5000 {
5001 SkPath p1, p2, out;
5007 p1.moveTo(0, 2);
5008 p1.lineTo(0, 4);
5010 REPORTER_ASSERT(reporter, !p1.interpolate(p2, 1, &out));
5011 p2.moveTo(6, 0);
5012 p2.lineTo(8, 0);
5018 REPORTER_ASSERT(reporter, p1.interpolate(p2, 0.5f, &out));
5019 REPORTER_ASSERT(reporter, out.getBounds() == SkRect::MakeLTRB(3, 1, 4, 2));
5020 p1.reset();
5021 p1.moveTo(4, 4);
5022 p1.conicTo(5, 4, 5, 5, 1 / SkScalarSqrt(2));
5023 p2.reset();
5024 p2.moveTo(4, 2);
5025 p2.conicTo(7, 2, 7, 5, 1 / SkScalarSqrt(2));
5027 REPORTER_ASSERT(reporter, p1.interpolate(p2, 0.5f, &out));
5028 REPORTER_ASSERT(reporter, out.getBounds() == SkRect::MakeLTRB(4, 3, 6, 5));
5029 p2.reset();
5030 p2.moveTo(4, 2);
5031 p2.conicTo(6, 3, 6, 5, 1);
5033 p2.reset();
5034 p2.moveTo(4, 4);
5035 p2.conicTo(5, 4, 5, 5, 0.5f);
5037}
#define SkScalarSqrt(x)
Definition: SkScalar.h:42
bool isInterpolatable(const SkPath &compare) const
Definition: SkPath.cpp:243
bool interpolate(const SkPath &ending, SkScalar weight, SkPath *out) const
Definition: SkPath.cpp:250

◆ test_is_closed_rect()

static void test_is_closed_rect ( skiatest::Reporter reporter)
static

Definition at line 2326 of file PathTest.cpp.

2326 {
2327 using std::swap;
2330 unsigned s = ~0U;
2331
2332 const SkRect testRect = SkRect::MakeXYWH(10, 10, 50, 70);
2333 const SkRect emptyRect = SkRect::MakeEmpty();
2334 for (int start = 0; start < 4; ++start) {
2336 SkPath path;
2337 path.addRect(testRect, dir, start);
2338 check_simple_rect(reporter, path, true, testRect, dir, start);
2339 path.close();
2340 check_simple_rect(reporter, path, true, testRect, dir, start);
2341 SkPath path2 = path;
2342 path2.lineTo(10, 10);
2345 path2 = path;
2346 path2.moveTo(10, 10);
2349 path2 = path;
2350 path2.addRect(testRect, dir, start);
2353 // Make the path by hand, manually closing it.
2354 path2.reset();
2355 SkPoint firstPt = {0.f, 0.f};
2356 for (auto [v, verbPts, w] : SkPathPriv::Iterate(path)) {
2357 switch(v) {
2358 case SkPathVerb::kMove:
2359 firstPt = verbPts[0];
2360 path2.moveTo(verbPts[0]);
2361 break;
2362 case SkPathVerb::kLine:
2363 path2.lineTo(verbPts[1]);
2364 break;
2365 default:
2366 break;
2367 }
2368 }
2369 // We haven't closed it yet...
2372 // ... now we do and test again.
2373 path2.lineTo(firstPt);
2374 check_simple_rect(reporter, path2, false, testRect, dir, start);
2375 // A redundant close shouldn't cause a failure.
2376 path2.close();
2377 check_simple_rect(reporter, path2, true, testRect, dir, start);
2378 // Degenerate point and line rects are not allowed
2379 path2.reset();
2380 path2.addRect(emptyRect, dir, start);
2383 SkRect degenRect = testRect;
2384 degenRect.fLeft = degenRect.fRight;
2385 path2.reset();
2386 path2.addRect(degenRect, dir, start);
2389 degenRect = testRect;
2390 degenRect.fTop = degenRect.fBottom;
2391 path2.reset();
2392 path2.addRect(degenRect, dir, start);
2395 // An inverted rect makes a rect path, but changes the winding dir and start point.
2399 static constexpr unsigned kXSwapStarts[] = { 1, 0, 3, 2 };
2400 static constexpr unsigned kYSwapStarts[] = { 3, 2, 1, 0 };
2401 SkRect swapRect = testRect;
2402 swap(swapRect.fLeft, swapRect.fRight);
2403 path2.reset();
2404 path2.addRect(swapRect, dir, start);
2405 check_simple_rect(reporter, path2, true, testRect, swapDir, kXSwapStarts[start]);
2406 swapRect = testRect;
2407 swap(swapRect.fTop, swapRect.fBottom);
2408 path2.reset();
2409 path2.addRect(swapRect, dir, start);
2410 check_simple_rect(reporter, path2, true, testRect, swapDir, kYSwapStarts[start]);
2411 }
2412 }
2413 // down, up, left, close
2414 SkPath path;
2415 path.moveTo(1, 1);
2416 path.lineTo(1, 2);
2417 path.lineTo(1, 1);
2418 path.lineTo(0, 1);
2419 SkRect rect;
2421 unsigned start;
2422 path.close();
2425 // right, left, up, close
2426 path.reset();
2427 path.moveTo(1, 1);
2428 path.lineTo(2, 1);
2429 path.lineTo(1, 1);
2430 path.lineTo(1, 0);
2431 path.close();
2434 // parallelogram with horizontal edges
2435 path.reset();
2436 path.moveTo(1, 0);
2437 path.lineTo(3, 0);
2438 path.lineTo(2, 1);
2439 path.lineTo(0, 1);
2440 path.close();
2443 // parallelogram with vertical edges
2444 path.reset();
2445 path.moveTo(0, 1);
2446 path.lineTo(0, 3);
2447 path.lineTo(1, 2);
2448 path.lineTo(1, 0);
2449 path.close();
2452
2453}
static void check_simple_rect(skiatest::Reporter *reporter, const SkPath &path, bool isClosed, const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: PathTest.cpp:2313

◆ test_isArc()

static void test_isArc ( skiatest::Reporter reporter)
static

Definition at line 2455 of file PathTest.cpp.

2455 {
2456 SkPath path;
2457 REPORTER_ASSERT(reporter, !path.isArc(nullptr));
2458
2459 // One circle, one oval:
2460 const SkRect kOvals[] = { SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 200)};
2461
2462 // Various start and sweep angles. Note that we can't test with more than a full revolution,
2463 // those cases are automatically converted to ovals by SkPath.
2464 const SkScalar kStartAngles[] = { -270, -135, -45, 0, 10, 70, 180, 350 };
2465 const SkScalar kSweepAngles[] = { -350, -190, -90, -5, 5, 89, 180, 270, 350 };
2466
2467 int mutator = 0;
2468
2469 for (SkRect oval : kOvals) {
2470 for (SkScalar startAngle : kStartAngles) {
2471 for (SkScalar sweepAngle : kSweepAngles) {
2472 // For now, isArc only works for arcs where useCenter is false!
2473 // TODO: When that's fixed, add more tests cases here.
2474 path.rewind();
2475 // Include an extra moveTo at the start - this should not interfere with isArc
2476 path.moveTo(oval.center());
2477 path.addArc(oval, startAngle, sweepAngle);
2478
2479 SkArc arc;
2480 REPORTER_ASSERT(reporter, path.isArc(&arc));
2482 oval == arc.fOval &&
2483 startAngle == arc.fStartAngle &&
2484 sweepAngle == arc.fSweepAngle &&
2485 !arc.isWedge());
2486
2487 // Apply some mutation. All of these should cause the path to no longer be an arc:
2488 switch (mutator) {
2489 case 0:
2490 path.addArc(oval, startAngle, sweepAngle);
2491 break;
2492 case 1:
2493 path.lineTo(oval.center());
2494 break;
2495 case 2:
2496 path.lineTo(path.getPoint(0));
2497 break;
2498 case 3:
2499 path.close();
2500 break;
2501 case 4:
2502 path.moveTo(oval.center());
2503 break;
2504 default:
2506 }
2507 mutator = (mutator + 1) % 5;
2508 REPORTER_ASSERT(reporter, !path.isArc(nullptr));
2509 }
2510 }
2511 }
2512
2513 // Having any non-move verb before the arc should cause isArc to return false:
2514 path.rewind();
2515 path.lineTo(kOvals[0].center());
2516 path.addArc(kOvals[0], kStartAngles[0], kSweepAngles[0]);
2517 REPORTER_ASSERT(reporter, !path.isArc(nullptr));
2518
2519 // Finally, transforming an arc path by a non-identity should always result in a non-arc path:
2520 // TODO: We could clearly preserve arcs for translation, and for scale/rotation with extra work.
2521 for (SkMatrix m :
2523 path.rewind();
2524 path.addArc(kOvals[0], kStartAngles[0], kSweepAngles[0]);
2525 REPORTER_ASSERT(reporter, path.isArc(nullptr));
2526 path.transform(SkMatrix::I());
2527 REPORTER_ASSERT(reporter, path.isArc(nullptr));
2528 path.transform(m);
2529 REPORTER_ASSERT(reporter, !path.isArc(nullptr));
2530 }
2531}
#define SkUNREACHABLE
Definition: SkAssert.h:135
static SkScalar center(float pos0, float pos1)
static SkMatrix RotateDeg(SkScalar deg)
Definition: SkMatrix.h:104
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
SkScalar sweepAngle
Definition: SkRecords.h:251
Definition: SkArc.h:15
SkScalar fSweepAngle
Definition: SkArc.h:60
SkScalar fStartAngle
Definition: SkArc.h:58
SkRect fOval
Definition: SkArc.h:55
bool isWedge() const
Definition: SkArc.h:28
constexpr SkPoint center() const
Definition: SkRect.h:792

◆ test_isfinite()

static void test_isfinite ( skiatest::Reporter reporter)
static

Definition at line 990 of file PathTest.cpp.

990 {
993}
static void test_rect_isfinite(skiatest::Reporter *reporter)
Definition: PathTest.cpp:932
static void test_path_isfinite(skiatest::Reporter *reporter)
Definition: PathTest.cpp:966

◆ test_isfinite_after_transform()

static void test_isfinite_after_transform ( skiatest::Reporter reporter)
static

Definition at line 810 of file PathTest.cpp.

810 {
811 SkPath path;
812 path.quadTo(157, 366, 286, 208);
813 path.arcTo(37, 442, 315, 163, 957494590897113.0f);
814
816 matrix.setScale(1000*1000, 1000*1000);
817
818 // Be sure that path::transform correctly updates isFinite and the bounds
819 // if the transformation overflows. The previous bug was that isFinite was
820 // set to true in this case, but the bounds were not set to empty (which
821 // they should be).
822 while (path.isFinite()) {
823 REPORTER_ASSERT(reporter, path.getBounds().isFinite());
824 REPORTER_ASSERT(reporter, !path.getBounds().isEmpty());
825 path.transform(matrix);
826 }
827 REPORTER_ASSERT(reporter, path.getBounds().isEmpty());
828
829 matrix.setTranslate(SK_Scalar1, SK_Scalar1);
830 path.transform(matrix);
831 // we need to still be non-finite
832 REPORTER_ASSERT(reporter, !path.isFinite());
833 REPORTER_ASSERT(reporter, path.getBounds().isEmpty());
834}

◆ test_islastcontourclosed()

static void test_islastcontourclosed ( skiatest::Reporter reporter)
static

Definition at line 995 of file PathTest.cpp.

995 {
996 SkPath path;
997 REPORTER_ASSERT(reporter, !path.isLastContourClosed());
998 path.moveTo(0, 0);
999 REPORTER_ASSERT(reporter, !path.isLastContourClosed());
1000 path.close();
1001 REPORTER_ASSERT(reporter, path.isLastContourClosed());
1002 path.lineTo(100, 100);
1003 REPORTER_ASSERT(reporter, !path.isLastContourClosed());
1004 path.moveTo(200, 200);
1005 REPORTER_ASSERT(reporter, !path.isLastContourClosed());
1006 path.close();
1007 REPORTER_ASSERT(reporter, path.isLastContourClosed());
1008 path.moveTo(0, 0);
1009 REPORTER_ASSERT(reporter, !path.isLastContourClosed());
1010}

◆ test_isLine()

static void test_isLine ( skiatest::Reporter reporter)
static

Definition at line 1822 of file PathTest.cpp.

1822 {
1823 SkPath path;
1824 SkPoint pts[2];
1825 const SkScalar value = SkIntToScalar(5);
1826
1827 REPORTER_ASSERT(reporter, !path.isLine(nullptr));
1828
1829 // set some non-zero values
1830 pts[0].set(value, value);
1831 pts[1].set(value, value);
1832 REPORTER_ASSERT(reporter, !path.isLine(pts));
1833 // check that pts was untouched
1836
1837 const SkScalar moveX = SkIntToScalar(1);
1838 const SkScalar moveY = SkIntToScalar(2);
1839 REPORTER_ASSERT(reporter, value != moveX && value != moveY);
1840
1841 path.moveTo(moveX, moveY);
1842 REPORTER_ASSERT(reporter, !path.isLine(nullptr));
1843 REPORTER_ASSERT(reporter, !path.isLine(pts));
1844 // check that pts was untouched
1847
1848 const SkScalar lineX = SkIntToScalar(2);
1849 const SkScalar lineY = SkIntToScalar(2);
1850 REPORTER_ASSERT(reporter, value != lineX && value != lineY);
1851
1852 path.lineTo(lineX, lineY);
1853 REPORTER_ASSERT(reporter, path.isLine(nullptr));
1854
1855 REPORTER_ASSERT(reporter, !pts[0].equals(moveX, moveY));
1856 REPORTER_ASSERT(reporter, !pts[1].equals(lineX, lineY));
1857 REPORTER_ASSERT(reporter, path.isLine(pts));
1858 REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
1859 REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
1860
1861 path.lineTo(0, 0); // too many points/verbs
1862 REPORTER_ASSERT(reporter, !path.isLine(nullptr));
1863 REPORTER_ASSERT(reporter, !path.isLine(pts));
1864 REPORTER_ASSERT(reporter, pts[0].equals(moveX, moveY));
1865 REPORTER_ASSERT(reporter, pts[1].equals(lineX, lineY));
1866
1867 path.reset();
1868 path.quadTo(1, 1, 2, 2);
1869 REPORTER_ASSERT(reporter, !path.isLine(nullptr));
1870}
bool equals(SkDrawable *a, SkDrawable *b)
uint8_t value

◆ test_isNestedFillRects()

static void test_isNestedFillRects ( skiatest::Reporter reporter)
static

Definition at line 2533 of file PathTest.cpp.

2533 {
2534 // passing tests (all moveTo / lineTo...
2535 SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; // CW
2536 SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
2537 SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
2538 SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
2539 SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; // CCW
2540 SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2541 SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
2542 SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
2543 SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2544 SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f}, {1, 0}, {.5f, 0}}; // CCW
2545 SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1}, {0, 1}, {0, .5f}}; // CW
2546 SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}}; // CW
2547 SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}; // CCW
2548 SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}}; // CW
2549
2550 // failing tests
2551 SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}}; // too few points
2552 SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}}; // diagonal
2553 SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}; // wraps
2554 SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}}; // backs up
2555 SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}}; // end overshoots
2556 SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}}; // end overshoots
2557 SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}}; // end overshoots
2558 SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}}; // 'L'
2559
2560 // success, no close is OK
2561 SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; // close doesn't match
2562 SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}}; // ditto
2563
2564 struct IsNestedRectTest {
2565 SkPoint *fPoints;
2566 int fPointCount;
2567 SkPathFirstDirection fDirection;
2568 bool fClose;
2569 bool fIsNestedRect; // nests with path.addRect(-1, -1, 2, 2);
2570 } tests[] = {
2571 { r1, std::size(r1), SkPathFirstDirection::kCW , true, true },
2572 { r2, std::size(r2), SkPathFirstDirection::kCW , true, true },
2573 { r3, std::size(r3), SkPathFirstDirection::kCW , true, true },
2574 { r4, std::size(r4), SkPathFirstDirection::kCW , true, true },
2575 { r5, std::size(r5), SkPathFirstDirection::kCCW, true, true },
2576 { r6, std::size(r6), SkPathFirstDirection::kCCW, true, true },
2577 { r7, std::size(r7), SkPathFirstDirection::kCCW, true, true },
2578 { r8, std::size(r8), SkPathFirstDirection::kCCW, true, true },
2579 { r9, std::size(r9), SkPathFirstDirection::kCCW, true, true },
2580 { ra, std::size(ra), SkPathFirstDirection::kCCW, true, true },
2581 { rb, std::size(rb), SkPathFirstDirection::kCW, true, true },
2582 { rc, std::size(rc), SkPathFirstDirection::kCW, true, true },
2583 { rd, std::size(rd), SkPathFirstDirection::kCCW, true, true },
2584 { re, std::size(re), SkPathFirstDirection::kCW, true, true },
2585
2586 { f1, std::size(f1), SkPathFirstDirection::kUnknown, true, false },
2587 { f2, std::size(f2), SkPathFirstDirection::kUnknown, true, false },
2588 { f3, std::size(f3), SkPathFirstDirection::kUnknown, true, false },
2589 { f4, std::size(f4), SkPathFirstDirection::kUnknown, true, false },
2590 { f5, std::size(f5), SkPathFirstDirection::kUnknown, true, false },
2591 { f6, std::size(f6), SkPathFirstDirection::kUnknown, true, false },
2592 { f7, std::size(f7), SkPathFirstDirection::kUnknown, true, false },
2593 { f8, std::size(f8), SkPathFirstDirection::kUnknown, true, false },
2594
2595 { c1, std::size(c1), SkPathFirstDirection::kCW, false, true },
2596 { c2, std::size(c2), SkPathFirstDirection::kCW, false, true },
2597 };
2598
2599 const size_t testCount = std::size(tests);
2600 int index;
2601 for (int rectFirst = 0; rectFirst <= 1; ++rectFirst) {
2602 for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
2603 SkPath path;
2604 if (rectFirst) {
2605 path.addRect(-1, -1, 2, 2, SkPathDirection::kCW);
2606 }
2607 path.moveTo(tests[testIndex].fPoints[0].fX, tests[testIndex].fPoints[0].fY);
2608 for (index = 1; index < tests[testIndex].fPointCount; ++index) {
2609 path.lineTo(tests[testIndex].fPoints[index].fX, tests[testIndex].fPoints[index].fY);
2610 }
2611 if (tests[testIndex].fClose) {
2612 path.close();
2613 }
2614 if (!rectFirst) {
2615 path.addRect(-1, -1, 2, 2, SkPathDirection::kCCW);
2616 }
2618 tests[testIndex].fIsNestedRect == SkPathPriv::IsNestedFillRects(path, nullptr));
2619 if (tests[testIndex].fIsNestedRect) {
2620 SkRect expected[2], computed[2];
2621 SkPathFirstDirection expectedDirs[2];
2622 SkPathDirection computedDirs[2];
2623 SkRect testBounds;
2624 testBounds.setBounds(tests[testIndex].fPoints, tests[testIndex].fPointCount);
2625 expected[0] = SkRect::MakeLTRB(-1, -1, 2, 2);
2626 expected[1] = testBounds;
2627 if (rectFirst) {
2628 expectedDirs[0] = SkPathFirstDirection::kCW;
2629 } else {
2630 expectedDirs[0] = SkPathFirstDirection::kCCW;
2631 }
2632 expectedDirs[1] = tests[testIndex].fDirection;
2634 REPORTER_ASSERT(reporter, expected[0] == computed[0]);
2635 REPORTER_ASSERT(reporter, expected[1] == computed[1]);
2636 REPORTER_ASSERT(reporter, expectedDirs[0] == SkPathPriv::AsFirstDirection(computedDirs[0]));
2637 REPORTER_ASSERT(reporter, expectedDirs[1] == SkPathPriv::AsFirstDirection(computedDirs[1]));
2638 }
2639 }
2640
2641 // fail, close then line
2642 SkPath path1;
2643 if (rectFirst) {
2644 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCW);
2645 }
2646 path1.moveTo(r1[0].fX, r1[0].fY);
2647 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2648 path1.lineTo(r1[index].fX, r1[index].fY);
2649 }
2650 path1.close();
2651 path1.lineTo(1, 0);
2652 if (!rectFirst) {
2653 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCCW);
2654 }
2656
2657 // fail, move in the middle
2658 path1.reset();
2659 if (rectFirst) {
2660 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCW);
2661 }
2662 path1.moveTo(r1[0].fX, r1[0].fY);
2663 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2664 if (index == 2) {
2665 path1.moveTo(1, .5f);
2666 }
2667 path1.lineTo(r1[index].fX, r1[index].fY);
2668 }
2669 path1.close();
2670 if (!rectFirst) {
2671 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCCW);
2672 }
2674
2675 // fail, move on the edge
2676 path1.reset();
2677 if (rectFirst) {
2678 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCW);
2679 }
2680 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2681 path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
2682 path1.lineTo(r1[index].fX, r1[index].fY);
2683 }
2684 path1.close();
2685 if (!rectFirst) {
2686 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCCW);
2687 }
2689
2690 // fail, quad
2691 path1.reset();
2692 if (rectFirst) {
2693 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCW);
2694 }
2695 path1.moveTo(r1[0].fX, r1[0].fY);
2696 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2697 if (index == 2) {
2698 path1.quadTo(1, .5f, 1, .5f);
2699 }
2700 path1.lineTo(r1[index].fX, r1[index].fY);
2701 }
2702 path1.close();
2703 if (!rectFirst) {
2704 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCCW);
2705 }
2707
2708 // fail, cubic
2709 path1.reset();
2710 if (rectFirst) {
2711 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCW);
2712 }
2713 path1.moveTo(r1[0].fX, r1[0].fY);
2714 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2715 if (index == 2) {
2716 path1.cubicTo(1, .5f, 1, .5f, 1, .5f);
2717 }
2718 path1.lineTo(r1[index].fX, r1[index].fY);
2719 }
2720 path1.close();
2721 if (!rectFirst) {
2722 path1.addRect(-1, -1, 2, 2, SkPathDirection::kCCW);
2723 }
2725
2726 // fail, not nested
2727 path1.reset();
2728 path1.addRect(1, 1, 3, 3, SkPathDirection::kCW);
2729 path1.addRect(2, 2, 4, 4, SkPathDirection::kCW);
2731 }
2732
2733 // pass, constructed explicitly from manually closed rects specified as moves/lines.
2734 SkPath path;
2735 path.moveTo(0, 0);
2736 path.lineTo(10, 0);
2737 path.lineTo(10, 10);
2738 path.lineTo(0, 10);
2739 path.lineTo(0, 0);
2740 path.moveTo(1, 1);
2741 path.lineTo(9, 1);
2742 path.lineTo(9, 9);
2743 path.lineTo(1, 9);
2744 path.lineTo(1, 1);
2746
2747 // pass, stroke rect
2748 SkPath src, dst;
2749 src.addRect(1, 1, 7, 7, SkPathDirection::kCW);
2750 SkPaint strokePaint;
2751 strokePaint.setStyle(SkPaint::kStroke_Style);
2752 strokePaint.setStrokeWidth(2);
2753 skpathutils::FillPathWithPaint(src, strokePaint, &dst);
2755}
static const size_t testCount
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setStrokeWidth(SkScalar width)
Definition: SkPaint.cpp:159
static bool IsNestedFillRects(const SkPath &, SkRect rect[2], SkPathDirection dirs[2]=nullptr)
Definition: SkPath.cpp:3780

◆ test_isRect()

static void test_isRect ( skiatest::Reporter reporter)
static

Definition at line 2129 of file PathTest.cpp.

2129 {
2131
2132 // passing tests (all moveTo / lineTo...
2133 SkPoint r1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
2134 SkPoint r2[] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
2135 SkPoint r3[] = {{1, 1}, {0, 1}, {0, 0}, {1, 0}};
2136 SkPoint r4[] = {{0, 1}, {0, 0}, {1, 0}, {1, 1}};
2137 SkPoint r5[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
2138 SkPoint r6[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2139 SkPoint r7[] = {{1, 1}, {1, 0}, {0, 0}, {0, 1}};
2140 SkPoint r8[] = {{1, 0}, {0, 0}, {0, 1}, {1, 1}};
2141 SkPoint r9[] = {{0, 1}, {1, 1}, {1, 0}, {0, 0}};
2142 SkPoint ra[] = {{0, 0}, {0, .5f}, {0, 1}, {.5f, 1}, {1, 1}, {1, .5f}, {1, 0}, {.5f, 0}};
2143 SkPoint rb[] = {{0, 0}, {.5f, 0}, {1, 0}, {1, .5f}, {1, 1}, {.5f, 1}, {0, 1}, {0, .5f}};
2144 SkPoint rc[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};
2145 SkPoint rd[] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
2146 SkPoint re[] = {{0, 0}, {1, 0}, {1, 0}, {1, 1}, {0, 1}};
2147 SkPoint rf[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 0}};
2148
2149 // failing tests
2150 SkPoint f1[] = {{0, 0}, {1, 0}, {1, 1}}; // too few points
2151 SkPoint f2[] = {{0, 0}, {1, 1}, {0, 1}, {1, 0}}; // diagonal
2152 SkPoint f3[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}, {1, 0}}; // wraps
2153 SkPoint f4[] = {{0, 0}, {1, 0}, {0, 0}, {1, 0}, {1, 1}, {0, 1}}; // backs up
2154 SkPoint f5[] = {{0, 0}, {1, 0}, {1, 1}, {2, 0}}; // end overshoots
2155 SkPoint f6[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 2}}; // end overshoots
2156 SkPoint f7[] = {{0, 0}, {1, 0}, {1, 1}, {0, 2}}; // end overshoots
2157 SkPoint f8[] = {{0, 0}, {1, 0}, {1, 1}, {1, 0}}; // 'L'
2158 SkPoint f9[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 0}, {2, 0}}; // overlaps
2159 SkPoint fa[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, -1}, {1, -1}}; // non colinear gap
2160 SkPoint fb[] = {{1, 0}, {8, 0}, {8, 8}, {0, 8}, {0, 1}}; // falls short
2161
2162 // no close, but we should detect them as fillably the same as a rect
2163 SkPoint c1[] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
2164 SkPoint c2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}};
2165 SkPoint c3[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}, {0, 0}}; // hit the start
2166
2167 // like c2, but we double-back on ourselves
2168 SkPoint d1[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, 1}, {0, 2}};
2169 // like c2, but we overshoot the start point
2170 SkPoint d2[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, -1}};
2171 SkPoint d3[] = {{0, 0}, {1, 0}, {1, 2}, {0, 2}, {0, -1}, {0, 0}};
2172
2173 struct IsRectTest {
2174 SkPoint *fPoints;
2175 int fPointCount;
2176 bool fClose;
2177 bool fIsRect;
2178 } tests[] = {
2179 { r1, std::size(r1), true, true },
2180 { r2, std::size(r2), true, true },
2181 { r3, std::size(r3), true, true },
2182 { r4, std::size(r4), true, true },
2183 { r5, std::size(r5), true, true },
2184 { r6, std::size(r6), true, true },
2185 { r7, std::size(r7), true, true },
2186 { r8, std::size(r8), true, true },
2187 { r9, std::size(r9), true, true },
2188 { ra, std::size(ra), true, true },
2189 { rb, std::size(rb), true, true },
2190 { rc, std::size(rc), true, true },
2191 { rd, std::size(rd), true, true },
2192 { re, std::size(re), true, true },
2193 { rf, std::size(rf), true, true },
2194
2195 { f1, std::size(f1), true, false },
2196 { f2, std::size(f2), true, false },
2197 { f3, std::size(f3), true, false },
2198 { f4, std::size(f4), true, false },
2199 { f5, std::size(f5), true, false },
2200 { f6, std::size(f6), true, false },
2201 { f7, std::size(f7), true, false },
2202 { f8, std::size(f8), true, false },
2203 { f9, std::size(f9), true, false },
2204 { fa, std::size(fa), true, false },
2205 { fb, std::size(fb), true, false },
2206
2207 { c1, std::size(c1), false, true },
2208 { c2, std::size(c2), false, true },
2209 { c3, std::size(c3), false, true },
2210
2211 { d1, std::size(d1), false, false },
2212 { d2, std::size(d2), false, true },
2213 { d3, std::size(d3), false, false },
2214 };
2215
2216 const size_t testCount = std::size(tests);
2217 int index;
2218 for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
2219 SkPath path;
2220 path.moveTo(tests[testIndex].fPoints[0].fX, tests[testIndex].fPoints[0].fY);
2221 for (index = 1; index < tests[testIndex].fPointCount; ++index) {
2222 path.lineTo(tests[testIndex].fPoints[index].fX, tests[testIndex].fPoints[index].fY);
2223 }
2224 if (tests[testIndex].fClose) {
2225 path.close();
2226 }
2227 REPORTER_ASSERT(reporter, tests[testIndex].fIsRect == path.isRect(nullptr));
2228
2229 if (tests[testIndex].fIsRect) {
2230 SkRect computed, expected;
2231 bool isClosed;
2232 SkPathDirection direction;
2233 int pointCount = tests[testIndex].fPointCount - (d2 == tests[testIndex].fPoints);
2234 expected.setBounds(tests[testIndex].fPoints, pointCount);
2237 REPORTER_ASSERT(reporter, path.isRect(&computed, &isClosed, &direction));
2238 REPORTER_ASSERT(reporter, expected == computed);
2239 REPORTER_ASSERT(reporter, isClosed == tests[testIndex].fClose);
2240 REPORTER_ASSERT(reporter, SkPathPriv::AsFirstDirection(direction) == cheapDirection);
2241 } else {
2242 SkRect computed;
2243 computed.setLTRB(123, 456, 789, 1011);
2244 for (auto c : {true, false})
2246 bool isClosed = c;
2247 SkPathDirection direction = d;
2248 REPORTER_ASSERT(reporter, !path.isRect(&computed, &isClosed, &direction));
2249 REPORTER_ASSERT(reporter, computed.fLeft == 123 && computed.fTop == 456);
2250 REPORTER_ASSERT(reporter, computed.fRight == 789 && computed.fBottom == 1011);
2251 REPORTER_ASSERT(reporter, isClosed == c);
2252 REPORTER_ASSERT(reporter, direction == d);
2253 }
2254 }
2255 }
2256
2257 // fail, close then line
2258 SkPath path1;
2259 path1.moveTo(r1[0].fX, r1[0].fY);
2260 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2261 path1.lineTo(r1[index].fX, r1[index].fY);
2262 }
2263 path1.close();
2264 path1.lineTo(1, 0);
2266
2267 // fail, move in the middle
2268 path1.reset();
2269 path1.moveTo(r1[0].fX, r1[0].fY);
2270 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2271 if (index == 2) {
2272 path1.moveTo(1, .5f);
2273 }
2274 path1.lineTo(r1[index].fX, r1[index].fY);
2275 }
2276 path1.close();
2278
2279 // fail, move on the edge
2280 path1.reset();
2281 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2282 path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
2283 path1.lineTo(r1[index].fX, r1[index].fY);
2284 }
2285 path1.close();
2287
2288 // fail, quad
2289 path1.reset();
2290 path1.moveTo(r1[0].fX, r1[0].fY);
2291 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2292 if (index == 2) {
2293 path1.quadTo(1, .5f, 1, .5f);
2294 }
2295 path1.lineTo(r1[index].fX, r1[index].fY);
2296 }
2297 path1.close();
2299
2300 // fail, cubic
2301 path1.reset();
2302 path1.moveTo(r1[0].fX, r1[0].fY);
2303 for (index = 1; index < SkToInt(std::size(r1)); ++index) {
2304 if (index == 2) {
2305 path1.cubicTo(1, .5f, 1, .5f, 1, .5f);
2306 }
2307 path1.lineTo(r1[index].fX, r1[index].fY);
2308 }
2309 path1.close();
2311}
static void test_isRect_open_close(skiatest::Reporter *reporter)
Definition: PathTest.cpp:2116

◆ test_isRect_open_close()

static void test_isRect_open_close ( skiatest::Reporter reporter)
static

Definition at line 2116 of file PathTest.cpp.

2116 {
2117 SkPath path;
2118 bool isClosed;
2119
2120 path.moveTo(0, 0); path.lineTo(1, 0); path.lineTo(1, 1); path.lineTo(0, 1);
2121 path.close();
2122
2123 REPORTER_ASSERT(reporter, path.isRect(nullptr, &isClosed, nullptr));
2124 REPORTER_ASSERT(reporter, isClosed);
2125}

◆ test_iter()

static void test_iter ( skiatest::Reporter reporter)
static

Definition at line 3072 of file PathTest.cpp.

3072 {
3073 SkPath p;
3074 SkPoint pts[4];
3075
3076 // Test an iterator with no path
3077 SkPath::Iter noPathIter;
3078 REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
3079
3080 // Test that setting an empty path works
3081 noPathIter.setPath(p, false);
3082 REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
3083
3084 // Test that close path makes no difference for an empty path
3085 noPathIter.setPath(p, true);
3086 REPORTER_ASSERT(reporter, noPathIter.next(pts) == SkPath::kDone_Verb);
3087
3088 // Test an iterator with an initial empty path
3089 SkPath::Iter iter(p, false);
3090 REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
3091
3092 // Test that close path makes no difference
3093 iter.setPath(p, true);
3094 REPORTER_ASSERT(reporter, iter.next(pts) == SkPath::kDone_Verb);
3095
3096
3097 struct iterTestData {
3098 const char* testPath;
3099 const bool forceClose;
3100 const size_t* numResultPtsPerVerb;
3101 const SkPoint* resultPts;
3102 const SkPath::Verb* resultVerbs;
3103 const size_t numResultVerbs;
3104 };
3105
3106 static const SkPath::Verb resultVerbs1[] = { SkPath::kDone_Verb };
3107 static const SkPath::Verb resultVerbs2[] = {
3109 };
3110 static const SkPath::Verb resultVerbs3[] = {
3112 };
3113 static const size_t resultPtsSizes1[] = { 0 };
3114 static const size_t resultPtsSizes2[] = { 1, 2, 1, 1, 0 };
3115 static const size_t resultPtsSizes3[] = { 1, 2, 1, 1, 1, 0 };
3116 static const SkPoint* resultPts1 = nullptr;
3117 static const SkPoint resultPts2[] = {
3118 { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
3119 };
3120 static const SkPoint resultPts3[] = {
3121 { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { SK_Scalar1, 0 }, { 0, 0 }, { 0, 0 }
3122 };
3123 static const struct iterTestData gIterTests[] = {
3124 { "M 1 0", false, resultPtsSizes1, resultPts1, resultVerbs1, std::size(resultVerbs1) },
3125 { "z", false, resultPtsSizes1, resultPts1, resultVerbs1, std::size(resultVerbs1) },
3126 { "z", true, resultPtsSizes1, resultPts1, resultVerbs1, std::size(resultVerbs1) },
3127 { "M 1 0 L 1 0 M 0 0 z", false, resultPtsSizes2, resultPts2, resultVerbs2, std::size(resultVerbs2) },
3128 { "M 1 0 L 1 0 M 0 0 z", true, resultPtsSizes3, resultPts3, resultVerbs3, std::size(resultVerbs3) }
3129 };
3130
3131 for (size_t i = 0; i < std::size(gIterTests); ++i) {
3132 p.reset();
3133 bool valid = SkParsePath::FromSVGString(gIterTests[i].testPath, &p);
3134 REPORTER_ASSERT(reporter, valid);
3135 iter.setPath(p, gIterTests[i].forceClose);
3136 int j = 0, l = 0;
3137 do {
3138 REPORTER_ASSERT(reporter, iter.next(pts) == gIterTests[i].resultVerbs[j]);
3139 for (int k = 0; k < (int)gIterTests[i].numResultPtsPerVerb[j]; ++k) {
3140 REPORTER_ASSERT(reporter, pts[k] == gIterTests[i].resultPts[l++]);
3141 }
3142 } while (gIterTests[i].resultVerbs[j++] != SkPath::kDone_Verb);
3143 REPORTER_ASSERT(reporter, j == (int)gIterTests[i].numResultVerbs);
3144 }
3145
3146 p.reset();
3147 iter.setPath(p, false);
3148 REPORTER_ASSERT(reporter, !iter.isClosedContour());
3149 p.lineTo(1, 1);
3150 p.close();
3151 iter.setPath(p, false);
3152 REPORTER_ASSERT(reporter, iter.isClosedContour());
3153 p.reset();
3154 iter.setPath(p, true);
3155 REPORTER_ASSERT(reporter, !iter.isClosedContour());
3156 p.lineTo(1, 1);
3157 iter.setPath(p, true);
3158 REPORTER_ASSERT(reporter, iter.isClosedContour());
3159 p.moveTo(0, 0);
3160 p.lineTo(2, 2);
3161 iter.setPath(p, false);
3162 REPORTER_ASSERT(reporter, !iter.isClosedContour());
3163
3164 // this checks to see if the NaN logic is executed in SkPath::autoClose(), but does not
3165 // check to see if the result is correct.
3166 for (int setNaN = 0; setNaN < 4; ++setNaN) {
3167 p.reset();
3168 p.moveTo(setNaN == 0 ? SK_ScalarNaN : 0, setNaN == 1 ? SK_ScalarNaN : 0);
3169 p.lineTo(setNaN == 2 ? SK_ScalarNaN : 1, setNaN == 3 ? SK_ScalarNaN : 1);
3170 iter.setPath(p, true);
3171 iter.next(pts);
3172 iter.next(pts);
3173 REPORTER_ASSERT(reporter, SkPath::kClose_Verb == iter.next(pts));
3174 }
3175
3176 p.reset();
3177 p.quadTo(0, 0, 0, 0);
3178 iter.setPath(p, false);
3179 iter.next(pts);
3180 REPORTER_ASSERT(reporter, SkPath::kQuad_Verb == iter.next(pts));
3181
3182 p.reset();
3183 p.conicTo(0, 0, 0, 0, 0.5f);
3184 iter.setPath(p, false);
3185 iter.next(pts);
3186 REPORTER_ASSERT(reporter, SkPath::kConic_Verb == iter.next(pts));
3187
3188 p.reset();
3189 p.cubicTo(0, 0, 0, 0, 0, 0);
3190 iter.setPath(p, false);
3191 iter.next(pts);
3192 REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == iter.next(pts));
3193
3194 p.moveTo(1, 1); // add a trailing moveto
3195 iter.setPath(p, false);
3196 iter.next(pts);
3197 REPORTER_ASSERT(reporter, SkPath::kCubic_Verb == iter.next(pts));
3198
3199 // The GM degeneratesegments.cpp test is more extensive
3200
3201 // Test out mixed degenerate and non-degenerate geometry with Conics
3202 const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } };
3203 SkRect r = SkRect::MakeWH(100, 100);
3204 SkRRect rr;
3205 rr.setRectRadii(r, radii);
3206 p.reset();
3207 p.addRRect(rr);
3208 iter.setPath(p, false);
3209 REPORTER_ASSERT(reporter, SkPath::kMove_Verb == iter.next(pts));
3210 REPORTER_ASSERT(reporter, SkPath::kLine_Verb == iter.next(pts));
3211 return;
3212 REPORTER_ASSERT(reporter, SkPath::kLine_Verb == iter.next(pts));
3213 REPORTER_ASSERT(reporter, SkPath::kConic_Verb == iter.next(pts));
3214 REPORTER_ASSERT(reporter, SK_ScalarRoot2Over2 == iter.conicWeight());
3215}
#define SK_ScalarRoot2Over2
Definition: SkScalar.h:23
void setPath(const SkPath &path, bool forceClose)
Definition: SkPath.cpp:1837
Verb next(SkPoint pts[4])
Definition: SkPath.cpp:1901

◆ test_iterative_intersect_line()

static void test_iterative_intersect_line ( )
static

Definition at line 149 of file PathTest.cpp.

149 {
150 // crbug.com/1320467
151 // SkLineClipper::IntersectLine used to clip against the horizontal segment. Then, if it still
152 // needed clipping, would clip against the vertical segment, but start over from the un-clipped
153 // endpoints. With that version, this draw would trigger an assert.
154 // With the fix (iteratively clipping the intermediate results after the first operation),
155 // this shouldn't assert:
156 SkPath path;
157 path.moveTo(-478.805145f, 153.862549f);
158 path.lineTo(6.27216804e+19f, 6.27216804e+19f);
159 path.lineTo(-666.754272f, 155.086304f);
160 path.close();
161
165}

◆ test_mask_overflow()

static void test_mask_overflow ( )
static

Definition at line 250 of file PathTest.cpp.

250 {
251 SkPath path;
252 path.moveTo(SkBits2Float(0x43e28000), SkBits2Float(0x43aa8000)); // 453, 341
253 path.lineTo(SkBits2Float(0x43de6000), SkBits2Float(0x43aa8000)); // 444.75f, 341
254 // 440.47f, 341, 437, 344.47f, 437, 348.75f
255 path.cubicTo(SkBits2Float(0x43dc3c29), SkBits2Float(0x43aa8000),
256 SkBits2Float(0x43da8000), SkBits2Float(0x43ac3c29),
257 SkBits2Float(0x43da8000), SkBits2Float(0x43ae6000));
258 path.lineTo(SkBits2Float(0x43da8000), SkBits2Float(0x43b18000)); // 437, 355
259 path.lineTo(SkBits2Float(0x43e28000), SkBits2Float(0x43b18000)); // 453, 355
260 path.lineTo(SkBits2Float(0x43e28000), SkBits2Float(0x43aa8000)); // 453, 341
261 test_draw_AA_path(500, 500, path);
262}

◆ test_open_oval()

static void test_open_oval ( skiatest::Reporter reporter)
static

Definition at line 3764 of file PathTest.cpp.

3764 {
3765 SkRect rect;
3766 SkMatrix m;
3767 SkPath path;
3768 unsigned start = 0;
3770
3772 path.addOpenOval(rect, SkPathDirection::kCW, /*start=*/1);
3773
3774 // Open ovals are not ovals...
3775 REPORTER_ASSERT(reporter, !path.isOval(nullptr));
3776 // ... until they're closed
3777 path.close();
3778 REPORTER_ASSERT(reporter, path.isOval(nullptr));
3779
3780 // We can transform an open oval before closing it
3781 path.reset();
3782 path.addOpenOval(rect, SkPathDirection::kCW, /*start=*/1);
3783
3784 m.setRotate(SkIntToScalar(90));
3785 SkPath tmp;
3786 path.transform(m, &tmp);
3787 // an oval rotated 90 degrees is still an oval. The start index changes from 1 to 2. Direction
3788 // is unchanged.
3789 REPORTER_ASSERT(reporter, !tmp.isOval(nullptr));
3790 tmp.close();
3794
3795 m.reset();
3796 m.setRotate(SkIntToScalar(30));
3797 tmp.reset();
3798 path.transform(m, &tmp);
3799 // an open oval rotated 30 degrees does not become an oval when closed
3800 tmp.close();
3801 REPORTER_ASSERT(reporter, !tmp.isOval(nullptr));
3802
3803 // Calling moveTo before addOpenOval does not result in an oval
3804 path.reset();
3805 path.moveTo(0, 0);
3806 path.addOpenOval(rect, SkPathDirection::kCW, /*start=*/1);
3807 path.close();
3808 REPORTER_ASSERT(reporter, !path.isOval(nullptr));
3809
3810 // Moving (or any other verb) before the close also does not result in an oval
3811 path.reset();
3812 path.addOpenOval(rect, SkPathDirection::kCW, /*start=*/1);
3813 path.moveTo(0, 0);
3814 path.close();
3815 REPORTER_ASSERT(reporter, !path.isOval(nullptr));
3816
3817 // copy path before closing
3818 path.reset();
3819 tmp.reset();
3820 tmp.addOpenOval(rect, SkPathDirection::kCW, /*start=*/1);
3821 path = tmp;
3822 path.close();
3826}
bool isOval(SkRect *bounds) const
Definition: SkPath.cpp:523
SkPath & addOpenOval(const SkRect &oval, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:1161

◆ test_operatorEqual()

static void test_operatorEqual ( skiatest::Reporter reporter)
static

Definition at line 4541 of file PathTest.cpp.

4541 {
4542 SkPath a;
4543 SkPath b;
4548 a.reset();
4550 a.lineTo(1, 1);
4552 a.reset();
4554 a.lineTo(1, 1);
4555 b.lineTo(1, 2);
4557 a.reset();
4558 a.lineTo(1, 2);
4560}

◆ test_oval()

static void test_oval ( skiatest::Reporter reporter)
static

Definition at line 3701 of file PathTest.cpp.

3701 {
3702 SkRect rect;
3703 SkMatrix m;
3704 SkPath path;
3705 unsigned start = 0;
3707
3709 path.addOval(rect);
3710
3711 // Defaults to dir = CW and start = 1
3712 REPORTER_ASSERT(reporter, path.isOval(nullptr));
3713
3714 m.setRotate(SkIntToScalar(90));
3715 SkPath tmp;
3716 path.transform(m, &tmp);
3717 // an oval rotated 90 degrees is still an oval. The start index changes from 1 to 2. Direction
3718 // is unchanged.
3722
3723 m.reset();
3724 m.setRotate(SkIntToScalar(30));
3725 tmp.reset();
3726 path.transform(m, &tmp);
3727 // an oval rotated 30 degrees is not an oval anymore.
3728 REPORTER_ASSERT(reporter, !tmp.isOval(nullptr));
3729
3730 // since empty path being transformed.
3731 path.reset();
3732 tmp.reset();
3733 m.reset();
3734 path.transform(m, &tmp);
3735 REPORTER_ASSERT(reporter, !tmp.isOval(nullptr));
3736
3737 // empty path is not an oval
3738 tmp.reset();
3739 REPORTER_ASSERT(reporter, !tmp.isOval(nullptr));
3740
3741 // only has moveTo()s
3742 tmp.reset();
3743 tmp.moveTo(0, 0);
3744 tmp.moveTo(SkIntToScalar(10), SkIntToScalar(10));
3745 REPORTER_ASSERT(reporter, !tmp.isOval(nullptr));
3746
3747 // mimic WebKit's calling convention,
3748 // call moveTo() first and then call addOval()
3749 path.reset();
3750 path.moveTo(0, 0);
3751 path.addOval(rect);
3752 REPORTER_ASSERT(reporter, path.isOval(nullptr));
3753
3754 // copy path
3755 path.reset();
3756 tmp.reset();
3757 tmp.addOval(rect);
3758 path = tmp;
3762}

◆ test_path_close_issue1474()

static void test_path_close_issue1474 ( skiatest::Reporter reporter)
static

Definition at line 359 of file PathTest.cpp.

359 {
360 // This test checks that r{Line,Quad,Conic,Cubic}To following a close()
361 // are relative to the point we close to, not relative to the point we close from.
362 SkPath path;
363 SkPoint last;
364
365 // Test rLineTo().
366 path.rLineTo(0, 100);
367 path.rLineTo(100, 0);
368 path.close(); // Returns us back to 0,0.
369 path.rLineTo(50, 50); // This should go to 50,50.
370
371 path.getLastPt(&last);
372 REPORTER_ASSERT(reporter, 50 == last.fX);
373 REPORTER_ASSERT(reporter, 50 == last.fY);
374
375 // Test rQuadTo().
376 path.rewind();
377 path.rLineTo(0, 100);
378 path.rLineTo(100, 0);
379 path.close();
380 path.rQuadTo(50, 50, 75, 75);
381
382 path.getLastPt(&last);
383 REPORTER_ASSERT(reporter, 75 == last.fX);
384 REPORTER_ASSERT(reporter, 75 == last.fY);
385
386 // Test rConicTo().
387 path.rewind();
388 path.rLineTo(0, 100);
389 path.rLineTo(100, 0);
390 path.close();
391 path.rConicTo(50, 50, 85, 85, 2);
392
393 path.getLastPt(&last);
394 REPORTER_ASSERT(reporter, 85 == last.fX);
395 REPORTER_ASSERT(reporter, 85 == last.fY);
396
397 // Test rCubicTo().
398 path.rewind();
399 path.rLineTo(0, 100);
400 path.rLineTo(100, 0);
401 path.close();
402 path.rCubicTo(50, 50, 85, 85, 95, 95);
403
404 path.getLastPt(&last);
405 REPORTER_ASSERT(reporter, 95 == last.fX);
406 REPORTER_ASSERT(reporter, 95 == last.fY);
407}

◆ test_path_crbug364224()

static void test_path_crbug364224 ( )
static

Definition at line 167 of file PathTest.cpp.

167 {
168 SkPath path;
171 SkCanvas* canvas = surface->getCanvas();
172
174 canvas->drawPath(path, paint);
175
177 canvas->drawPath(path, paint);
178}
static void make_path_crbug364224(SkPath *path)
Definition: PathTest.cpp:105
static void make_path_crbug364224_simplified(SkPath *path)
Definition: PathTest.cpp:129

◆ test_path_crbug389050()

static void test_path_crbug389050 ( skiatest::Reporter reporter)
static

Definition at line 1365 of file PathTest.cpp.

1365 {
1366 SkPath tinyConvexPolygon;
1367 tinyConvexPolygon.moveTo(600.131559f, 800.112512f);
1368 tinyConvexPolygon.lineTo(600.161735f, 800.118627f);
1369 tinyConvexPolygon.lineTo(600.148962f, 800.142338f);
1370 tinyConvexPolygon.lineTo(600.134891f, 800.137724f);
1371 tinyConvexPolygon.close();
1372 tinyConvexPolygon.isConvex();
1374
1375 SkPath platTriangle;
1376 platTriangle.moveTo(0, 0);
1377 platTriangle.lineTo(200, 0);
1378 platTriangle.lineTo(100, 0.04f);
1379 platTriangle.close();
1380 platTriangle.isConvex();
1382
1383 platTriangle.reset();
1384 platTriangle.moveTo(0, 0);
1385 platTriangle.lineTo(200, 0);
1386 platTriangle.lineTo(100, 0.03f);
1387 platTriangle.close();
1388 platTriangle.isConvex();
1390}

◆ test_path_crbugskia2820()

static void test_path_crbugskia2820 ( skiatest::Reporter reporter)
static

Definition at line 291 of file PathTest.cpp.

291 {
292 SkPath path;
294
296 stroke.setStrokeStyle(2 * SK_Scalar1);
297 stroke.applyToPath(&path, path);
298}
static void make_path_crbugskia2820(SkPath *path, skiatest::Reporter *reporter)
Definition: PathTest.cpp:278

◆ test_path_crbugskia5995()

static void test_path_crbugskia5995 ( )
static

Definition at line 300 of file PathTest.cpp.

300 {
301 SkPath path;
302 path.moveTo(SkBits2Float(0x40303030), SkBits2Float(0x3e303030)); // 2.75294f, 0.172059f
303 path.quadTo(SkBits2Float(0x41d63030), SkBits2Float(0x30303030), SkBits2Float(0x41013030),
304 SkBits2Float(0x00000000)); // 26.7735f, 6.40969e-10f, 8.07426f, 0
305 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
306 test_draw_AA_path(500, 500, path);
307}

◆ test_path_crbugskia6003()

static void test_path_crbugskia6003 ( )
static

Definition at line 4742 of file PathTest.cpp.

4742 {
4744 SkCanvas* canvas = surface->getCanvas();
4745 SkPaint paint;
4746 paint.setAntiAlias(true);
4747 SkPath path;
4748 path.moveTo(SkBits2Float(0x4325e666), SkBits2Float(0x42a1999a)); // 165.9f, 80.8f
4749 path.lineTo(SkBits2Float(0x4325e666), SkBits2Float(0x42a2999a)); // 165.9f, 81.3f
4750 path.lineTo(SkBits2Float(0x4325b333), SkBits2Float(0x42a2999a)); // 165.7f, 81.3f
4751 path.lineTo(SkBits2Float(0x4325b333), SkBits2Float(0x42a16666)); // 165.7f, 80.7f
4752 path.lineTo(SkBits2Float(0x4325b333), SkBits2Float(0x429f6666)); // 165.7f, 79.7f
4753 // 165.7f, 79.7f, 165.8f, 79.7f, 165.8f, 79.7f
4754 path.cubicTo(SkBits2Float(0x4325b333), SkBits2Float(0x429f6666), SkBits2Float(0x4325cccc),
4755 SkBits2Float(0x429f6666), SkBits2Float(0x4325cccc), SkBits2Float(0x429f6666));
4756 // 165.8f, 79.7f, 165.8f, 79.7f, 165.9f, 79.7f
4757 path.cubicTo(SkBits2Float(0x4325cccc), SkBits2Float(0x429f6666), SkBits2Float(0x4325cccc),
4758 SkBits2Float(0x429f6666), SkBits2Float(0x4325e666), SkBits2Float(0x429f6666));
4759 path.lineTo(SkBits2Float(0x4325e666), SkBits2Float(0x42a1999a)); // 165.9f, 80.8f
4760 path.close();
4761 canvas->clipPath(path, true);
4762 canvas->drawRect(SkRect::MakeWH(500, 500), paint);
4763}

◆ test_path_isfinite()

static void test_path_isfinite ( skiatest::Reporter reporter)
static

Definition at line 966 of file PathTest.cpp.

966 {
967 const SkScalar inf = SK_ScalarInfinity;
968 const SkScalar negInf = SK_ScalarNegativeInfinity;
969 const SkScalar nan = SK_ScalarNaN;
970
971 SkPath path;
972 REPORTER_ASSERT(reporter, path.isFinite());
973
974 path.reset();
975 REPORTER_ASSERT(reporter, path.isFinite());
976
977 path.reset();
978 path.moveTo(SK_Scalar1, 0);
979 REPORTER_ASSERT(reporter, path.isFinite());
980
981 path.reset();
982 path.moveTo(inf, negInf);
983 REPORTER_ASSERT(reporter, !path.isFinite());
984
985 path.reset();
986 path.moveTo(nan, 0);
987 REPORTER_ASSERT(reporter, !path.isFinite());
988}

◆ test_path_to_region()

static void test_path_to_region ( skiatest::Reporter reporter)
static

Definition at line 333 of file PathTest.cpp.

333 {
334 PathProc procs[] = {
337 };
338
340 clip.setRect({0, 0, 1255, 1925});
341
342 for (size_t i = 0; i < std::size(procs); ++i) {
343 SkPath path;
344 procs[i](&path);
345
346 SkRegion rgn;
347 rgn.setPath(path, clip);
348 path.toggleInverseFillType();
349 rgn.setPath(path, clip);
350 }
351}
static void make_path0(SkPath *path)
Definition: PathTest.cpp:309
static void make_path1(SkPath *path)
Definition: PathTest.cpp:320
void(* PathProc)(SkPath *)
Definition: PathTest.cpp:324
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
bool setPath(const SkPath &path, const SkRegion &clip)

◆ test_poly()

static void test_poly ( skiatest::Reporter reporter,
const SkPath path,
const SkPoint  srcPts[],
bool  expectClose 
)
static

Definition at line 1019 of file PathTest.cpp.

1020 {
1021 bool firstTime = true;
1022 bool foundClose = false;
1023 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
1024 switch (verb) {
1025 case SkPathVerb::kMove:
1026 REPORTER_ASSERT(reporter, firstTime);
1027 REPORTER_ASSERT(reporter, pts[0] == srcPts[0]);
1028 srcPts++;
1029 firstTime = false;
1030 break;
1031 case SkPathVerb::kLine:
1032 REPORTER_ASSERT(reporter, !firstTime);
1033 REPORTER_ASSERT(reporter, pts[1] == srcPts[0]);
1034 srcPts++;
1035 break;
1036 case SkPathVerb::kQuad:
1037 REPORTER_ASSERT(reporter, false, "unexpected quad verb");
1038 break;
1039 case SkPathVerb::kConic:
1040 REPORTER_ASSERT(reporter, false, "unexpected conic verb");
1041 break;
1042 case SkPathVerb::kCubic:
1043 REPORTER_ASSERT(reporter, false, "unexpected cubic verb");
1044 break;
1045 case SkPathVerb::kClose:
1046 REPORTER_ASSERT(reporter, !firstTime);
1047 REPORTER_ASSERT(reporter, !foundClose);
1048 REPORTER_ASSERT(reporter, expectClose);
1049 foundClose = true;
1050 break;
1051 }
1052 }
1053 REPORTER_ASSERT(reporter, foundClose == expectClose);
1054}
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.

◆ test_range_iter()

static void test_range_iter ( skiatest::Reporter reporter)
static

Definition at line 3217 of file PathTest.cpp.

3217 {
3218 SkPath path;
3219
3220 // Test an iterator with an initial empty path
3221 SkPathPriv::Iterate iterate(path);
3222 REPORTER_ASSERT(reporter, iterate.begin() == iterate.end());
3223
3224 // Test that a move-only path returns the move.
3225 path.moveTo(SK_Scalar1, 0);
3226 iterate = SkPathPriv::Iterate(path);
3227 SkPathPriv::RangeIter iter = iterate.begin();
3228 {
3229 auto [verb, pts, w] = *iter++;
3231 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
3232 REPORTER_ASSERT(reporter, pts[0].fY == 0);
3233 }
3234 REPORTER_ASSERT(reporter, iter == iterate.end());
3235
3236 // No matter how many moves we add, we should get them all back
3237 path.moveTo(SK_Scalar1*2, SK_Scalar1);
3238 path.moveTo(SK_Scalar1*3, SK_Scalar1*2);
3239 iterate = SkPathPriv::Iterate(path);
3240 iter = iterate.begin();
3241 {
3242 auto [verb, pts, w] = *iter++;
3244 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
3245 REPORTER_ASSERT(reporter, pts[0].fY == 0);
3246 }
3247 {
3248 auto [verb, pts, w] = *iter++;
3250 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
3251 REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
3252 }
3253 {
3254 auto [verb, pts, w] = *iter++;
3256 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
3257 REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
3258 }
3259 REPORTER_ASSERT(reporter, iter == iterate.end());
3260
3261 // Initial close is never ever stored
3262 path.reset();
3263 path.close();
3264 iterate = SkPathPriv::Iterate(path);
3265 REPORTER_ASSERT(reporter, iterate.begin() == iterate.end());
3266
3267 // Move/close sequences
3268 path.reset();
3269 path.close(); // Not stored, no purpose
3270 path.moveTo(SK_Scalar1, 0);
3271 path.close();
3272 path.close(); // Not stored, no purpose
3273 path.moveTo(SK_Scalar1*2, SK_Scalar1);
3274 path.close();
3275 path.moveTo(SK_Scalar1*3, SK_Scalar1*2);
3276 path.moveTo(SK_Scalar1*4, SK_Scalar1*3);
3277 path.close();
3278 iterate = SkPathPriv::Iterate(path);
3279 iter = iterate.begin();
3280 {
3281 auto [verb, pts, w] = *iter++;
3283 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1);
3284 REPORTER_ASSERT(reporter, pts[0].fY == 0);
3285 }
3286 {
3287 auto [verb, pts, w] = *iter++;
3289 }
3290 {
3291 auto [verb, pts, w] = *iter++;
3293 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*2);
3294 REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1);
3295 }
3296 {
3297 auto [verb, pts, w] = *iter++;
3299 }
3300 {
3301 auto [verb, pts, w] = *iter++;
3303 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*3);
3304 REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*2);
3305 }
3306 {
3307 auto [verb, pts, w] = *iter++;
3309 REPORTER_ASSERT(reporter, pts[0].fX == SK_Scalar1*4);
3310 REPORTER_ASSERT(reporter, pts[0].fY == SK_Scalar1*3);
3311 }
3312 {
3313 auto [verb, pts, w] = *iter++;
3315 }
3316 REPORTER_ASSERT(reporter, iter == iterate.end());
3317
3318 // Generate random paths and verify
3319 SkPoint randomPts[25];
3320 for (int i = 0; i < 5; ++i) {
3321 for (int j = 0; j < 5; ++j) {
3322 randomPts[i*5+j].set(SK_Scalar1*i, SK_Scalar1*j);
3323 }
3324 }
3325
3326 // Max of 10 segments, max 3 points per segment
3327 SkRandom rand(9876543);
3328 SkPoint expectedPts[31]; // May have leading moveTo
3329 SkPathVerb expectedVerbs[22]; // May have leading moveTo
3330 SkPathVerb nextVerb;
3331
3332 for (int i = 0; i < 500; ++i) {
3333 path.reset();
3334 bool lastWasClose = true;
3335 bool haveMoveTo = false;
3336 SkPoint lastMoveToPt = { 0, 0 };
3337 int numPoints = 0;
3338 int numVerbs = (rand.nextU() >> 16) % 10;
3339 int numIterVerbs = 0;
3340 for (int j = 0; j < numVerbs; ++j) {
3341 do {
3342 nextVerb = static_cast<SkPathVerb>((rand.nextU() >> 16) % SkPath::kDone_Verb);
3343 } while (lastWasClose && nextVerb == SkPathVerb::kClose);
3344 switch (nextVerb) {
3345 case SkPathVerb::kMove:
3346 expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
3347 path.moveTo(expectedPts[numPoints]);
3348 lastMoveToPt = expectedPts[numPoints];
3349 numPoints += 1;
3350 lastWasClose = false;
3351 haveMoveTo = true;
3352 break;
3353 case SkPathVerb::kLine:
3354 if (!haveMoveTo) {
3355 expectedPts[numPoints++] = lastMoveToPt;
3356 expectedVerbs[numIterVerbs++] = SkPathVerb::kMove;
3357 haveMoveTo = true;
3358 }
3359 expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
3360 path.lineTo(expectedPts[numPoints]);
3361 numPoints += 1;
3362 lastWasClose = false;
3363 break;
3364 case SkPathVerb::kQuad:
3365 if (!haveMoveTo) {
3366 expectedPts[numPoints++] = lastMoveToPt;
3367 expectedVerbs[numIterVerbs++] = SkPathVerb::kMove;
3368 haveMoveTo = true;
3369 }
3370 expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
3371 expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
3372 path.quadTo(expectedPts[numPoints], expectedPts[numPoints + 1]);
3373 numPoints += 2;
3374 lastWasClose = false;
3375 break;
3376 case SkPathVerb::kConic:
3377 if (!haveMoveTo) {
3378 expectedPts[numPoints++] = lastMoveToPt;
3379 expectedVerbs[numIterVerbs++] = SkPathVerb::kMove;
3380 haveMoveTo = true;
3381 }
3382 expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
3383 expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
3384 path.conicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
3385 rand.nextUScalar1() * 4);
3386 numPoints += 2;
3387 lastWasClose = false;
3388 break;
3389 case SkPathVerb::kCubic:
3390 if (!haveMoveTo) {
3391 expectedPts[numPoints++] = lastMoveToPt;
3392 expectedVerbs[numIterVerbs++] = SkPathVerb::kMove;
3393 haveMoveTo = true;
3394 }
3395 expectedPts[numPoints] = randomPts[(rand.nextU() >> 16) % 25];
3396 expectedPts[numPoints + 1] = randomPts[(rand.nextU() >> 16) % 25];
3397 expectedPts[numPoints + 2] = randomPts[(rand.nextU() >> 16) % 25];
3398 path.cubicTo(expectedPts[numPoints], expectedPts[numPoints + 1],
3399 expectedPts[numPoints + 2]);
3400 numPoints += 3;
3401 lastWasClose = false;
3402 break;
3403 case SkPathVerb::kClose:
3404 path.close();
3405 haveMoveTo = false;
3406 lastWasClose = true;
3407 break;
3408 default:
3409 SkDEBUGFAIL("unexpected verb");
3410 }
3411 expectedVerbs[numIterVerbs++] = nextVerb;
3412 }
3413
3414 numVerbs = numIterVerbs;
3415 numIterVerbs = 0;
3416 int numIterPts = 0;
3417 SkPoint lastMoveTo;
3418 SkPoint lastPt;
3419 lastMoveTo.set(0, 0);
3420 lastPt.set(0, 0);
3421 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
3422 REPORTER_ASSERT(reporter, verb == expectedVerbs[numIterVerbs]);
3423 numIterVerbs++;
3424 switch (verb) {
3425 case SkPathVerb::kMove:
3426 REPORTER_ASSERT(reporter, numIterPts < numPoints);
3427 REPORTER_ASSERT(reporter, pts[0] == expectedPts[numIterPts]);
3428 lastPt = lastMoveTo = pts[0];
3429 numIterPts += 1;
3430 break;
3431 case SkPathVerb::kLine:
3432 REPORTER_ASSERT(reporter, numIterPts < numPoints + 1);
3433 REPORTER_ASSERT(reporter, pts[0] == lastPt);
3434 REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
3435 lastPt = pts[1];
3436 numIterPts += 1;
3437 break;
3438 case SkPathVerb::kQuad:
3439 case SkPathVerb::kConic:
3440 REPORTER_ASSERT(reporter, numIterPts < numPoints + 2);
3441 REPORTER_ASSERT(reporter, pts[0] == lastPt);
3442 REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
3443 REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
3444 lastPt = pts[2];
3445 numIterPts += 2;
3446 break;
3447 case SkPathVerb::kCubic:
3448 REPORTER_ASSERT(reporter, numIterPts < numPoints + 3);
3449 REPORTER_ASSERT(reporter, pts[0] == lastPt);
3450 REPORTER_ASSERT(reporter, pts[1] == expectedPts[numIterPts]);
3451 REPORTER_ASSERT(reporter, pts[2] == expectedPts[numIterPts + 1]);
3452 REPORTER_ASSERT(reporter, pts[3] == expectedPts[numIterPts + 2]);
3453 lastPt = pts[3];
3454 numIterPts += 3;
3455 break;
3456 case SkPathVerb::kClose:
3457 lastPt = lastMoveTo;
3458 break;
3459 default:
3460 SkDEBUGFAIL("unexpected verb");
3461 }
3462 }
3463 REPORTER_ASSERT(reporter, numIterPts == numPoints);
3464 REPORTER_ASSERT(reporter, numIterVerbs == numVerbs);
3465 }
3466}
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
SkPathVerb
Definition: SkPathTypes.h:48

◆ test_rect_isfinite()

static void test_rect_isfinite ( skiatest::Reporter reporter)
static

Definition at line 932 of file PathTest.cpp.

932 {
933 const SkScalar inf = SK_ScalarInfinity;
934 const SkScalar negInf = SK_ScalarNegativeInfinity;
935 const SkScalar nan = SK_ScalarNaN;
936
937 SkRect r;
938 r.setEmpty();
940 r.setLTRB(0, 0, inf, negInf);
942 r.setLTRB(0, 0, nan, 0);
944
945 SkPoint pts[] = {
946 { 0, 0 },
947 { SK_Scalar1, 0 },
948 { 0, SK_Scalar1 },
949 };
950
951 bool isFine = r.setBoundsCheck(pts, 3);
952 REPORTER_ASSERT(reporter, isFine);
954
955 pts[1].set(inf, 0);
956 isFine = r.setBoundsCheck(pts, 3);
957 REPORTER_ASSERT(reporter, !isFine);
959
960 pts[1].set(nan, 0);
961 isFine = r.setBoundsCheck(pts, 3);
962 REPORTER_ASSERT(reporter, !isFine);
964}
bool isFinite() const
Definition: SkRect.h:711
bool setBoundsCheck(const SkPoint pts[], int count)
Definition: SkRect.cpp:61

◆ test_rMoveTo()

static void test_rMoveTo ( skiatest::Reporter reporter)
static

Definition at line 4111 of file PathTest.cpp.

4111 {
4112 SkPath p;
4113 p.moveTo(10, 11);
4114 p.lineTo(20, 21);
4115 p.close();
4116 p.rMoveTo(30, 31);
4118 check_move(reporter, &iter, 10, 11);
4119 check_line(reporter, &iter, 20, 21);
4120 check_close(reporter, &iter);
4121 check_move(reporter, &iter, 10 + 30, 11 + 31);
4123
4124 p.moveTo(10, 11);
4125 p.lineTo(20, 21);
4126 p.rMoveTo(30, 31);
4127 iter = SkPathPriv::Iterate(p).begin();
4128 check_move(reporter, &iter, 10, 11);
4129 check_line(reporter, &iter, 20, 21);
4130 check_move(reporter, &iter, 20 + 30, 21 + 31);
4132
4133 p.rMoveTo(30, 31);
4134 iter = SkPathPriv::Iterate(p).begin();
4135 check_move(reporter, &iter, 30, 31);
4137}

◆ test_rrect()

static void test_rrect ( skiatest::Reporter reporter)
static

Definition at line 3862 of file PathTest.cpp.

3862 {
3863 SkPath p;
3864 SkRRect rr;
3865 SkVector radii[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
3866 SkRect r = {10, 20, 30, 40};
3867 rr.setRectRadii(r, radii);
3868 p.addRRect(rr);
3870 p.addRRect(rr, SkPathDirection::kCCW);
3872 p.addRoundRect(r, &radii[0].fX);
3874 p.addRoundRect(r, &radii[0].fX, SkPathDirection::kCCW);
3876 p.addRoundRect(r, radii[1].fX, radii[1].fY);
3878 p.addRoundRect(r, radii[1].fX, radii[1].fY, SkPathDirection::kCCW);
3880 for (size_t i = 0; i < std::size(radii); ++i) {
3881 SkVector save = radii[i];
3882 radii[i].set(0, 0);
3883 rr.setRectRadii(r, radii);
3884 p.addRRect(rr);
3886 radii[i] = save;
3887 }
3888 p.addRoundRect(r, 0, 0);
3889 SkRect returnedRect;
3890 REPORTER_ASSERT(reporter, p.isRect(&returnedRect));
3891 REPORTER_ASSERT(reporter, returnedRect == r);
3893 SkVector zeroRadii[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
3894 rr.setRectRadii(r, zeroRadii);
3895 p.addRRect(rr);
3896 bool closed;
3898 REPORTER_ASSERT(reporter, p.isRect(nullptr, &closed, &dir));
3899 REPORTER_ASSERT(reporter, closed);
3902 p.addRRect(rr, SkPathDirection::kCW);
3903 p.addRRect(rr, SkPathDirection::kCW);
3904 REPORTER_ASSERT(reporter, !p.isConvex());
3905 p.reset();
3906 p.addRRect(rr, SkPathDirection::kCCW);
3907 p.addRRect(rr, SkPathDirection::kCCW);
3908 REPORTER_ASSERT(reporter, !p.isConvex());
3909 p.reset();
3910 SkRect emptyR = {10, 20, 10, 30};
3911 rr.setRectRadii(emptyR, radii);
3912 p.addRRect(rr);
3913 // The round rect is "empty" in that it has no fill area. However,
3914 // the path isn't "empty" in that it should have verbs and points.
3915 REPORTER_ASSERT(reporter, !p.isEmpty());
3916 p.reset();
3917 SkRect largeR = {0, 0, SK_ScalarMax, SK_ScalarMax};
3918 rr.setRectRadii(largeR, radii);
3919 p.addRRect(rr);
3921
3922 // we check for non-finites
3923 SkRect infR = {0, 0, SK_ScalarMax, SK_ScalarInfinity};
3924 rr.setRectRadii(infR, radii);
3926}
static void test_rrect_convexity_is_unknown(skiatest::Reporter *reporter, SkPath *path, SkPathDirection dir)
Definition: PathTest.cpp:3852
static void test_rrect_is_convex(skiatest::Reporter *reporter, SkPath *path, SkPathDirection dir)
Definition: PathTest.cpp:3842
bool isEmpty() const
Definition: SkRRect.h:83

◆ test_rrect_convexity_is_unknown()

static void test_rrect_convexity_is_unknown ( skiatest::Reporter reporter,
SkPath path,
SkPathDirection  dir 
)
static

Definition at line 3852 of file PathTest.cpp.

◆ test_rrect_is_convex()

static void test_rrect_is_convex ( skiatest::Reporter reporter,
SkPath path,
SkPathDirection  dir 
)
static

Definition at line 3842 of file PathTest.cpp.

◆ test_sect_with_horizontal_needs_pinning()

static void test_sect_with_horizontal_needs_pinning ( )
static

Definition at line 135 of file PathTest.cpp.

135 {
136 // Test that sect_with_horizontal in SkLineClipper.cpp needs to pin after computing the
137 // intersection.
138 SkPath path;
139 path.reset();
140 path.moveTo(-540000, -720000);
141 path.lineTo(-9.10000017e-05f, 9.99999996e-13f);
142 path.lineTo(1, 1);
143
144 // Without the pinning code in sect_with_horizontal(), this would assert in the lineclipper
147}

◆ test_segment_masks()

static void test_segment_masks ( skiatest::Reporter reporter)
static

Definition at line 3047 of file PathTest.cpp.

3047 {
3048 SkPath p, p2;
3049
3050 p.moveTo(0, 0);
3051 p.quadTo(100, 100, 200, 200);
3052 REPORTER_ASSERT(reporter, SkPath::kQuad_SegmentMask == p.getSegmentMasks());
3053 REPORTER_ASSERT(reporter, !p.isEmpty());
3054 p2 = p;
3055 REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
3056 p.cubicTo(100, 100, 200, 200, 300, 300);
3057 REPORTER_ASSERT(reporter, kCurveSegmentMask == p.getSegmentMasks());
3058 REPORTER_ASSERT(reporter, !p.isEmpty());
3059 p2 = p;
3060 REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
3061
3062 p.reset();
3063 p.moveTo(0, 0);
3064 p.cubicTo(100, 100, 200, 200, 300, 300);
3066 p2 = p;
3067 REPORTER_ASSERT(reporter, p2.getSegmentMasks() == p.getSegmentMasks());
3068
3069 REPORTER_ASSERT(reporter, !p.isEmpty());
3070}
@ kQuad_SegmentMask
Definition: SkPath.h:1446
@ kCubic_SegmentMask
Definition: SkPath.h:1448
uint32_t getSegmentMasks() const
Definition: SkPath.cpp:434

◆ test_skbug_3239()

static void test_skbug_3239 ( skiatest::Reporter reporter)
static

Definition at line 87 of file PathTest.cpp.

87 {
88 const float min = SkBits2Float(0xcb7f16c8); /* -16717512.000000 */
89 const float max = SkBits2Float(0x4b7f1c1d); /* 16718877.000000 */
90 const float big = SkBits2Float(0x4b7f1bd7); /* 16718807.000000 */
91
92 const float rad = 33436320;
93
94 const SkRect rectx = SkRect::MakeLTRB(min, min, max, big);
95 const SkRect recty = SkRect::MakeLTRB(min, min, big, max);
96
97 SkVector radii[4];
98 for (int i = 0; i < 4; ++i) {
99 set_radii(radii, i, rad);
100 test_add_rrect(reporter, rectx, radii);
101 test_add_rrect(reporter, recty, radii);
102 }
103}
static void test_add_rrect(skiatest::Reporter *reporter, const SkRect &bounds, const SkVector radii[4])
Definition: PathTest.cpp:67
static void set_radii(SkVector radii[4], int index, float rad)
Definition: PathTest.cpp:62

◆ test_skbug_3469()

static void test_skbug_3469 ( skiatest::Reporter reporter)
static

Definition at line 79 of file PathTest.cpp.

79 {
81 path.moveTo(20, 20);
82 path.quadTo(20, 50, 80, 50);
83 path.quadTo(20, 50, 20, 80);
84 REPORTER_ASSERT(reporter, !path.isConvex());
85}

◆ test_skbug_6947()

static void test_skbug_6947 ( )
static

Definition at line 4775 of file PathTest.cpp.

4775 {
4776 SkPath path;
4777 SkPoint points[] =
4778 {{125.126022f, -0.499872506f}, {125.288895f, -0.499338806f},
4779 {125.299316f, -0.499290764f}, {126.294594f, 0.505449712f},
4780 {125.999992f, 62.5047531f}, {124.0f, 62.4980202f},
4781 {124.122749f, 0.498142242f}, {125.126022f, -0.499872506f},
4782 {125.119476f, 1.50011659f}, {125.122749f, 0.50012207f},
4783 {126.122749f, 0.502101898f}, {126.0f, 62.5019798f},
4784 {125.0f, 62.5f}, {124.000008f, 62.4952469f},
4785 {124.294609f, 0.495946467f}, {125.294601f, 0.50069809f},
4786 {125.289886f, 1.50068688f}, {125.282349f, 1.50065041f},
4787 {125.119476f, 1.50011659f}};
4793 int pointIndex = 0;
4794 for(auto verb : verbs) {
4795 switch (verb) {
4796 case kMove:
4797 path.moveTo(points[pointIndex++]);
4798 break;
4799 case kLine:
4800 path.lineTo(points[pointIndex++]);
4801 break;
4802 case kClose:
4803 default:
4804 path.close();
4805 break;
4806 }
4807 }
4808 test_draw_AA_path(250, 125, path);
4809}
@ kMove
Definition: embedder.h:985

◆ test_skbug_7015()

static void test_skbug_7015 ( )
static

Definition at line 4811 of file PathTest.cpp.

4811 {
4812 SkPath path;
4813 path.setFillType(SkPathFillType::kWinding);
4814 path.moveTo(SkBits2Float(0x4388c000), SkBits2Float(0x43947c08)); // 273.5f, 296.969f
4815 path.lineTo(SkBits2Float(0x4386c000), SkBits2Float(0x43947c08)); // 269.5f, 296.969f
4816 // 269.297f, 292.172f, 273.695f, 292.172f, 273.5f, 296.969f
4817 path.cubicTo(SkBits2Float(0x4386a604), SkBits2Float(0x43921604),
4818 SkBits2Float(0x4388d8f6), SkBits2Float(0x43921604),
4819 SkBits2Float(0x4388c000), SkBits2Float(0x43947c08));
4820 path.close();
4821 test_draw_AA_path(500, 500, path);
4822}

◆ test_skbug_7051()

static void test_skbug_7051 ( )
static

Definition at line 4824 of file PathTest.cpp.

4824 {
4825 SkPath path;
4826 path.moveTo(10, 10);
4827 path.cubicTo(10, 20, 10, 30, 30, 30);
4828 path.lineTo(50, 20);
4829 path.lineTo(50, 10);
4830 path.close();
4831 test_draw_AA_path(100, 100, path);
4832}

◆ test_skbug_7435()

static void test_skbug_7435 ( )
static

Definition at line 4834 of file PathTest.cpp.

4834 {
4835 SkPaint paint;
4836 SkPath path;
4837 path.setFillType(SkPathFillType::kWinding);
4838 path.moveTo(SkBits2Float(0x7f07a5af), SkBits2Float(0xff07ff1d)); // 1.80306e+38f, -1.8077e+38f
4839 path.lineTo(SkBits2Float(0x7edf4b2d), SkBits2Float(0xfedffe0a)); // 1.48404e+38f, -1.48868e+38f
4840 path.lineTo(SkBits2Float(0x7edf4585), SkBits2Float(0xfee003b2)); // 1.48389e+38f, -1.48883e+38f
4841 path.lineTo(SkBits2Float(0x7ef348e9), SkBits2Float(0xfef403c6)); // 1.6169e+38f, -1.62176e+38f
4842 path.lineTo(SkBits2Float(0x7ef74c4e), SkBits2Float(0xfef803cb)); // 1.64358e+38f, -1.64834e+38f
4843 path.conicTo(SkBits2Float(0x7ef74f23), SkBits2Float(0xfef8069e), SkBits2Float(0x7ef751f6), SkBits2Float(0xfef803c9), SkBits2Float(0x3f3504f3)); // 1.64365e+38f, -1.64841e+38f, 1.64372e+38f, -1.64834e+38f, 0.707107f
4844 path.conicTo(SkBits2Float(0x7ef754c8), SkBits2Float(0xfef800f5), SkBits2Float(0x7ef751f5), SkBits2Float(0xfef7fe22), SkBits2Float(0x3f353472)); // 1.6438e+38f, -1.64827e+38f, 1.64372e+38f, -1.64819e+38f, 0.707832f
4845 path.lineTo(SkBits2Float(0x7edb57a9), SkBits2Float(0xfedbfe06)); // 1.45778e+38f, -1.4621e+38f
4846 path.lineTo(SkBits2Float(0x7e875976), SkBits2Float(0xfe87fdb3)); // 8.99551e+37f, -9.03815e+37f
4847 path.lineTo(SkBits2Float(0x7ded5c2b), SkBits2Float(0xfdeff59e)); // 3.94382e+37f, -3.98701e+37f
4848 path.lineTo(SkBits2Float(0x7d7a78a7), SkBits2Float(0xfd7fda0f)); // 2.08083e+37f, -2.12553e+37f
4849 path.lineTo(SkBits2Float(0x7d7a6403), SkBits2Float(0xfd7fe461)); // 2.08016e+37f, -2.12587e+37f
4850 path.conicTo(SkBits2Float(0x7d7a4764), SkBits2Float(0xfd7ff2b0), SkBits2Float(0x7d7a55b4), SkBits2Float(0xfd8007a8), SkBits2Float(0x3f3504f3)); // 2.07924e+37f, -2.12633e+37f, 2.0797e+37f, -2.12726e+37f, 0.707107f
4851 path.conicTo(SkBits2Float(0x7d7a5803), SkBits2Float(0xfd8009f7), SkBits2Float(0x7d7a5ba9), SkBits2Float(0xfd800bcc), SkBits2Float(0x3f7cba66)); // 2.07977e+37f, -2.12741e+37f, 2.07989e+37f, -2.12753e+37f, 0.987219f
4852 path.lineTo(SkBits2Float(0x7d8d2067), SkBits2Float(0xfd900bdb)); // 2.34487e+37f, -2.39338e+37f
4853 path.lineTo(SkBits2Float(0x7ddd137a), SkBits2Float(0xfde00c2d)); // 3.67326e+37f, -3.72263e+37f
4854 path.lineTo(SkBits2Float(0x7ddd2a1b), SkBits2Float(0xfddff58e)); // 3.67473e+37f, -3.72116e+37f
4855 path.lineTo(SkBits2Float(0x7c694ae5), SkBits2Float(0xfc7fa67c)); // 4.8453e+36f, -5.30965e+36f
4856 path.lineTo(SkBits2Float(0xfc164a8b), SkBits2Float(0x7c005af5)); // -3.12143e+36f, 2.66584e+36f
4857 path.lineTo(SkBits2Float(0xfc8ae983), SkBits2Float(0x7c802da7)); // -5.77019e+36f, 5.32432e+36f
4858 path.lineTo(SkBits2Float(0xfc8b16d9), SkBits2Float(0x7c80007b)); // -5.77754e+36f, 5.31699e+36f
4859 path.lineTo(SkBits2Float(0xfc8b029c), SkBits2Float(0x7c7f8788)); // -5.77426e+36f, 5.30714e+36f
4860 path.lineTo(SkBits2Float(0xfc8b0290), SkBits2Float(0x7c7f8790)); // -5.77425e+36f, 5.30714e+36f
4861 path.lineTo(SkBits2Float(0xfc8b16cd), SkBits2Float(0x7c80007f)); // -5.77753e+36f, 5.31699e+36f
4862 path.lineTo(SkBits2Float(0xfc8b4409), SkBits2Float(0x7c7fa672)); // -5.78487e+36f, 5.30965e+36f
4863 path.lineTo(SkBits2Float(0x7d7aa2ba), SkBits2Float(0xfd800bd1)); // 2.0822e+37f, -2.12753e+37f
4864 path.lineTo(SkBits2Float(0x7e8757ee), SkBits2Float(0xfe88035b)); // 8.99512e+37f, -9.03962e+37f
4865 path.lineTo(SkBits2Float(0x7ef7552d), SkBits2Float(0xfef803ca)); // 1.64381e+38f, -1.64834e+38f
4866 path.lineTo(SkBits2Float(0x7f0fa653), SkBits2Float(0xff1001f9)); // 1.90943e+38f, -1.91419e+38f
4867 path.lineTo(SkBits2Float(0x7f0fa926), SkBits2Float(0xff0fff24)); // 1.90958e+38f, -1.91404e+38f
4868 path.lineTo(SkBits2Float(0x7f0da75c), SkBits2Float(0xff0dff22)); // 1.8829e+38f, -1.88746e+38f
4869 path.lineTo(SkBits2Float(0x7f07a5af), SkBits2Float(0xff07ff1d)); // 1.80306e+38f, -1.8077e+38f
4870 path.close();
4871 path.moveTo(SkBits2Float(0x7f07a2db), SkBits2Float(0xff0801f1)); // 1.80291e+38f, -1.80785e+38f
4872 path.lineTo(SkBits2Float(0x7f0da48a), SkBits2Float(0xff0e01f8)); // 1.88275e+38f, -1.88761e+38f
4873 path.lineTo(SkBits2Float(0x7f0fa654), SkBits2Float(0xff1001fa)); // 1.90943e+38f, -1.91419e+38f
4874 path.lineTo(SkBits2Float(0x7f0fa7bd), SkBits2Float(0xff10008f)); // 1.90951e+38f, -1.91412e+38f
4875 path.lineTo(SkBits2Float(0x7f0fa927), SkBits2Float(0xff0fff25)); // 1.90958e+38f, -1.91404e+38f
4876 path.lineTo(SkBits2Float(0x7ef75ad5), SkBits2Float(0xfef7fe22)); // 1.64395e+38f, -1.64819e+38f
4877 path.lineTo(SkBits2Float(0x7e875d96), SkBits2Float(0xfe87fdb3)); // 8.99659e+37f, -9.03815e+37f
4878 path.lineTo(SkBits2Float(0x7d7acff6), SkBits2Float(0xfd7fea5b)); // 2.08367e+37f, -2.12606e+37f
4879 path.lineTo(SkBits2Float(0xfc8b0588), SkBits2Float(0x7c8049b7)); // -5.77473e+36f, 5.32887e+36f
4880 path.lineTo(SkBits2Float(0xfc8b2b16), SkBits2Float(0x7c803d32)); // -5.78083e+36f, 5.32684e+36f
4881 path.conicTo(SkBits2Float(0xfc8b395c), SkBits2Float(0x7c803870), SkBits2Float(0xfc8b4405), SkBits2Float(0x7c802dd1), SkBits2Float(0x3f79349d)); // -5.78314e+36f, 5.32607e+36f, -5.78487e+36f, 5.32435e+36f, 0.973459f
4882 path.conicTo(SkBits2Float(0xfc8b715b), SkBits2Float(0x7c8000a5), SkBits2Float(0xfc8b442f), SkBits2Float(0x7c7fa69e), SkBits2Float(0x3f3504f3)); // -5.79223e+36f, 5.31702e+36f, -5.7849e+36f, 5.30966e+36f, 0.707107f
4883 path.lineTo(SkBits2Float(0xfc16ffaa), SkBits2Float(0x7bff4c12)); // -3.13612e+36f, 2.65116e+36f
4884 path.lineTo(SkBits2Float(0x7c6895e0), SkBits2Float(0xfc802dc0)); // 4.83061e+36f, -5.32434e+36f
4885 path.lineTo(SkBits2Float(0x7ddd137b), SkBits2Float(0xfde00c2e)); // 3.67326e+37f, -3.72263e+37f
4886 path.lineTo(SkBits2Float(0x7ddd1ecb), SkBits2Float(0xfde000de)); // 3.67399e+37f, -3.72189e+37f
4887 path.lineTo(SkBits2Float(0x7ddd2a1c), SkBits2Float(0xfddff58f)); // 3.67473e+37f, -3.72116e+37f
4888 path.lineTo(SkBits2Float(0x7d8d3711), SkBits2Float(0xfd8ff543)); // 2.34634e+37f, -2.39191e+37f
4889 path.lineTo(SkBits2Float(0x7d7a88fe), SkBits2Float(0xfd7fea69)); // 2.08136e+37f, -2.12606e+37f
4890 path.lineTo(SkBits2Float(0x7d7a7254), SkBits2Float(0xfd800080)); // 2.08063e+37f, -2.1268e+37f
4891 path.lineTo(SkBits2Float(0x7d7a80a4), SkBits2Float(0xfd800ed0)); // 2.08109e+37f, -2.12773e+37f
4892 path.lineTo(SkBits2Float(0x7d7a80a8), SkBits2Float(0xfd800ecf)); // 2.08109e+37f, -2.12773e+37f
4893 path.lineTo(SkBits2Float(0x7d7a7258), SkBits2Float(0xfd80007f)); // 2.08063e+37f, -2.1268e+37f
4894 path.lineTo(SkBits2Float(0x7d7a5bb9), SkBits2Float(0xfd800bd0)); // 2.0799e+37f, -2.12753e+37f
4895 path.lineTo(SkBits2Float(0x7ded458b), SkBits2Float(0xfdf00c3e)); // 3.94235e+37f, -3.98848e+37f
4896 path.lineTo(SkBits2Float(0x7e8753ce), SkBits2Float(0xfe88035b)); // 8.99405e+37f, -9.03962e+37f
4897 path.lineTo(SkBits2Float(0x7edb5201), SkBits2Float(0xfedc03ae)); // 1.45763e+38f, -1.46225e+38f
4898 path.lineTo(SkBits2Float(0x7ef74c4d), SkBits2Float(0xfef803ca)); // 1.64358e+38f, -1.64834e+38f
4899 path.lineTo(SkBits2Float(0x7ef74f21), SkBits2Float(0xfef800f6)); // 1.64365e+38f, -1.64827e+38f
4900 path.lineTo(SkBits2Float(0x7ef751f4), SkBits2Float(0xfef7fe21)); // 1.64372e+38f, -1.64819e+38f
4901 path.lineTo(SkBits2Float(0x7ef34e91), SkBits2Float(0xfef3fe1e)); // 1.61705e+38f, -1.62161e+38f
4902 path.lineTo(SkBits2Float(0x7edf4b2d), SkBits2Float(0xfedffe0a)); // 1.48404e+38f, -1.48868e+38f
4903 path.lineTo(SkBits2Float(0x7edf4859), SkBits2Float(0xfee000de)); // 1.48397e+38f, -1.48876e+38f
4904 path.lineTo(SkBits2Float(0x7edf4585), SkBits2Float(0xfee003b2)); // 1.48389e+38f, -1.48883e+38f
4905 path.lineTo(SkBits2Float(0x7f07a2db), SkBits2Float(0xff0801f1)); // 1.80291e+38f, -1.80785e+38f
4906 path.close();
4907 path.moveTo(SkBits2Float(0xfab120db), SkBits2Float(0x77b50b4f)); // -4.59851e+35f, 7.34402e+33f
4908 path.lineTo(SkBits2Float(0xfd6597e5), SkBits2Float(0x7d60177f)); // -1.90739e+37f, 1.86168e+37f
4909 path.lineTo(SkBits2Float(0xfde2cea1), SkBits2Float(0x7de00c2e)); // -3.76848e+37f, 3.72263e+37f
4910 path.lineTo(SkBits2Float(0xfe316511), SkBits2Float(0x7e300657)); // -5.89495e+37f, 5.84943e+37f
4911 path.lineTo(SkBits2Float(0xfe415da1), SkBits2Float(0x7e400666)); // -6.42568e+37f, 6.38112e+37f
4912 path.lineTo(SkBits2Float(0xfe41634a), SkBits2Float(0x7e4000be)); // -6.42641e+37f, 6.38039e+37f
4913 path.lineTo(SkBits2Float(0xfe41634a), SkBits2Float(0x7e3ff8be)); // -6.42641e+37f, 6.37935e+37f
4914 path.lineTo(SkBits2Float(0xfe416349), SkBits2Float(0x7e3ff8be)); // -6.42641e+37f, 6.37935e+37f
4915 path.lineTo(SkBits2Float(0xfe415f69), SkBits2Float(0x7e3ff8be)); // -6.42591e+37f, 6.37935e+37f
4916 path.lineTo(SkBits2Float(0xfe415bc9), SkBits2Float(0x7e3ff8be)); // -6.42544e+37f, 6.37935e+37f
4917 path.lineTo(SkBits2Float(0xfe415bc9), SkBits2Float(0x7e4000be)); // -6.42544e+37f, 6.38039e+37f
4918 path.lineTo(SkBits2Float(0xfe416171), SkBits2Float(0x7e3ffb16)); // -6.42617e+37f, 6.37966e+37f
4919 path.lineTo(SkBits2Float(0xfe016131), SkBits2Float(0x7dfff5ae)); // -4.29938e+37f, 4.25286e+37f
4920 path.lineTo(SkBits2Float(0xfe0155e2), SkBits2Float(0x7e000628)); // -4.29791e+37f, 4.25433e+37f
4921 path.lineTo(SkBits2Float(0xfe0958ea), SkBits2Float(0x7e080630)); // -4.56415e+37f, 4.52018e+37f
4922 path.lineTo(SkBits2Float(0xfe115c92), SkBits2Float(0x7e100638)); // -4.83047e+37f, 4.78603e+37f
4923 path.conicTo(SkBits2Float(0xfe11623c), SkBits2Float(0x7e100bdf), SkBits2Float(0xfe1167e2), SkBits2Float(0x7e100636), SkBits2Float(0x3f3504f3)); // -4.8312e+37f, 4.78676e+37f, -4.83194e+37f, 4.78603e+37f, 0.707107f
4924 path.conicTo(SkBits2Float(0xfe116d87), SkBits2Float(0x7e10008e), SkBits2Float(0xfe1167e2), SkBits2Float(0x7e0ffae8), SkBits2Float(0x3f35240a)); // -4.83267e+37f, 4.78529e+37f, -4.83194e+37f, 4.78456e+37f, 0.707581f
4925 path.lineTo(SkBits2Float(0xfe016b92), SkBits2Float(0x7dfff5af)); // -4.30072e+37f, 4.25286e+37f
4926 path.lineTo(SkBits2Float(0xfdc2d963), SkBits2Float(0x7dbff56e)); // -3.23749e+37f, 3.18946e+37f
4927 path.lineTo(SkBits2Float(0xfd65ae25), SkBits2Float(0x7d5fea3d)); // -1.90811e+37f, 1.86021e+37f
4928 path.lineTo(SkBits2Float(0xfab448de), SkBits2Float(0xf7b50a19)); // -4.68046e+35f, -7.34383e+33f
4929 path.lineTo(SkBits2Float(0xfab174d9), SkBits2Float(0x43480000)); // -4.60703e+35f, 200
4930 path.lineTo(SkBits2Float(0xfab174d9), SkBits2Float(0x7800007f)); // -4.60703e+35f, 1.03848e+34f
4931 path.lineTo(SkBits2Float(0xfab3f4db), SkBits2Float(0x7800007f)); // -4.67194e+35f, 1.03848e+34f
4932 path.lineTo(SkBits2Float(0xfab3f4db), SkBits2Float(0x43480000)); // -4.67194e+35f, 200
4933 path.lineTo(SkBits2Float(0xfab120db), SkBits2Float(0x77b50b4f)); // -4.59851e+35f, 7.34402e+33f
4934 path.close();
4935 path.moveTo(SkBits2Float(0xfab59cf2), SkBits2Float(0xf800007e)); // -4.71494e+35f, -1.03847e+34f
4936 path.lineTo(SkBits2Float(0xfaa7cc52), SkBits2Float(0xf800007f)); // -4.35629e+35f, -1.03848e+34f
4937 path.lineTo(SkBits2Float(0xfd6580e5), SkBits2Float(0x7d60177f)); // -1.90664e+37f, 1.86168e+37f
4938 path.lineTo(SkBits2Float(0xfdc2c2c1), SkBits2Float(0x7dc00c0f)); // -3.23602e+37f, 3.19093e+37f
4939 path.lineTo(SkBits2Float(0xfe016040), SkBits2Float(0x7e000626)); // -4.29925e+37f, 4.25433e+37f
4940 path.lineTo(SkBits2Float(0xfe115c90), SkBits2Float(0x7e100636)); // -4.83047e+37f, 4.78603e+37f
4941 path.lineTo(SkBits2Float(0xfe116239), SkBits2Float(0x7e10008f)); // -4.8312e+37f, 4.78529e+37f
4942 path.lineTo(SkBits2Float(0xfe1167e0), SkBits2Float(0x7e0ffae6)); // -4.83194e+37f, 4.78456e+37f
4943 path.lineTo(SkBits2Float(0xfe096438), SkBits2Float(0x7e07fade)); // -4.56562e+37f, 4.51871e+37f
4944 path.lineTo(SkBits2Float(0xfe016130), SkBits2Float(0x7dfff5ac)); // -4.29938e+37f, 4.25286e+37f
4945 path.lineTo(SkBits2Float(0xfe015b89), SkBits2Float(0x7e00007f)); // -4.29864e+37f, 4.25359e+37f
4946 path.lineTo(SkBits2Float(0xfe0155e1), SkBits2Float(0x7e000627)); // -4.29791e+37f, 4.25433e+37f
4947 path.lineTo(SkBits2Float(0xfe415879), SkBits2Float(0x7e4008bf)); // -6.42501e+37f, 6.38143e+37f
4948 path.lineTo(SkBits2Float(0xfe415f69), SkBits2Float(0x7e4008bf)); // -6.42591e+37f, 6.38143e+37f
4949 path.lineTo(SkBits2Float(0xfe416349), SkBits2Float(0x7e4008bf)); // -6.42641e+37f, 6.38143e+37f
4950 path.lineTo(SkBits2Float(0xfe41634a), SkBits2Float(0x7e4008bf)); // -6.42641e+37f, 6.38143e+37f
4951 path.conicTo(SkBits2Float(0xfe416699), SkBits2Float(0x7e4008bf), SkBits2Float(0xfe4168f1), SkBits2Float(0x7e400668), SkBits2Float(0x3f6c8ed9)); // -6.42684e+37f, 6.38143e+37f, -6.42715e+37f, 6.38113e+37f, 0.924055f
4952 path.conicTo(SkBits2Float(0xfe416e9a), SkBits2Float(0x7e4000c2), SkBits2Float(0xfe4168f3), SkBits2Float(0x7e3ffb17), SkBits2Float(0x3f3504f3)); // -6.42788e+37f, 6.38039e+37f, -6.42715e+37f, 6.37966e+37f, 0.707107f
4953 path.lineTo(SkBits2Float(0xfe317061), SkBits2Float(0x7e2ffb07)); // -5.89642e+37f, 5.84796e+37f
4954 path.lineTo(SkBits2Float(0xfde2e542), SkBits2Float(0x7ddff58e)); // -3.76995e+37f, 3.72116e+37f
4955 path.lineTo(SkBits2Float(0xfd65c525), SkBits2Float(0x7d5fea3d)); // -1.90886e+37f, 1.86021e+37f
4956 path.lineTo(SkBits2Float(0xfab6c8db), SkBits2Float(0xf7b50b4f)); // -4.74536e+35f, -7.34402e+33f
4957 path.lineTo(SkBits2Float(0xfab59cf2), SkBits2Float(0xf800007e)); // -4.71494e+35f, -1.03847e+34f
4958 path.close();
4959 path.moveTo(SkBits2Float(0xfab3f4db), SkBits2Float(0x43480000)); // -4.67194e+35f, 200
4960 path.lineTo(SkBits2Float(0xfab174d9), SkBits2Float(0x43480000)); // -4.60703e+35f, 200
4961 path.quadTo(SkBits2Float(0xfd0593a5), SkBits2Float(0x7d00007f), SkBits2Float(0xfd659785), SkBits2Float(0x7d6000de)); // -1.10971e+37f, 1.0634e+37f, -1.90737e+37f, 1.86095e+37f
4962 path.quadTo(SkBits2Float(0xfda2cdf2), SkBits2Float(0x7da0009f), SkBits2Float(0xfdc2ce12), SkBits2Float(0x7dc000be)); // -2.70505e+37f, 2.6585e+37f, -3.23675e+37f, 3.1902e+37f
4963 path.quadTo(SkBits2Float(0xfde2ce31), SkBits2Float(0x7de000de), SkBits2Float(0xfe0165e9), SkBits2Float(0x7e00007f)); // -3.76845e+37f, 3.72189e+37f, -4.29999e+37f, 4.25359e+37f
4964 path.quadTo(SkBits2Float(0xfe1164b9), SkBits2Float(0x7e10008f), SkBits2Float(0xfe116239), SkBits2Float(0x7e10008f)); // -4.83153e+37f, 4.78529e+37f, -4.8312e+37f, 4.78529e+37f
4965 path.quadTo(SkBits2Float(0xfe116039), SkBits2Float(0x7e10008f), SkBits2Float(0xfe095e91), SkBits2Float(0x7e080087)); // -4.83094e+37f, 4.78529e+37f, -4.56488e+37f, 4.51944e+37f
4966 path.quadTo(SkBits2Float(0xfe015d09), SkBits2Float(0x7e00007f), SkBits2Float(0xfe015b89), SkBits2Float(0x7e00007f)); // -4.29884e+37f, 4.25359e+37f, -4.29864e+37f, 4.25359e+37f
4967 path.lineTo(SkBits2Float(0xfe415bc9), SkBits2Float(0x7e4000be)); // -6.42544e+37f, 6.38039e+37f
4968 path.quadTo(SkBits2Float(0xfe415da9), SkBits2Float(0x7e4000be), SkBits2Float(0xfe415f69), SkBits2Float(0x7e4000be)); // -6.42568e+37f, 6.38039e+37f, -6.42591e+37f, 6.38039e+37f
4969 path.quadTo(SkBits2Float(0xfe416149), SkBits2Float(0x7e4000be), SkBits2Float(0xfe416349), SkBits2Float(0x7e4000be)); // -6.42615e+37f, 6.38039e+37f, -6.42641e+37f, 6.38039e+37f
4970 path.quadTo(SkBits2Float(0xfe416849), SkBits2Float(0x7e4000be), SkBits2Float(0xfe316ab9), SkBits2Float(0x7e3000af)); // -6.42706e+37f, 6.38039e+37f, -5.89569e+37f, 5.84869e+37f
4971 path.quadTo(SkBits2Float(0xfe216d29), SkBits2Float(0x7e20009f), SkBits2Float(0xfde2d9f2), SkBits2Float(0x7de000de)); // -5.36431e+37f, 5.31699e+37f, -3.76921e+37f, 3.72189e+37f
4972 path.quadTo(SkBits2Float(0xfda2d9b2), SkBits2Float(0x7da0009f), SkBits2Float(0xfd65ae85), SkBits2Float(0x7d6000de)); // -2.70582e+37f, 2.6585e+37f, -1.90812e+37f, 1.86095e+37f
4973 path.quadTo(SkBits2Float(0xfd05a9a6), SkBits2Float(0x7d00007f), SkBits2Float(0xfab3f4db), SkBits2Float(0x43480000)); // -1.11043e+37f, 1.0634e+37f, -4.67194e+35f, 200
4974 path.close();
4975 path.moveTo(SkBits2Float(0x7f07a445), SkBits2Float(0xff080087)); // 1.80299e+38f, -1.80778e+38f
4976 path.quadTo(SkBits2Float(0x7f0ba519), SkBits2Float(0xff0c008b), SkBits2Float(0x7f0da5f3), SkBits2Float(0xff0e008d)); // 1.8562e+38f, -1.86095e+38f, 1.88283e+38f, -1.88753e+38f
4977 path.quadTo(SkBits2Float(0x7f0fa6d5), SkBits2Float(0xff10008f), SkBits2Float(0x7f0fa7bd), SkBits2Float(0xff10008f)); // 1.90946e+38f, -1.91412e+38f, 1.90951e+38f, -1.91412e+38f
4978 path.quadTo(SkBits2Float(0x7f0faa7d), SkBits2Float(0xff10008f), SkBits2Float(0x7ef75801), SkBits2Float(0xfef800f6)); // 1.90965e+38f, -1.91412e+38f, 1.64388e+38f, -1.64827e+38f
4979 path.quadTo(SkBits2Float(0x7ecf5b09), SkBits2Float(0xfed000ce), SkBits2Float(0x7e875ac2), SkBits2Float(0xfe880087)); // 1.37811e+38f, -1.38242e+38f, 8.99585e+37f, -9.03889e+37f
4980 path.quadTo(SkBits2Float(0x7e0eb505), SkBits2Float(0xfe10008f), SkBits2Float(0x7d7ab958), SkBits2Float(0xfd80007f)); // 4.74226e+37f, -4.78529e+37f, 2.08293e+37f, -2.1268e+37f
4981 path.quadTo(SkBits2Float(0xfc8ac1cd), SkBits2Float(0x7c80007f), SkBits2Float(0xfc8b16cd), SkBits2Float(0x7c80007f)); // -5.76374e+36f, 5.31699e+36f, -5.77753e+36f, 5.31699e+36f
4982 path.quadTo(SkBits2Float(0xfc8b36cd), SkBits2Float(0x7c80007f), SkBits2Float(0xfc16a51a), SkBits2Float(0x7c00007f)); // -5.78273e+36f, 5.31699e+36f, -3.12877e+36f, 2.6585e+36f
4983 path.quadTo(SkBits2Float(0xfab6e4de), SkBits2Float(0x43480000), SkBits2Float(0x7c68f062), SkBits2Float(0xfc80007f)); // -4.7482e+35f, 200, 4.83795e+36f, -5.31699e+36f
4984 path.lineTo(SkBits2Float(0x7ddd1ecb), SkBits2Float(0xfde000de)); // 3.67399e+37f, -3.72189e+37f
4985 path.quadTo(SkBits2Float(0x7d9d254b), SkBits2Float(0xfda0009f), SkBits2Float(0x7d8d2bbc), SkBits2Float(0xfd90008f)); // 2.61103e+37f, -2.6585e+37f, 2.3456e+37f, -2.39265e+37f
4986 path.quadTo(SkBits2Float(0x7d7a64d8), SkBits2Float(0xfd80007f), SkBits2Float(0x7d7a7258), SkBits2Float(0xfd80007f)); // 2.08019e+37f, -2.1268e+37f, 2.08063e+37f, -2.1268e+37f
4987 path.quadTo(SkBits2Float(0x7d7a9058), SkBits2Float(0xfd80007f), SkBits2Float(0x7ded50db), SkBits2Float(0xfdf000ee)); // 2.0816e+37f, -2.1268e+37f, 3.94309e+37f, -3.98774e+37f
4988 path.quadTo(SkBits2Float(0x7e2eace5), SkBits2Float(0xfe3000af), SkBits2Float(0x7e8756a2), SkBits2Float(0xfe880087)); // 5.80458e+37f, -5.84869e+37f, 8.99478e+37f, -9.03889e+37f
4989 path.quadTo(SkBits2Float(0x7ebf56d9), SkBits2Float(0xfec000be), SkBits2Float(0x7edb54d5), SkBits2Float(0xfedc00da)); // 1.27167e+38f, -1.27608e+38f, 1.45771e+38f, -1.46217e+38f
4990 path.quadTo(SkBits2Float(0x7ef752e1), SkBits2Float(0xfef800f6), SkBits2Float(0x7ef74f21), SkBits2Float(0xfef800f6)); // 1.64375e+38f, -1.64827e+38f, 1.64365e+38f, -1.64827e+38f
4991 path.quadTo(SkBits2Float(0x7ef74d71), SkBits2Float(0xfef800f6), SkBits2Float(0x7ef34bbd), SkBits2Float(0xfef400f2)); // 1.64361e+38f, -1.64827e+38f, 1.61698e+38f, -1.62168e+38f
4992 path.quadTo(SkBits2Float(0x7eef4a19), SkBits2Float(0xfef000ee), SkBits2Float(0x7edf4859), SkBits2Float(0xfee000de)); // 1.59035e+38f, -1.5951e+38f, 1.48397e+38f, -1.48876e+38f
4993 path.lineTo(SkBits2Float(0x7f07a445), SkBits2Float(0xff080087)); // 1.80299e+38f, -1.80778e+38f
4994 path.close();
4996 ->getCanvas()
4997 ->drawPath(path, paint);
4998}

◆ test_strokerec()

static void test_strokerec ( skiatest::Reporter reporter)
static

Definition at line 1074 of file PathTest.cpp.

1074 {
1076 REPORTER_ASSERT(reporter, rec.isFillStyle());
1077
1078 rec.setHairlineStyle();
1079 REPORTER_ASSERT(reporter, rec.isHairlineStyle());
1080
1081 rec.setStrokeStyle(SK_Scalar1, false);
1083
1084 rec.setStrokeStyle(SK_Scalar1, true);
1086
1087 rec.setStrokeStyle(0, false);
1089
1090 rec.setStrokeStyle(0, true);
1092}
@ kStrokeAndFill_Style
Definition: SkStrokeRec.h:36

◆ test_tiny_path_convexity()

static void test_tiny_path_convexity ( skiatest::Reporter reporter,
const char *  pathBug,
SkScalar  tx,
SkScalar  ty,
SkScalar  scale 
)
static

Definition at line 587 of file PathTest.cpp.

588 {
589 SkPath smallPath;
590 SkAssertResult(SkParsePath::FromSVGString(pathBug, &smallPath));
591 bool smallConvex = smallPath.isConvex();
592 SkPath largePath;
593 SkAssertResult(SkParsePath::FromSVGString(pathBug, &largePath));
595 matrix.reset();
596 matrix.preTranslate(100, 100);
597 matrix.preScale(scale, scale);
598 largePath.transform(matrix);
599 bool largeConvex = largePath.isConvex();
600 REPORTER_ASSERT(reporter, smallConvex == largeConvex);
601}

◆ test_transform()

static void test_transform ( skiatest::Reporter reporter)
static

Definition at line 2848 of file PathTest.cpp.

2848 {
2849 SkPath p;
2850
2851#define CONIC_PERSPECTIVE_BUG_FIXED 0
2852 static const SkPoint pts[] = {
2853 { 0, 0 }, // move
2854 { SkIntToScalar(10), SkIntToScalar(10) }, // line
2855 { SkIntToScalar(20), SkIntToScalar(10) }, { SkIntToScalar(20), 0 }, // quad
2856 { 0, 0 }, { 0, SkIntToScalar(10) }, { SkIntToScalar(1), SkIntToScalar(10) }, // cubic
2857#if CONIC_PERSPECTIVE_BUG_FIXED
2858 { 0, 0 }, { SkIntToScalar(20), SkIntToScalar(10) }, // conic
2859#endif
2860 };
2861 const int kPtCount = std::size(pts);
2862
2863 p.moveTo(pts[0]);
2864 p.lineTo(pts[1]);
2865 p.quadTo(pts[2], pts[3]);
2866 p.cubicTo(pts[4], pts[5], pts[6]);
2867#if CONIC_PERSPECTIVE_BUG_FIXED
2868 p.conicTo(pts[4], pts[5], 0.5f);
2869#endif
2870 p.close();
2871
2872 {
2874 matrix.reset();
2875 SkPath p1;
2876 p.transform(matrix, &p1);
2877 REPORTER_ASSERT(reporter, p == p1);
2878 }
2879
2880
2881 {
2883 matrix.setScale(SK_Scalar1 * 2, SK_Scalar1 * 3);
2884
2885 SkPath p1; // Leave p1 non-unique (i.e., the empty path)
2886
2887 p.transform(matrix, &p1);
2888 SkPoint pts1[kPtCount];
2889 int count = p1.getPoints(pts1, kPtCount);
2891 for (int i = 0; i < count; ++i) {
2892 SkPoint newPt = SkPoint::Make(pts[i].fX * 2, pts[i].fY * 3);
2893 REPORTER_ASSERT(reporter, newPt == pts1[i]);
2894 }
2895 }
2896
2897 {
2899 matrix.reset();
2900 matrix.setPerspX(4);
2901
2902 SkPath p1;
2903 p1.moveTo(SkPoint::Make(0, 0));
2904
2905 p.transform(matrix, &p1, SkApplyPerspectiveClip::kNo);
2908 SkRect pBounds = p.getBounds();
2909 SkRect p1Bounds = p1.getBounds();
2914 }
2915
2916 p.reset();
2917 p.addCircle(0, 0, 1, SkPathDirection::kCW);
2918
2919 {
2921 matrix.reset();
2922 SkPath p1;
2923 p1.moveTo(SkPoint::Make(0, 0));
2924
2925 p.transform(matrix, &p1);
2927 }
2928
2929
2930 {
2932 matrix.reset();
2933 matrix.setScaleX(-1);
2934 SkPath p1;
2935 p1.moveTo(SkPoint::Make(0, 0)); // Make p1 unique (i.e., not empty path)
2936
2937 p.transform(matrix, &p1);
2939 }
2940
2941 {
2943 matrix.setAll(1, 1, 0, 1, 1, 0, 0, 0, 1);
2944 SkPath p1;
2945 p1.moveTo(SkPoint::Make(0, 0)); // Make p1 unique (i.e., not empty path)
2946
2947 p.transform(matrix, &p1);
2949 }
2950
2951 {
2952 SkPath p1;
2953 p1.addRect({ 10, 20, 30, 40 });
2954 SkPath p2;
2955 p2.addRect({ 10, 20, 30, 40 });
2956 uint32_t id1 = p1.getGenerationID();
2957 uint32_t id2 = p2.getGenerationID();
2958 REPORTER_ASSERT(reporter, id1 != id2);
2960 matrix.setScale(2, 2);
2961 p1.transform(matrix, &p2);
2964 p1.transform(matrix);
2966 }
2967}
@ kNo
Don't pre-clip the geometry before applying the (perspective) matrix.
static const int kPtCount[]
int getPoints(SkPoint points[], int max) const
Definition: SkPath.cpp:539

◆ test_tricky_cubic()

static void test_tricky_cubic ( )
static

Definition at line 794 of file PathTest.cpp.

794 {
795 const SkPoint pts[] = {
796 { SkDoubleToScalar(18.8943768), SkDoubleToScalar(129.121277) },
797 { SkDoubleToScalar(18.8937435), SkDoubleToScalar(129.121689) },
798 { SkDoubleToScalar(18.8950119), SkDoubleToScalar(129.120422) },
799 { SkDoubleToScalar(18.5030727), SkDoubleToScalar(129.13121) },
800 };
801
802 SkPath path;
803 path.moveTo(pts[0]);
804 path.cubicTo(pts[1], pts[2], pts[3]);
805 test_draw_AA_path(19, 130, path);
806}
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64

◆ test_zero_length_paths()

static void test_zero_length_paths ( skiatest::Reporter reporter)
static

Definition at line 2969 of file PathTest.cpp.

2969 {
2970 SkPath p;
2971 uint8_t verbs[32];
2972
2973 struct SUPPRESS_VISIBILITY_WARNING zeroPathTestData {
2974 const char* testPath;
2975 const size_t numResultPts;
2976 const SkRect resultBound;
2977 const SkPath::Verb* resultVerbs;
2978 const size_t numResultVerbs;
2979 };
2980
2981 static const SkPath::Verb resultVerbs1[] = { SkPath::kMove_Verb };
2982 static const SkPath::Verb resultVerbs2[] = { SkPath::kMove_Verb, SkPath::kMove_Verb };
2983 static const SkPath::Verb resultVerbs3[] = { SkPath::kMove_Verb, SkPath::kClose_Verb };
2985 static const SkPath::Verb resultVerbs5[] = { SkPath::kMove_Verb, SkPath::kLine_Verb };
2987 static const SkPath::Verb resultVerbs7[] = { SkPath::kMove_Verb, SkPath::kLine_Verb, SkPath::kClose_Verb };
2988 static const SkPath::Verb resultVerbs8[] = {
2990 };
2991 static const SkPath::Verb resultVerbs9[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb };
2993 static const SkPath::Verb resultVerbs11[] = { SkPath::kMove_Verb, SkPath::kQuad_Verb, SkPath::kClose_Verb };
2994 static const SkPath::Verb resultVerbs12[] = {
2996 };
2997 static const SkPath::Verb resultVerbs13[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb };
2999 static const SkPath::Verb resultVerbs15[] = { SkPath::kMove_Verb, SkPath::kCubic_Verb, SkPath::kClose_Verb };
3000 static const SkPath::Verb resultVerbs16[] = {
3002 };
3003 static const struct zeroPathTestData gZeroLengthTests[] = {
3004 { "M 1 1", 1, {1, 1, 1, 1}, resultVerbs1, std::size(resultVerbs1) },
3005 { "M 1 1 M 2 1", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs2, std::size(resultVerbs2) },
3006 { "M 1 1 z", 1, {1, 1, 1, 1}, resultVerbs3, std::size(resultVerbs3) },
3007 { "M 1 1 z M 2 1 z", 2, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs4, std::size(resultVerbs4) },
3008 { "M 1 1 L 1 1", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs5, std::size(resultVerbs5) },
3009 { "M 1 1 L 1 1 M 2 1 L 2 1", 4, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs6, std::size(resultVerbs6) },
3010 { "M 1 1 L 1 1 z", 2, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs7, std::size(resultVerbs7) },
3011 { "M 1 1 L 1 1 z M 2 1 L 2 1 z", 4, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs8, std::size(resultVerbs8) },
3012 { "M 1 1 Q 1 1 1 1", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs9, std::size(resultVerbs9) },
3013 { "M 1 1 Q 1 1 1 1 M 2 1 Q 2 1 2 1", 6, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs10, std::size(resultVerbs10) },
3014 { "M 1 1 Q 1 1 1 1 z", 3, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs11, std::size(resultVerbs11) },
3015 { "M 1 1 Q 1 1 1 1 z M 2 1 Q 2 1 2 1 z", 6, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs12, std::size(resultVerbs12) },
3016 { "M 1 1 C 1 1 1 1 1 1", 4, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs13, std::size(resultVerbs13) },
3017 { "M 1 1 C 1 1 1 1 1 1 M 2 1 C 2 1 2 1 2 1", 8, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs14,
3018 std::size(resultVerbs14)
3019 },
3020 { "M 1 1 C 1 1 1 1 1 1 z", 4, {SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1}, resultVerbs15, std::size(resultVerbs15) },
3021 { "M 1 1 C 1 1 1 1 1 1 z M 2 1 C 2 1 2 1 2 1 z", 8, {SK_Scalar1, SK_Scalar1, 2*SK_Scalar1, SK_Scalar1}, resultVerbs16,
3022 std::size(resultVerbs16)
3023 }
3024 };
3025
3026 for (size_t i = 0; i < std::size(gZeroLengthTests); ++i) {
3027 p.reset();
3028 bool valid = SkParsePath::FromSVGString(gZeroLengthTests[i].testPath, &p);
3029 REPORTER_ASSERT(reporter, valid);
3030 REPORTER_ASSERT(reporter, !p.isEmpty());
3031 REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultPts == (size_t)p.countPoints());
3032 REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultBound == p.getBounds());
3033 REPORTER_ASSERT(reporter, gZeroLengthTests[i].numResultVerbs == (size_t)p.getVerbs(verbs, std::size(verbs)));
3034 for (size_t j = 0; j < gZeroLengthTests[i].numResultVerbs; ++j) {
3035 REPORTER_ASSERT(reporter, gZeroLengthTests[i].resultVerbs[j] == verbs[j]);
3036 }
3037 }
3038}

◆ write_and_read_back()

static void write_and_read_back ( skiatest::Reporter reporter,
const SkPath p 
)
static

Definition at line 2757 of file PathTest.cpp.

2758 {
2759 SkBinaryWriteBuffer writer({});
2760 writer.writePath(p);
2761 size_t size = writer.bytesWritten();
2762 SkAutoMalloc storage(size);
2763 writer.writeToMemory(storage.get());
2764 SkReadBuffer reader(storage.get(), size);
2765
2766 SkPath readBack;
2767 REPORTER_ASSERT(reporter, readBack != p);
2768 reader.readPath(&readBack);
2769 REPORTER_ASSERT(reporter, readBack == p);
2770
2773
2774 SkRect oval0, oval1;
2775 SkPathDirection dir0, dir1;
2776 unsigned start0, start1;
2777 REPORTER_ASSERT(reporter, readBack.isOval(nullptr) == p.isOval(nullptr));
2778 if (SkPathPriv::IsOval(p, &oval0, &dir0, &start0) &&
2779 SkPathPriv::IsOval(readBack, &oval1, &dir1, &start1)) {
2780 REPORTER_ASSERT(reporter, oval0 == oval1);
2781 REPORTER_ASSERT(reporter, dir0 == dir1);
2782 REPORTER_ASSERT(reporter, start0 == start1);
2783 }
2784 REPORTER_ASSERT(reporter, readBack.isRRect(nullptr) == p.isRRect(nullptr));
2785 SkRRect rrect0, rrect1;
2786 if (SkPathPriv::IsRRect(p, &rrect0, &dir0, &start0) &&
2787 SkPathPriv::IsRRect(readBack, &rrect1, &dir1, &start1)) {
2788 REPORTER_ASSERT(reporter, rrect0 == rrect1);
2789 REPORTER_ASSERT(reporter, dir0 == dir1);
2790 REPORTER_ASSERT(reporter, start0 == start1);
2791 }
2792 const SkRect& origBounds = p.getBounds();
2793 const SkRect& readBackBounds = readBack.getBounds();
2794
2795 REPORTER_ASSERT(reporter, origBounds == readBackBounds);
2796}
void writePath(const SkPath &path) override
static bool IsRRect(const SkPath &path, SkRRect *rrect, SkPathDirection *dir, unsigned *start)
Definition: SkPathPriv.h:272
bool isRRect(SkRRect *rrect) const
Definition: SkPath.cpp:527

Variable Documentation

◆ kDontCheckDir

const SkPathFirstDirection kDontCheckDir = static_cast<SkPathFirstDirection>(3)

Definition at line 1097 of file PathTest.cpp.