/*
 * Copyright © 2014  Google, Inc.
 *
 *  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.
 *
 * Google Author(s): Behdad Esfahbod
 */

#include <stdlib.h>
#include <stdio.h>

#include "hb-fc.h"

static hb_bool_t
hb_fc_get_glyph (hb_font_t *font /*HB_UNUSED*/,
		 void *font_data,
		 hb_codepoint_t unicode,
		 hb_codepoint_t variation_selector,
		 hb_codepoint_t *glyph,
		 void *user_data /*HB_UNUSED*/)

{
  FcCharSet *cs = (FcCharSet *) font_data;

  if (variation_selector)
  {
    /* Fontconfig doesn't cache cmap-14 info.  However:
     * 1. If the font maps the variation_selector, assume it's
     *    supported,
     * 2. If the font doesn't map it, still say it's supported,
     *    but return 0.  This way, the caller will see the zero
     *    and reject.  If we return unsupported here, then the
     *    variation selector will be hidden and ignored.
     */
    if (FcCharSetHasChar (cs, unicode) &&
	FcCharSetHasChar (cs, variation_selector))
    {
      unsigned int var_num = 0;
      if (variation_selector - 0xFE00u < 16)
        var_num = variation_selector - 0xFE00 + 1;
      else if (variation_selector - 0xE0100u < (256 - 16))
        var_num = variation_selector - 0xE0100 + 17;
      *glyph = (var_num << 21) | unicode;
    }
    else
    {
      *glyph = 0;
    }
    return true;
  }

  *glyph = FcCharSetHasChar (cs, unicode) ? unicode : 0;
  return *glyph != 0;
}

static hb_font_funcs_t *
_hb_fc_get_font_funcs ()
{
  static const hb_font_funcs_t *fc_ffuncs;

  const hb_font_funcs_t *ffuncs;

  if (!(ffuncs = fc_ffuncs))
  {
    hb_font_funcs_t *newfuncs = hb_font_funcs_create ();

    hb_font_funcs_set_glyph_func (newfuncs, hb_fc_get_glyph, nullptr, nullptr);

    /* XXX MT-unsafe */
    if (fc_ffuncs)
      hb_font_funcs_destroy (newfuncs);
    else
      fc_ffuncs = ffuncs = newfuncs;
  }

  return const_cast<hb_font_funcs_t *> (fc_ffuncs);
}


hb_font_t *
hb_fc_font_create (FcPattern *fcfont)
{
  static hb_face_t *face;
  hb_font_t *font;

  FcCharSet *cs;
  if (FcResultMatch != FcPatternGetCharSet (fcfont, FC_CHARSET, 0, &cs))
    return hb_font_get_empty ();

  if (!face) /* XXX MT-unsafe */
    face = hb_face_create (hb_blob_get_empty (), 0);

  font = hb_font_create (face);

  hb_font_set_funcs (font,
		     _hb_fc_get_font_funcs (),
		     FcCharSetCopy (cs),
		     (hb_destroy_func_t) FcCharSetDestroy);

  return font;
}

hb_bool_t
hb_fc_can_render (hb_font_t *font, const char *text)
{
  static const char *ot[] = {"ot", nullptr};

  hb_buffer_t *buffer = hb_buffer_create ();
  hb_buffer_add_utf8 (buffer, text, -1, 0, -1);

  /* XXX Do we need this?  I think Arabic and Hangul shapers are the
   * only one that make any use of this.  The Hangul case is not really
   * needed, and for Arabic we'll miss a very narrow set of fonts.
   * Might be better to force generic shaper perhaps. */
  hb_buffer_guess_segment_properties (buffer);

  if (!hb_shape_full (font, buffer, nullptr, 0, ot))
    abort (); /* hb-ot shaper not enabled? */

  unsigned int len;
  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &len);
  for (unsigned int i = 0; i < len; i++)
   {
    if (!info[i].codepoint)
     {
      return false;
     }
   }

  return true;
}
