/*
 * Copyright © 2022  Behdad Esfahbod
 *
 *  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_FT_COLR_HH
#define HB_FT_COLR_HH

#include "hb.hh"

#include "hb-paint-extents.hh"

#include FT_COLOR_H


static hb_paint_composite_mode_t
_hb_ft_paint_composite_mode (FT_Composite_Mode mode)
{
  switch (mode)
  {
    case FT_COLR_COMPOSITE_CLEAR:          return HB_PAINT_COMPOSITE_MODE_CLEAR;
    case FT_COLR_COMPOSITE_SRC:            return HB_PAINT_COMPOSITE_MODE_SRC;
    case FT_COLR_COMPOSITE_DEST:           return HB_PAINT_COMPOSITE_MODE_DEST;
    case FT_COLR_COMPOSITE_SRC_OVER:       return HB_PAINT_COMPOSITE_MODE_SRC_OVER;
    case FT_COLR_COMPOSITE_DEST_OVER:      return HB_PAINT_COMPOSITE_MODE_DEST_OVER;
    case FT_COLR_COMPOSITE_SRC_IN:         return HB_PAINT_COMPOSITE_MODE_SRC_IN;
    case FT_COLR_COMPOSITE_DEST_IN:        return HB_PAINT_COMPOSITE_MODE_DEST_IN;
    case FT_COLR_COMPOSITE_SRC_OUT:        return HB_PAINT_COMPOSITE_MODE_SRC_OUT;
    case FT_COLR_COMPOSITE_DEST_OUT:       return HB_PAINT_COMPOSITE_MODE_DEST_OUT;
    case FT_COLR_COMPOSITE_SRC_ATOP:       return HB_PAINT_COMPOSITE_MODE_SRC_ATOP;
    case FT_COLR_COMPOSITE_DEST_ATOP:      return HB_PAINT_COMPOSITE_MODE_DEST_ATOP;
    case FT_COLR_COMPOSITE_XOR:            return HB_PAINT_COMPOSITE_MODE_XOR;
    case FT_COLR_COMPOSITE_PLUS:           return HB_PAINT_COMPOSITE_MODE_PLUS;
    case FT_COLR_COMPOSITE_SCREEN:         return HB_PAINT_COMPOSITE_MODE_SCREEN;
    case FT_COLR_COMPOSITE_OVERLAY:        return HB_PAINT_COMPOSITE_MODE_OVERLAY;
    case FT_COLR_COMPOSITE_DARKEN:         return HB_PAINT_COMPOSITE_MODE_DARKEN;
    case FT_COLR_COMPOSITE_LIGHTEN:        return HB_PAINT_COMPOSITE_MODE_LIGHTEN;
    case FT_COLR_COMPOSITE_COLOR_DODGE:    return HB_PAINT_COMPOSITE_MODE_COLOR_DODGE;
    case FT_COLR_COMPOSITE_COLOR_BURN:     return HB_PAINT_COMPOSITE_MODE_COLOR_BURN;
    case FT_COLR_COMPOSITE_HARD_LIGHT:     return HB_PAINT_COMPOSITE_MODE_HARD_LIGHT;
    case FT_COLR_COMPOSITE_SOFT_LIGHT:     return HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT;
    case FT_COLR_COMPOSITE_DIFFERENCE:     return HB_PAINT_COMPOSITE_MODE_DIFFERENCE;
    case FT_COLR_COMPOSITE_EXCLUSION:      return HB_PAINT_COMPOSITE_MODE_EXCLUSION;
    case FT_COLR_COMPOSITE_MULTIPLY:       return HB_PAINT_COMPOSITE_MODE_MULTIPLY;
    case FT_COLR_COMPOSITE_HSL_HUE:        return HB_PAINT_COMPOSITE_MODE_HSL_HUE;
    case FT_COLR_COMPOSITE_HSL_SATURATION: return HB_PAINT_COMPOSITE_MODE_HSL_SATURATION;
    case FT_COLR_COMPOSITE_HSL_COLOR:      return HB_PAINT_COMPOSITE_MODE_HSL_COLOR;
    case FT_COLR_COMPOSITE_HSL_LUMINOSITY: return HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY;

    case FT_COLR_COMPOSITE_MAX:            HB_FALLTHROUGH;
    default:                               return HB_PAINT_COMPOSITE_MODE_CLEAR;
  }
}

typedef struct hb_ft_paint_context_t hb_ft_paint_context_t;

static void
_hb_ft_paint (hb_ft_paint_context_t *c,
	      FT_OpaquePaint opaque_paint);

struct hb_ft_paint_context_t
{
  hb_ft_paint_context_t (const hb_ft_font_t *ft_font,
			 hb_font_t *font,
			 hb_paint_funcs_t *paint_funcs, void *paint_data,
			 FT_Color *palette,
			 unsigned palette_index,
			 hb_color_t foreground) :
    ft_font (ft_font), font(font),
    funcs (paint_funcs), data (paint_data),
    palette (palette), palette_index (palette_index), foreground (foreground) {}

  void recurse (FT_OpaquePaint paint)
  {
    if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
    depth_left--;
    edge_count--;
    _hb_ft_paint (this, paint);
    depth_left++;
  }

  const hb_ft_font_t *ft_font;
  hb_font_t *font;
  hb_paint_funcs_t *funcs;
  void *data;
  FT_Color *palette;
  unsigned palette_index;
  hb_color_t foreground;
  int depth_left = HB_MAX_NESTING_LEVEL;
  int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
};

static unsigned
_hb_ft_color_line_get_color_stops (hb_color_line_t *color_line,
				   void *color_line_data,
				   unsigned int start,
				   unsigned int *count,
				   hb_color_stop_t *color_stops,
				   void *user_data)
{
  FT_ColorLine *cl = (FT_ColorLine *) color_line_data;
  hb_ft_paint_context_t *c = (hb_ft_paint_context_t *) user_data;

  if (count)
  {
    FT_ColorStop stop;
    unsigned wrote = 0;
    FT_ColorStopIterator iter = cl->color_stop_iterator;

    if (start >= cl->color_stop_iterator.num_color_stops)
    {
      *count = 0;
      return cl->color_stop_iterator.num_color_stops;
    }

    while (cl->color_stop_iterator.current_color_stop < start)
      FT_Get_Colorline_Stops(c->ft_font->ft_face,
			     &stop,
			     &cl->color_stop_iterator);

    while (count && *count &&
	   FT_Get_Colorline_Stops(c->ft_font->ft_face,
				  &stop,
				  &cl->color_stop_iterator))
    {
      // https://github.com/harfbuzz/harfbuzz/issues/4013
      if (sizeof stop.stop_offset == 2)
	color_stops->offset = stop.stop_offset / 16384.f;
      else
	color_stops->offset = stop.stop_offset / 65536.f;

      color_stops->is_foreground = stop.color.palette_index == 0xFFFF;
      if (color_stops->is_foreground)
	color_stops->color = HB_COLOR (hb_color_get_blue (c->foreground),
				       hb_color_get_green (c->foreground),
				       hb_color_get_red (c->foreground),
				       (hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
      else
      {
	hb_color_t color;
        if (c->funcs->custom_palette_color (c->data, stop.color.palette_index, &color))
	{
	  color_stops->color = HB_COLOR (hb_color_get_blue (color),
					 hb_color_get_green (color),
					 hb_color_get_red (color),
					 (hb_color_get_alpha (color) * stop.color.alpha) >> 14);
	}
	else
	{
	  FT_Color ft_color = c->palette[stop.color.palette_index];
	  color_stops->color = HB_COLOR (ft_color.blue,
					 ft_color.green,
					 ft_color.red,
					 (ft_color.alpha * stop.color.alpha) >> 14);
	}
      }

      color_stops++;
      wrote++;
    }

    *count = wrote;

    // reset the iterator for next time
    cl->color_stop_iterator = iter;
  }

  return cl->color_stop_iterator.num_color_stops;
}

static hb_paint_extend_t
_hb_ft_color_line_get_extend (hb_color_line_t *color_line,
			      void *color_line_data,
			      void *user_data)
{
  FT_ColorLine *c = (FT_ColorLine *) color_line_data;
  switch (c->extend)
  {
    default:
    case FT_COLR_PAINT_EXTEND_PAD:     return HB_PAINT_EXTEND_PAD;
    case FT_COLR_PAINT_EXTEND_REPEAT:  return HB_PAINT_EXTEND_REPEAT;
    case FT_COLR_PAINT_EXTEND_REFLECT: return HB_PAINT_EXTEND_REFLECT;
  }
}

void
_hb_ft_paint (hb_ft_paint_context_t *c,
	      FT_OpaquePaint opaque_paint)
{
  FT_Face ft_face = c->ft_font->ft_face;
  FT_COLR_Paint paint;
  if (!FT_Get_Paint (ft_face, opaque_paint, &paint))
    return;

  switch (paint.format)
  {
    case FT_COLR_PAINTFORMAT_COLR_LAYERS:
    {
      FT_OpaquePaint other_paint = {0};
      while (FT_Get_Paint_Layers (ft_face,
				  &paint.u.colr_layers.layer_iterator,
				  &other_paint))
      {
	c->funcs->push_group (c->data);
	c->recurse (other_paint);
	c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
      }
    }
    break;
    case FT_COLR_PAINTFORMAT_SOLID:
    {
      bool is_foreground = paint.u.solid.color.palette_index ==  0xFFFF;
      hb_color_t color;
      if (is_foreground)
	color = HB_COLOR (hb_color_get_blue (c->foreground),
			  hb_color_get_green (c->foreground),
			  hb_color_get_red (c->foreground),
			  (hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
      else
      {
	if (c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index, &color))
	{
	  color = HB_COLOR (hb_color_get_blue (color),
			    hb_color_get_green (color),
			    hb_color_get_red (color),
			    (hb_color_get_alpha (color) * paint.u.solid.color.alpha) >> 14);
	}
	else
	{
	  FT_Color ft_color = c->palette[paint.u.solid.color.palette_index];
	  color = HB_COLOR (ft_color.blue,
			    ft_color.green,
			    ft_color.red,
			    (ft_color.alpha * paint.u.solid.color.alpha) >> 14);
	}
      }
      c->funcs->color (c->data, is_foreground, color);
    }
    break;
    case FT_COLR_PAINTFORMAT_LINEAR_GRADIENT:
    {
      hb_color_line_t cl = {
	&paint.u.linear_gradient.colorline,
	_hb_ft_color_line_get_color_stops, c,
	_hb_ft_color_line_get_extend, nullptr
      };

      c->funcs->linear_gradient (c->data, &cl,
				 paint.u.linear_gradient.p0.x / 65536.f,
				 paint.u.linear_gradient.p0.y / 65536.f,
				 paint.u.linear_gradient.p1.x / 65536.f,
				 paint.u.linear_gradient.p1.y / 65536.f,
				 paint.u.linear_gradient.p2.x / 65536.f,
				 paint.u.linear_gradient.p2.y / 65536.f);
    }
    break;
    case FT_COLR_PAINTFORMAT_RADIAL_GRADIENT:
    {
      hb_color_line_t cl = {
	&paint.u.linear_gradient.colorline,
	_hb_ft_color_line_get_color_stops, c,
	_hb_ft_color_line_get_extend, nullptr
      };

      c->funcs->radial_gradient (c->data, &cl,
				 paint.u.radial_gradient.c0.x / 65536.f,
				 paint.u.radial_gradient.c0.y / 65536.f,
				 paint.u.radial_gradient.r0 / 65536.f,
				 paint.u.radial_gradient.c1.x / 65536.f,
				 paint.u.radial_gradient.c1.y / 65536.f,
				 paint.u.radial_gradient.r1 / 65536.f);
    }
    break;
    case FT_COLR_PAINTFORMAT_SWEEP_GRADIENT:
    {
      hb_color_line_t cl = {
	&paint.u.linear_gradient.colorline,
	_hb_ft_color_line_get_color_stops, c,
	_hb_ft_color_line_get_extend, nullptr
      };

      c->funcs->sweep_gradient (c->data, &cl,
				paint.u.sweep_gradient.center.x / 65536.f,
				paint.u.sweep_gradient.center.y / 65536.f,
				(paint.u.sweep_gradient.start_angle / 65536.f + 1) * (float) M_PI,
				(paint.u.sweep_gradient.end_angle / 65536.f + 1) * (float) M_PI);
    }
    break;
    case FT_COLR_PAINTFORMAT_GLYPH:
    {
      c->funcs->push_inverse_root_transform (c->data, c->font);
      c->ft_font->lock.unlock ();
      c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font);
      c->ft_font->lock.lock ();
      c->funcs->push_root_transform (c->data, c->font);
      c->recurse (paint.u.glyph.paint);
      c->funcs->pop_transform (c->data);
      c->funcs->pop_clip (c->data);
      c->funcs->pop_transform (c->data);
    }
    break;
    case FT_COLR_PAINTFORMAT_COLR_GLYPH:
    {
      FT_OpaquePaint other_paint = {0};
      if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID,
				    FT_COLOR_NO_ROOT_TRANSFORM,
				    &other_paint))
      {
        bool has_clip_box;
        FT_ClipBox clip_box;
        has_clip_box = FT_Get_Color_Glyph_ClipBox (ft_face, paint.u.colr_glyph.glyphID, &clip_box);

        if (has_clip_box)
	{
	  /* The FreeType ClipBox is in scaled coordinates, whereas we need
	   * unscaled clipbox here. Oh well...
	   */

	  float upem = c->font->face->get_upem ();
	  float xscale = upem / (c->font->x_scale ? c->font->x_scale : upem);
	  float yscale = upem / (c->font->y_scale ? c->font->y_scale : upem);

          c->funcs->push_clip_rectangle (c->data,
					 clip_box.bottom_left.x * xscale,
					 clip_box.bottom_left.y * yscale,
					 clip_box.top_right.x * xscale,
					 clip_box.top_right.y * yscale);
	}

	c->recurse (other_paint);

        if (has_clip_box)
          c->funcs->pop_clip (c->data);
      }
    }
    break;
    case FT_COLR_PAINTFORMAT_TRANSFORM:
    {
      c->funcs->push_transform (c->data,
				paint.u.transform.affine.xx / 65536.f,
				paint.u.transform.affine.yx / 65536.f,
				paint.u.transform.affine.xy / 65536.f,
				paint.u.transform.affine.yy / 65536.f,
				paint.u.transform.affine.dx / 65536.f,
				paint.u.transform.affine.dy / 65536.f);
      c->recurse (paint.u.transform.paint);
      c->funcs->pop_transform (c->data);
    }
    break;
    case FT_COLR_PAINTFORMAT_TRANSLATE:
    {
      float dx = paint.u.translate.dx / 65536.f;
      float dy = paint.u.translate.dy / 65536.f;

      bool p1 = c->funcs->push_translate (c->data, dx, dy);
      c->recurse (paint.u.translate.paint);
      if (p1) c->funcs->pop_transform (c->data);
    }
    break;
    case FT_COLR_PAINTFORMAT_SCALE:
    {
      float dx = paint.u.scale.center_x / 65536.f;
      float dy = paint.u.scale.center_y / 65536.f;
      float sx = paint.u.scale.scale_x / 65536.f;
      float sy = paint.u.scale.scale_y / 65536.f;

      bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
      bool p2 = c->funcs->push_scale (c->data, sx, sy);
      bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
      c->recurse (paint.u.scale.paint);
      if (p3) c->funcs->pop_transform (c->data);
      if (p2) c->funcs->pop_transform (c->data);
      if (p1) c->funcs->pop_transform (c->data);
    }
    break;
    case FT_COLR_PAINTFORMAT_ROTATE:
    {
      float dx = paint.u.rotate.center_x / 65536.f;
      float dy = paint.u.rotate.center_y / 65536.f;
      float a = paint.u.rotate.angle / 65536.f;

      bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
      bool p2 = c->funcs->push_rotate (c->data, a);
      bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
      c->recurse (paint.u.rotate.paint);
      if (p3) c->funcs->pop_transform (c->data);
      if (p2) c->funcs->pop_transform (c->data);
      if (p1) c->funcs->pop_transform (c->data);
    }
    break;
    case FT_COLR_PAINTFORMAT_SKEW:
    {
      float dx = paint.u.skew.center_x / 65536.f;
      float dy = paint.u.skew.center_y / 65536.f;
      float sx = paint.u.skew.x_skew_angle / 65536.f;
      float sy = paint.u.skew.y_skew_angle / 65536.f;

      bool p1 = c->funcs->push_translate (c->data, +dx, +dy);
      bool p2 = c->funcs->push_skew (c->data, sx, sy);
      bool p3 = c->funcs->push_translate (c->data, -dx, -dy);
      c->recurse (paint.u.skew.paint);
      if (p3) c->funcs->pop_transform (c->data);
      if (p2) c->funcs->pop_transform (c->data);
      if (p1) c->funcs->pop_transform (c->data);
    }
    break;
    case FT_COLR_PAINTFORMAT_COMPOSITE:
    {
      c->recurse (paint.u.composite.backdrop_paint);
      c->funcs->push_group (c->data);
      c->recurse (paint.u.composite.source_paint);
      c->funcs->pop_group (c->data, _hb_ft_paint_composite_mode (paint.u.composite.composite_mode));
    }
    break;

    case FT_COLR_PAINT_FORMAT_MAX: break;
    default: HB_FALLTHROUGH;
    case FT_COLR_PAINTFORMAT_UNSUPPORTED: break;
  }
}


