// Copyright (c) 2012 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 "ui/gfx/render_text_mac.h"

#import <AppKit/AppKit.h>
#include <ApplicationServices/ApplicationServices.h>
#include <CoreText/CoreText.h>

#include <algorithm>
#include <cmath>
#include <utility>

#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/sys_string_conversions.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/ports/SkTypeface_mac.h"
#include "ui/gfx/decorated_text.h"

namespace {

// This function makes a copy of |font| with the given symbolic traits. On OSX
// 10.11, CTFontCreateCopyWithSymbolicTraits has the right behavior but
// CTFontCreateWithFontDescriptor does not. The opposite holds true for OSX
// 10.10.
base::ScopedCFTypeRef<CTFontRef> CopyFontWithSymbolicTraits(CTFontRef font,
                                                            int sym_traits) {
  if (base::mac::IsAtLeastOS10_11()) {
    return base::ScopedCFTypeRef<CTFontRef>(CTFontCreateCopyWithSymbolicTraits(
        font, 0, nullptr, sym_traits, sym_traits));
  }

  base::ScopedCFTypeRef<CTFontDescriptorRef> orig_desc(
      CTFontCopyFontDescriptor(font));
  base::ScopedCFTypeRef<CFDictionaryRef> orig_attributes(
      CTFontDescriptorCopyAttributes(orig_desc));
  // Make a mutable copy of orig_attributes.
  base::ScopedCFTypeRef<CFMutableDictionaryRef> attributes(
      CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, orig_attributes));

  base::ScopedCFTypeRef<CFMutableDictionaryRef> traits(
      CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                &kCFTypeDictionaryKeyCallBacks,
                                &kCFTypeDictionaryValueCallBacks));
  base::ScopedCFTypeRef<CFNumberRef> n(
      CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &sym_traits));
  CFDictionarySetValue(traits, kCTFontSymbolicTrait, n.release());
  CFDictionarySetValue(attributes, kCTFontTraitsAttribute, traits.release());

  base::ScopedCFTypeRef<CFStringRef> family_name(CTFontCopyFamilyName(font));
  CFDictionarySetValue(attributes, kCTFontNameAttribute, family_name.release());

  base::ScopedCFTypeRef<CTFontDescriptorRef> desc(
      CTFontDescriptorCreateWithAttributes(attributes));
  return base::ScopedCFTypeRef<CTFontRef>(
      CTFontCreateWithFontDescriptor(desc, 0.0, nullptr));
}

// Returns whether |font_list| has a valid primary native font.
bool HasValidPrimaryNativeFont(const gfx::FontList& font_list) {
  return font_list.GetPrimaryFont().GetNativeFont();
}

// Checks whether |font_list| is valid. If it isn't, returns the default font
// list (or a font list derived from it). The returned font list will have a
// valid primary native font.
gfx::FontList GetValidFontList(const gfx::FontList& font_list) {
  if (HasValidPrimaryNativeFont(font_list))
    return font_list;

  const gfx::FontList default_font_list;
  const int size_delta =
      font_list.GetFontSize() - default_font_list.GetFontSize();
  const gfx::FontList derived_font_list = default_font_list.Derive(
      size_delta, font_list.GetFontStyle(), font_list.GetFontWeight());
  if (HasValidPrimaryNativeFont(derived_font_list))
    return derived_font_list;

  DCHECK(HasValidPrimaryNativeFont(default_font_list));
  return default_font_list;
}

}  // namespace

namespace gfx {

namespace internal {

// Note: this is only used by RenderTextHarfbuzz.
sk_sp<SkTypeface> CreateSkiaTypeface(const Font& font,
                                     bool italic,
                                     Font::Weight weight) {
  const Font::FontStyle style = italic ? Font::ITALIC : Font::NORMAL;
  Font font_with_style = font.Derive(0, style, weight);
  if (!font_with_style.GetNativeFont())
    return nullptr;

  return sk_sp<SkTypeface>(SkCreateTypefaceFromCTFont(
      base::mac::NSToCFCast(font_with_style.GetNativeFont())));
}

}  // namespace internal

RenderTextMac::RenderTextMac() : common_baseline_(0), runs_valid_(false) {}

RenderTextMac::~RenderTextMac() {}

std::unique_ptr<RenderText> RenderTextMac::CreateInstanceOfSameType() const {
  return base::WrapUnique(new RenderTextMac);
}

void RenderTextMac::SetFontList(const FontList& font_list) {
  // Ensure the font list used has a valid native font.
  RenderText::SetFontList(GetValidFontList(font_list));
}

bool RenderTextMac::MultilineSupported() const {
  return false;
}

const base::string16& RenderTextMac::GetDisplayText() {
  return text_elided() ? display_text() : layout_text();
}

Size RenderTextMac::GetStringSize() {
  SizeF size_f = GetStringSizeF();
  return Size(std::ceil(size_f.width()), size_f.height());
}

SizeF RenderTextMac::GetStringSizeF() {
  EnsureLayout();
  return string_size_;
}

SelectionModel RenderTextMac::FindCursorPosition(const Point& point) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return SelectionModel();
}

