| /* |
| * Copyright 2020 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "src/core/SkMarkerStack.h" |
| |
| void SkMarkerStack::setMarker(uint32_t id, const SkM44& mx, void* boundary) { |
| // We compute and cache the inverse here. Most clients are only interested in that, and we'll |
| // be fetching matrices from this far more often than we insert them. |
| SkM44 inv; |
| SkAssertResult(mx.invert(&inv)); |
| |
| // Look if we've already seen id in this save-frame. |
| // If so, replace, else append |
| for (auto it = fStack.rbegin(); it != fStack.rend(); ++it) { |
| if (it->fBoundary != boundary) { // we've gone past the save-frame |
| break; // fall out so we append |
| } |
| if (it->fID == id) { // in current frame, so replace |
| it->fMatrix = mx; |
| it->fMatrixInverse = inv; |
| return; |
| } |
| } |
| // if we get here, we should append a new marker |
| fStack.push_back({boundary, mx, inv, id}); |
| } |
| |
| bool SkMarkerStack::findMarker(uint32_t id, SkM44* mx) const { |
| // search from top to bottom, so we find the most recent id |
| for (auto it = fStack.rbegin(); it != fStack.rend(); ++it) { |
| if (it->fID == id) { |
| if (mx) { |
| *mx = it->fMatrix; |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| bool SkMarkerStack::findMarkerInverse(uint32_t id, SkM44* mx) const { |
| // search from top to bottom, so we find the most recent id |
| for (auto it = fStack.rbegin(); it != fStack.rend(); ++it) { |
| if (it->fID == id) { |
| if (mx) { |
| *mx = it->fMatrixInverse; |
| } |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void SkMarkerStack::restore(void* boundary) { |
| while (!fStack.empty() && fStack.back().fBoundary == boundary) { |
| fStack.pop_back(); |
| } |
| } |