/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "platform/fonts/Font.h"

#include "platform/LayoutTestSupport.h"
#include "platform/LayoutUnit.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/fonts/CharacterRange.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/FontFallbackIterator.h"
#include "platform/fonts/FontFallbackList.h"
#include "platform/fonts/GlyphBuffer.h"
#include "platform/fonts/GlyphPageTreeNode.h"
#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/shaping/CachingWordShaper.h"
#include "platform/fonts/shaping/HarfBuzzFace.h"
#include "platform/fonts/shaping/HarfBuzzShaper.h"
#include "platform/fonts/shaping/SimpleShaper.h"
#include "platform/geometry/FloatRect.h"
#include "platform/text/BidiResolver.h"
#include "platform/text/Character.h"
#include "platform/text/TextRun.h"
#include "platform/text/TextRunIterator.h"
#include "platform/transforms/AffineTransform.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/CharacterNames.h"
#include "wtf/text/Unicode.h"

using namespace WTF;
using namespace Unicode;

namespace blink {

Font::Font() : m_canShapeWordByWord(0), m_shapeWordByWordComputed(0) {}

Font::Font(const FontDescription& fd)
    : m_fontDescription(fd),
      m_canShapeWordByWord(0),
      m_shapeWordByWordComputed(0) {}

Font::Font(const Font& other)
    : m_fontDescription(other.m_fontDescription),
      m_fontFallbackList(other.m_fontFallbackList),
      // TODO(yosin): We should have a comment the reason why don't we copy
      // |m_canShapeWordByWord| and |m_shapeWordByWordComputed| from |other|,
      // since |operator=()| copies them from |other|.
      m_canShapeWordByWord(0),
      m_shapeWordByWordComputed(0) {}

Font& Font::operator=(const Font& other) {
  m_fontDescription = other.m_fontDescription;
  m_fontFallbackList = other.m_fontFallbackList;
  m_canShapeWordByWord = other.m_canShapeWordByWord;
  m_shapeWordByWordComputed = other.m_shapeWordByWordComputed;
  return *this;
}

bool Font::operator==(const Font& other) const {
  FontSelector* first =
      m_fontFallbackList ? m_fontFallbackList->getFontSelector() : 0;
  FontSelector* second = other.m_fontFallbackList
                             ? other.m_fontFallbackList->getFontSelector()
                             : 0;

  return first == second && m_fontDescription == other.m_fontDescription &&
         (m_fontFallbackList ? m_fontFallbackList->fontSelectorVersion() : 0) ==
             (other.m_fontFallbackList
                  ? other.m_fontFallbackList->fontSelectorVersion()
                  : 0) &&
         (m_fontFallbackList ? m_fontFallbackList->generation() : 0) ==
             (other.m_fontFallbackList ? other.m_fontFallbackList->generation()
                                       : 0);
}

void Font::update(FontSelector* fontSelector) const {
  // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr,
  // but it ends up being reasonably safe (because inherited fonts in the render
  // tree pick up the new style anyway. Other copies are transient, e.g., the
  // state in the GraphicsContext, and won't stick around long enough to get you
  // in trouble). Still, this is pretty disgusting, and could eventually be
  // rectified by using RefPtrs for Fonts themselves.
  if (!m_fontFallbackList)
    m_fontFallbackList = FontFallbackList::create();
  m_fontFallbackList->invalidate(fontSelector);
}

float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo,
                             GlyphBuffer& glyphBuffer,
                             const GlyphData* emphasisData) const {
  if (codePath(runInfo) == ComplexPath) {
    float width;
    CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
    if (emphasisData) {
      width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run,
                                                    emphasisData, &glyphBuffer,
                                                    runInfo.from, runInfo.to);
    } else {
      width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr, &glyphBuffer,
                                     runInfo.from, runInfo.to);
    }

    return width;
  }

  SimpleShaper shaper(this, runInfo.run, emphasisData,
                      nullptr /* fallbackFonts */, nullptr);
  shaper.advance(runInfo.from);
  shaper.advance(runInfo.to, &glyphBuffer);
  float width = shaper.runWidthSoFar();

  if (runInfo.run.rtl()) {
    // Glyphs are shaped & stored in RTL advance order - reverse them for LTR
    // drawing.
    shaper.advance(runInfo.run.length());
    glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar());
  }

  return width;
}

