/*
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cobalt/renderer/rasterizer/skia/font.h"

#include "base/lazy_instance.h"

#include "third_party/skia/include/core/SkPaint.h"

namespace {
const float kXHeightEstimateFactor = 0.56f;
}  // namespace

namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace skia {
namespace {

struct NonTrivialStaticFields {
  NonTrivialStaticFields() {
    default_paint.setAntiAlias(true);
    default_paint.setSubpixelText(true);
  }

  SkPaint default_paint;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

// |non_trivial_static_fields| will be lazily created on the first time it's
// accessed.
base::LazyInstance<NonTrivialStaticFields> non_trivial_static_fields =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

Font::Font(SkiaTypeface* typeface, SkScalar size)
    : typeface_(typeface), size_(size) {
  glyph_bounds_thread_checker_.DetachFromThread();
}

SkTypeface* Font::GetSkTypeface() const { return typeface_->GetSkTypeface(); }

render_tree::TypefaceId Font::GetTypefaceId() const {
  return typeface_->GetId();
}

render_tree::FontMetrics Font::GetFontMetrics() const {
  SkPaint paint = GetSkPaint();

  SkPaint::FontMetrics font_metrics;
  paint.getFontMetrics(&font_metrics);

  // The x-height is the height of the 'x' glyph. It is used to find the visual
  // 'middle' of the font to allow vertical alignment to the middle of the font.
  // See also https://en.wikipedia.org/wiki/X-height
  float x_height;
  if (font_metrics.fXHeight) {
    x_height = font_metrics.fXHeight;
  } else {
    // If the font does not have an 'x' glyph, we need to estimate the value.
    // A good estimation  is to use 0.56 * the font ascent.
    x_height = font_metrics.fAscent * kXHeightEstimateFactor;
  }

  // In Skia, ascent is negative, while descent and leading are positive.
  return render_tree::FontMetrics(-font_metrics.fAscent, font_metrics.fDescent,
                                  font_metrics.fLeading, x_height);
}

render_tree::GlyphIndex Font::GetGlyphForCharacter(int32 utf32_character) {
  return typeface_->GetGlyphForCharacter(utf32_character);
}

const math::RectF& Font::GetGlyphBounds(render_tree::GlyphIndex glyph) {
  DCHECK(glyph_bounds_thread_checker_.CalledOnValidThread());
  // Check to see if the glyph falls within the the first 256 glyphs. These
  // characters are part of the primary page and are stored within an array as
  // an optimization.
  if (glyph < kPrimaryPageSize) {
    // The first page is lazily allocated, so we don't use the memory if it's
    // never used.
    if (!primary_page_glyph_bounds_) {
      primary_page_glyph_bounds_.reset(new math::RectF[kPrimaryPageSize]);
      // If the page has already been allocated, then check for the glyph's
      // bounds having already been set. If this is the case, simply return the
      // bounds.
    } else if (primary_page_glyph_bounds_bits_[glyph]) {
      return primary_page_glyph_bounds_[glyph];
    }
    // Otherwise, check for the glyph's bounds within the map.
  } else {
    GlyphToBoundsMap::iterator map_iterator = glyph_to_bounds_map_.find(glyph);
    if (map_iterator != glyph_to_bounds_map_.end()) {
      return map_iterator->second;
    }
  }

  // If we reach this point, the glyph's bounds were not previously cached and
  // need to be calculated them now.
  SkPaint paint = GetSkPaint();
  paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);

  SkRect skia_bounds;
  float width = paint.measureText(&glyph, 2, &skia_bounds);

  // Both cache and return the glyph's bounds.
  if (glyph < kPrimaryPageSize) {
    primary_page_glyph_bounds_bits_.set(glyph, true);
    return primary_page_glyph_bounds_[glyph] =
               math::RectF(0, skia_bounds.top(), width, skia_bounds.height());
  } else {
    return glyph_to_bounds_map_[glyph] =
               math::RectF(0, skia_bounds.top(), width, skia_bounds.height());
  }
}

float Font::GetGlyphWidth(render_tree::GlyphIndex glyph) {
  return GetGlyphBounds(glyph).width();
}

SkPaint Font::GetSkPaint() const {
  SkPaint paint(GetDefaultSkPaint());
  SkAutoTUnref<SkTypeface> typeface(typeface_->GetSkTypeface());
  paint.setTypeface(typeface);
  paint.setTextSize(size_);
  return paint;
}

const SkPaint& Font::GetDefaultSkPaint() {
  return non_trivial_static_fields.Get().default_paint;
}

}  // namespace skia
}  // namespace rasterizer
}  // namespace renderer
}  // namespace cobalt
