/*
 * Copyright (C) 2015 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "platform/fonts/shaping/CachingWordShaper.h"

#include "platform/fonts/CharacterRange.h"
#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/shaping/CachingWordShapeIterator.h"
#include "platform/fonts/shaping/HarfBuzzShaper.h"
#include "platform/fonts/shaping/ShapeCache.h"
#include "platform/fonts/shaping/ShapeResultBuffer.h"
#include "wtf/text/CharacterNames.h"

namespace blink {

ShapeCache* CachingWordShaper::shapeCache() const {
  return m_font.m_fontFallbackList->shapeCache(m_font.m_fontDescription);
}

float CachingWordShaper::width(const TextRun& run,
                               HashSet<const SimpleFontData*>* fallbackFonts,
                               FloatRect* glyphBounds) {
  float width = 0;
  RefPtr<const ShapeResult> wordResult;
  CachingWordShapeIterator iterator(shapeCache(), run, &m_font);
  while (iterator.next(&wordResult)) {
    if (wordResult) {
      if (glyphBounds) {
        FloatRect adjustedBounds = wordResult->bounds();
        // Translate glyph bounds to the current glyph position which
        // is the total width before this glyph.
        adjustedBounds.setX(adjustedBounds.x() + width);
        glyphBounds->unite(adjustedBounds);
      }
      width += wordResult->width();
      if (fallbackFonts)
        wordResult->fallbackFonts(fallbackFonts);
    }
  }

  return width;
}

static inline float shapeResultsForRun(
    ShapeCache* shapeCache,
    const Font* font,
    const TextRun& run,
    ShapeResultBuffer* resultsBuffer) {
  CachingWordShapeIterator iterator(shapeCache, run, font);
  RefPtr<const ShapeResult> wordResult;
  float totalWidth = 0;
  while (iterator.next(&wordResult)) {
    if (wordResult) {
      totalWidth += wordResult->width();
      resultsBuffer->appendResult(std::move(wordResult));
    }
  }
  return totalWidth;
}

int CachingWordShaper::offsetForPosition(const TextRun& run,
                                         float targetX,
                                         bool includePartialGlyphs) {
  ShapeResultBuffer buffer;
  shapeResultsForRun(shapeCache(), &m_font, run, &buffer);

  return buffer.offsetForPosition(run, targetX, includePartialGlyphs);
}

float CachingWordShaper::fillGlyphBuffer(
    const TextRun& run,
    GlyphBuffer* glyphBuffer,
    unsigned from,
    unsigned to) {
  ShapeResultBuffer buffer;
  shapeResultsForRun(shapeCache(), &m_font, run, &buffer);

  return buffer.fillGlyphBuffer(glyphBuffer, run, from, to);
}

float CachingWordShaper::fillGlyphBufferForTextEmphasis(
    const TextRun& run,
    const GlyphData* emphasisData,
    GlyphBuffer* glyphBuffer,
    unsigned from,
    unsigned to) {
  ShapeResultBuffer buffer;
  shapeResultsForRun(shapeCache(), &m_font, run, &buffer);

  return buffer.fillGlyphBufferForTextEmphasis(glyphBuffer, run, emphasisData,
                                               from, to);
}

CharacterRange CachingWordShaper::getCharacterRange(const TextRun& run,
                                                    unsigned from,
                                                    unsigned to) {
  ShapeResultBuffer buffer;
  float totalWidth =
      shapeResultsForRun(shapeCache(), &m_font, run, &buffer);

  return buffer.getCharacterRange(run.direction(), totalWidth, from, to);
}

Vector<CharacterRange> CachingWordShaper::individualCharacterRanges(
    const TextRun& run) {
  ShapeResultBuffer buffer;
  float totalWidth =
      shapeResultsForRun(shapeCache(), &m_font, run, &buffer);

  auto ranges = buffer.individualCharacterRanges(run.direction(), totalWidth);
  // The shaper can fail to return glyph metrics for all characters (see
  // crbug.com/613915 and crbug.com/615661) so add empty ranges to ensure all
  // characters have an associated range.
  while (ranges.size() < static_cast<unsigned>(run.length()))
    ranges.push_back(CharacterRange(0, 0));
  return ranges;
}

Vector<ShapeResultBuffer::RunFontData> CachingWordShaper::runFontData(
      const TextRun& run) const {
  ShapeResultBuffer buffer;
  shapeResultsForRun(shapeCache(), &m_font, run, &buffer);

  return buffer.runFontData();
}

};  // namespace blink