bool Font::drawText(SkCanvas* canvas,
                    const TextRunPaintInfo& runInfo,
                    const FloatPoint& point,
                    float deviceScaleFactor,
                    const SkPaint& paint) const {
  // Don't draw anything while we are using custom fonts that are in the process
  // of loading.
  if (shouldSkipDrawing())
    return false;

  if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) {
    // we have a pre-cached blob -- happy joy!
    canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(),
                         paint);
    return true;
  }

  GlyphBuffer glyphBuffer;
  buildGlyphBuffer(runInfo, glyphBuffer);

  drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point,
                  deviceScaleFactor);
  return true;
}

bool Font::drawBidiText(SkCanvas* canvas,
                        const TextRunPaintInfo& runInfo,
                        const FloatPoint& point,
                        CustomFontNotReadyAction customFontNotReadyAction,
                        float deviceScaleFactor,
                        const SkPaint& paint) const {
  // Don't draw anything while we are using custom fonts that are in the process
  // of loading, except if the 'force' argument is set to true (in which case it
  // will use a fallback font).
  if (shouldSkipDrawing() &&
      customFontNotReadyAction == DoNotPaintIfFontNotReady)
    return false;

  // sub-run painting is not supported for Bidi text.
  const TextRun& run = runInfo.run;
  ASSERT((runInfo.from == 0) && (runInfo.to == run.length()));
  BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
  bidiResolver.setStatus(
      BidiStatus(run.direction(), run.directionalOverride()));
  bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0));

  // FIXME: This ownership should be reversed. We should pass BidiRunList
  // to BidiResolver in createBidiRunsForLine.
  BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs();
  bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length()));
  if (!bidiRuns.runCount())
    return true;

  FloatPoint currPoint = point;
  BidiCharacterRun* bidiRun = bidiRuns.firstRun();
  while (bidiRun) {
    TextRun subrun =
        run.subRun(bidiRun->start(), bidiRun->stop() - bidiRun->start());
    bool isRTL = bidiRun->level() % 2;
    subrun.setDirection(isRTL ? RTL : LTR);
    subrun.setDirectionalOverride(bidiRun->dirOverride(false));

    TextRunPaintInfo subrunInfo(subrun);
    subrunInfo.bounds = runInfo.bounds;

    // TODO: investigate blob consolidation/caching (technically,
    //       all subruns could be part of the same blob).
    GlyphBuffer glyphBuffer;
    float runWidth = buildGlyphBuffer(subrunInfo, glyphBuffer);
    drawGlyphBuffer(canvas, paint, subrunInfo, glyphBuffer, currPoint,
                    deviceScaleFactor);

    bidiRun = bidiRun->next();
    currPoint.move(runWidth, 0);
  }

  bidiRuns.deleteRuns();
  return true;
}

void Font::drawEmphasisMarks(SkCanvas* canvas,
                             const TextRunPaintInfo& runInfo,
                             const AtomicString& mark,
                             const FloatPoint& point,
                             float deviceScaleFactor,
                             const SkPaint& paint) const {
  if (shouldSkipDrawing())
    return;

  FontCachePurgePreventer purgePreventer;

  GlyphData emphasisGlyphData;
  if (!getEmphasisMarkGlyphData(mark, emphasisGlyphData))
    return;

  ASSERT(emphasisGlyphData.fontData);
  if (!emphasisGlyphData.fontData)
    return;

  GlyphBuffer glyphBuffer;
  buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData);

  if (glyphBuffer.isEmpty())
    return;

  drawGlyphBuffer(canvas, paint, runInfo, glyphBuffer, point,
                  deviceScaleFactor);
}

