// 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 #include "ppapi/cpp/image_data.h" #include "ppapi/cpp/rect.h" #include "ppapi/cpp/rect.h" // 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: // Stores information about a rectangle that has finished painting. The // PaintManager will paint it only when everything else on the screen is also // ready. struct ReadyRect { pp::Point offset; pp::Rect rect; pp::ImageData image_data; }; struct PaintUpdate { PaintUpdate(); ~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). pp::Point 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. pp::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 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& ready, const std::vector& pending); // Returns the rectangles that are ready to be painted. std::vector GetReadyRects() const; // The given rect should be repainted. void InvalidateRect(const pp::Rect& rect); // The given rect should be scrolled by the given amounts. void ScrollRect(const pp::Rect& clip_rect, const pp::Point& 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. pp::Rect GetScrollDamage() const; pp::Point scroll_delta; pp::Rect scroll_rect; // Does not include the scroll damage rect unless // synthesized_scroll_damage_rect_ is set. std::vector paint_rects; // Rectangles that are finished painting. std::vector ready_rects; // Whether we have added the scroll damage rect to paint_rects yet or not. bool synthesized_scroll_damage_rect_; }; pp::Rect ScrollPaintRect(const pp::Rect& paint_rect, const pp::Point& 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 pp::Rect& rect, bool check_scroll); InternalPaintUpdate update_; }; #endif // PDF_PAINT_AGGREGATOR_H_