| 143 | } |
| 144 | |
| 145 | void ToolLoopManager::doLoopStep(bool last_step) |
| 146 | { |
| 147 | // Original set of points to interwine (original user stroke, |
| 148 | // relative to sprite origin). |
| 149 | Stroke main_stroke; |
| 150 | if (!last_step) |
| 151 | m_toolLoop->getController()->getStrokeToInterwine(m_stroke, main_stroke); |
| 152 | else |
| 153 | main_stroke = m_stroke; |
| 154 | |
| 155 | // Calculate the area to be updated in all document observers. |
| 156 | Symmetry* symmetry = m_toolLoop->getSymmetry(); |
| 157 | Strokes strokes; |
| 158 | if (symmetry) |
| 159 | symmetry->generateStrokes(main_stroke, strokes, m_toolLoop); |
| 160 | else |
| 161 | strokes.push_back(main_stroke); |
| 162 | |
| 163 | calculateDirtyArea(strokes); |
| 164 | |
| 165 | // Validate source image area. |
| 166 | if (m_toolLoop->getInk()->needsSpecialSourceArea()) { |
| 167 | gfx::Region srcArea; |
| 168 | m_toolLoop->getInk()->createSpecialSourceArea(m_dirtyArea, srcArea); |
| 169 | m_toolLoop->validateSrcImage(srcArea); |
| 170 | } |
| 171 | else { |
| 172 | m_toolLoop->validateSrcImage(m_dirtyArea); |
| 173 | } |
| 174 | |
| 175 | // Invalidate destionation image areas. |
| 176 | if (m_toolLoop->getTracePolicy() == TracePolicy::Last) { |
| 177 | // Copy source to destination (reset the previous trace). Useful |
| 178 | // for tools like Line and Ellipse (we kept the last trace only). |
| 179 | m_toolLoop->invalidateDstImage(); |
| 180 | } |
| 181 | else if (m_toolLoop->getTracePolicy() == TracePolicy::AccumulateUpdateLast) { |
| 182 | // Revalidate only this last dirty area (e.g. pixel-perfect |
| 183 | // freehand algorithm needs this trace policy to redraw only the |
| 184 | // last dirty area, which can vary in one pixel from the previous |
| 185 | // tool loop cycle). |
| 186 | m_toolLoop->invalidateDstImage(m_dirtyArea); |
| 187 | } |
| 188 | |
| 189 | m_toolLoop->validateDstImage(m_dirtyArea); |
| 190 | |
| 191 | // Join or fill user points |
| 192 | if (!m_toolLoop->getFilled() || (!last_step && !m_toolLoop->getPreviewFilled())) |
| 193 | m_toolLoop->getIntertwine()->joinStroke(m_toolLoop, main_stroke); |
| 194 | else |
| 195 | m_toolLoop->getIntertwine()->fillStroke(m_toolLoop, main_stroke); |
| 196 | |
| 197 | if (m_toolLoop->getTracePolicy() == TracePolicy::Overlap) { |
| 198 | // Copy destination to source (yes, destination to source). In |
| 199 | // this way each new trace overlaps the previous one. |
| 200 | m_toolLoop->copyValidDstToSrcImage(m_dirtyArea); |
| 201 | } |
| 202 |
nothing calls this directly
no test coverage detected