float Font::width(const TextRun& run,
                  HashSet<const SimpleFontData*>* fallbackFonts,
                  FloatRect* glyphBounds) const {
  FontCachePurgePreventer purgePreventer;

  if (codePath(TextRunPaintInfo(run)) == ComplexPath)
    return floatWidthForComplexText(run, fallbackFonts, glyphBounds);
  return floatWidthForSimpleText(run, fallbackFonts, glyphBounds);
}

namespace {

enum BlobRotation {
  NoRotation,
  CCWRotation,
};

class GlyphBufferBloberizer {
  STACK_ALLOCATED()
 public:
  GlyphBufferBloberizer(const GlyphBuffer& buffer,
                        const Font* font,
                        float deviceScaleFactor)
      : m_buffer(buffer),
        m_font(font),
        m_deviceScaleFactor(deviceScaleFactor),
        m_hasVerticalOffsets(buffer.hasVerticalOffsets()),
        m_index(0),
        m_blobCount(0),
        m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation(
                                                       buffer.fontDataAt(0))) {}

  bool done() const { return m_index >= m_buffer.size(); }
  unsigned blobCount() const { return m_blobCount; }

  std::pair<sk_sp<SkTextBlob>, BlobRotation> next() {
    ASSERT(!done());
    const BlobRotation currentRotation = m_rotation;

    while (m_index < m_buffer.size()) {
      const SimpleFontData* fontData = m_buffer.fontDataAt(m_index);
      ASSERT(fontData);

      const BlobRotation newRotation = computeBlobRotation(fontData);
      if (newRotation != m_rotation) {
        // We're switching to an orientation which requires a different rotation
        //   => emit the pending blob (and start a new one with the new
        //      rotation).
        m_rotation = newRotation;
        break;
      }

      const unsigned start = m_index++;
      while (m_index < m_buffer.size() &&
             m_buffer.fontDataAt(m_index) == fontData)
        m_index++;

      appendRun(start, m_index - start, fontData);
    }

    m_blobCount++;
    return std::make_pair(m_builder.make(), currentRotation);
  }

 private:
  static BlobRotation computeBlobRotation(const SimpleFontData* font) {
    // For vertical upright text we need to compensate the inherited 90deg CW
    // rotation (using a 90deg CCW rotation).
    return (font->platformData().isVerticalAnyUpright() && font->verticalData())
               ? CCWRotation
               : NoRotation;
  }

  void appendRun(unsigned start,
                 unsigned count,
                 const SimpleFontData* fontData) {
    SkPaint paint;
    fontData->platformData().setupPaint(&paint, m_deviceScaleFactor, m_font);
    paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

    const SkTextBlobBuilder::RunBuffer& buffer =
        m_hasVerticalOffsets ? m_builder.allocRunPos(paint, count)
                             : m_builder.allocRunPosH(paint, count, 0);

    const uint16_t* glyphs = m_buffer.glyphs(start);
    const float* offsets = m_buffer.offsets(start);
    std::copy(glyphs, glyphs + count, buffer.glyphs);

    if (m_rotation == NoRotation) {
      std::copy(offsets, offsets + (m_hasVerticalOffsets ? 2 * count : count),
                buffer.pos);
    } else {
      ASSERT(m_hasVerticalOffsets);

      const float verticalBaselineXOffset =
          fontData->getFontMetrics().floatAscent() -
          fontData->getFontMetrics().floatAscent(IdeographicBaseline);

      // TODO(fmalita): why don't we apply this adjustment when building the
      // glyph buffer?
      for (unsigned i = 0; i < 2 * count; i += 2) {
        buffer.pos[i] = SkFloatToScalar(offsets[i] + verticalBaselineXOffset);
        buffer.pos[i + 1] = SkFloatToScalar(offsets[i + 1]);
      }
    }
  }

