// 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.

#include "pdf/paint_aggregator.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>

#include "base/logging.h"

namespace {

bool IsNegative(int32_t num) {
  return num < 0;
}

}  // namespace

// ----------------------------------------------------------------------------
// ALGORITHM NOTES
//
// We attempt to maintain a scroll rect in the presence of invalidations that
// are contained within the scroll rect.  If an invalidation crosses a scroll
// rect, then we just treat the scroll rect as an invalidation rect.
//
// For invalidations performed prior to scrolling and contained within the
// scroll rect, we offset the invalidation rects to account for the fact that
// the consumer will perform scrolling before painting.
//
// We only support scrolling along one axis at a time.  A diagonal scroll will
// therefore be treated as an invalidation.
// ----------------------------------------------------------------------------

PaintAggregator::PaintUpdate::PaintUpdate() = default;

PaintAggregator::PaintUpdate::PaintUpdate(const PaintUpdate& that) = default;

PaintAggregator::PaintUpdate::~PaintUpdate() = default;

PaintAggregator::InternalPaintUpdate::InternalPaintUpdate()
    : synthesized_scroll_damage_rect_(false) {}

PaintAggregator::InternalPaintUpdate::~InternalPaintUpdate() {}

pp::Rect PaintAggregator::InternalPaintUpdate::GetScrollDamage() const {
  // Should only be scrolling in one direction at a time.
  DCHECK(!(scroll_delta.x() && scroll_delta.y()));

  pp::Rect damaged_rect;

  // Compute the region we will expose by scrolling, and paint that into a
  // shared memory section.
  if (scroll_delta.x()) {
    int32_t dx = scroll_delta.x();
    damaged_rect.set_y(scroll_rect.y());
    damaged_rect.set_height(scroll_rect.height());
    if (dx > 0) {
      damaged_rect.set_x(scroll_rect.x());
      damaged_rect.set_width(dx);
    } else {
      damaged_rect.set_x(scroll_rect.right() + dx);
      damaged_rect.set_width(-dx);
    }
  } else {
    int32_t dy = scroll_delta.y();
    damaged_rect.set_x(scroll_rect.x());
    damaged_rect.set_width(scroll_rect.width());
    if (dy > 0) {
      damaged_rect.set_y(scroll_rect.y());
      damaged_rect.set_height(dy);
    } else {
      damaged_rect.set_y(scroll_rect.bottom() + dy);
      damaged_rect.set_height(-dy);
    }
  }

  // In case the scroll offset exceeds the width/height of the scroll rect
  return scroll_rect.Intersect(damaged_rect);
}

PaintAggregator::PaintAggregator() {}

bool PaintAggregator::HasPendingUpdate() const {
  return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty();
}

void PaintAggregator::ClearPendingUpdate() {
  update_ = InternalPaintUpdate();
}

PaintAggregator::PaintUpdate PaintAggregator::GetPendingUpdate() {
  // Convert the internal paint update to the external one, which includes a
  // bit more precomputed info for the caller.
  PaintUpdate ret;
  ret.scroll_delta = update_.scroll_delta;
  ret.scroll_rect = update_.scroll_rect;
  ret.has_scroll = ret.scroll_delta.x() != 0 || ret.scroll_delta.y() != 0;

  // Include the scroll damage (if any) in the paint rects.
  // Code invalidates damaged rect here, it pick it up from the list of paint
  // rects in the next block.
  if (ret.has_scroll && !update_.synthesized_scroll_damage_rect_) {
    update_.synthesized_scroll_damage_rect_ = true;
    pp::Rect scroll_damage = update_.GetScrollDamage();
    InvalidateRectInternal(scroll_damage, false);
  }

  ret.paint_rects.reserve(update_.paint_rects.size() + 1);
  ret.paint_rects.insert(ret.paint_rects.end(), update_.paint_rects.begin(),
                         update_.paint_rects.end());

  return ret;
}

void PaintAggregator::SetIntermediateResults(
    const std::vector<ReadyRect>& ready,
    const std::vector<pp::Rect>& pending) {
  update_.ready_rects.insert(update_.ready_rects.end(), ready.begin(),
                             ready.end());
  update_.paint_rects = pending;
}

std::vector<PaintAggregator::ReadyRect> PaintAggregator::GetReadyRects() const {
  return update_.ready_rects;
}

void PaintAggregator::InvalidateRect(const pp::Rect& rect) {
  InvalidateRectInternal(rect, true);
}

