// 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() = default;

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() = default;

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);
  }
}