  const GlyphBuffer& m_buffer;
  const Font* m_font;
  const float m_deviceScaleFactor;
  const bool m_hasVerticalOffsets;

  SkTextBlobBuilder m_builder;
  unsigned m_index;
  unsigned m_blobCount;
  BlobRotation m_rotation;
};

}  // anonymous namespace

void Font::drawGlyphBuffer(SkCanvas* canvas,
                           const SkPaint& paint,
                           const TextRunPaintInfo& runInfo,
                           const GlyphBuffer& glyphBuffer,
                           const FloatPoint& point,
                           float deviceScaleFactor) const {
  GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor);
  std::pair<sk_sp<SkTextBlob>, BlobRotation> blob;

  while (!bloberizer.done()) {
    blob = bloberizer.next();
    ASSERT(blob.first);

    SkAutoCanvasRestore autoRestore(canvas, false);
    if (blob.second == CCWRotation) {
      canvas->save();

      SkMatrix m;
      m.setSinCos(-1, 0, point.x(), point.y());
      canvas->concat(m);
    }

    canvas->drawTextBlob(blob.first, point.x(), point.y(), paint);
  }

  // Cache results when
  //   1) requested by clients, and
  //   2) the glyph buffer is encoded as a single blob, and
  //   3) the blob is not upright/rotated
  if (runInfo.cachedTextBlob && bloberizer.blobCount() == 1 &&
      blob.second == NoRotation) {
    ASSERT(!*runInfo.cachedTextBlob);
    *runInfo.cachedTextBlob = std::move(blob.first);
    ASSERT(*runInfo.cachedTextBlob);
  }
}

static inline FloatRect pixelSnappedSelectionRect(FloatRect rect) {
  // Using roundf() rather than ceilf() for the right edge as a compromise to
  // ensure correct caret positioning.
  float roundedX = roundf(rect.x());
  return FloatRect(roundedX, rect.y(), roundf(rect.maxX() - roundedX),
                   rect.height());
}

FloatRect Font::selectionRectForText(const TextRun& run,
                                     const FloatPoint& point,
                                     int h,
                                     int from,
                                     int to,
                                     bool accountForGlyphBounds) const {
  to = (to == -1 ? run.length() : to);

  TextRunPaintInfo runInfo(run);
  runInfo.from = from;
  runInfo.to = to;

  FontCachePurgePreventer purgePreventer;

  if (codePath(runInfo) != ComplexPath)
    return pixelSnappedSelectionRect(selectionRectForSimpleText(
        run, point, h, from, to, accountForGlyphBounds));
  return pixelSnappedSelectionRect(
      selectionRectForComplexText(run, point, h, from, to));
}

int Font::offsetForPosition(const TextRun& run,
                            float x,
                            bool includePartialGlyphs) const {
  FontCachePurgePreventer purgePreventer;

  if (codePath(TextRunPaintInfo(run)) != ComplexPath &&
      !getFontDescription().getTypesettingFeatures())
    return offsetForPositionForSimpleText(run, x, includePartialGlyphs);

  return offsetForPositionForComplexText(run, x, includePartialGlyphs);
}

CodePath Font::codePath(const TextRunPaintInfo& runInfo) const {
  if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled() ||
      LayoutTestSupport::alwaysUseComplexTextForTest()) {
    return ComplexPath;
  }

  const TextRun& run = runInfo.run;

  if (getFontDescription().getTypesettingFeatures())
    return ComplexPath;

  if (m_fontDescription.featureSettings() &&
      m_fontDescription.featureSettings()->size() > 0)
    return ComplexPath;

  if (m_fontDescription.isVerticalBaseline())
    return ComplexPath;

  if (m_fontDescription.widthVariant() != RegularWidth)
    return ComplexPath;

  // FIXME: This really shouldn't be needed but for some reason the
  // TextRendering setting doesn't propagate to typesettingFeatures in time
  // for the prefs width calculation.
  if (getFontDescription().textRendering() == OptimizeLegibility ||
      getFontDescription().textRendering() == GeometricPrecision)
    return ComplexPath;

  if (run.is8Bit())
    return SimplePath;

  // Start from 0 since drawing and highlighting also measure the characters
  // before run->from.
  return Character::characterRangeCodePath(run.characters16(), run.length());
}

