/*
 * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved.
 * Copyright (C) 2006 Alexey Proskuryakov
 *
 * 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "third_party/blink/renderer/platform/fonts/font_metrics.h"

#include "build/build_config.h"
#include "third_party/blink/renderer/platform/fonts/font_platform_data.h"
#include "third_party/blink/renderer/platform/fonts/vdmx_parser.h"

#include <SkPaint.h>
#include <SkTypeface.h>

namespace blink {

#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
// This is the largest VDMX table which we'll try to load and parse.
static const size_t kMaxVDMXTableSize = 1024 * 1024;  // 1 MB
#endif

void FontMetrics::AscentDescentWithHacks(
    float& ascent,
    float& descent,
    unsigned& visual_overflow_inflation_for_ascent,
    unsigned& visual_overflow_inflation_for_descent,
    const FontPlatformData& platform_data,
    const SkPaint& paint,
    bool subpixel_ascent_descent) {
  SkTypeface* face = paint.getTypeface();
  DCHECK(face);

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

  int vdmx_ascent = 0, vdmx_descent = 0;
  bool is_vdmx_valid = false;

#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
  // Manually digging up VDMX metrics is only applicable when bytecode hinting
  // using FreeType.  With DirectWrite or CoreText, no bytecode hinting is ever
  // done.  This code should be pushed into FreeType (hinted font metrics).
  static const uint32_t kVdmxTag = SkSetFourByteTag('V', 'D', 'M', 'X');
  int pixel_size = platform_data.size() + 0.5;
  if (!paint.isAutohinted() && (paint.getHinting() == SkFontHinting::kFull ||
                                paint.getHinting() == SkFontHinting::kNormal)) {
    size_t vdmx_size = face->getTableSize(kVdmxTag);
    if (vdmx_size && vdmx_size < kMaxVDMXTableSize) {
      uint8_t* vdmx_table = (uint8_t*)WTF::Partitions::FastMalloc(
          vdmx_size, WTF_HEAP_PROFILER_TYPE_NAME(FontMetrics));
      if (vdmx_table &&
          face->getTableData(kVdmxTag, 0, vdmx_size, vdmx_table) == vdmx_size &&
          ParseVDMX(&vdmx_ascent, &vdmx_descent, vdmx_table, vdmx_size,
                    pixel_size))
        is_vdmx_valid = true;
      WTF::Partitions::FastFree(vdmx_table);
    }
  }
#endif

  // Beware those who step here: This code is designed to match Win32 font
  // metrics *exactly* except:
  // - the adjustment of ascent/descent on Linux/Android
  // - metrics.fAscent and .fDesscent are not rounded to int for tiny fonts
  if (is_vdmx_valid) {
    ascent = vdmx_ascent;
    descent = -vdmx_descent;
  } else if (subpixel_ascent_descent &&
             (-metrics.fAscent < 3 ||
              -metrics.fAscent + metrics.fDescent < 2)) {
    // For tiny fonts, the rounding of fAscent and fDescent results in equal
    // baseline for different types of text baselines (crbug.com/338908).
    // Please see CanvasRenderingContext2D::getFontBaseline for the heuristic.
    ascent = -metrics.fAscent;
    descent = metrics.fDescent;
  } else {
    ascent = SkScalarRoundToScalar(-metrics.fAscent);
    descent = SkScalarRoundToScalar(metrics.fDescent);

    if (ascent < -metrics.fAscent)
      visual_overflow_inflation_for_ascent = 1;
    if (descent < metrics.fDescent) {
      visual_overflow_inflation_for_descent = 1;
#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
      // When subpixel positioning is enabled, if the descent is rounded down,
      // the descent part of the glyph may be truncated when displayed in a
      // 'overflow: hidden' container.  To avoid that, borrow 1 unit from the
      // ascent when possible.
      if (platform_data.GetFontRenderStyle().use_subpixel_positioning &&
          ascent >= 1) {
        ++descent;
        --ascent;
        // We should inflate overflow 1 more pixel for ascent instead.
        visual_overflow_inflation_for_descent = 0;
        ++(visual_overflow_inflation_for_ascent);
      }
#endif
    }
  }

#if defined(OS_MACOSX)
  // We are preserving this ascent hack to match Safari's ascent adjustment
  // in their SimpleFontDataMac.mm, for details see crbug.com/445830.
  // We need to adjust Times, Helvetica, and Courier to closely match the
  // vertical metrics of their Microsoft counterparts that are the de facto
  // web standard. The AppKit adjustment of 20% is too big and is
  // incorrectly added to line spacing, so we use a 15% adjustment instead
  // and add it to the ascent.
  String family_name = platform_data.FontFamilyName();
  if (family_name == font_family_names::kTimes ||
      family_name == font_family_names::kHelvetica ||
      family_name == font_family_names::kCourier)
    ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
#endif
}
}
