/*
 * Copyright © 2018  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_LCAR_TABLE_HH
#define HB_AAT_LAYOUT_LCAR_TABLE_HH

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

/*
 * lcar -- Ligature caret
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html
 */
#define HB_AAT_TAG_lcar HB_TAG('l','c','a','r')


namespace AAT {

typedef ArrayOf<HBINT16> LigCaretClassEntry;

struct lcar
{
  enum { tableTag = HB_AAT_TAG_lcar };

  unsigned int get_lig_carets (hb_font_t      *font,
			       hb_direction_t  direction,
			       hb_codepoint_t  glyph,
			       unsigned int    start_offset,
			       unsigned int   *caret_count /* IN/OUT */,
			       hb_position_t  *caret_array /* OUT */) const
  {
    const OffsetTo<LigCaretClassEntry>* entry_offset = lookup.get_value (glyph,
									 font->face->get_num_glyphs ());
    const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry);
    if (caret_count)
    {
      hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count);
      unsigned int count = arr.len;
      for (unsigned int i = 0; i < count; ++i)
	switch (format)
	{
	case 0: caret_array[i] = font->em_scale_dir (arr[i], direction); break;
	case 1:
	  hb_position_t x, y;
	  font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y);
	  caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
	  break;
	}
    }
    return array.len;
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (likely (c->check_struct (this) &&
			  version.major == 1 &&
			  lookup.sanitize (c, this)));
  }

  protected:
  FixedVersion<>version;	/* Version number of the ligature caret table */
  HBUINT16	format;		/* Format of the ligature caret table. */
  Lookup<OffsetTo<LigCaretClassEntry> >
		lookup;		/* data Lookup table associating glyphs */

  public:
  DEFINE_SIZE_MIN (8);
};

} /* namespace AAT */

#endif /* HB_AAT_LAYOUT_LCAR_TABLE_HH */