bool RenderTextMac::IsSelectionSupported() const {
  return false;
}

std::vector<RenderText::FontSpan> RenderTextMac::GetFontSpansForTesting() {
  EnsureLayout();
  if (!runs_valid_)
    ComputeRuns();

  std::vector<RenderText::FontSpan> spans;
  for (size_t i = 0; i < runs_.size(); ++i) {
    const CFRange cf_range = CTRunGetStringRange(runs_[i].ct_run);
    const Range range(cf_range.location, cf_range.location + cf_range.length);
    spans.push_back(RenderText::FontSpan(
        Font(base::mac::CFToNSCast(runs_[i].ct_font.get())), range));
  }

  return spans;
}

int RenderTextMac::GetDisplayTextBaseline() {
  EnsureLayout();
  return common_baseline_;
}

SelectionModel RenderTextMac::AdjacentCharSelectionModel(
    const SelectionModel& selection,
    VisualCursorDirection direction) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return SelectionModel();
}

SelectionModel RenderTextMac::AdjacentWordSelectionModel(
    const SelectionModel& selection,
    VisualCursorDirection direction) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return SelectionModel();
}

Range RenderTextMac::GetCursorSpan(const Range& text_range) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return Range();
}

std::vector<Rect> RenderTextMac::GetSubstringBounds(const Range& range) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return std::vector<Rect>();
}

size_t RenderTextMac::TextIndexToDisplayIndex(size_t index) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return index;
}

size_t RenderTextMac::DisplayIndexToTextIndex(size_t index) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return index;
}

bool RenderTextMac::IsValidCursorIndex(size_t index) {
  // TODO(asvitkine): Implement this. http://crbug.com/131618
  return IsValidLogicalIndex(index);
}

void RenderTextMac::OnLayoutTextAttributeChanged(bool text_changed) {
  DCHECK(!multiline()) << "RenderTextMac does not support multi line";
  if (text_changed) {
    if (elide_behavior() != NO_ELIDE && elide_behavior() != FADE_TAIL &&
        !layout_text().empty()) {
      UpdateDisplayText(std::ceil(GetLayoutTextWidth()));
    } else {
      UpdateDisplayText(0);
    }
  }
  InvalidateStyle();
}

void RenderTextMac::OnDisplayTextAttributeChanged() {
  OnLayoutTextAttributeChanged(true);
}

void RenderTextMac::OnTextColorChanged() {
  InvalidateStyle();
}

void RenderTextMac::EnsureLayout() {
  if (line_.get())
    return;
  runs_.clear();
  runs_valid_ = false;

  line_ = EnsureLayoutInternal(GetDisplayText(), &attributes_);
  string_size_ = GetCTLineSize(line_.get(), &common_baseline_);
}

void RenderTextMac::DrawVisualText(internal::SkiaTextRenderer* renderer) {
  DCHECK(line_);
  if (!runs_valid_)
    ComputeRuns();

  ApplyFadeEffects(renderer);
  ApplyTextShadows(renderer);
  renderer->SetFontRenderParams(
      font_list().GetPrimaryFont().GetFontRenderParams(),
      subpixel_rendering_suppressed());

  for (size_t i = 0; i < runs_.size(); ++i) {
    const TextRun& run = runs_[i];
    renderer->SetForegroundColor(run.foreground);
    renderer->SetTextSize(CTFontGetSize(run.ct_font));

    // The painter adds its own ref. So don't |release()| it from the ref ptr in
    // TextRun.
    renderer->SetTypeface(run.typeface);

    renderer->DrawPosText(&run.glyph_positions[0], &run.glyphs[0],
                          run.glyphs.size());
    if (run.underline)
      renderer->DrawUnderline(run.origin.x(), run.origin.y(), run.width);
    if (run.strike)
      renderer->DrawStrike(run.origin.x(), run.origin.y(), run.width,
                           strike_thickness_factor());
  }
}

RenderTextMac::TextRun::TextRun()
    : ct_run(NULL),
      origin(SkPoint::Make(0, 0)),
      width(0),
      foreground(SK_ColorBLACK),
      underline(false),
      strike(false) {}

RenderTextMac::TextRun::TextRun(TextRun&& other) = default;

RenderTextMac::TextRun::~TextRun() {}