bool Font::canShapeWordByWord() const {
  if (!m_shapeWordByWordComputed) {
    m_canShapeWordByWord = computeCanShapeWordByWord();
    m_shapeWordByWordComputed = true;
  }
  return m_canShapeWordByWord;
};

bool Font::computeCanShapeWordByWord() const {
  if (!getFontDescription().getTypesettingFeatures())
    return true;

  if (!primaryFont())
    return false;

  const FontPlatformData& platformData = primaryFont()->platformData();
  TypesettingFeatures features = getFontDescription().getTypesettingFeatures();
  return !platformData.hasSpaceInLigaturesOrKerning(features);
};

void Font::willUseFontData(const String& text) const {
  const FontFamily& family = getFontDescription().family();
  if (m_fontFallbackList && m_fontFallbackList->getFontSelector() &&
      !family.familyIsEmpty())
    m_fontFallbackList->getFontSelector()->willUseFontData(
        getFontDescription(), family.family(), text);
}

static inline GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation(
    UChar32 character,
    bool isUpright,
    GlyphData& data,
    unsigned pageNumber) {
  if (isUpright) {
    RefPtr<SimpleFontData> uprightFontData =
        data.fontData->uprightOrientationFontData();
    GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getNormalRootChild(
        uprightFontData.get(), pageNumber);
    GlyphPage* uprightPage = uprightNode->page();
    if (uprightPage) {
      GlyphData uprightData = uprightPage->glyphDataForCharacter(character);
      // If the glyphs are the same, then we know we can just use the horizontal
      // glyph rotated vertically to be upright.
      if (data.glyph == uprightData.glyph)
        return data;
      // The glyphs are distinct, meaning that the font has a vertical-right
      // glyph baked into it. We can't use that glyph, so we fall back to the
      // upright data and use the horizontal glyph.
      if (uprightData.fontData)
        return uprightData;
    }
  } else {
    RefPtr<SimpleFontData> verticalRightFontData =
        data.fontData->verticalRightOrientationFontData();
    GlyphPageTreeNode* verticalRightNode =
        GlyphPageTreeNode::getNormalRootChild(verticalRightFontData.get(),
                                              pageNumber);
    GlyphPage* verticalRightPage = verticalRightNode->page();
    if (verticalRightPage) {
      GlyphData verticalRightData =
          verticalRightPage->glyphDataForCharacter(character);
      // If the glyphs are distinct, we will make the assumption that the font
      // has a vertical-right glyph baked into it.
      if (data.glyph != verticalRightData.glyph)
        return data;
      // The glyphs are identical, meaning that we should just use the
      // horizontal glyph.
      if (verticalRightData.fontData)
        return verticalRightData;
    }
  }
  return data;
}

PassRefPtr<FontFallbackIterator> Font::createFontFallbackIterator(
    FontFallbackPriority fallbackPriority) const {
  return FontFallbackIterator::create(m_fontDescription, m_fontFallbackList,
                                      fallbackPriority);
}

