Home | History | Annotate | Download | only in pdf
      1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef PDF_PAINT_AGGREGATOR_H_
      6 #define PDF_PAINT_AGGREGATOR_H_
      7 
      8 #include <vector>
      9 
     10 #include "ppapi/cpp/image_data.h"
     11 #include "ppapi/cpp/rect.h"
     12 #include "ppapi/cpp/rect.h"
     13 
     14 // This class is responsible for aggregating multiple invalidation and scroll
     15 // commands to produce a scroll and repaint sequence. You can use this manually
     16 // to track your updates, but most applications will use the PaintManager to
     17 // additionally handle the necessary callbacks on top of the PaintAggregator
     18 // functionality.
     19 //
     20 // See http://code.google.com/p/ppapi/wiki/2DPaintingModel
     21 class PaintAggregator {
     22  public:
     23   // Stores information about a rectangle that has finished painting.  The
     24   // PaintManager will paint it only when everything else on the screen is also
     25   // ready.
     26   struct ReadyRect {
     27     pp::Point offset;
     28     pp::Rect rect;
     29     pp::ImageData image_data;
     30   };
     31 
     32   struct PaintUpdate {
     33     PaintUpdate();
     34     ~PaintUpdate();
     35 
     36     // True if there is a scroll applied. This indicates that the scroll delta
     37     // and scroll_rect are nonzero (just as a convenience).
     38     bool has_scroll;
     39 
     40     // The amount to scroll by. Either the X or Y may be nonzero to indicate a
     41     // scroll in that direction, but there will never be a scroll in both
     42     // directions at the same time (this will be converted to a paint of the
     43     // region instead).
     44     //
     45     // If there is no scroll, this will be (0, 0).
     46     pp::Point scroll_delta;
     47 
     48     // The rectangle that should be scrolled by the scroll_delta. If there is no
     49     // scroll, this will be (0, 0, 0, 0). We only track one scroll command at
     50     // once. If there are multiple ones, they will be converted to invalidates.
     51     pp::Rect scroll_rect;
     52 
     53     // A list of all the individual dirty rectangles. This is an aggregated list
     54     // of all invalidate calls. Different rectangles may be unified to produce a
     55     // minimal list with no overlap that is more efficient to paint. This list
     56     // also contains the region exposed by any scroll command.
     57     std::vector<pp::Rect> paint_rects;
     58   };
     59 
     60   PaintAggregator();
     61 
     62   // There is a PendingUpdate if InvalidateRect or ScrollRect were called and
     63   // ClearPendingUpdate was not called.
     64   bool HasPendingUpdate() const;
     65   void ClearPendingUpdate();
     66 
     67   PaintUpdate GetPendingUpdate();
     68 
     69   // Sets the result of a call to the plugin to paint.  This includes rects that
     70   // are finished painting (ready), and ones that are still in-progress
     71   // (pending).
     72   void SetIntermediateResults(const std::vector<ReadyRect>& ready,
     73                               const std::vector<pp::Rect>& pending);
     74 
     75   // Returns the rectangles that are ready to be painted.
     76   std::vector<ReadyRect> GetReadyRects() const;
     77 
     78   // The given rect should be repainted.
     79   void InvalidateRect(const pp::Rect& rect);
     80 
     81   // The given rect should be scrolled by the given amounts.
     82   void ScrollRect(const pp::Rect& clip_rect, const pp::Point& amount);
     83 
     84  private:
     85   // This structure is an internal version of PaintUpdate. It's different in
     86   // two respects:
     87   //
     88   //  - The scroll damange (area exposed by the scroll operation, if any) is
     89   //    maintained separately from the dirty rects generated by calling
     90   //    InvalidateRect. We need to know this distinction for some operations.
     91   //
     92   //  - The paint bounds union is computed on the fly so we don't have to keep
     93   //    a rectangle up-to-date as we do different operations.
     94   class InternalPaintUpdate {
     95    public:
     96     InternalPaintUpdate();
     97     ~InternalPaintUpdate();
     98 
     99     // Computes the rect damaged by scrolling within |scroll_rect| by
    100     // |scroll_delta|. This rect must be repainted. It is not included in
    101     // paint_rects.
    102     pp::Rect GetScrollDamage() const;
    103 
    104     pp::Point scroll_delta;
    105     pp::Rect scroll_rect;
    106 
    107     // Does not include the scroll damage rect unless
    108     // synthesized_scroll_damage_rect_ is set.
    109     std::vector<pp::Rect> paint_rects;
    110 
    111     // Rectangles that are finished painting.
    112     std::vector<ReadyRect> ready_rects;
    113 
    114     // Whether we have added the scroll damage rect to paint_rects yet or not.
    115     bool synthesized_scroll_damage_rect_;
    116   };
    117 
    118   pp::Rect ScrollPaintRect(const pp::Rect& paint_rect,
    119                            const pp::Point& amount) const;
    120   void InvalidateScrollRect();
    121 
    122   // Internal method used by InvalidateRect. If |check_scroll| is true, then the
    123   // method checks if there's a pending scroll and if so also invalidates |rect|
    124   // in the new scroll position.
    125   void InvalidateRectInternal(const pp::Rect& rect, bool check_scroll);
    126 
    127   InternalPaintUpdate update_;
    128 };
    129 
    130 #endif  // PDF_PAINT_AGGREGATOR_H_
    131