diff options
Diffstat (limited to 'content/renderer/render_widget.cc')
-rw-r--r-- | content/renderer/render_widget.cc | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index bbc4ecc..99b3731 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -24,6 +24,7 @@ #include "ipc/ipc_sync_message.h" #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkShader.h" +#include "third_party/skia/include/effects/SkTableColorFilter.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPoint.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" @@ -98,7 +99,8 @@ RenderWidget::RenderWidget(WebKit::WebPopupType popup_type) is_accelerated_compositing_active_(false), animation_update_pending_(false), animation_task_posted_(false), - invalidation_task_posted_(false) { + invalidation_task_posted_(false), + invert_(false) { RenderProcess::current()->AddRefProcess(); DCHECK(RenderThread::Get()); has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( @@ -217,6 +219,7 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) + IPC_MESSAGE_HANDLER(ViewMsg_InvertWebContent, OnInvertWebContent) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -587,6 +590,16 @@ void RenderWidget::PaintRect(const gfx::Rect& rect, canvas->translate(static_cast<SkScalar>(-canvas_origin.x()), static_cast<SkScalar>(-canvas_origin.y())); + if (invert_) { + // Draw everything to a temporary bitmap and then apply an + // inverting color map to the result. This is balanced by an extra + // call to canvas->restore(), below. + DCHECK(invert_paint_.get()); + SkRect bounds; + bounds.set(rect.x(), rect.y(), rect.right(), rect.bottom()); + canvas->saveLayer(&bounds, invert_paint_.get()); + } + // If there is a custom background, tile it. if (!background_.empty()) { SkPaint paint; @@ -647,6 +660,9 @@ void RenderWidget::PaintRect(const gfx::Rect& rect, skia::GetTopDevice(*canvas)->accessBitmap(false); } + if (invert_) + canvas->restore(); + PaintDebugBorder(rect, canvas); canvas->restore(); } @@ -1389,6 +1405,37 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) { webwidget_->setTextDirection(direction); } +void RenderWidget::OnInvertWebContent(bool invert) { + if (invert_ == invert) + return; + + invert_ = invert; + + if (invert_ && !invert_paint_.get()) { + // Gamma-aware color inversion: each source pixel value x is normally + // displayed on a computer monitor with a gamma correction x^gamma, + // where gamma is typically in the range 1.8...2.2. By approximating + // gamma as exactly 2, the formula to invert one value is sqrt(1 - x^2). + uint8_t table[256]; + for (unsigned int i = 0; i < 256; i++) { + double value = i / 255.0; + value = sqrt(1 - (value * value)); + table[i] = static_cast<uint8_t>(255 * value); + } + + // Create a Skia Paint with this inverting color map. + invert_paint_.reset(new SkPaint()); + invert_paint_->setStyle(SkPaint::kFill_Style); + invert_paint_->setColor(SK_ColorBLACK); + SkColorFilter* filter = SkTableColorFilter::CreateARGB( + NULL, table, table, table); + invert_paint_->setColorFilter(filter); + filter->unref(); + } + + OnMsgRepaint(size_); +} + webkit::ppapi::PluginInstance* RenderWidget::GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, |