GlyphData Font::glyphDataForCharacter(UChar32& c,
                                      bool mirror,
                                      bool normalizeSpace,
                                      FontDataVariant variant) const {
  ASSERT(isMainThread());

  if (variant == AutoVariant) {
    if (m_fontDescription.variantCaps() == FontDescription::SmallCaps) {
      UChar32 upperC =
          toUpper(c, LayoutLocale::localeString(m_fontDescription.locale()));
      if (upperC != c) {
        c = upperC;
        variant = SmallCapsVariant;
      } else {
        variant = NormalVariant;
      }
    } else {
      variant = NormalVariant;
    }
  }

  if (normalizeSpace && Character::isNormalizedCanvasSpaceCharacter(c))
    c = spaceCharacter;

  if (mirror)
    c = mirroredChar(c);

  unsigned pageNumber = (c / GlyphPage::size);

  GlyphPageTreeNodeBase* node = m_fontFallbackList->getPageNode(pageNumber);
  if (!node) {
    node = GlyphPageTreeNode::getRootChild(fontDataAt(0), pageNumber);
    m_fontFallbackList->setPageNode(pageNumber, node);
  }
  RELEASE_ASSERT(node);  // Diagnosing crbug.com/446566 crash bug.

  GlyphPage* page = 0;
  if (variant == NormalVariant) {
    // Fastest loop, for the common case (normal variant).
    while (true) {
      page = node->page(m_fontDescription.script());
      if (page) {
        GlyphData data = page->glyphDataForCharacter(c);
        if (data.fontData) {
          if (!data.fontData->platformData().isVerticalAnyUpright() ||
              data.fontData->isTextOrientationFallback())
            return data;

          bool isUpright = m_fontDescription.isVerticalUpright(c);
          if (!isUpright || !Character::isCJKIdeographOrSymbol(c))
            return glyphDataForNonCJKCharacterWithGlyphOrientation(
                c, isUpright, data, pageNumber);

          return data;
        }

        if (node->isSystemFallback())
          break;
      }

      // Proceed with the fallback list.
      node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()),
                                                 pageNumber);
      m_fontFallbackList->setPageNode(pageNumber, node);
    }
  }
  if (variant != NormalVariant) {
    while (true) {
      page = node->page(m_fontDescription.script());
      if (page) {
        GlyphData data = page->glyphDataForCharacter(c);
        if (data.fontData) {
          // The variantFontData function should not normally return 0.
          // But if it does, we will just render the capital letter big.
          RefPtr<SimpleFontData> variantFontData =
              data.fontData->variantFontData(m_fontDescription, variant);
          if (!variantFontData)
            return data;

          GlyphPageTreeNode* variantNode =
              GlyphPageTreeNode::getNormalRootChild(variantFontData.get(),
                                                    pageNumber);
          GlyphPage* variantPage = variantNode->page();
          if (variantPage) {
            GlyphData data = variantPage->glyphDataForCharacter(c);
            if (data.fontData)
              return data;
          }

          // Do not attempt system fallback off the variantFontData. This is the
          // very unlikely case that a font has the lowercase character but the
          // small caps font does not have its uppercase version.
          return variantFontData->missingGlyphData();
        }

        if (node->isSystemFallback())
          break;
      }

      // Proceed with the fallback list.
      node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()),
                                                 pageNumber);
      m_fontFallbackList->setPageNode(pageNumber, node);
    }
  }

  ASSERT(page);
  ASSERT(node->isSystemFallback());

  // System fallback is character-dependent. When we get here, we
  // know that the character in question isn't in the system fallback
  // font's glyph page. Try to lazily create it here.

  // FIXME: Unclear if this should normalizeSpaces above 0xFFFF.
  // Doing so changes fast/text/international/plane2-diffs.html
  UChar32 characterToRender = c;
  if (characterToRender <= 0xFFFF)
    characterToRender = Character::normalizeSpaces(characterToRender);

  const FontData* fontData = fontDataAt(0);
  if (fontData) {
    const SimpleFontData* fontDataToSubstitute =
        fontData->fontDataForCharacter(characterToRender);
    RefPtr<SimpleFontData> characterFontData =
        FontCache::fontCache()->fallbackFontForCharacter(
            m_fontDescription, characterToRender, fontDataToSubstitute);
    if (characterFontData && variant != NormalVariant) {
      characterFontData =
          characterFontData->variantFontData(m_fontDescription, variant);
    }
    if (characterFontData) {
      // Got the fallback glyph and font.
      unsigned pageNumberForRendering = characterToRender / GlyphPage::size;
      GlyphPage* fallbackPage =
          GlyphPageTreeNode::getRootChild(characterFontData.get(),
                                          pageNumberForRendering)
              ->page();
      GlyphData data =
          fallbackPage && fallbackPage->glyphForCharacter(characterToRender)
              ? fallbackPage->glyphDataForCharacter(characterToRender)
              : characterFontData->missingGlyphData();
      // Cache it so we don't have to do system fallback again next time.
      if (variant == NormalVariant) {
        page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
        data.fontData->setMaxGlyphPageTreeLevel(
            std::max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
        if (data.fontData->platformData().isVerticalAnyUpright() &&
            !data.fontData->isTextOrientationFallback() &&
            !Character::isCJKIdeographOrSymbol(characterToRender))
          return glyphDataForNonCJKCharacterWithGlyphOrientation(
              characterToRender,
              m_fontDescription.isVerticalUpright(characterToRender), data,
              pageNumberForRendering);
      }
      return data;
    }
  }

  // Even system fallback can fail; use the missing glyph in that case.
  // FIXME: It would be nicer to use the missing glyph from the last resort font
  // instead.
  ASSERT(primaryFont());
  GlyphData data = primaryFont()->missingGlyphData();
  if (variant == NormalVariant) {
    page->setGlyphDataForCharacter(c, data.glyph, data.fontData);
    data.fontData->setMaxGlyphPageTreeLevel(
        std::max(data.fontData->maxGlyphPageTreeLevel(), node->level()));
  }
  return data;
}

