1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h"
9cb93a386Sopenharmony_ci#include "tools/random_parse_path.h"
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ciconst struct Legal {
12cb93a386Sopenharmony_ci    char fSymbol;
13cb93a386Sopenharmony_ci    int fScalars;
14cb93a386Sopenharmony_ci} gLegal[] = {
15cb93a386Sopenharmony_ci    { 'M', 2 },
16cb93a386Sopenharmony_ci    { 'H', 1 },
17cb93a386Sopenharmony_ci    { 'V', 1 },
18cb93a386Sopenharmony_ci    { 'L', 2 },
19cb93a386Sopenharmony_ci    { 'Q', 4 },
20cb93a386Sopenharmony_ci    { 'T', 2 },
21cb93a386Sopenharmony_ci    { 'C', 6 },
22cb93a386Sopenharmony_ci    { 'S', 4 },
23cb93a386Sopenharmony_ci    { 'A', 4 },
24cb93a386Sopenharmony_ci    { 'Z', 0 },
25cb93a386Sopenharmony_ci};
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cibool gEasy = false;  // set to true while debugging to suppress unusual whitespace
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci// mostly do nothing, then bias towards spaces
30cb93a386Sopenharmony_ciconst char gWhiteSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, ' ', ' ', ' ', ' ', 0x09, 0x0D, 0x0A };
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_cistatic void add_white(SkRandom* rand, SkString* atom) {
33cb93a386Sopenharmony_ci    if (gEasy) {
34cb93a386Sopenharmony_ci        atom->append(" ");
35cb93a386Sopenharmony_ci        return;
36cb93a386Sopenharmony_ci    }
37cb93a386Sopenharmony_ci    int reps = rand->nextRangeU(0, 2);
38cb93a386Sopenharmony_ci    for (int rep = 0; rep < reps; ++rep) {
39cb93a386Sopenharmony_ci        int index = rand->nextRangeU(0, (int) SK_ARRAY_COUNT(gWhiteSpace) - 1);
40cb93a386Sopenharmony_ci        if (gWhiteSpace[index]) {
41cb93a386Sopenharmony_ci            atom->append(&gWhiteSpace[index], 1);
42cb93a386Sopenharmony_ci        }
43cb93a386Sopenharmony_ci    }
44cb93a386Sopenharmony_ci}
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_cistatic void add_comma(SkRandom* rand, SkString* atom) {
47cb93a386Sopenharmony_ci    if (gEasy) {
48cb93a386Sopenharmony_ci        atom->append(",");
49cb93a386Sopenharmony_ci        return;
50cb93a386Sopenharmony_ci    }
51cb93a386Sopenharmony_ci    size_t count = atom->size();
52cb93a386Sopenharmony_ci    add_white(rand, atom);
53cb93a386Sopenharmony_ci    if (rand->nextBool()) {
54cb93a386Sopenharmony_ci        atom->append(",");
55cb93a386Sopenharmony_ci    }
56cb93a386Sopenharmony_ci    do {
57cb93a386Sopenharmony_ci        add_white(rand, atom);
58cb93a386Sopenharmony_ci    } while (count == atom->size());
59cb93a386Sopenharmony_ci}
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_cistatic void add_some_white(SkRandom* rand, SkString* atom) {
62cb93a386Sopenharmony_ci    size_t count = atom->size();
63cb93a386Sopenharmony_ci    do {
64cb93a386Sopenharmony_ci        add_white(rand, atom);
65cb93a386Sopenharmony_ci    } while (count == atom->size());
66cb93a386Sopenharmony_ci}
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ciSkString MakeRandomParsePathPiece(SkRandom* rand) {
69cb93a386Sopenharmony_ci    SkString atom;
70cb93a386Sopenharmony_ci    int legalIndex = rand->nextRangeU(0, (int) SK_ARRAY_COUNT(gLegal) - 1);
71cb93a386Sopenharmony_ci    const Legal& legal = gLegal[legalIndex];
72cb93a386Sopenharmony_ci    gEasy ? atom.append("\n") : add_white(rand, &atom);
73cb93a386Sopenharmony_ci    char symbol = legal.fSymbol | (rand->nextBool() ? 0x20 : 0);
74cb93a386Sopenharmony_ci    atom.append(&symbol, 1);
75cb93a386Sopenharmony_ci    int reps = rand->nextRangeU(1, 3);
76cb93a386Sopenharmony_ci    for (int rep = 0; rep < reps; ++rep) {
77cb93a386Sopenharmony_ci        for (int index = 0; index < legal.fScalars; ++index) {
78cb93a386Sopenharmony_ci            SkScalar coord = rand->nextRangeF(0, 100);
79cb93a386Sopenharmony_ci            add_white(rand, &atom);
80cb93a386Sopenharmony_ci            atom.appendScalar(coord);
81cb93a386Sopenharmony_ci            if (rep < reps - 1 && index < legal.fScalars - 1) {
82cb93a386Sopenharmony_ci                add_comma(rand, &atom);
83cb93a386Sopenharmony_ci            } else {
84cb93a386Sopenharmony_ci                add_some_white(rand, &atom);
85cb93a386Sopenharmony_ci            }
86cb93a386Sopenharmony_ci            if ('A' == legal.fSymbol && 1 == index) {
87cb93a386Sopenharmony_ci                atom.appendScalar(rand->nextRangeF(-720, 720));
88cb93a386Sopenharmony_ci                add_comma(rand, &atom);
89cb93a386Sopenharmony_ci                atom.appendU32(rand->nextRangeU(0, 1));
90cb93a386Sopenharmony_ci                add_comma(rand, &atom);
91cb93a386Sopenharmony_ci                atom.appendU32(rand->nextRangeU(0, 1));
92cb93a386Sopenharmony_ci                add_comma(rand, &atom);
93cb93a386Sopenharmony_ci            }
94cb93a386Sopenharmony_ci        }
95cb93a386Sopenharmony_ci    }
96cb93a386Sopenharmony_ci    return atom;
97cb93a386Sopenharmony_ci}
98