/*
 * Copyright © 2019  Ebrahim Byagowi
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

#ifndef HB_AAT_LAYOUT_OPBD_TABLE_HH
#define HB_AAT_LAYOUT_OPBD_TABLE_HH

#include "hb-aat-layout-common.hh"
#include "hb-open-type.hh"

/*
 * opbd -- Optical Bounds
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html
 */
#define HB_AAT_TAG_opbd HB_TAG('o','p','b','d')


namespace AAT {

struct OpticalBounds
{
  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this)));
  }

  FWORD		leftSide;
  FWORD		topSide;
  FWORD		rightSide;
  FWORD		bottomSide;
  public:
  DEFINE_SIZE_STATIC (8);
};

struct opbdFormat0
{
  bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
		   hb_glyph_extents_t *extents, const void *base) const
  {
    const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
    if (!bounds_offset) return false;
    const OpticalBounds &bounds = base+*bounds_offset;

    if (extents)
      *extents = {
	font->em_scale_x (bounds.leftSide),
	font->em_scale_y (bounds.topSide),
	font->em_scale_x (bounds.rightSide),
	font->em_scale_y (bounds.bottomSide)
      };
    return true;
  }

  bool sanitize (hb_sanitize_context_t *c, const void *base) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
  }

  protected:
  Lookup<OffsetTo<OpticalBounds>>
		lookupTable;	/* Lookup table associating glyphs with the four
				 * int16 values for the left-side, top-side,
				 * right-side, and bottom-side optical bounds. */
  public:
  DEFINE_SIZE_MIN (2);
};

struct opbdFormat1
{
  bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
		   hb_glyph_extents_t *extents, const void *base) const
  {
    const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
    if (!bounds_offset) return false;
    const OpticalBounds &bounds = base+*bounds_offset;

    hb_position_t left = 0, top = 0, right = 0, bottom = 0, ignore;
    if (font->get_glyph_contour_point (glyph_id, bounds.leftSide, &left, &ignore) ||
	font->get_glyph_contour_point (glyph_id, bounds.topSide, &ignore, &top) ||
	font->get_glyph_contour_point (glyph_id, bounds.rightSide, &right, &ignore) ||
	font->get_glyph_contour_point (glyph_id, bounds.bottomSide, &ignore, &bottom))
    {
      if (extents)
	*extents = {left, top, right, bottom};
      return true;
    }
    return false;
  }

  bool sanitize (hb_sanitize_context_t *c, const void *base) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
  }

  protected:
  Lookup<OffsetTo<OpticalBounds>>
		lookupTable;	/* Lookup table associating glyphs with the four
				 * int16 values for the left-side, top-side,
				 * right-side, and bottom-side optical bounds. */
  public:
  DEFINE_SIZE_MIN (2);
};

struct opbd
{
  static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd;

  bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
		   hb_glyph_extents_t *extents) const
  {
    switch (format)
    {
    case 0: return u.format0.get_bounds (font, glyph_id, extents, this);
    case 1: return u.format1.get_bounds (font, glyph_id, extents, this);
    default:return false;
    }
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (unlikely (!c->check_struct (this) || version.major != 1))
      return_trace (false);

    switch (format)
    {
    case 0: return_trace (u.format0.sanitize (c, this));
    case 1: return_trace (u.format1.sanitize (c, this));
    default:return_trace (true);
    }
  }

  protected:
  FixedVersion<>version;	/* Version number of the optical bounds
				 * table (0x00010000 for the current version). */
  HBUINT16	format;		/* Format of the optical bounds table.
				 * Format 0 indicates distance and Format 1 indicates
				 * control point. */
  union {
  opbdFormat0 format0;
  opbdFormat1 format1;
  } u;
  public:
  DEFINE_SIZE_MIN (8);
};

} /* namespace AAT */


#endif /* HB_AAT_LAYOUT_OPBD_TABLE_HH */