bool Font::getEmphasisMarkGlyphData(const AtomicString& mark,
                                    GlyphData& glyphData) const {
  if (mark.isEmpty())
    return false;

  TextRun emphasisMarkRun(mark, mark.length());
  TextRunPaintInfo emphasisPaintInfo(emphasisMarkRun);
  GlyphBuffer glyphBuffer;
  buildGlyphBuffer(emphasisPaintInfo, glyphBuffer);

  if (glyphBuffer.isEmpty())
    return false;

  ASSERT(glyphBuffer.fontDataAt(0));
  glyphData.fontData =
      glyphBuffer.fontDataAt(0)->emphasisMarkFontData(m_fontDescription).get();
  glyphData.glyph = glyphBuffer.glyphAt(0);

  return true;
}

int Font::emphasisMarkAscent(const AtomicString& mark) const {
  FontCachePurgePreventer purgePreventer;

  GlyphData markGlyphData;
  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
    return 0;

  const SimpleFontData* markFontData = markGlyphData.fontData;
  ASSERT(markFontData);
  if (!markFontData)
    return 0;

  return markFontData->getFontMetrics().ascent();
}

int Font::emphasisMarkDescent(const AtomicString& mark) const {
  FontCachePurgePreventer purgePreventer;

  GlyphData markGlyphData;
  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
    return 0;

  const SimpleFontData* markFontData = markGlyphData.fontData;
  ASSERT(markFontData);
  if (!markFontData)
    return 0;

  return markFontData->getFontMetrics().descent();
}

int Font::emphasisMarkHeight(const AtomicString& mark) const {
  FontCachePurgePreventer purgePreventer;

  GlyphData markGlyphData;
  if (!getEmphasisMarkGlyphData(mark, markGlyphData))
    return 0;

  const SimpleFontData* markFontData = markGlyphData.fontData;
  ASSERT(markFontData);
  if (!markFontData)
    return 0;

  return markFontData->getFontMetrics().height();
}

float Font::floatWidthForComplexText(
    const TextRun& run,
    HashSet<const SimpleFontData*>* fallbackFonts,
    FloatRect* glyphBounds) const {
  CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
  float width = shaper.width(this, run, fallbackFonts, glyphBounds);
  return width;
}

// Return the code point index for the given |x| offset into the text run.
int Font::offsetForPositionForComplexText(const TextRun& run,
                                          float xFloat,
                                          bool includePartialGlyphs) const {
  CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
  return shaper.offsetForPosition(this, run, xFloat, includePartialGlyphs);
}