void PaintAggregator::ScrollRect(const pp::Rect& clip_rect,
                                 const pp::Point& amount) {
  // We only support scrolling along one axis at a time.
  if (amount.x() != 0 && amount.y() != 0) {
    InvalidateRect(clip_rect);
    return;
  }

  // We can only scroll one rect at a time.
  if (!update_.scroll_rect.IsEmpty() && update_.scroll_rect != clip_rect) {
    InvalidateRect(clip_rect);
    return;
  }

  // Again, we only support scrolling along one axis at a time.  Make sure this
  // update doesn't scroll on a different axis than any existing one.
  if ((amount.x() && update_.scroll_delta.y()) ||
      (amount.y() && update_.scroll_delta.x())) {
    InvalidateRect(clip_rect);
    return;
  }

  // If we scroll in a reverse direction to the direction we originally scrolled
  // and there were invalidations that happened in-between we may end up
  // incorrectly clipping the invalidated rects (see crbug.com/488390). This bug
  // doesn't exist in the original implementation
  // (ppapi/utility/graphics/paint_aggregator.cc) which uses a different method
  // of handling invalidations that occur after a scroll. The problem is that
  // when we scroll the invalidated region, we clip it to the scroll rect. This
  // can cause us to lose information about what the invalidated region was if
  // it gets scrolled back into view. We either need to not do this clipping or
  // disallow combining scrolls that occur in different directions with
  // invalidations that happen in-between. This code really needs some tests...
  if (!update_.paint_rects.empty()) {
    if (IsNegative(amount.x()) != IsNegative(update_.scroll_delta.x()) ||
        IsNegative(amount.y()) != IsNegative(update_.scroll_delta.y())) {
      InvalidateRect(clip_rect);
      return;
    }
  }

  // The scroll rect is new or isn't changing (though the scroll amount may
  // be changing).
  update_.scroll_rect = clip_rect;
  update_.scroll_delta += amount;

  // We might have just wiped out a pre-existing scroll.
  if (update_.scroll_delta == pp::Point()) {
    update_.scroll_rect = pp::Rect();
    return;
  }

  // Adjust any paint rects that intersect the scroll. For the portion of the
  // paint that is inside the scroll area, move it by the scroll amount and
  // replace the existing paint with it. For the portion (if any) that is
  // outside the scroll, just invalidate it.
  std::vector<pp::Rect> leftover_rects;
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    if (!update_.scroll_rect.Intersects(update_.paint_rects[i]))
      continue;

    pp::Rect intersection =
        update_.paint_rects[i].Intersect(update_.scroll_rect);
    pp::Rect rect = update_.paint_rects[i];
    while (!rect.IsEmpty()) {
      pp::Rect leftover = rect.Subtract(intersection);
      if (leftover.IsEmpty())
        break;
      // Don't want to call InvalidateRectInternal now since it'll modify
      // update_.paint_rects, so keep track of this and do it below.
      leftover_rects.push_back(leftover);
      rect = rect.Subtract(leftover);
    }

    update_.paint_rects[i] = ScrollPaintRect(intersection, amount);

    // The rect may have been scrolled out of view.
    if (update_.paint_rects[i].IsEmpty()) {
      update_.paint_rects.erase(update_.paint_rects.begin() + i);
      i--;
    }
  }

  for (const auto& leftover_rect : leftover_rects)
    InvalidateRectInternal(leftover_rect, false);

  for (auto& update_rect : update_.ready_rects) {
    if (update_.scroll_rect.Contains(update_rect.rect))
      update_rect.rect = ScrollPaintRect(update_rect.rect, amount);
  }

  if (update_.synthesized_scroll_damage_rect_) {
    pp::Rect damage = update_.GetScrollDamage();
    InvalidateRect(damage);
  }
}

pp::Rect PaintAggregator::ScrollPaintRect(const pp::Rect& paint_rect,
                                          const pp::Point& amount) const {
  pp::Rect result = paint_rect;
  result.Offset(amount);
  result = update_.scroll_rect.Intersect(result);
  return result;
}

void PaintAggregator::InvalidateScrollRect() {
  pp::Rect scroll_rect = update_.scroll_rect;
  update_.scroll_rect = pp::Rect();
  update_.scroll_delta = pp::Point();
  InvalidateRect(scroll_rect);
}

void PaintAggregator::InvalidateRectInternal(const pp::Rect& rect_old,
                                             bool check_scroll) {
  pp::Rect rect = rect_old;
  // Check if any rects that are ready to be painted overlap.
  for (size_t i = 0; i < update_.ready_rects.size(); ++i) {
    const pp::Rect& existing_rect = update_.ready_rects[i].rect;
    if (rect.Intersects(existing_rect)) {
      // Re-invalidate in case the union intersects other paint rects.
      rect = existing_rect.Union(rect);
      update_.ready_rects.erase(update_.ready_rects.begin() + i);
      break;
    }
  }

  bool add_paint = true;

  // Combine overlapping paints using smallest bounding box.
  for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
    const pp::Rect& existing_rect = update_.paint_rects[i];
    if (existing_rect.Contains(rect))  // Optimize out redundancy.
      add_paint = false;
    if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) {
      // Re-invalidate in case the union intersects other paint rects.
      pp::Rect combined_rect = existing_rect.Union(rect);
      update_.paint_rects.erase(update_.paint_rects.begin() + i);
      InvalidateRectInternal(combined_rect, check_scroll);
      add_paint = false;
    }
  }

  if (add_paint) {
    // Add a non-overlapping paint.
    update_.paint_rects.push_back(rect);
  }

  // If the new paint overlaps with a scroll, then also invalidate the rect in
  // its new position.
  if (check_scroll && !update_.scroll_rect.IsEmpty() &&
      update_.scroll_rect.Intersects(rect)) {
    InvalidateRectInternal(ScrollPaintRect(rect, update_.scroll_delta), false);
  }
}
