From 3627d2ebbba3415f815167842369d28ec5cfeecb Mon Sep 17 00:00:00 2001 From: Ben Wagner Date: Tue, 26 Jun 2018 14:23:20 -0400 Subject: Add subpixel offset to Viewer app. This adds a two dimensional location dragger to drag the origin across a pixel. Also makes the perspective dragger hidden when perspective is off. Also adds 'Z' to toggle the zoom window mouse follow. Change-Id: Ic75d16c95848b392608770c8ed0d4db23733242f Reviewed-on: https://skia-review.googlesource.com/137701 Reviewed-by: Brian Osman Commit-Queue: Ben Wagner --- tools/viewer/Viewer.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++------- tools/viewer/Viewer.h | 3 +++ 2 files changed, 55 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index c9014fd77d..3675cc4fe2 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -177,6 +177,8 @@ Viewer::Viewer(int argc, char** argv, void* platformData) , fShowSlidePicker(false) , fShowImGuiTestWindow(false) , fShowZoomWindow(false) + , fZoomWindowFixed(false) + , fZoomWindowLocation{0.0f, 0.0f} , fLastImage(nullptr) , fBackendType(sk_app::Window::kNativeGL_BackendType) , fColorMode(ColorMode::kLegacy) @@ -185,6 +187,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData) , fColorSpaceTransferFn(g2Dot2_TransferFn) , fZoomLevel(0.0f) , fRotation(0.0f) + , fOffset{0.0f, 0.0f} , fGestureDevice(GestureDevice::kNone) , fPerspectiveMode(kPerspective_Off) , fTileCnt(0) @@ -264,6 +267,10 @@ Viewer::Viewer(int argc, char** argv, void* platformData) this->fShowZoomWindow = !this->fShowZoomWindow; fWindow->inval(); }); + fCommands.addCommand('Z', "GUI", "Toggle zoom window state", [this]() { + this->fZoomWindowFixed = !this->fZoomWindowFixed; + fWindow->inval(); + }); fCommands.addCommand('s', "Overlays", "Toggle stats display", [this]() { fStatsLayer.setActive(!fStatsLayer.getActive()); fWindow->inval(); @@ -942,6 +949,7 @@ SkMatrix Viewer::computePreTouchMatrix() { SkMatrix m = fDefaultMatrix; SkScalar zoomScale = (fZoomLevel < 0) ? SK_Scalar1 / (SK_Scalar1 - fZoomLevel) : SK_Scalar1 + fZoomLevel; + m.preTranslate(fOffset.x(), fOffset.y()); m.preScale(zoomScale, zoomScale); const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions(); @@ -1351,6 +1359,28 @@ static ImVec2 ImGui_DragPoint(const char* label, SkPoint* p, return ImVec2(pos.x + p->fX * size.x, pos.y + p->fY * size.y); } +static bool ImGui_DragLocation(SkPoint* pt) { + ImDrawList* drawList = ImGui::GetWindowDrawList(); + + // Fit our image/canvas to the available width, and scale the height to maintain aspect ratio. + float canvasWidth = SkTMax(ImGui::GetContentRegionAvailWidth(), 50.0f); + ImVec2 size = ImVec2(canvasWidth, canvasWidth); + ImVec2 pos = ImGui::GetCursorScreenPos(); + + // Background rectangle + drawList->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), IM_COL32(0, 0, 0, 128)); + + // Location marker + bool dragging = false; + ImVec2 tl = ImGui_DragPoint("SL", pt + 0, pos, size, &dragging); + drawList->AddCircle(tl, 5.0f, 0xFFFFFFFF); + + ImGui::SetCursorScreenPos(ImVec2(pos.x, pos.y + size.y)); + ImGui::Spacing(); + + return dragging; +} + static bool ImGui_DragQuad(SkPoint* pts) { ImDrawList* drawList = ImGui::GetWindowDrawList(); @@ -1519,14 +1549,21 @@ void Viewer::drawImGui() { this->preTouchMatrixChanged(); paramsChanged = true; } + if (ImGui::CollapsingHeader("Subpixel offset", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { + if (ImGui_DragLocation(&fOffset)) { + this->preTouchMatrixChanged(); + paramsChanged = true; + } + } int perspectiveMode = static_cast(fPerspectiveMode); if (ImGui::Combo("Perspective", &perspectiveMode, "Off\0Real\0Fake\0\0")) { fPerspectiveMode = static_cast(perspectiveMode); this->preTouchMatrixChanged(); - this->updateTitle(); + paramsChanged = true; } - if (ImGui_DragQuad(fPerspectivePoints)) { + if (perspectiveMode != kPerspective_Off && ImGui_DragQuad(fPerspectivePoints)) { this->preTouchMatrixChanged(); + paramsChanged = true; } } @@ -1800,15 +1837,22 @@ void Viewer::drawImGui() { zoomFactor = SkTMin(zoomFactor * 2, 32); } - ImVec2 mousePos = ImGui::GetMousePos(); + if (!fZoomWindowFixed) { + ImVec2 mousePos = ImGui::GetMousePos(); + fZoomWindowLocation = SkPoint::Make(mousePos.x, mousePos.y); + } + SkScalar x = fZoomWindowLocation.x(); + SkScalar y = fZoomWindowLocation.y(); + int xInt = SkScalarRoundToInt(x); + int yInt = SkScalarRoundToInt(y); ImVec2 avail = ImGui::GetContentRegionAvail(); uint32_t pixel = 0; SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); - if (fLastImage->readPixels(info, &pixel, info.minRowBytes(), mousePos.x, mousePos.y)) { + if (fLastImage->readPixels(info, &pixel, info.minRowBytes(), xInt, yInt)) { ImGui::SameLine(); ImGui::Text("(X, Y): %d, %d RGBA: %x %x %x %x", - sk_float_round2int(mousePos.x), sk_float_round2int(mousePos.y), + xInt, yInt, SkGetPackedR32(pixel), SkGetPackedG32(pixel), SkGetPackedB32(pixel), SkGetPackedA32(pixel)); } @@ -1817,13 +1861,13 @@ void Viewer::drawImGui() { // Translate so the region of the image that's under the mouse cursor is centered // in the zoom canvas: c->scale(zoomFactor, zoomFactor); - c->translate(avail.x * 0.5f / zoomFactor - mousePos.x - 0.5f, - avail.y * 0.5f / zoomFactor - mousePos.y - 0.5f); + c->translate(avail.x * 0.5f / zoomFactor - x - 0.5f, + avail.y * 0.5f / zoomFactor - y - 0.5f); c->drawImage(this->fLastImage, 0, 0); SkPaint outline; outline.setStyle(SkPaint::kStroke_Style); - c->drawRect(SkRect::MakeXYWH(mousePos.x, mousePos.y, 1, 1), outline); + c->drawRect(SkRect::MakeXYWH(x, y, 1, 1), outline); }); } diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index 653548d9be..6fdcd36675 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -132,6 +132,8 @@ private: bool fShowImGuiTestWindow; bool fShowZoomWindow; + bool fZoomWindowFixed; + SkPoint fZoomWindowLocation; sk_sp fLastImage; sk_app::Window::BackendType fBackendType; @@ -144,6 +146,7 @@ private: // transform data SkScalar fZoomLevel; SkScalar fRotation; + SkVector fOffset; sk_app::CommandSet fCommands; -- cgit v1.2.3