float RenderTextMac::GetLayoutTextWidth() {
  base::ScopedCFTypeRef<CFMutableArrayRef> attributes_owner;
  base::ScopedCFTypeRef<CTLineRef> line(
      EnsureLayoutInternal(layout_text(), &attributes_owner));
  SkScalar baseline;
  return GetCTLineSize(line.get(), &baseline).width();
}

SizeF RenderTextMac::GetCTLineSize(CTLineRef line, SkScalar* baseline) {
  CGFloat ascent = 0;
  CGFloat descent = 0;
  CGFloat leading = 0;
  // TODO(asvitkine): Consider using CTLineGetBoundsWithOptions() on 10.8+.
  double width = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
  // Ensure ascent and descent are not smaller than ones of the font list.
  // Keep them tall enough to draw often-used characters.
  // For example, if a text field contains a Japanese character, which is
  // smaller than Latin ones, and then later a Latin one is inserted, this
  // ensures that the text baseline does not shift.
  CGFloat font_list_height = font_list().GetHeight();
  CGFloat font_list_baseline = font_list().GetBaseline();
  ascent = std::max(ascent, font_list_baseline);
  descent = std::max(descent, font_list_height - font_list_baseline);
  *baseline = ascent;
  return SizeF(width, std::max(ascent + descent + leading,
                               static_cast<CGFloat>(min_line_height())));
}

base::ScopedCFTypeRef<CTLineRef> RenderTextMac::EnsureLayoutInternal(
    const base::string16& text,
    base::ScopedCFTypeRef<CFMutableArrayRef>* attributes_owner) {
  CTFontRef ct_font =
      base::mac::NSToCFCast(font_list().GetPrimaryFont().GetNativeFont());
  DCHECK(ct_font);

  const void* keys[] = {kCTFontAttributeName};
  const void* values[] = {ct_font};
  base::ScopedCFTypeRef<CFDictionaryRef> attributes(
      CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL,
                         &kCFTypeDictionaryValueCallBacks));

  base::ScopedCFTypeRef<CFStringRef> cf_text(base::SysUTF16ToCFStringRef(text));
  base::ScopedCFTypeRef<CFAttributedStringRef> attr_text(
      CFAttributedStringCreate(NULL, cf_text, attributes));
  base::ScopedCFTypeRef<CFMutableAttributedStringRef> attr_text_mutable(
      CFAttributedStringCreateMutableCopy(NULL, 0, attr_text));

  // TODO(asvitkine|msw): Respect GetTextDirection(), which may not match the
  // natural text direction. See kCTTypesetterOptionForcedEmbeddingLevel, etc.

  *attributes_owner = ApplyStyles(text, attr_text_mutable, ct_font);
  return base::ScopedCFTypeRef<CTLineRef>(
      CTLineCreateWithAttributedString(attr_text_mutable));
}

base::ScopedCFTypeRef<CFMutableArrayRef> RenderTextMac::ApplyStyles(
    const base::string16& text,
    CFMutableAttributedStringRef attr_string,
    CTFontRef font) {
  // Temporarily apply composition underlines and selection colors.
  ApplyCompositionAndSelectionStyles();

  // Note: CFAttributedStringSetAttribute() does not appear to retain the values
  // passed in, as can be verified via CFGetRetainCount(). To ensure the
  // attribute objects do not leak, they are saved to |attributes_|.
  // Clear the attributes storage.
  base::ScopedCFTypeRef<CFMutableArrayRef> attributes(
      CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));

  // https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html
  internal::StyleIterator style(colors(), baselines(), font_size_overrides(),
                                weights(), styles());
  const size_t layout_text_length = CFAttributedStringGetLength(attr_string);
  for (size_t i = 0, end = 0; i < layout_text_length; i = end) {
    end = TextIndexToGivenTextIndex(text, style.GetRange().end());
    const CFRange range = CFRangeMake(i, end - i);
    base::ScopedCFTypeRef<CGColorRef> foreground(
        skia::CGColorCreateFromSkColor(style.color()));
    CFAttributedStringSetAttribute(attr_string, range,
                                   kCTForegroundColorAttributeName, foreground);
    CFArrayAppendValue(attributes, foreground);

    if (style.style(UNDERLINE) || style.style(HEAVY_UNDERLINE)) {
      CTUnderlineStyle value = style.style(HEAVY_UNDERLINE)
                                   ? kCTUnderlineStyleThick
                                   : kCTUnderlineStyleSingle;
      base::ScopedCFTypeRef<CFNumberRef> underline_value(
          CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
      CFAttributedStringSetAttribute(
          attr_string, range, kCTUnderlineStyleAttributeName, underline_value);
      CFArrayAppendValue(attributes, underline_value);
    }

    // TODO(mboc): Apply font weights other than bold below.
    const int traits =
        (style.style(ITALIC) ? kCTFontItalicTrait : 0) |
        (style.weight() >= Font::Weight::BOLD ? kCTFontBoldTrait : 0);
    if (traits != 0) {
      base::ScopedCFTypeRef<CTFontRef> styled_font =
          CopyFontWithSymbolicTraits(font, traits);
      // TODO(asvitkine): Handle |styled_font| == NULL case better.
      if (styled_font) {
        CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName,
                                       styled_font);
        CFArrayAppendValue(attributes, styled_font);
      }
    }

    style.UpdatePosition(DisplayIndexToTextIndex(end));
  }

  // Undo the temporarily applied composition underlines and selection colors.
  UndoCompositionAndSelectionStyles();

  return attributes;
}