static bool
hb_ft_paint_glyph_colr (hb_font_t *font,
			void *font_data,
			hb_codepoint_t gid,
			hb_paint_funcs_t *paint_funcs, void *paint_data,
			unsigned int palette_index,
			hb_color_t foreground,
			void *user_data)
{
  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
  FT_Face ft_face = ft_font->ft_face;

  /* Face is locked. */

  FT_Error error;
  FT_Color*         palette;
  FT_LayerIterator  iterator;

  FT_Bool  have_layers;
  FT_UInt  layer_glyph_index;
  FT_UInt  layer_color_index;

  error = FT_Palette_Select(ft_face, palette_index, &palette);
  if (error)
    palette = NULL;

  /* COLRv1 */
  FT_OpaquePaint paint = {0};
  if (FT_Get_Color_Glyph_Paint (ft_face, gid,
			        FT_COLOR_NO_ROOT_TRANSFORM,
			        &paint))
  {
    hb_ft_paint_context_t c (ft_font, font,
			     paint_funcs, paint_data,
			     palette, palette_index, foreground);

    bool is_bounded = true;
    FT_ClipBox clip_box;
    if (FT_Get_Color_Glyph_ClipBox (ft_face, gid, &clip_box))
    {
      c.funcs->push_clip_rectangle (c.data,
				    clip_box.bottom_left.x +
				      roundf (hb_min (font->slant_xy * clip_box.bottom_left.y,
						      font->slant_xy * clip_box.top_left.y)),
				    clip_box.bottom_left.y,
				    clip_box.top_right.x +
				      roundf (hb_max (font->slant_xy * clip_box.bottom_right.y,
						      font->slant_xy * clip_box.top_right.y)),
				    clip_box.top_right.y);
    }
    else
    {

      auto *extents_funcs = hb_paint_extents_get_funcs ();
      hb_paint_extents_context_t extents_data;
      hb_ft_paint_context_t ce (ft_font, font,
			        extents_funcs, &extents_data,
			        palette, palette_index, foreground);
      ce.funcs->push_root_transform (ce.data, font);
      ce.recurse (paint);
      ce.funcs->pop_transform (ce.data);
      hb_extents_t extents = extents_data.get_extents ();
      is_bounded = extents_data.is_bounded ();

      c.funcs->push_clip_rectangle (c.data,
				    extents.xmin,
				    extents.ymin,
				    extents.xmax,
				    extents.ymax);
    }

    c.funcs->push_root_transform (c.data, font);

    if (is_bounded)
      c.recurse (paint);

    c.funcs->pop_transform (c.data);
    c.funcs->pop_clip (c.data);

    return true;
  }

  /* COLRv0 */
  iterator.p  = NULL;
  have_layers = FT_Get_Color_Glyph_Layer(ft_face,
					 gid,
					 &layer_glyph_index,
					 &layer_color_index,
					 &iterator);

  if (palette && have_layers)
  {
    do
    {
      hb_bool_t is_foreground = true;
      hb_color_t color = foreground;

      if ( layer_color_index != 0xFFFF )
      {
	FT_Color layer_color = palette[layer_color_index];
	color = HB_COLOR (layer_color.blue,
			  layer_color.green,
			  layer_color.red,
			  layer_color.alpha);
	is_foreground = false;
      }

      ft_font->lock.unlock ();
      paint_funcs->push_clip_glyph (paint_data, layer_glyph_index, font);
      ft_font->lock.lock ();
      paint_funcs->color (paint_data, is_foreground, color);
      paint_funcs->pop_clip (paint_data);

    } while (FT_Get_Color_Glyph_Layer(ft_face,
				      gid,
				      &layer_glyph_index,
				      &layer_color_index,
				      &iterator));
    return true;
  }

  return false;
}


#endif /* HB_FT_COLR_HH */
