------------------------------------------------------------------------------
| 2075 | |
| 2076 | //------------------------------------------------------------------------------ |
| 2077 | void vtkSVGContextDevice2D::DrawPath(vtkPath* path, std::ostream& out) |
| 2078 | { |
| 2079 | // The text renderer always uses floats to generate paths, so we'll optimize |
| 2080 | // a bit here: |
| 2081 | vtkFloatArray* points = vtkArrayDownCast<vtkFloatArray>(path->GetPoints()->GetData()); |
| 2082 | vtkIntArray* codes = path->GetCodes(); |
| 2083 | |
| 2084 | if (!points) |
| 2085 | { |
| 2086 | vtkErrorMacro("This method expects the path point precision to be floats."); |
| 2087 | return; |
| 2088 | } |
| 2089 | |
| 2090 | vtkIdType numTuples = points->GetNumberOfTuples(); |
| 2091 | if (numTuples != codes->GetNumberOfTuples() || codes->GetNumberOfComponents() != 1 || |
| 2092 | points->GetNumberOfComponents() != 3) |
| 2093 | { |
| 2094 | vtkErrorMacro("Invalid path data."); |
| 2095 | return; |
| 2096 | } |
| 2097 | |
| 2098 | if (numTuples == 0) |
| 2099 | { // Nothing to do. |
| 2100 | return; |
| 2101 | } |
| 2102 | |
| 2103 | // Use a lambda to invert the y positions for SVG: |
| 2104 | auto y = [](float yIn) -> float { return -yIn; }; |
| 2105 | |
| 2106 | typedef vtkPath::ControlPointType CodeEnum; |
| 2107 | typedef vtkIntArray::ValueType CodeType; |
| 2108 | CodeType* code = codes->GetPointer(0); |
| 2109 | CodeType* codeEnd = code + numTuples; |
| 2110 | |
| 2111 | typedef vtkFloatArray::ValueType PointType; |
| 2112 | PointType* point = points->GetPointer(0); |
| 2113 | |
| 2114 | // These are only used in an assertion, ifdef silences warning on non-debug |
| 2115 | // builds |
| 2116 | #ifndef NDEBUG |
| 2117 | PointType* pointBegin = point; |
| 2118 | CodeType* codeBegin = code; |
| 2119 | #endif |
| 2120 | |
| 2121 | // Track the last code so we can save a little space by chaining draw commands |
| 2122 | int lastCode = -1; |
| 2123 | |
| 2124 | while (code < codeEnd) |
| 2125 | { |
| 2126 | assert("Sanity check" && (code - codeBegin) * 3 == point - pointBegin); |
| 2127 | |
| 2128 | switch (static_cast<CodeEnum>(*code)) |
| 2129 | { |
| 2130 | case vtkPath::MOVE_TO: |
| 2131 | if (lastCode != *code) |
| 2132 | { |
| 2133 | lastCode = *code; |
| 2134 | out << "M"; |
no test coverage detected