// 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/TextPainter.h"

#include "core/CSSPropertyNames.h"
#include "core/frame/Settings.h"
#include "core/layout/LayoutObject.h"
#include "core/layout/LayoutTextCombine.h"
#include "core/layout/api/LineLayoutAPIShim.h"
#include "core/layout/api/LineLayoutItem.h"
#include "core/paint/BoxPainter.h"
#include "core/paint/PaintInfo.h"
#include "core/style/ComputedStyle.h"
#include "core/style/ShadowList.h"
#include "platform/fonts/Font.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/text/TextRun.h"
#include "wtf/Assertions.h"
#include "wtf/text/CharacterNames.h"

namespace blink {

TextPainter::TextPainter(GraphicsContext& context,
                         const Font& font,
                         const TextRun& run,
                         const LayoutPoint& textOrigin,
                         const LayoutRect& textBounds,
                         bool horizontal)
    : m_graphicsContext(context),
      m_font(font),
      m_run(run),
      m_textOrigin(textOrigin),
      m_textBounds(textBounds),
      m_horizontal(horizontal),
      m_emphasisMarkOffset(0),
      m_combinedText(0) {}

TextPainter::~TextPainter() {}

void TextPainter::setEmphasisMark(const AtomicString& emphasisMark,
                                  TextEmphasisPosition position) {
  m_emphasisMark = emphasisMark;
  const SimpleFontData* fontData = m_font.primaryFont();
  DCHECK(fontData);

  if (!fontData || emphasisMark.isNull()) {
    m_emphasisMarkOffset = 0;
  } else if (position == TextEmphasisPositionOver) {
    m_emphasisMarkOffset = -fontData->getFontMetrics().ascent() -
                           m_font.emphasisMarkDescent(emphasisMark);
  } else {
    DCHECK(position == TextEmphasisPositionUnder);
    m_emphasisMarkOffset = fontData->getFontMetrics().descent() +
                           m_font.emphasisMarkAscent(emphasisMark);
  }
}

void TextPainter::paint(unsigned startOffset,
                        unsigned endOffset,
                        unsigned length,
                        const Style& textStyle,
                        TextBlobPtr* cachedTextBlob) {
  GraphicsContextStateSaver stateSaver(m_graphicsContext, false);
  updateGraphicsContext(textStyle, stateSaver);
  if (m_combinedText) {
    m_graphicsContext.save();
    m_combinedText->transformToInlineCoordinates(m_graphicsContext,
                                                 m_textBounds);
    paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob);
    m_graphicsContext.restore();
  } else {
    paintInternal<PaintText>(startOffset, endOffset, length, cachedTextBlob);
  }

  if (!m_emphasisMark.isEmpty()) {
    if (textStyle.emphasisMarkColor != textStyle.fillColor)
      m_graphicsContext.setFillColor(textStyle.emphasisMarkColor);

    if (m_combinedText)
      paintEmphasisMarkForCombinedText();
    else
      paintInternal<PaintEmphasisMark>(startOffset, endOffset, length);
  }
}

// static
void TextPainter::updateGraphicsContext(GraphicsContext& context,
                                        const Style& textStyle,
                                        bool horizontal,
                                        GraphicsContextStateSaver& stateSaver) {
  TextDrawingModeFlags mode = context.textDrawingMode();
  if (textStyle.strokeWidth > 0) {
    TextDrawingModeFlags newMode = mode | TextModeStroke;
    if (mode != newMode) {
      if (!stateSaver.saved())
        stateSaver.save();
      context.setTextDrawingMode(newMode);
      mode = newMode;
    }
  }

  if (mode & TextModeFill && textStyle.fillColor != context.fillColor())
    context.setFillColor(textStyle.fillColor);

  if (mode & TextModeStroke) {
    if (textStyle.strokeColor != context.strokeColor())
      context.setStrokeColor(textStyle.strokeColor);
    if (textStyle.strokeWidth != context.strokeThickness())
      context.setStrokeThickness(textStyle.strokeWidth);
  }

  if (textStyle.shadow) {
    if (!stateSaver.saved())
      stateSaver.save();
    context.setDrawLooper(textStyle.shadow->createDrawLooper(
        DrawLooperBuilder::ShadowIgnoresAlpha, textStyle.currentColor,
        horizontal));
  }
}

