Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Unified Diff: components/test_runner/pixel_dump.cc

Issue 1835673002: Moving pixel-capturing code from web_test_proxy_base.* into pixel_dump.* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@replicating-accept-languages
Patch Set: Rebasing... Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/test_runner/pixel_dump.h ('k') | components/test_runner/test_runner.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/test_runner/pixel_dump.cc
diff --git a/components/test_runner/pixel_dump.cc b/components/test_runner/pixel_dump.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1b49c178325bd0a49a39c2af9f1cd63807e11009
--- /dev/null
+++ b/components/test_runner/pixel_dump.cc
@@ -0,0 +1,203 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/test_runner/pixel_dump.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
+#include "components/test_runner/layout_test_runtime_flags.h"
+// FIXME: Including platform_canvas.h here is a layering violation.
+#include "skia/ext/platform_canvas.h"
+#include "third_party/WebKit/public/platform/Platform.h"
+#include "third_party/WebKit/public/platform/WebClipboard.h"
+#include "third_party/WebKit/public/platform/WebCompositeAndReadbackAsyncCallback.h"
+#include "third_party/WebKit/public/platform/WebData.h"
+#include "third_party/WebKit/public/platform/WebImage.h"
+#include "third_party/WebKit/public/platform/WebPoint.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebPagePopup.h"
+#include "third_party/WebKit/public/web/WebPrintParams.h"
+#include "third_party/WebKit/public/web/WebView.h"
+#include "ui/gfx/geometry/point.h"
+
+namespace test_runner {
+
+namespace {
+
+struct PixelsDumpRequest {
+ PixelsDumpRequest(blink::WebView* web_view,
+ const LayoutTestRuntimeFlags& layout_test_runtime_flags,
+ const base::Callback<void(const SkBitmap&)>& callback)
+ : web_view(web_view),
+ layout_test_runtime_flags(layout_test_runtime_flags),
+ callback(callback) {}
+
+ blink::WebView* web_view;
+ const LayoutTestRuntimeFlags& layout_test_runtime_flags;
+ base::Callback<void(const SkBitmap&)> callback;
+};
+
+class CaptureCallback : public blink::WebCompositeAndReadbackAsyncCallback {
+ public:
+ CaptureCallback(const base::Callback<void(const SkBitmap&)>& callback);
+ virtual ~CaptureCallback();
+
+ void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; }
+ void set_popup_position(const gfx::Point& position) {
+ popup_position_ = position;
+ }
+
+ // WebCompositeAndReadbackAsyncCallback implementation.
+ void didCompositeAndReadback(const SkBitmap& bitmap) override;
+
+ private:
+ base::Callback<void(const SkBitmap&)> callback_;
+ SkBitmap main_bitmap_;
+ bool wait_for_popup_;
+ gfx::Point popup_position_;
+};
+
+void DrawSelectionRect(const PixelsDumpRequest& dump_request,
+ SkCanvas* canvas) {
+ // See if we need to draw the selection bounds rect. Selection bounds
+ // rect is the rect enclosing the (possibly transformed) selection.
+ // The rect should be drawn after everything is laid out and painted.
+ if (!dump_request.layout_test_runtime_flags.dump_selection_rect())
+ return;
+ // If there is a selection rect - draw a red 1px border enclosing rect
+ blink::WebRect wr = dump_request.web_view->mainFrame()->selectionBoundsRect();
+ if (wr.isEmpty())
+ return;
+ // Render a red rectangle bounding selection rect
+ SkPaint paint;
+ paint.setColor(0xFFFF0000); // Fully opaque red
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setFlags(SkPaint::kAntiAlias_Flag);
+ paint.setStrokeWidth(1.0f);
+ SkIRect rect; // Bounding rect
+ rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height);
+ canvas->drawIRect(rect, paint);
+}
+
+void CapturePixelsForPrinting(scoped_ptr<PixelsDumpRequest> dump_request) {
+ dump_request->web_view->updateAllLifecyclePhases();
+
+ blink::WebSize page_size_in_pixels = dump_request->web_view->size();
+ blink::WebFrame* web_frame = dump_request->web_view->mainFrame();
+
+ int page_count = web_frame->printBegin(page_size_in_pixels);
+ int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1;
+
+ bool is_opaque = false;
+ skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::TryCreateBitmapCanvas(
+ page_size_in_pixels.width, totalHeight, is_opaque)));
+ if (!canvas) {
+ dump_request->callback.Run(SkBitmap());
+ return;
+ }
+ web_frame->printPagesWithBoundaries(canvas.get(), page_size_in_pixels);
+ web_frame->printEnd();
+
+ DrawSelectionRect(*dump_request, canvas.get());
+ const SkBitmap bitmap = skia::ReadPixels(canvas.get());
+ dump_request->callback.Run(bitmap);
+}
+
+CaptureCallback::CaptureCallback(
+ const base::Callback<void(const SkBitmap&)>& callback)
+ : callback_(callback), wait_for_popup_(false) {}
+
+CaptureCallback::~CaptureCallback() {}
+
+void CaptureCallback::didCompositeAndReadback(const SkBitmap& bitmap) {
+ TRACE_EVENT2("shell", "CaptureCallback::didCompositeAndReadback", "x",
+ bitmap.info().width(), "y", bitmap.info().height());
+ if (!wait_for_popup_) {
+ callback_.Run(bitmap);
+ delete this;
+ return;
+ }
+ if (main_bitmap_.isNull()) {
+ bitmap.deepCopyTo(&main_bitmap_);
+ return;
+ }
+ SkCanvas canvas(main_bitmap_);
+ canvas.drawBitmap(bitmap, popup_position_.x(), popup_position_.y());
+ callback_.Run(main_bitmap_);
+ delete this;
+}
+
+void DidCapturePixelsAsync(scoped_ptr<PixelsDumpRequest> dump_request,
+ const SkBitmap& bitmap) {
+ SkCanvas canvas(bitmap);
+ DrawSelectionRect(*dump_request, &canvas);
+ if (!dump_request->callback.is_null())
+ dump_request->callback.Run(bitmap);
+}
+
+} // namespace
+
+void DumpPixelsAsync(blink::WebView* web_view,
+ const LayoutTestRuntimeFlags& layout_test_runtime_flags,
+ float device_scale_factor_for_test,
+ const base::Callback<void(const SkBitmap&)>& callback) {
+ TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync");
+ DCHECK(!callback.is_null());
+ DCHECK(!layout_test_runtime_flags.dump_drag_image());
+
+ scoped_ptr<PixelsDumpRequest> pixels_request(
+ new PixelsDumpRequest(web_view, layout_test_runtime_flags, callback));
+
+ if (layout_test_runtime_flags.is_printing()) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&CapturePixelsForPrinting,
+ base::Passed(std::move(pixels_request))));
+ return;
+ }
+
+ CaptureCallback* capture_callback = new CaptureCallback(base::Bind(
+ &DidCapturePixelsAsync, base::Passed(std::move(pixels_request))));
+ web_view->compositeAndReadbackAsync(capture_callback);
+ if (blink::WebPagePopup* popup = web_view->pagePopup()) {
+ capture_callback->set_wait_for_popup(true);
+ blink::WebPoint position = popup->positionRelativeToOwner();
+ position.x *= device_scale_factor_for_test;
+ position.y *= device_scale_factor_for_test;
+ capture_callback->set_popup_position(position);
+ popup->compositeAndReadbackAsync(capture_callback);
+ }
+}
+
+void CopyImageAtAndCapturePixels(
+ blink::WebView* web_view,
+ int x,
+ int y,
+ const base::Callback<void(const SkBitmap&)>& callback) {
+ DCHECK(!callback.is_null());
+ uint64_t sequence_number =
+ blink::Platform::current()->clipboard()->sequenceNumber(
+ blink::WebClipboard::Buffer());
+ web_view->copyImageAt(blink::WebPoint(x, y));
+ if (sequence_number ==
+ blink::Platform::current()->clipboard()->sequenceNumber(
+ blink::WebClipboard::Buffer())) {
+ SkBitmap emptyBitmap;
+ callback.Run(emptyBitmap);
+ return;
+ }
+
+ blink::WebData data = blink::Platform::current()->clipboard()->readImage(
+ blink::WebClipboard::Buffer());
+ blink::WebImage image = blink::WebImage::fromData(data, blink::WebSize());
+ const SkBitmap& bitmap = image.getSkBitmap();
+ SkAutoLockPixels autoLock(bitmap);
+ callback.Run(bitmap);
+}
+
+} // namespace test_runner
« no previous file with comments | « components/test_runner/pixel_dump.h ('k') | components/test_runner/test_runner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698