// Copyright 2016 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 "platform/fonts/shaping/ShapeResultBuffer.h"

#include "platform/fonts/CharacterRange.h"
#include "platform/fonts/GlyphBuffer.h"
#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/shaping/ShapeResultInlineHeaders.h"
#include "platform/geometry/FloatPoint.h"
#include "platform/text/Character.h"
#include "platform/text/TextBreakIterator.h"
#include "platform/text/TextDirection.h"

namespace blink {

namespace {

inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer,
                             float advance,
                             hb_direction_t direction,
                             const SimpleFontData* fontData,
                             const HarfBuzzRunGlyphData& glyphData) {
  FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction)
                               ? FloatPoint(advance, 0)
                               : FloatPoint(0, advance);
  glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset);
}

inline void addEmphasisMark(GlyphBuffer* buffer,
                            const GlyphData* emphasisData,
                            FloatPoint glyphCenter,
                            float midGlyphOffset) {
  ASSERT(buffer);
  ASSERT(emphasisData);

  const SimpleFontData* emphasisFontData = emphasisData->fontData;
  ASSERT(emphasisFontData);

  bool isVertical = emphasisFontData->platformData().isVerticalAnyUpright() &&
                    emphasisFontData->verticalData();

  if (!isVertical) {
    buffer->add(emphasisData->glyph, emphasisFontData,
                midGlyphOffset - glyphCenter.x());
  } else {
    buffer->add(emphasisData->glyph, emphasisFontData,
                FloatPoint(-glyphCenter.x(), midGlyphOffset - glyphCenter.y()));
  }
}

inline unsigned countGraphemesInCluster(const UChar* str,
                                        unsigned strLength,
                                        uint16_t startIndex,
                                        uint16_t endIndex) {
  if (startIndex > endIndex) {
    uint16_t tempIndex = startIndex;
    startIndex = endIndex;
    endIndex = tempIndex;
  }
  uint16_t length = endIndex - startIndex;
  ASSERT(static_cast<unsigned>(startIndex + length) <= strLength);
  TextBreakIterator* cursorPosIterator =
      cursorMovementIterator(&str[startIndex], length);

  int cursorPos = cursorPosIterator->current();
  int numGraphemes = -1;
  while (0 <= cursorPos) {
    cursorPos = cursorPosIterator->next();
    numGraphemes++;
  }
  return std::max(0, numGraphemes);
}

}  // anonymous namespace

template <TextDirection direction>
float ShapeResultBuffer::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
                                               const ShapeResult::RunInfo* run,
                                               float initialAdvance,
                                               unsigned from,
                                               unsigned to,
                                               unsigned runOffset) {
  if (!run)
    return 0;
  float advanceSoFar = initialAdvance;
  const unsigned numGlyphs = run->m_glyphData.size();
  for (unsigned i = 0; i < numGlyphs; ++i) {
    const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
    uint16_t currentCharacterIndex =
        run->m_startIndex + glyphData.characterIndex + runOffset;
    if ((direction == TextDirection::Rtl && currentCharacterIndex >= to) ||
        (direction == TextDirection::Ltr && currentCharacterIndex < from)) {
      advanceSoFar += glyphData.advance;
    } else if ((direction == TextDirection::Rtl &&
                currentCharacterIndex >= from) ||
               (direction == TextDirection::Ltr &&
                currentCharacterIndex < to)) {
      addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction,
                       run->m_fontData.get(), glyphData);
      advanceSoFar += glyphData.advance;
    }
  }
  return advanceSoFar - initialAdvance;
}

float ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun(
    GlyphBuffer* glyphBuffer,
    const ShapeResult::RunInfo* run,
    const TextRun& textRun,
    const GlyphData* emphasisData,
    float initialAdvance,
    unsigned from,
    unsigned to,
    unsigned runOffset) {
  if (!run)
    return 0;

  unsigned graphemesInCluster = 1;
  float clusterAdvance = 0;

  FloatPoint glyphCenter =
      emphasisData->fontData->boundsForGlyph(emphasisData->glyph).center();

  TextDirection direction = textRun.direction();

  // A "cluster" in this context means a cluster as it is used by HarfBuzz:
  // The minimal group of characters and corresponding glyphs, that cannot be
  // broken down further from a text shaping point of view.  A cluster can
  // contain multiple glyphs and grapheme clusters, with mutually overlapping
  // boundaries. Below we count grapheme clusters per HarfBuzz clusters, then
  // linearly split the sum of corresponding glyph advances by the number of
  // grapheme clusters in order to find positions for emphasis mark drawing.
  uint16_t clusterStart = static_cast<uint16_t>(
      direction == TextDirection::Rtl
          ? run->m_startIndex + run->m_numCharacters + runOffset
          : run->glyphToCharacterIndex(0) + runOffset);

  float advanceSoFar = initialAdvance;
  const unsigned numGlyphs = run->m_glyphData.size();
  for (unsigned i = 0; i < numGlyphs; ++i) {
    const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
    uint16_t currentCharacterIndex =
        run->m_startIndex + glyphData.characterIndex + runOffset;
    bool isRunEnd = (i + 1 == numGlyphs);
    bool isClusterEnd =
        isRunEnd || (run->glyphToCharacterIndex(i + 1) + runOffset !=
                     currentCharacterIndex);

    if ((direction == TextDirection::Rtl && currentCharacterIndex >= to) ||
        (direction != TextDirection::Rtl && currentCharacterIndex < from)) {
      advanceSoFar += glyphData.advance;
      direction == TextDirection::Rtl ? --clusterStart : ++clusterStart;
      continue;
    }

    clusterAdvance += glyphData.advance;

    if (textRun.is8Bit()) {
      float glyphAdvanceX = glyphData.advance;
      if (Character::canReceiveTextEmphasis(textRun[currentCharacterIndex])) {
        addEmphasisMark(glyphBuffer, emphasisData, glyphCenter,
                        advanceSoFar + glyphAdvanceX / 2);
      }
      advanceSoFar += glyphAdvanceX;
    } else if (isClusterEnd) {
      uint16_t clusterEnd;
      if (direction == TextDirection::Rtl)
        clusterEnd = currentCharacterIndex;
      else
        clusterEnd = static_cast<uint16_t>(
            isRunEnd ? run->m_startIndex + run->m_numCharacters + runOffset
                     : run->glyphToCharacterIndex(i + 1) + runOffset);

      graphemesInCluster = countGraphemesInCluster(textRun.characters16(),
                                                   textRun.charactersLength(),
                                                   clusterStart, clusterEnd);
      if (!graphemesInCluster || !clusterAdvance)
        continue;

      float glyphAdvanceX = clusterAdvance / graphemesInCluster;
      for (unsigned j = 0; j < graphemesInCluster; ++j) {
        // Do not put emphasis marks on space, separator, and control
        // characters.
        if (Character::canReceiveTextEmphasis(textRun[currentCharacterIndex]))
          addEmphasisMark(glyphBuffer, emphasisData, glyphCenter,
                          advanceSoFar + glyphAdvanceX / 2);
        advanceSoFar += glyphAdvanceX;
      }
      clusterStart = clusterEnd;
      clusterAdvance = 0;
    }
  }
  return advanceSoFar - initialAdvance;
}

float ShapeResultBuffer::fillFastHorizontalGlyphBuffer(
    GlyphBuffer* glyphBuffer,
    TextDirection dir) const {
  ASSERT(!hasVerticalOffsets());

  float advance = 0;

  for (unsigned i = 0; i < m_results.size(); ++i) {
    const auto& wordResult = isLeftToRightDirection(dir)
                                 ? m_results[i]
                                 : m_results[m_results.size() - 1 - i];
    ASSERT(!wordResult->hasVerticalOffsets());

    for (const auto& run : wordResult->m_runs) {
      ASSERT(run);
      ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction));

      for (const auto& glyphData : run->m_glyphData) {
        ASSERT(!glyphData.offset.height());

        glyphBuffer->add(glyphData.glyph, run->m_fontData.get(),
                         advance + glyphData.offset.width());
        advance += glyphData.advance;
      }
    }
  }

  ASSERT(!glyphBuffer->hasVerticalOffsets());

  return advance;
}