Color TextPainter::textColorForWhiteBackground(Color textColor) {
  int distanceFromWhite = differenceSquared(textColor, Color::white);
  // semi-arbitrarily chose 65025 (255^2) value here after a few tests;
  return distanceFromWhite > 65025 ? textColor : textColor.dark();
}

// static
TextPainter::Style TextPainter::textPaintingStyle(LineLayoutItem lineLayoutItem,
                                                  const ComputedStyle& style,
                                                  const PaintInfo& paintInfo) {
  TextPainter::Style textStyle;
  bool isPrinting = paintInfo.isPrinting();

  if (paintInfo.phase == PaintPhaseTextClip) {
    // When we use the text as a clip, we only care about the alpha, thus we
    // make all the colors black.
    textStyle.currentColor = Color::black;
    textStyle.fillColor = Color::black;
    textStyle.strokeColor = Color::black;
    textStyle.emphasisMarkColor = Color::black;
    textStyle.strokeWidth = style.textStrokeWidth();
    textStyle.shadow = 0;
  } else {
    textStyle.currentColor = style.visitedDependentColor(CSSPropertyColor);
    textStyle.fillColor =
        lineLayoutItem.resolveColor(style, CSSPropertyWebkitTextFillColor);
    textStyle.strokeColor =
        lineLayoutItem.resolveColor(style, CSSPropertyWebkitTextStrokeColor);
    textStyle.emphasisMarkColor =
        lineLayoutItem.resolveColor(style, CSSPropertyWebkitTextEmphasisColor);
    textStyle.strokeWidth = style.textStrokeWidth();
    textStyle.shadow = style.textShadow();

    // Adjust text color when printing with a white background.
    DCHECK(lineLayoutItem.document().printing() == isPrinting);
    bool forceBackgroundToWhite =
        BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(
            style, lineLayoutItem.document());
    if (forceBackgroundToWhite) {
      textStyle.fillColor = textColorForWhiteBackground(textStyle.fillColor);
      textStyle.strokeColor =
          textColorForWhiteBackground(textStyle.strokeColor);
      textStyle.emphasisMarkColor =
          textColorForWhiteBackground(textStyle.emphasisMarkColor);
    }

    // Text shadows are disabled when printing. http://crbug.com/258321
    if (isPrinting)
      textStyle.shadow = 0;
  }

  return textStyle;
}

TextPainter::Style TextPainter::selectionPaintingStyle(
    LineLayoutItem lineLayoutItem,
    bool haveSelection,
    const PaintInfo& paintInfo,
    const TextPainter::Style& textStyle) {
  const LayoutObject& layoutObject =
      *LineLayoutAPIShim::constLayoutObjectFrom(lineLayoutItem);
  TextPainter::Style selectionStyle = textStyle;
  bool usesTextAsClip = paintInfo.phase == PaintPhaseTextClip;
  bool isPrinting = paintInfo.isPrinting();

  if (haveSelection) {
    if (!usesTextAsClip) {
      selectionStyle.fillColor = layoutObject.selectionForegroundColor(
          paintInfo.getGlobalPaintFlags());
      selectionStyle.emphasisMarkColor =
          layoutObject.selectionEmphasisMarkColor(
              paintInfo.getGlobalPaintFlags());
    }

    if (const ComputedStyle* pseudoStyle =
            layoutObject.getCachedPseudoStyle(PseudoIdSelection)) {
      selectionStyle.strokeColor =
          usesTextAsClip ? Color::black
                         : layoutObject.resolveColor(
                               *pseudoStyle, CSSPropertyWebkitTextStrokeColor);
      selectionStyle.strokeWidth = pseudoStyle->textStrokeWidth();
      selectionStyle.shadow = usesTextAsClip ? 0 : pseudoStyle->textShadow();
    }

    // Text shadows are disabled when printing. http://crbug.com/258321
    if (isPrinting)
      selectionStyle.shadow = 0;
  }

  return selectionStyle;
}

