/****************************************************************************
 *
 * ftsdfrend.c
 *
 *   Signed Distance Field renderer interface (body).
 *
 * Copyright (C) 2020 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * Written by Anuj Verma.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/services/svprop.h>
#include <freetype/ftoutln.h>
#include <freetype/ftbitmap.h>
#include "ftsdfrend.h"
#include "ftsdf.h"

#include "ftsdferrs.h"


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  sdf


  /**************************************************************************
   *
   * macros and default property values
   *
   */
#define SDF_RENDERER( rend )  ( (SDF_Renderer)rend )


  /**************************************************************************
   *
   * for setting properties
   *
   */

  /* property setter function */
  static FT_Error
  sdf_property_set( FT_Module    module,
                    const char*  property_name,
                    const void*  value,
                    FT_Bool      value_is_string )
  {
    FT_Error      error  = FT_Err_Ok;
    SDF_Renderer  render = SDF_RENDERER( FT_RENDERER( module ) );

    FT_UNUSED( value_is_string );


    if ( ft_strcmp( property_name, "spread" ) == 0 )
    {
      FT_Int  val = *(const FT_Int*)value;


      if ( val > MAX_SPREAD || val < MIN_SPREAD )
      {
        FT_TRACE0(( "[sdf] sdf_property_set:"
                    " the `spread' property can have a value\n" ));
        FT_TRACE0(( "                       "
                    " within range [%d, %d] (value provided: %d)\n",
                    MIN_SPREAD, MAX_SPREAD, val ));

        error = FT_THROW( Invalid_Argument );
        goto Exit;
      }

      render->spread = (FT_UInt)val;
      FT_TRACE7(( "[sdf] sdf_property_set:"
                  " updated property `spread' to %d\n", val ));
    }

    else if ( ft_strcmp( property_name, "flip_sign" ) == 0 )
    {
      FT_Int  val = *(const FT_Int*)value;


      render->flip_sign = val ? 1 : 0;
      FT_TRACE7(( "[sdf] sdf_property_set:"
                  " updated property `flip_sign' to %d\n", val ));
    }

    else if ( ft_strcmp( property_name, "flip_y" ) == 0 )
    {
      FT_Int  val = *(const FT_Int*)value;


      render->flip_y = val ? 1 : 0;
      FT_TRACE7(( "[sdf] sdf_property_set:"
                  " updated property `flip_y' to %d\n", val ));
    }

    else if ( ft_strcmp( property_name, "overlaps" ) == 0 )
    {
      FT_Int  val = *(const FT_Int*)value;


      render->overlaps = val;
      FT_TRACE7(( "[sdf] sdf_property_set:"
                  " updated property `overlaps' to %d\n", val ));
    }

    else
    {
      FT_TRACE0(( "[sdf] sdf_property_set:"
                  " missing property `%s'\n", property_name ));
      error = FT_THROW( Missing_Property );
    }

  Exit:
    return error;
  }


  /* property getter function */
  static FT_Error
  sdf_property_get( FT_Module    module,
                    const char*  property_name,
                    void*        value )
  {
    FT_Error      error  = FT_Err_Ok;
    SDF_Renderer  render = SDF_RENDERER( FT_RENDERER( module ) );


    if ( ft_strcmp( property_name, "spread" ) == 0 )
    {
      FT_Int*  val = (FT_Int*)value;


      *val = render->spread;
    }

    else if ( ft_strcmp( property_name, "flip_sign" ) == 0 )
    {
      FT_Int*  val = (FT_Int*)value;


      *val = render->flip_sign;
    }

    else if ( ft_strcmp( property_name, "flip_y" ) == 0 )
    {
      FT_Int*  val = (FT_Int*)value;


      *val = render->flip_y;
    }

    else if ( ft_strcmp( property_name, "overlaps" ) == 0 )
    {
      FT_Int*  val = (FT_Int*)value;


      *val = render->overlaps;
    }

    else
    {
      FT_TRACE0(( "[sdf] sdf_property_get:"
                  " missing property `%s'\n", property_name ));
      error = FT_THROW( Missing_Property );
    }

    return error;
  }


  FT_DEFINE_SERVICE_PROPERTIESREC(
    sdf_service_properties,

    (FT_Properties_SetFunc)sdf_property_set,        /* set_property */
    (FT_Properties_GetFunc)sdf_property_get )       /* get_property */


  FT_DEFINE_SERVICEDESCREC1(
    sdf_services,

    FT_SERVICE_ID_PROPERTIES, &sdf_service_properties )


  static FT_Module_Interface
  ft_sdf_requester( FT_Renderer  render,
                    const char*  module_interface )
  {
    FT_UNUSED( render );

    return ft_service_list_lookup( sdf_services, module_interface );
  }


  /*************************************************************************/
  /*************************************************************************/
  /**                                                                     **/
  /**  OUTLINE TO SDF CONVERTER                                           **/
  /**                                                                     **/
  /*************************************************************************/
  /*************************************************************************/

  /**************************************************************************
   *
   * interface functions
   *
   */

  static FT_Error
  ft_sdf_init( FT_Renderer  render )
  {
    SDF_Renderer  sdf_render = SDF_RENDERER( render );


    sdf_render->spread    = DEFAULT_SPREAD;
    sdf_render->flip_sign = 0;
    sdf_render->flip_y    = 0;
    sdf_render->overlaps  = 0;

    return FT_Err_Ok;
  }


  static void
  ft_sdf_done( FT_Renderer  render )
  {
    FT_UNUSED( render );
  }


  /* generate signed distance field from a glyph's slot image */
  static FT_Error
  ft_sdf_render( FT_Renderer       module,
                 FT_GlyphSlot      slot,
                 FT_Render_Mode    mode,
                 const FT_Vector*  origin )
  {
    FT_Error     error   = FT_Err_Ok;
    FT_Outline*  outline = &slot->outline;
    FT_Bitmap*   bitmap  = &slot->bitmap;
    FT_Memory    memory  = NULL;
    FT_Renderer  render  = NULL;

    FT_Pos  x_shift = 0;
    FT_Pos  y_shift = 0;

    FT_Pos  x_pad = 0;
    FT_Pos  y_pad = 0;

    SDF_Raster_Params  params;
    SDF_Renderer       sdf_module = SDF_RENDERER( module );


    render = &sdf_module->root;
    memory = render->root.memory;

    /* check whether slot format is correct before rendering */
    if ( slot->format != render->glyph_format )
    {
      error = FT_THROW( Invalid_Glyph_Format );
      goto Exit;
    }

    /* check whether render mode is correct */
    if ( mode != FT_RENDER_MODE_SDF )
    {
      FT_ERROR(( "[sdf] ft_sdf_render:"
                 " sdf module only render when"
                 " using `FT_RENDER_MODE_SDF'\n" ));
      error = FT_THROW( Cannot_Render_Glyph );
      goto Exit;
    }

    /* deallocate the previously allocated bitmap */
    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    {
      FT_FREE( bitmap->buffer );
      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    }

    /* preset the bitmap using the glyph's outline;         */
    /* the sdf bitmap is similar to an antialiased bitmap   */
    /* with a slightly bigger size and different pixel mode */
    if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) )
    {
      error = FT_THROW( Raster_Overflow );
      goto Exit;
    }

    if ( !bitmap->rows || !bitmap->pitch )
      goto Exit;

    /* the padding will simply be equal to the `spread' */
    x_pad = sdf_module->spread;
    y_pad = sdf_module->spread;

    /* apply the padding; will be in all the directions */
    bitmap->rows  += y_pad * 2;
    bitmap->width += x_pad * 2;

    /* ignore the pitch, pixel mode and set custom */
    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY16;
    bitmap->pitch      = bitmap->width * 2;
    bitmap->num_grays  = 65535;

    /* allocate new buffer */
    if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
      goto Exit;

    slot->internal->flags |= FT_GLYPH_OWN_BITMAP;

    x_shift  = 64 * -( slot->bitmap_left - x_pad );
    y_shift  = 64 * -( slot->bitmap_top + y_pad );
    y_shift += 64 * (FT_Int)bitmap->rows;

    if ( origin )
    {
      x_shift += origin->x;
      y_shift += origin->y;
    }

    /* translate outline to render it into the bitmap */
    if ( x_shift || y_shift )
      FT_Outline_Translate( outline, x_shift, y_shift );

    /* set up parameters */
    params.root.target = bitmap;
    params.root.source = outline;
    params.root.flags  = FT_RASTER_FLAG_SDF;
    params.spread      = sdf_module->spread;
    params.flip_sign   = sdf_module->flip_sign;
    params.flip_y      = sdf_module->flip_y;
    params.overlaps    = sdf_module->overlaps;

    /* render the outline */
    error = render->raster_render( render->raster,
                                   (const FT_Raster_Params*)&params );

  Exit:
    if ( !error )
    {
      /* the glyph is successfully rendered to a bitmap */
      slot->format = FT_GLYPH_FORMAT_BITMAP;
    }
    else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    {
      FT_FREE( bitmap->buffer );
      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    }

    if ( x_shift || y_shift )
      FT_Outline_Translate( outline, -x_shift, -y_shift );

    return error;
  }


  /* transform the glyph using matrix and/or delta */
  static FT_Error
  ft_sdf_transform( FT_Renderer       render,
                    FT_GlyphSlot      slot,
                    const FT_Matrix*  matrix,
                    const FT_Vector*  delta )
  {
    FT_Error  error = FT_Err_Ok;


    if ( slot->format != render->glyph_format )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    if ( matrix )
      FT_Outline_Transform( &slot->outline, matrix );

    if ( delta )
      FT_Outline_Translate( &slot->outline, delta->x, delta->y );

  Exit:
    return error;
  }


  /* return the control box of a glyph's outline */
  static void
  ft_sdf_get_cbox( FT_Renderer   render,
                   FT_GlyphSlot  slot,
                   FT_BBox*      cbox )
  {
    FT_ZERO( cbox );

    if ( slot->format == render->glyph_format )
      FT_Outline_Get_CBox( &slot->outline, cbox );
  }


  /* set render specific modes or attributes */
  static FT_Error
  ft_sdf_set_mode( FT_Renderer  render,
                   FT_ULong     mode_tag,
                   FT_Pointer   data )
  {
    /* pass it to the rasterizer */
    return render->clazz->raster_class->raster_set_mode( render->raster,
                                                         mode_tag,
                                                         data );
  }


  FT_DEFINE_RENDERER(
    ft_sdf_renderer_class,

    FT_MODULE_RENDERER,
    sizeof ( SDF_Renderer_Module ),

    "sdf",
    0x10000L,
    0x20000L,

    NULL,

    (FT_Module_Constructor)ft_sdf_init,
    (FT_Module_Destructor) ft_sdf_done,
    (FT_Module_Requester)  ft_sdf_requester,

    FT_GLYPH_FORMAT_OUTLINE,

    (FT_Renderer_RenderFunc)   ft_sdf_render,     /* render_glyph    */
    (FT_Renderer_TransformFunc)ft_sdf_transform,  /* transform_glyph */
    (FT_Renderer_GetCBoxFunc)  ft_sdf_get_cbox,   /* get_glyph_cbox  */
    (FT_Renderer_SetModeFunc)  ft_sdf_set_mode,   /* set_mode        */

    (FT_Raster_Funcs*)&ft_sdf_raster              /* raster_class    */
  )


  /*************************************************************************/
  /*************************************************************************/
  /**                                                                     **/
  /**  BITMAP TO SDF CONVERTER                                            **/
  /**                                                                     **/
  /*************************************************************************/
  /*************************************************************************/

  /* generate signed distance field from glyph's bitmap */
  static FT_Error
  ft_bsdf_render( FT_Renderer       module,
                  FT_GlyphSlot      slot,
                  FT_Render_Mode    mode,
                  const FT_Vector*  origin )
  {
    FT_Error   error  = FT_Err_Ok;
    FT_Memory  memory = NULL;

    FT_Bitmap*   bitmap  = &slot->bitmap;
    FT_Renderer  render  = NULL;
    FT_Bitmap    target;

    FT_Pos  x_pad = 0;
    FT_Pos  y_pad = 0;

    SDF_Raster_Params  params;
    SDF_Renderer       sdf_module = SDF_RENDERER( module );


    /* initialize the bitmap in case any error occurs */
    FT_Bitmap_Init( &target );

    render = &sdf_module->root;
    memory = render->root.memory;

    /* check whether slot format is correct before rendering */
    if ( slot->format != render->glyph_format )
    {
      FT_ERROR(( "ft_bsdf_render: slot format must be a bitmap\n" ));

      error = FT_THROW( Invalid_Glyph_Format );
      goto Exit;
    }

    /* check whether render mode is correct */
    if ( mode != FT_RENDER_MODE_SDF )
    {
      FT_ERROR(( "ft_bsdf_render: need `FT_RENDER_MODE_SDF' mode\n" ));

      error = FT_THROW( Cannot_Render_Glyph );
      goto Exit;
    }

    if ( origin )
    {
      FT_ERROR(( "ft_bsdf_render: can't translate the bitmap\n" ));

      error = FT_THROW( Unimplemented_Feature );
      goto Exit;
    }

    if ( !bitmap->rows || !bitmap->pitch )
      goto Exit;

    FT_Bitmap_New( &target );

    /* padding will simply be equal to `spread` */
    x_pad = sdf_module->spread;
    y_pad = sdf_module->spread;

    /* apply padding, which extends to all directions */
    target.rows  = bitmap->rows + y_pad * 2;
    target.width = bitmap->width + x_pad * 2;

    /* set up the target bitmap */
    target.pixel_mode = FT_PIXEL_MODE_GRAY16;
    target.pitch      = target.width * 2;
    target.num_grays  = 65535;

    if ( FT_ALLOC_MULT( target.buffer, target.rows, target.pitch ) )
      goto Exit;

    /* set up parameters */
    params.root.target = &target;
    params.root.source = bitmap;
    params.root.flags  = FT_RASTER_FLAG_SDF;
    params.spread      = sdf_module->spread;
    params.flip_sign   = sdf_module->flip_sign;
    params.flip_y      = sdf_module->flip_y;

    error = render->raster_render( render->raster,
                                   (const FT_Raster_Params*)&params );

  Exit:
    if ( !error )
    {
      /* the glyph is successfully converted to a SDF */
      if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
      {
        FT_FREE( bitmap->buffer );
        slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
      }

      slot->bitmap           = target;
      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
    }
    else if ( target.buffer )
      FT_FREE( target.buffer );

    return error;
  }


  FT_DEFINE_RENDERER(
    ft_bitmap_sdf_renderer_class,

    FT_MODULE_RENDERER,
    sizeof ( SDF_Renderer_Module ),

    "bsdf",
    0x10000L,
    0x20000L,

    NULL,

    (FT_Module_Constructor)ft_sdf_init,
    (FT_Module_Destructor) ft_sdf_done,
    (FT_Module_Requester)  ft_sdf_requester,

    FT_GLYPH_FORMAT_BITMAP,

    (FT_Renderer_RenderFunc)   ft_bsdf_render,    /* render_glyph    */
    (FT_Renderer_TransformFunc)ft_sdf_transform,  /* transform_glyph */
    (FT_Renderer_GetCBoxFunc)  ft_sdf_get_cbox,   /* get_glyph_cbox  */
    (FT_Renderer_SetModeFunc)  ft_sdf_set_mode,   /* set_mode        */

    (FT_Raster_Funcs*)&ft_bitmap_sdf_raster       /* raster_class    */
  )


/* END */
