summaryrefslogtreecommitdiff
path: root/chromium/pdf/paint_aggregator.h
blob: 91bf03fbaa11b7cc4f6e74121fe2a333a8580a96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// 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_