summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/render_widget.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer/render_widget.cc')
-rw-r--r--chrome/renderer/render_widget.cc74
1 files changed, 70 insertions, 4 deletions
diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc
index d7676ed..243665a 100644
--- a/chrome/renderer/render_widget.cc
+++ b/chrome/renderer/render_widget.cc
@@ -149,6 +149,7 @@ IPC_DEFINE_MESSAGE_MAP(RenderWidget)
IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(ViewMsg_ImeSetInputMode, OnImeSetInputMode)
IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
+ IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize)
IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint)
IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
@@ -250,8 +251,8 @@ void RenderWidget::OnWasRestored(bool needs_repainting) {
return;
needs_repainting_on_restore_ = false;
- // Tag the next paint as a restore ack, which is picked up by DoDeferredUpdate
- // when it sends out the next PaintRect message.
+ // Tag the next paint as a restore ack, which is picked up by
+ // DoDeferredUpdate when it sends out the next PaintRect message.
set_next_paint_is_restore_ack();
// Generate a full repaint.
@@ -268,7 +269,7 @@ void RenderWidget::OnUpdateRectAck() {
update_reply_pending_ = false;
// If we sent an UpdateRect message with a zero-sized bitmap, then we should
- // have no current update buf.
+ // have no current paint buffer.
if (current_paint_buf_) {
RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
current_paint_buf_ = NULL;
@@ -720,6 +721,72 @@ void RenderWidget::OnImeSetComposition(WebCompositionCommand command,
ime_control_busy_ = false;
}
+// Forces a repaint even if we're hidden, so we can update backing
+// store even before a tab has been shown for the first time, and it
+// does it synchronously.
+void RenderWidget::OnMsgPaintAtSize(const TransportDIB::Handle& dib_handle,
+ const gfx::Size& desired_size) {
+ if (!webwidget_ || dib_handle == TransportDIB::DefaultHandleValue())
+ return;
+
+ if (webwidget_->size().isEmpty() ||
+ desired_size.IsEmpty()) {
+ // If one of these is empty, then we just return the dib we were
+ // given, to avoid leaking it.
+ Send(new ViewHostMsg_PaintAtSize_ACK(routing_id_,
+ dib_handle,
+ desired_size));
+ return;
+ }
+
+ // Map the given DIB ID into this process, and unmap it at the end
+ // of this function.
+ scoped_ptr<TransportDIB> paint_at_scale_buffer(TransportDIB::Map(dib_handle));
+
+ DCHECK(paint_at_scale_buffer.get());
+ if (!paint_at_scale_buffer.get())
+ return;
+
+ // Have to make sure we're laid out before rendering.
+ webwidget_->layout();
+
+ gfx::Size canvas_size = webwidget_->size();
+ float x_scale = static_cast<float>(desired_size.width()) /
+ static_cast<float>(canvas_size.width());
+ float y_scale = static_cast<float>(desired_size.height()) /
+ static_cast<float>(canvas_size.height());
+
+ gfx::Rect orig_bounds(gfx::Point(0,0), canvas_size);
+ canvas_size.set_width(static_cast<int>(canvas_size.width() * x_scale));
+ canvas_size.set_height(static_cast<int>(canvas_size.height() * y_scale));
+ gfx::Rect bounds(gfx::Point(0,0), canvas_size);
+
+ scoped_ptr<skia::PlatformCanvas> canvas(
+ paint_at_scale_buffer->GetPlatformCanvas(canvas_size.width(),
+ canvas_size.height()));
+ if (!canvas.get()) {
+ NOTREACHED();
+ return;
+ }
+
+ // Reset bounds to what we actually received, but they should be the
+ // same.
+ DCHECK_EQ(bounds.width(), canvas->getDevice()->width());
+ DCHECK_EQ(bounds.height(), canvas->getDevice()->height());
+ bounds.set_width(canvas->getDevice()->width());
+ bounds.set_height(canvas->getDevice()->height());
+
+ canvas->save();
+ // Add the scale factor to the canvas, so that we'll get what we expect.
+ canvas->scale(SkFloatToScalar(x_scale), SkFloatToScalar(y_scale));
+
+ // Paint the entire thing (using original bounds, not scaled bounds).
+ PaintRect(orig_bounds, orig_bounds.origin(), canvas.get());
+ canvas->restore();
+
+ Send(new ViewHostMsg_PaintAtSize_ACK(routing_id_, dib_handle, bounds.size()));
+}
+
void RenderWidget::OnMsgRepaint(const gfx::Size& size_to_paint) {
// During shutdown we can just ignore this message.
if (!webwidget_)
@@ -878,4 +945,3 @@ void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) {
}
}
}
-