/****************************************************************************
 *
 * ftsdfrend.c
 *
 *   Signed Distance Field renderer interface (body).
 *
 * Copyright (C) 2020-2021 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_Bool  val = *(const FT_Bool*)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 */