float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer,
                                         const TextRun& textRun,
                                         unsigned from,
                                         unsigned to) const {
  // Fast path: full run with no vertical offsets
  if (!from && to == textRun.length() && !hasVerticalOffsets())
    return fillFastHorizontalGlyphBuffer(glyphBuffer, textRun.direction());

  float advance = 0;

  if (textRun.rtl()) {
    unsigned wordOffset = textRun.length();
    for (unsigned j = 0; j < m_results.size(); j++) {
      unsigned resolvedIndex = m_results.size() - 1 - j;
      const RefPtr<const ShapeResult>& wordResult = m_results[resolvedIndex];
      for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
        advance += fillGlyphBufferForRun<TextDirection::Rtl>(
            glyphBuffer, wordResult->m_runs[i].get(), advance, from, to,
            wordOffset - wordResult->numCharacters());
      }
      wordOffset -= wordResult->numCharacters();
    }
  } else {
    unsigned wordOffset = 0;
    for (unsigned j = 0; j < m_results.size(); j++) {
      const RefPtr<const ShapeResult>& wordResult = m_results[j];
      for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
        advance += fillGlyphBufferForRun<TextDirection::Ltr>(
            glyphBuffer, wordResult->m_runs[i].get(), advance, from, to,
            wordOffset);
      }
      wordOffset += wordResult->numCharacters();
    }
  }

  return advance;
}

float ShapeResultBuffer::fillGlyphBufferForTextEmphasis(
    GlyphBuffer* glyphBuffer,
    const TextRun& textRun,
    const GlyphData* emphasisData,
    unsigned from,
    unsigned to) const {
  float advance = 0;
  unsigned wordOffset = textRun.rtl() ? textRun.length() : 0;

  for (unsigned j = 0; j < m_results.size(); j++) {
    unsigned resolvedIndex = textRun.rtl() ? m_results.size() - 1 - j : j;
    const RefPtr<const ShapeResult>& wordResult = m_results[resolvedIndex];
    for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
      unsigned resolvedOffset =
          wordOffset - (textRun.rtl() ? wordResult->numCharacters() : 0);
      advance += fillGlyphBufferForTextEmphasisRun(
          glyphBuffer, wordResult->m_runs[i].get(), textRun, emphasisData,
          advance, from, to, resolvedOffset);
    }
    wordOffset += wordResult->numCharacters() * (textRun.rtl() ? -1 : 1);
  }

  return advance;
}

CharacterRange ShapeResultBuffer::getCharacterRange(TextDirection direction,
                                                    float totalWidth,
                                                    unsigned absoluteFrom,
                                                    unsigned absoluteTo) const {
  float currentX = 0;
  float fromX = 0;
  float toX = 0;
  bool foundFromX = false;
  bool foundToX = false;

  if (direction == TextDirection::Rtl)
    currentX = totalWidth;

  // The absoluteFrom and absoluteTo arguments represent the start/end offset
  // for the entire run, from/to are continuously updated to be relative to
  // the current word (ShapeResult instance).
  int from = absoluteFrom;
  int to = absoluteTo;

  unsigned totalNumCharacters = 0;
  for (unsigned j = 0; j < m_results.size(); j++) {
    const RefPtr<const ShapeResult> result = m_results[j];
    if (direction == TextDirection::Rtl) {
      // Convert logical offsets to visual offsets, because results are in
      // logical order while runs are in visual order.
      if (!foundFromX && from >= 0 &&
          static_cast<unsigned>(from) < result->numCharacters())
        from = result->numCharacters() - from - 1;
      if (!foundToX && to >= 0 &&
          static_cast<unsigned>(to) < result->numCharacters())
        to = result->numCharacters() - to - 1;
      currentX -= result->width();
    }
    for (unsigned i = 0; i < result->m_runs.size(); i++) {
      if (!result->m_runs[i])
        continue;
      DCHECK_EQ(direction == TextDirection::Rtl, result->m_runs[i]->rtl());
      int numCharacters = result->m_runs[i]->m_numCharacters;
      if (!foundFromX && from >= 0 && from < numCharacters) {
        fromX =
            result->m_runs[i]->xPositionForVisualOffset(from, AdjustToStart) +
            currentX;
        foundFromX = true;
      } else {
        from -= numCharacters;
      }

      if (!foundToX && to >= 0 && to < numCharacters) {
        toX = result->m_runs[i]->xPositionForVisualOffset(to, AdjustToEnd) +
              currentX;
        foundToX = true;
      } else {
        to -= numCharacters;
      }

      if (foundFromX && foundToX)
        break;
      currentX += result->m_runs[i]->m_width;
    }
    if (direction == TextDirection::Rtl)
      currentX -= result->width();
    totalNumCharacters += result->numCharacters();
  }

  // The position in question might be just after the text.
  if (!foundFromX && absoluteFrom == totalNumCharacters) {
    fromX = direction == TextDirection::Rtl ? 0 : totalWidth;
    foundFromX = true;
  }
  if (!foundToX && absoluteTo == totalNumCharacters) {
    toX = direction == TextDirection::Rtl ? 0 : totalWidth;
    foundToX = true;
  }
  if (!foundFromX)
    fromX = 0;
  if (!foundToX)
    toX = direction == TextDirection::Rtl ? 0 : totalWidth;

  // None of our runs is part of the selection, possibly invalid arguments.
  if (!foundToX && !foundFromX)
    fromX = toX = 0;
  if (fromX < toX)
    return CharacterRange(fromX, toX);
  return CharacterRange(toX, fromX);
}

