// Copyright 2014 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 "core/paint/ImagePainter.h"

#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/editing/FrameSelection.h"
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAreaElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/layout/LayoutImage.h"
#include "core/layout/LayoutReplaced.h"
#include "core/layout/TextRunConstructor.h"
#include "core/page/Page.h"
#include "core/paint/BoxPainter.h"
#include "core/paint/LayoutObjectDrawingRecorder.h"
#include "core/paint/PaintInfo.h"
#include "platform/geometry/LayoutPoint.h"
#include "platform/graphics/Path.h"

namespace blink {

void ImagePainter::paint(const PaintInfo& paintInfo,
                         const LayoutPoint& paintOffset) {
  m_layoutImage.LayoutReplaced::paint(paintInfo, paintOffset);

  if (paintInfo.phase == PaintPhaseOutline)
    paintAreaElementFocusRing(paintInfo, paintOffset);
}

void ImagePainter::paintAreaElementFocusRing(const PaintInfo& paintInfo,
                                             const LayoutPoint& paintOffset) {
  Document& document = m_layoutImage.document();

  if (paintInfo.isPrinting() ||
      !document.frame()->selection().isFocusedAndActive())
    return;

  Element* focusedElement = document.focusedElement();
  if (!isHTMLAreaElement(focusedElement))
    return;

  HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
  if (areaElement.imageElement() != m_layoutImage.node())
    return;

  // Even if the theme handles focus ring drawing for entire elements, it won't
  // do it for an area within an image, so we don't call
  // LayoutTheme::themeDrawsFocusRing here.

  const ComputedStyle& areaElementStyle = *areaElement.ensureComputedStyle();
  int outlineWidth = areaElementStyle.outlineWidth();
  if (!outlineWidth)
    return;

  Path path = areaElement.getPath(&m_layoutImage);
  if (path.isEmpty())
    return;

  LayoutPoint adjustedPaintOffset = paintOffset;
  adjustedPaintOffset.moveBy(m_layoutImage.location());
  path.translate(FloatSize(adjustedPaintOffset.x(), adjustedPaintOffset.y()));

  if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
          paintInfo.context, m_layoutImage, DisplayItem::kImageAreaFocusRing))
    return;

  LayoutRect focusRect = m_layoutImage.contentBoxRect();
  focusRect.moveBy(adjustedPaintOffset);
  LayoutObjectDrawingRecorder drawingRecorder(paintInfo.context, m_layoutImage,
                                              DisplayItem::kImageAreaFocusRing,
                                              focusRect);

  // FIXME: Clip path instead of context when Skia pathops is ready.
  // https://crbug.com/251206

  paintInfo.context.save();
  paintInfo.context.clip(pixelSnappedIntRect(focusRect));
  paintInfo.context.drawFocusRing(
      path, outlineWidth, areaElementStyle.outlineOffset(),
      m_layoutImage.resolveColor(areaElementStyle, CSSPropertyOutlineColor));
  paintInfo.context.restore();
}

void ImagePainter::paintReplaced(const PaintInfo& paintInfo,
                                 const LayoutPoint& paintOffset) {
  LayoutUnit cWidth = m_layoutImage.contentWidth();
  LayoutUnit cHeight = m_layoutImage.contentHeight();

  GraphicsContext& context = paintInfo.context;

  if (!m_layoutImage.imageResource()->hasImage()) {
    if (paintInfo.phase == PaintPhaseSelection)
      return;
    if (cWidth > 2 && cHeight > 2) {
      if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
              context, m_layoutImage, paintInfo.phase))
        return;
      // Draw an outline rect where the image should be.
      IntRect paintRect = pixelSnappedIntRect(
          LayoutRect(paintOffset.x() + m_layoutImage.borderLeft() +
                         m_layoutImage.paddingLeft(),
                     paintOffset.y() + m_layoutImage.borderTop() +
                         m_layoutImage.paddingTop(),
                     cWidth, cHeight));
      LayoutObjectDrawingRecorder drawingRecorder(context, m_layoutImage,
                                                  paintInfo.phase, paintRect);
      context.setStrokeStyle(SolidStroke);
      context.setStrokeColor(Color::lightGray);
      context.setFillColor(Color::transparent);
      context.drawRect(paintRect);
    }
  } else if (cWidth > 0 && cHeight > 0) {
    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
            context, m_layoutImage, paintInfo.phase))
      return;

    LayoutRect contentRect = m_layoutImage.contentBoxRect();
    contentRect.moveBy(paintOffset);
    LayoutRect paintRect = m_layoutImage.replacedContentRect();
    paintRect.moveBy(paintOffset);

    LayoutObjectDrawingRecorder drawingRecorder(context, m_layoutImage,
                                                paintInfo.phase, contentRect);
    paintIntoRect(context, paintRect, contentRect);
  }
}

void ImagePainter::paintIntoRect(GraphicsContext& context,
                                 const LayoutRect& destRect,
                                 const LayoutRect& contentRect) {
  if (!m_layoutImage.imageResource()->hasImage() ||
      m_layoutImage.imageResource()->errorOccurred())
    return;  // FIXME: should we just ASSERT these conditions? (audit all
             // callers).

  IntRect pixelSnappedDestRect = pixelSnappedIntRect(destRect);
  if (pixelSnappedDestRect.isEmpty())
    return;

  RefPtr<Image> image = m_layoutImage.imageResource()->image(
      pixelSnappedDestRect.size(), m_layoutImage.style()->effectiveZoom());
  if (!image || image->isNull())
    return;

  // FIXME: why is interpolation quality selection not included in the
  // Instrumentation reported cost of drawing an image?
  InterpolationQuality interpolationQuality =
      BoxPainter::chooseInterpolationQuality(
          m_layoutImage, image.get(), image.get(),
          LayoutSize(pixelSnappedDestRect.size()));

  FloatRect srcRect = image->rect();
  // If the content rect requires clipping, adjust |srcRect| and
  // |pixelSnappedDestRect| over using a clip.
  if (!contentRect.contains(destRect)) {
    IntRect pixelSnappedContentRect = pixelSnappedIntRect(contentRect);
    pixelSnappedContentRect.intersect(pixelSnappedDestRect);
    if (pixelSnappedContentRect.isEmpty())
      return;
    srcRect = mapRect(pixelSnappedContentRect, pixelSnappedDestRect, srcRect);
    pixelSnappedDestRect = pixelSnappedContentRect;
  }

  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage",
               "data", InspectorPaintImageEvent::data(m_layoutImage));

  InterpolationQuality previousInterpolationQuality =
      context.imageInterpolationQuality();
  context.setImageInterpolationQuality(interpolationQuality);
  context.drawImage(
      image.get(), pixelSnappedDestRect, &srcRect, SkXfermode::kSrcOver_Mode,
      LayoutObject::shouldRespectImageOrientation(&m_layoutImage));
  context.setImageInterpolationQuality(previousInterpolationQuality);
}

}  // namespace blink