void RenderTextMac::ComputeRuns() {
  DCHECK(line_);

  CFArrayRef ct_runs = CTLineGetGlyphRuns(line_);
  const CFIndex ct_runs_count = CFArrayGetCount(ct_runs);

  // TODO(asvitkine): Don't use GetLineOffset() until draw time, since it may be
  // updated based on alignment changes without resetting the layout.
  Vector2d text_offset = GetLineOffset(0);
  // Skia will draw glyphs with respect to the baseline.
  text_offset += Vector2d(0, common_baseline_);

  const SkScalar x = SkIntToScalar(text_offset.x());
  const SkScalar y = SkIntToScalar(text_offset.y());
  SkPoint run_origin = SkPoint::Make(x, y);

  const CFRange empty_cf_range = CFRangeMake(0, 0);
  for (CFIndex i = 0; i < ct_runs_count; ++i) {
    CTRunRef ct_run =
        base::mac::CFCast<CTRunRef>(CFArrayGetValueAtIndex(ct_runs, i));
    const size_t glyph_count = CTRunGetGlyphCount(ct_run);
    const double run_width =
        CTRunGetTypographicBounds(ct_run, empty_cf_range, NULL, NULL, NULL);
    if (glyph_count == 0) {
      run_origin.offset(run_width, 0);
      continue;
    }

    runs_.emplace_back();
    TextRun* run = &runs_.back();
    run->ct_run = ct_run;
    run->origin = run_origin;
    run->width = run_width;
    run->glyphs.resize(glyph_count);
    CTRunGetGlyphs(ct_run, empty_cf_range, &run->glyphs[0]);

    run->glyph_positions.resize(glyph_count);
    const CGPoint* positions_ptr = CTRunGetPositionsPtr(ct_run);
    std::vector<CGPoint> positions;
    if (positions_ptr == NULL) {
      positions.resize(glyph_count);
      CTRunGetPositions(ct_run, empty_cf_range, &positions[0]);
      positions_ptr = &positions[0];
    }
    for (size_t glyph = 0; glyph < glyph_count; glyph++) {
      SkPoint* point = &run->glyph_positions[glyph];
      point->set(x + SkDoubleToScalar(positions_ptr[glyph].x),
                 y + SkDoubleToScalar(positions_ptr[glyph].y));
    }

    // TODO(asvitkine): Style boundaries are not necessarily per-run. Handle
    //                  this better. Also, support strike.
    CFDictionaryRef attributes = CTRunGetAttributes(ct_run);
    CTFontRef ct_font = base::mac::GetValueFromDictionary<CTFontRef>(
        attributes, kCTFontAttributeName);
    run->ct_font.reset(ct_font, base::scoped_policy::RETAIN);
    run->typeface.reset(SkCreateTypefaceFromCTFont(ct_font));

    const CGColorRef foreground = base::mac::GetValueFromDictionary<CGColorRef>(
        attributes, kCTForegroundColorAttributeName);
    if (foreground)
      run->foreground = skia::CGColorRefToSkColor(foreground);

    const CFNumberRef underline =
        base::mac::GetValueFromDictionary<CFNumberRef>(
            attributes, kCTUnderlineStyleAttributeName);
    CTUnderlineStyle value = kCTUnderlineStyleNone;
    if (underline && CFNumberGetValue(underline, kCFNumberSInt32Type, &value))
      run->underline = (value == kCTUnderlineStyleSingle);

    run_origin.offset(run_width, 0);
  }
  runs_valid_ = true;
}

void RenderTextMac::InvalidateStyle() {
  line_.reset();
  attributes_.reset();
  runs_.clear();
  runs_valid_ = false;
}

bool RenderTextMac::GetDecoratedTextForRange(const Range& range,
                                             DecoratedText* decorated_text) {
  // TODO(karandeepb): This is not invoked on any codepath currently. Style the
  // returned text if need be.
  if (obscured())
    return false;

  decorated_text->text = GetTextFromRange(range);
  return true;
}

}  // namespace gfx
