| 89 | |
| 90 | template <typename T, int (*readChar)(T *), int (*readCoord)(T *, Point2 &)> |
| 91 | static bool readContour(T *input, Contour &output, const Point2 *first, int terminator, bool &colorsSpecified) { |
| 92 | Point2 p[4], start; |
| 93 | if (first) |
| 94 | p[0] = *first; |
| 95 | else { |
| 96 | int result = readCoord(input, p[0]); |
| 97 | if (result != 2) |
| 98 | return result != 1 && readChar(input) == terminator; |
| 99 | } |
| 100 | start = p[0]; |
| 101 | int c = '\0'; |
| 102 | while ((c = readChar(input)) != terminator) { |
| 103 | if (c != ';') |
| 104 | return false; |
| 105 | EdgeColor color = WHITE; |
| 106 | int result = readCoord(input, p[1]); |
| 107 | if (result == 2) { |
| 108 | output.addEdge(EdgeHolder(p[0], p[1], color)); |
| 109 | p[0] = p[1]; |
| 110 | continue; |
| 111 | } else if (result == 1) |
| 112 | return false; |
| 113 | else { |
| 114 | int controlPoints = 0; |
| 115 | switch ((c = readChar(input))) { |
| 116 | case '#': |
| 117 | output.addEdge(EdgeHolder(p[0], start, color)); |
| 118 | p[0] = start; |
| 119 | continue; |
| 120 | case ';': |
| 121 | goto FINISH_EDGE; |
| 122 | case '(': |
| 123 | goto READ_CONTROL_POINTS; |
| 124 | case 'C': case 'c': |
| 125 | color = CYAN; |
| 126 | colorsSpecified = true; |
| 127 | break; |
| 128 | case 'M': case 'm': |
| 129 | color = MAGENTA; |
| 130 | colorsSpecified = true; |
| 131 | break; |
| 132 | case 'Y': case 'y': |
| 133 | color = YELLOW; |
| 134 | colorsSpecified = true; |
| 135 | break; |
| 136 | case 'W': case 'w': |
| 137 | color = WHITE; |
| 138 | colorsSpecified = true; |
| 139 | break; |
| 140 | default: |
| 141 | return c == terminator; |
| 142 | } |
| 143 | switch (readChar(input)) { |
| 144 | case ';': |
| 145 | goto FINISH_EDGE; |
| 146 | case '(': |
| 147 | READ_CONTROL_POINTS: |
| 148 | if ((controlPoints = readControlPoints<T, readChar, readCoord>(input, p+1)) < 0) |
nothing calls this directly
no test coverage detected