1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 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 "tools/viewer/BisectSlide.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 11cb93a386Sopenharmony_ci#include "src/utils/SkOSPath.h" 12cb93a386Sopenharmony_ci#include "tools/ToolUtils.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci#include <utility> 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cisk_sp<BisectSlide> BisectSlide::Create(const char filepath[]) { 17cb93a386Sopenharmony_ci SkFILEStream stream(filepath); 18cb93a386Sopenharmony_ci if (!stream.isValid()) { 19cb93a386Sopenharmony_ci SkDebugf("BISECT: invalid input file at \"%s\"\n", filepath); 20cb93a386Sopenharmony_ci return nullptr; 21cb93a386Sopenharmony_ci } 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci sk_sp<BisectSlide> bisect(new BisectSlide(filepath)); 24cb93a386Sopenharmony_ci ToolUtils::sniff_paths(filepath, [&](const SkMatrix& matrix, 25cb93a386Sopenharmony_ci const SkPath& path, 26cb93a386Sopenharmony_ci const SkPaint& paint) { 27cb93a386Sopenharmony_ci SkRect bounds; 28cb93a386Sopenharmony_ci SkIRect ibounds; 29cb93a386Sopenharmony_ci matrix.mapRect(&bounds, path.getBounds()); 30cb93a386Sopenharmony_ci bounds.roundOut(&ibounds); 31cb93a386Sopenharmony_ci bisect->fDrawBounds.join(ibounds); 32cb93a386Sopenharmony_ci bisect->fFoundPaths.push_back() = {path, paint, matrix}; 33cb93a386Sopenharmony_ci }); 34cb93a386Sopenharmony_ci return bisect; 35cb93a386Sopenharmony_ci} 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ciBisectSlide::BisectSlide(const char filepath[]) 38cb93a386Sopenharmony_ci : fFilePath(filepath) { 39cb93a386Sopenharmony_ci const char* basename = strrchr(fFilePath.c_str(), SkOSPath::SEPARATOR); 40cb93a386Sopenharmony_ci fName.printf("BISECT_%s", basename ? basename + 1 : fFilePath.c_str()); 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_cibool BisectSlide::onChar(SkUnichar c) { 44cb93a386Sopenharmony_ci switch (c) { 45cb93a386Sopenharmony_ci case 'X': 46cb93a386Sopenharmony_ci if (!fTossedPaths.empty()) { 47cb93a386Sopenharmony_ci using std::swap; 48cb93a386Sopenharmony_ci swap(fFoundPaths, fTossedPaths); 49cb93a386Sopenharmony_ci if ('X' == fTrail.back()) { 50cb93a386Sopenharmony_ci fTrail.pop_back(); 51cb93a386Sopenharmony_ci } else { 52cb93a386Sopenharmony_ci fTrail.push_back('X'); 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci return true; 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci case 'x': 58cb93a386Sopenharmony_ci if (fFoundPaths.count() > 1) { 59cb93a386Sopenharmony_ci int midpt = (fFoundPaths.count() + 1) / 2; 60cb93a386Sopenharmony_ci fPathHistory.emplace(fFoundPaths, fTossedPaths); 61cb93a386Sopenharmony_ci fTossedPaths.reset(fFoundPaths.begin() + midpt, fFoundPaths.count() - midpt); 62cb93a386Sopenharmony_ci fFoundPaths.resize_back(midpt); 63cb93a386Sopenharmony_ci fTrail.push_back('x'); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci return true; 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci case 'Z': { 68cb93a386Sopenharmony_ci if (!fPathHistory.empty()) { 69cb93a386Sopenharmony_ci fFoundPaths = fPathHistory.top().first; 70cb93a386Sopenharmony_ci fTossedPaths = fPathHistory.top().second; 71cb93a386Sopenharmony_ci fPathHistory.pop(); 72cb93a386Sopenharmony_ci char ch; 73cb93a386Sopenharmony_ci do { 74cb93a386Sopenharmony_ci ch = fTrail.back(); 75cb93a386Sopenharmony_ci fTrail.pop_back(); 76cb93a386Sopenharmony_ci } while (ch != 'x'); 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci return true; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci case 'D': 82cb93a386Sopenharmony_ci SkDebugf("viewer --bisect %s", fFilePath.c_str()); 83cb93a386Sopenharmony_ci if (!fTrail.empty()) { 84cb93a386Sopenharmony_ci SkDebugf(" "); 85cb93a386Sopenharmony_ci for (char ch : fTrail) { 86cb93a386Sopenharmony_ci SkDebugf("%c", ch); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci } 89cb93a386Sopenharmony_ci SkDebugf("\n"); 90cb93a386Sopenharmony_ci for (const FoundPath& foundPath : fFoundPaths) { 91cb93a386Sopenharmony_ci foundPath.fPath.dump(); 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci return true; 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci return false; 97cb93a386Sopenharmony_ci} 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_civoid BisectSlide::draw(SkCanvas* canvas) { 100cb93a386Sopenharmony_ci SkAutoCanvasRestore acr(canvas, true); 101cb93a386Sopenharmony_ci canvas->translate(-fDrawBounds.left(), -fDrawBounds.top()); 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci for (const FoundPath& path : fFoundPaths) { 104cb93a386Sopenharmony_ci SkAutoCanvasRestore acr2(canvas, true); 105cb93a386Sopenharmony_ci canvas->concat(path.fViewMatrix); 106cb93a386Sopenharmony_ci canvas->drawPath(path.fPath, path.fPaint); 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci} 109