template <TextPainter::PaintInternalStep step>
void TextPainter::paintInternalRun(TextRunPaintInfo& textRunPaintInfo,
                                   unsigned from,
                                   unsigned to) {
  DCHECK(from <= textRunPaintInfo.run.length());
  DCHECK(to <= textRunPaintInfo.run.length());

  textRunPaintInfo.from = from;
  textRunPaintInfo.to = to;

  if (step == PaintEmphasisMark) {
    m_graphicsContext.drawEmphasisMarks(
        m_font, textRunPaintInfo, m_emphasisMark,
        FloatPoint(m_textOrigin) + IntSize(0, m_emphasisMarkOffset));
  } else {
    DCHECK(step == PaintText);
    m_graphicsContext.drawText(m_font, textRunPaintInfo,
                               FloatPoint(m_textOrigin));
  }
}

template <TextPainter::PaintInternalStep Step>
void TextPainter::paintInternal(unsigned startOffset,
                                unsigned endOffset,
                                unsigned truncationPoint,
                                TextBlobPtr* cachedTextBlob) {
  TextRunPaintInfo textRunPaintInfo(m_run);
  textRunPaintInfo.bounds = FloatRect(m_textBounds);
  if (startOffset <= endOffset) {
    // FIXME: We should be able to use cachedTextBlob in more cases.
    textRunPaintInfo.cachedTextBlob = cachedTextBlob;
    paintInternalRun<Step>(textRunPaintInfo, startOffset, endOffset);
  } else {
    if (endOffset > 0)
      paintInternalRun<Step>(textRunPaintInfo, 0, endOffset);
    if (startOffset < truncationPoint)
      paintInternalRun<Step>(textRunPaintInfo, startOffset, truncationPoint);
  }
}

void TextPainter::clipDecorationsStripe(float upper,
                                        float stripeWidth,
                                        float dilation) {
  TextRunPaintInfo textRunPaintInfo(m_run);

  if (!m_run.length())
    return;

  Vector<Font::TextIntercept> textIntercepts;
  m_font.getTextIntercepts(
      textRunPaintInfo, m_graphicsContext.deviceScaleFactor(),
      m_graphicsContext.fillPaint(),
      std::make_tuple(upper, upper + stripeWidth), textIntercepts);

  for (auto intercept : textIntercepts) {
    FloatPoint clipOrigin(m_textOrigin);
    FloatRect clipRect(
        clipOrigin + FloatPoint(intercept.m_begin, upper),
        FloatSize(intercept.m_end - intercept.m_begin, stripeWidth));
    clipRect.inflateX(dilation);
    // We need to ensure the clip rectangle is covering the full underline
    // extent. For horizontal drawing, using enclosingIntRect would be
    // sufficient, since we can clamp to full device pixels that way. However,
    // for vertical drawing, we have a transformation applied, which breaks the
    // integers-equal-device pixels assumption, so vertically inflating by 1
    // pixel makes sure we're always covering. This should only be done on the
    // clipping rectangle, not when computing the glyph intersects.
    clipRect.inflateY(1.0);
    m_graphicsContext.clipOut(clipRect);
  }
}

void TextPainter::paintEmphasisMarkForCombinedText() {
  const SimpleFontData* fontData = m_font.primaryFont();
  DCHECK(fontData);
  if (!fontData)
    return;

  DCHECK(m_combinedText);
  TextRun placeholderTextRun(&ideographicFullStopCharacter, 1);
  FloatPoint emphasisMarkTextOrigin(m_textBounds.x().toFloat(),
                                    m_textBounds.y().toFloat() +
                                        fontData->getFontMetrics().ascent() +
                                        m_emphasisMarkOffset);
  TextRunPaintInfo textRunPaintInfo(placeholderTextRun);
  textRunPaintInfo.bounds = FloatRect(m_textBounds);
  m_graphicsContext.concatCTM(rotation(m_textBounds, Clockwise));
  m_graphicsContext.drawEmphasisMarks(m_combinedText->originalFont(),
                                      textRunPaintInfo, m_emphasisMark,
                                      emphasisMarkTextOrigin);
  m_graphicsContext.concatCTM(rotation(m_textBounds, Counterclockwise));
}

}  // namespace blink