void ShapeResultBuffer::addRunInfoRanges(const ShapeResult::RunInfo& runInfo,
                                         float offset,
                                         Vector<CharacterRange>& ranges) {
  Vector<float> characterWidths(runInfo.m_numCharacters);
  for (const auto& glyph : runInfo.m_glyphData)
    characterWidths[glyph.characterIndex] += glyph.advance;

  for (unsigned characterIndex = 0; characterIndex < runInfo.m_numCharacters;
       characterIndex++) {
    float start = offset;
    offset += characterWidths[characterIndex];
    float end = offset;

    // To match getCharacterRange we flip ranges to ensure start <= end.
    if (end < start)
      ranges.append(CharacterRange(end, start));
    else
      ranges.append(CharacterRange(start, end));
  }
}

Vector<CharacterRange> ShapeResultBuffer::individualCharacterRanges(
    TextDirection direction,
    float totalWidth) const {
  Vector<CharacterRange> ranges;
  float currentX = direction == TextDirection::Rtl ? totalWidth : 0;
  for (const RefPtr<const ShapeResult> result : m_results) {
    if (direction == TextDirection::Rtl)
      currentX -= result->width();
    unsigned runCount = result->m_runs.size();
    for (unsigned index = 0; index < runCount; index++) {
      unsigned runIndex =
          direction == TextDirection::Rtl ? runCount - 1 - index : index;
      addRunInfoRanges(*result->m_runs[runIndex], currentX, ranges);
      currentX += result->m_runs[runIndex]->m_width;
    }
    if (direction == TextDirection::Rtl)
      currentX -= result->width();
  }
  return ranges;
}

int ShapeResultBuffer::offsetForPosition(const TextRun& run,
                                         float targetX,
                                         bool includePartialGlyphs) const {
  unsigned totalOffset;
  if (run.rtl()) {
    totalOffset = run.length();
    for (unsigned i = m_results.size(); i; --i) {
      const RefPtr<const ShapeResult>& wordResult = m_results[i - 1];
      if (!wordResult)
        continue;
      totalOffset -= wordResult->numCharacters();
      if (targetX >= 0 && targetX <= wordResult->width()) {
        int offsetForWord =
            wordResult->offsetForPosition(targetX, includePartialGlyphs);
        return totalOffset + offsetForWord;
      }
      targetX -= wordResult->width();
    }
  } else {
    totalOffset = 0;
    for (const auto& wordResult : m_results) {
      if (!wordResult)
        continue;
      int offsetForWord =
          wordResult->offsetForPosition(targetX, includePartialGlyphs);
      ASSERT(offsetForWord >= 0);
      totalOffset += offsetForWord;
      if (targetX >= 0 && targetX <= wordResult->width())
        return totalOffset;
      targetX -= wordResult->width();
    }
  }
  return totalOffset;
}

}  // namespace blink
