aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/viewer
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2018-04-26 15:55:00 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-26 20:21:23 +0000
commit9bb47cf0ffcf8a802c0126fa3ee2b5ee7287959b (patch)
tree10ef3658aadde01838b2a686128e9f65ffcbe24c /tools/viewer
parent06c330410b6a6e0877e0c0c799a33aa5a4a914e9 (diff)
Add perspective support (rect to rect) to Viewer
Change-Id: I312d5b3e6b7f37a3a7bfd5561bcdb31b43e207b8 Reviewed-on: https://skia-review.googlesource.com/123934 Commit-Queue: Brian Osman <brianosman@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com> Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Ben Wagner <bungeman@google.com> Auto-Submit: Brian Osman <brianosman@google.com>
Diffstat (limited to 'tools/viewer')
-rw-r--r--tools/viewer/Viewer.cpp87
-rw-r--r--tools/viewer/Viewer.h3
2 files changed, 88 insertions, 2 deletions
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 04426ffc7e..3411e5684b 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -178,6 +178,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
, fZoomLevel(0.0f)
, fRotation(0.0f)
, fGestureDevice(GestureDevice::kNone)
+ , fPerspective(false)
, fTileCnt(0)
, fThreadCnt(0)
{
@@ -494,6 +495,10 @@ Viewer::Viewer(int argc, char** argv, void* platformData)
this->listNames();
}
+ fPerspectivePoints[0].set(0, 0);
+ fPerspectivePoints[1].set(1, 0);
+ fPerspectivePoints[2].set(0, 1);
+ fPerspectivePoints[3].set(1, 1);
fAnimTimer.run();
auto gamutImage = GetResourceAsImage("images/gamut.png");
@@ -878,6 +883,21 @@ SkMatrix Viewer::computePreTouchMatrix() {
: SK_Scalar1 + fZoomLevel;
m.preScale(zoomScale, zoomScale);
m.preRotate(fRotation);
+
+ if (fPerspective) {
+ SkScalar w = fWindow->width(), h = fWindow->height();
+ SkPoint orthoPts[4] = { { 0, 0 }, { w, 0 }, { 0, h }, { w, h } };
+ SkPoint perspPts[4] = {
+ { fPerspectivePoints[0].fX * w, fPerspectivePoints[0].fY * h },
+ { fPerspectivePoints[1].fX * w, fPerspectivePoints[1].fY * h },
+ { fPerspectivePoints[2].fX * w, fPerspectivePoints[2].fY * h },
+ { fPerspectivePoints[3].fX * w, fPerspectivePoints[3].fY * h }
+ };
+ SkMatrix persp;
+ persp.setPolyToPoly(orthoPts, perspPts, 4);
+ m.preConcat(persp);
+ }
+
return m;
}
@@ -1204,7 +1224,6 @@ static void ImGui_Primaries(SkColorSpacePrimaries* primaries, SkPaint* gamutPain
// Magic numbers are pixel locations of the origin and upper-right corner.
drawList->AddImage(gamutPaint, pos, ImVec2(pos.x + size.x, pos.y + size.y),
ImVec2(242, 61), ImVec2(1897, 1922));
- ImVec2 endPos = ImGui::GetCursorPos();
// Primary markers
ImVec2 r = ImGui_DragPrimary("R", &primaries->fRX, &primaries->fRY, pos, size);
@@ -1220,7 +1239,65 @@ static void ImGui_Primaries(SkColorSpacePrimaries* primaries, SkPaint* gamutPain
drawList->AddTriangle(r, g, b, 0xFFFFFFFF);
// Re-position cursor immediate after the diagram for subsequent controls
- ImGui::SetCursorPos(endPos);
+ ImGui::SetCursorScreenPos(ImVec2(pos.x, pos.y + size.y));
+}
+
+static ImVec2 ImGui_DragPoint(const char* label, SkPoint* p,
+ const ImVec2& pos, const ImVec2& size, bool* dragging) {
+ // Transform points ([0, 0] - [1.0, 1.0]) to screen coords
+ ImVec2 center(pos.x + p->fX * size.x, pos.y + p->fY * size.y);
+
+ // Invisible 10x10 button
+ ImGui::SetCursorScreenPos(ImVec2(center.x - 5, center.y - 5));
+ ImGui::InvisibleButton(label, ImVec2(10, 10));
+
+ if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) {
+ ImGuiIO& io = ImGui::GetIO();
+ // Normalized mouse position, relative to our gamut box
+ ImVec2 mousePosXY((io.MousePos.x - pos.x) / size.x, (io.MousePos.y - pos.y) / size.y);
+ // Clamp to edge of box
+ p->fX = SkTPin(mousePosXY.x, 0.0f, 1.0f);
+ p->fY = SkTPin(mousePosXY.y, 0.0f, 1.0f);
+ *dragging = true;
+ }
+
+ // Return screen coordinates for the caller. We could just return center here, but we'd have
+ // one frame of lag during drag.
+ return ImVec2(pos.x + p->fX * size.x, pos.y + p->fY * size.y);
+}
+
+static bool ImGui_DragQuad(SkPoint* pts) {
+ 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));
+
+ // Corner markers
+ bool dragging = false;
+ ImVec2 tl = ImGui_DragPoint("TL", pts + 0, pos, size, &dragging);
+ ImVec2 tr = ImGui_DragPoint("TR", pts + 1, pos, size, &dragging);
+ ImVec2 bl = ImGui_DragPoint("BL", pts + 2, pos, size, &dragging);
+ ImVec2 br = ImGui_DragPoint("BR", pts + 3, pos, size, &dragging);
+
+ // Draw markers and quad
+ drawList->AddCircle(tl, 5.0f, 0xFFFFFFFF);
+ drawList->AddCircle(tr, 5.0f, 0xFFFFFFFF);
+ drawList->AddCircle(bl, 5.0f, 0xFFFFFFFF);
+ drawList->AddCircle(br, 5.0f, 0xFFFFFFFF);
+ drawList->AddLine(tl, tr, 0xFFFFFFFF);
+ drawList->AddLine(tr, br, 0xFFFFFFFF);
+ drawList->AddLine(br, bl, 0xFFFFFFFF);
+ drawList->AddLine(bl, tl, 0xFFFFFFFF);
+
+ ImGui::SetCursorScreenPos(ImVec2(pos.x, pos.y + size.y));
+ ImGui::Spacing();
+
+ return dragging;
}
void Viewer::drawImGui() {
@@ -1356,6 +1433,12 @@ void Viewer::drawImGui() {
this->preTouchMatrixChanged();
paramsChanged = true;
}
+ if (ImGui::Checkbox("Perspective", &fPerspective)) {
+ this->preTouchMatrixChanged();
+ }
+ if (ImGui_DragQuad(fPerspectivePoints)) {
+ this->preTouchMatrixChanged();
+ }
}
if (ImGui::CollapsingHeader("Paint")) {
diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h
index 25cbed656c..be35a88525 100644
--- a/tools/viewer/Viewer.h
+++ b/tools/viewer/Viewer.h
@@ -158,6 +158,9 @@ private:
// identity unless the window initially scales the content to fit the screen.
SkMatrix fDefaultMatrix;
+ bool fPerspective;
+ SkPoint fPerspectivePoints[4];
+
SkTArray<std::function<void(void)>> fDeferredActions;
Json::Value fAllSlideNames; // cache all slide names for fast updateUIState