// Return the rectangle for selecting the given range of code-points in the
// TextRun.
FloatRect Font::selectionRectForComplexText(const TextRun& run,
                                            const FloatPoint& point,
                                            int height,
                                            int from,
                                            int to) const {
  CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
  CharacterRange range = shaper.getCharacterRange(this, run, from, to);
  return FloatRect(point.x() + range.start, point.y(), range.width(), height);
}

CharacterRange Font::getCharacterRange(const TextRun& run,
                                       unsigned from,
                                       unsigned to) const {
  FontCachePurgePreventer purgePreventer;
  CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
  return shaper.getCharacterRange(this, run, from, to);
}

Vector<CharacterRange> Font::individualCharacterRanges(
    const TextRun& run) const {
  // TODO(pdr): Android is temporarily (crbug.com/577306) using the old simple
  // shaper and using the complex shaper here can show differences between
  // the two shapers. This function is currently only called through SVG
  // which now exclusively uses the complex shaper, so the primary difference
  // will be improved shaping in SVG when compared to HTML.
  FontCachePurgePreventer purgePreventer;
  CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
  auto ranges = shaper.individualCharacterRanges(this, run);
  // The shaper should return ranges.size == run.length but on some platforms
  // (OSX10.9.5) we are seeing cases in the upper end of the unicode range
  // where this is not true (see: crbug.com/620952). To catch these cases on
  // more popular platforms, and to protect users, we are using a CHECK here.
  CHECK_EQ(ranges.size(), run.length());
  return ranges;
}

float Font::floatWidthForSimpleText(
    const TextRun& run,
    HashSet<const SimpleFontData*>* fallbackFonts,
    FloatRect* glyphBounds) const {
  SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds);
  shaper.advance(run.length());
  return shaper.runWidthSoFar();
}

FloatRect Font::selectionRectForSimpleText(const TextRun& run,
                                           const FloatPoint& point,
                                           int h,
                                           int from,
                                           int to,
                                           bool accountForGlyphBounds) const {
  FloatRect bounds;
  SimpleShaper shaper(this, run, nullptr, nullptr,
                      accountForGlyphBounds ? &bounds : nullptr);
  shaper.advance(from);
  float fromX = shaper.runWidthSoFar();
  shaper.advance(to);
  float toX = shaper.runWidthSoFar();

  if (run.rtl()) {
    shaper.advance(run.length());
    float totalWidth = shaper.runWidthSoFar();
    float beforeWidth = fromX;
    float afterWidth = toX;
    fromX = totalWidth - afterWidth;
    toX = totalWidth - beforeWidth;
  }

  return FloatRect(point.x() + fromX,
                   accountForGlyphBounds ? bounds.y() : point.y(), toX - fromX,
                   accountForGlyphBounds ? bounds.maxY() - bounds.y() : h);
}

int Font::offsetForPositionForSimpleText(const TextRun& run,
                                         float x,
                                         bool includePartialGlyphs) const {
  float delta = x;

  SimpleShaper shaper(this, run);
  unsigned offset;
  if (run.rtl()) {
    delta -= floatWidthForSimpleText(run);
    while (1) {
      offset = shaper.currentOffset();
      float w;
      if (!shaper.advanceOneCharacter(w))
        break;
      delta += w;
      if (includePartialGlyphs) {
        if (delta - w / 2 >= 0)
          break;
      } else {
        if (delta >= 0)
          break;
      }
    }
  } else {
    while (1) {
      offset = shaper.currentOffset();
      float w;
      if (!shaper.advanceOneCharacter(w))
        break;
      delta -= w;
      if (includePartialGlyphs) {
        if (delta + w / 2 <= 0)
          break;
      } else {
        if (delta <= 0)
          break;
      }
    }
  }

  return offset;
}

bool Font::loadingCustomFonts() const {
  return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
}

bool Font::isFallbackValid() const {
  return !m_fontFallbackList || m_fontFallbackList->isValid();
}

}  // namespace blink
