blob: 91bf03fbaa11b7cc4f6e74121fe2a333a8580a96 [file] [log] [blame]
// Copyright (c) 2010 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.
#ifndef PDF_PAINT_AGGREGATOR_H_
#define PDF_PAINT_AGGREGATOR_H_
#include <vector>
#include "pdf/paint_ready_rect.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
namespace chrome_pdf {
// This class is responsible for aggregating multiple invalidation and scroll
// commands to produce a scroll and repaint sequence. You can use this manually
// to track your updates, but most applications will use the PaintManager to
// additionally handle the necessary callbacks on top of the PaintAggregator
// functionality.
//
// See http://code.google.com/p/ppapi/wiki/2DPaintingModel
class PaintAggregator {
public:
struct PaintUpdate {
PaintUpdate();
PaintUpdate(const PaintUpdate& that);
~PaintUpdate();
// True if there is a scroll applied. This indicates that the scroll delta
// and scroll_rect are nonzero (just as a convenience).
bool has_scroll;
// The amount to scroll by. Either the X or Y may be nonzero to indicate a
// scroll in that direction, but there will never be a scroll in both
// directions at the same time (this will be converted to a paint of the
// region instead).
//
// If there is no scroll, this will be (0, 0).
gfx::Vector2d scroll_delta;
// The rectangle that should be scrolled by the scroll_delta. If there is no
// scroll, this will be (0, 0, 0, 0). We only track one scroll command at
// once. If there are multiple ones, they will be converted to invalidates.
gfx::Rect scroll_rect;
// A list of all the individual dirty rectangles. This is an aggregated list
// of all invalidate calls. Different rectangles may be unified to produce a
// minimal list with no overlap that is more efficient to paint. This list
// also contains the region exposed by any scroll command.
std::vector<gfx::Rect> paint_rects;
};
PaintAggregator();
// There is a PendingUpdate if InvalidateRect or ScrollRect were called and
// ClearPendingUpdate was not called.
bool HasPendingUpdate() const;
void ClearPendingUpdate();
PaintUpdate GetPendingUpdate();
// Sets the result of a call to the plugin to paint. This includes rects that
// are finished painting (ready), and ones that are still in-progress
// (pending).
void SetIntermediateResults(const std::vector<PaintReadyRect>& ready,
const std::vector<gfx::Rect>& pending);
// Returns the rectangles that are ready to be painted.
std::vector<PaintReadyRect> GetReadyRects() const;
// The given rect should be repainted.
void InvalidateRect(const gfx::Rect& rect);
// The given rect should be scrolled by the given amounts.
void ScrollRect(const gfx::Rect& clip_rect, const gfx::Vector2d& amount);
private:
// This structure is an internal version of PaintUpdate. It's different in
// two respects:
//
// - The scroll damange (area exposed by the scroll operation, if any) is
// maintained separately from the dirty rects generated by calling
// InvalidateRect. We need to know this distinction for some operations.
//
// - The paint bounds union is computed on the fly so we don't have to keep
// a rectangle up to date as we do different operations.
class InternalPaintUpdate {
public:
InternalPaintUpdate();
~InternalPaintUpdate();
// Computes the rect damaged by scrolling within |scroll_rect| by
// |scroll_delta|. This rect must be repainted. It is not included in
// paint_rects.
gfx::Rect GetScrollDamage() const;
gfx::Vector2d scroll_delta;
gfx::Rect scroll_rect;
// Does not include the scroll damage rect unless
// synthesized_scroll_damage_rect_ is set.
std::vector<gfx::Rect> paint_rects;
// Rectangles that are finished painting.
std::vector<PaintReadyRect> ready_rects;
// Whether we have added the scroll damage rect to paint_rects yet or not.
bool synthesized_scroll_damage_rect_;
};
gfx::Rect ScrollPaintRect(const gfx::Rect& paint_rect,
const gfx::Vector2d& amount) const;
void InvalidateScrollRect();
// Internal method used by InvalidateRect. If |check_scroll| is true, then the
// method checks if there's a pending scroll and if so also invalidates |rect|
// in the new scroll position.
void InvalidateRectInternal(const gfx::Rect& rect, bool check_scroll);
InternalPaintUpdate update_;
};
} // namespace chrome_pdf
#endif // PDF_PAINT_AGGREGATOR_H_