/****************************************************************************
 *
 * ftsmooth.c
 *
 *   Anti-aliasing renderer interface (body).
 *
 * Copyright (C) 2000-2020 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * 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/ftoutln.h>
#include "ftsmooth.h"
#include "ftgrays.h"

#include "ftsmerrs.h"


  /* sets render-specific mode */
  static FT_Error
  ft_smooth_set_mode( FT_Renderer  render,
                      FT_ULong     mode_tag,
                      FT_Pointer   data )
  {
    /* we simply pass it to the raster */
    return render->clazz->raster_class->raster_set_mode( render->raster,
                                                         mode_tag,
                                                         data );
  }

  /* transform a given glyph image */
  static FT_Error
  ft_smooth_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 glyph's control box */
  static void
  ft_smooth_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 );
  }

  typedef struct TOrigin_
  {
    unsigned char*  origin;  /* pixmap origin at the bottom-left */
    int             pitch;   /* pitch to go down one row */

  } TOrigin;

#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING

  /* initialize renderer -- init its raster */
  static FT_Error
  ft_smooth_init( FT_Renderer  render )
  {
    FT_Vector*  sub = render->root.library->lcd_geometry;


    /* set up default subpixel geometry for striped RGB panels. */
    sub[0].x = -21;
    sub[0].y = 0;
    sub[1].x = 0;
    sub[1].y = 0;
    sub[2].x = 21;
    sub[2].y = 0;

    render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );

    return 0;
  }


  /* This function writes every third byte in direct rendering mode */
  static void
  ft_smooth_lcd_spans( int             y,
                       int             count,
                       const FT_Span*  spans,
                       TOrigin*        target )
  {
    unsigned char*  dst_line = target->origin - y * target->pitch;
    unsigned char*  dst;
    unsigned short  w;


    for ( ; count--; spans++ )
      for ( dst = dst_line + spans->x * 3, w = spans->len; w--; dst += 3 )
        *dst = spans->coverage;
  }


  static FT_Error
  ft_smooth_raster_lcd( FT_Renderer  render,
                        FT_Outline*  outline,
                        FT_Bitmap*   bitmap )
  {
    FT_Error      error = FT_Err_Ok;
    FT_Vector*    sub   = render->root.library->lcd_geometry;
    FT_Pos        x, y;

    FT_Raster_Params   params;
    TOrigin            target;


    /* Render 3 separate coverage bitmaps, shifting the outline.  */
    /* Set up direct rendering to record them on each third byte. */
    params.target     = bitmap;
    params.source     = outline;
    params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
    params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans;
    params.user       = &target;

    params.clip_box.xMin = 0;
    params.clip_box.yMin = 0;
    params.clip_box.xMax = bitmap->width;
    params.clip_box.yMax = bitmap->rows;

    if ( bitmap->pitch < 0 )
      target.origin = bitmap->buffer;
    else
      target.origin = bitmap->buffer
                      + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;

    target.pitch = bitmap->pitch;

    FT_Outline_Translate( outline,
                          -sub[0].x,
                          -sub[0].y );
    error = render->raster_render( render->raster, &params );
    x = sub[0].x;
    y = sub[0].y;
    if ( error )
      goto Exit;

    target.origin++;
    FT_Outline_Translate( outline,
                          sub[0].x - sub[1].x,
                          sub[0].y - sub[1].y );
    error = render->raster_render( render->raster, &params );
    x = sub[1].x;
    y = sub[1].y;
    if ( error )
      goto Exit;

    target.origin++;
    FT_Outline_Translate( outline,
                          sub[1].x - sub[2].x,
                          sub[1].y - sub[2].y );
    error = render->raster_render( render->raster, &params );
    x = sub[2].x;
    y = sub[2].y;

  Exit:
    FT_Outline_Translate( outline, x, y );

    return error;
  }


  static FT_Error
  ft_smooth_raster_lcdv( FT_Renderer  render,
                         FT_Outline*  outline,
                         FT_Bitmap*   bitmap )
  {
    FT_Error     error = FT_Err_Ok;
    int          pitch = bitmap->pitch;
    FT_Vector*   sub   = render->root.library->lcd_geometry;
    FT_Pos       x, y;

    FT_Raster_Params  params;


    params.target = bitmap;
    params.source = outline;
    params.flags  = FT_RASTER_FLAG_AA;

    /* Render 3 separate coverage bitmaps, shifting the outline. */
    /* Notice that the subpixel geometry vectors are rotated.    */
    /* Triple the pitch to render on each third row.            */
    bitmap->pitch *= 3;
    bitmap->rows  /= 3;

    FT_Outline_Translate( outline,
                          -sub[0].y,
                          sub[0].x );
    error = render->raster_render( render->raster, &params );
    x = sub[0].y;
    y = -sub[0].x;
    if ( error )
      goto Exit;

    bitmap->buffer += pitch;
    FT_Outline_Translate( outline,
                          sub[0].y - sub[1].y,
                          sub[1].x - sub[0].x );
    error = render->raster_render( render->raster, &params );
    x = sub[1].y;
    y = -sub[1].x;
    bitmap->buffer -= pitch;
    if ( error )
      goto Exit;

    bitmap->buffer += 2 * pitch;
    FT_Outline_Translate( outline,
                          sub[1].y - sub[2].y,
                          sub[2].x - sub[1].x );
    error = render->raster_render( render->raster, &params );
    x = sub[2].y;
    y = -sub[2].x;
    bitmap->buffer -= 2 * pitch;

  Exit:
    FT_Outline_Translate( outline, x, y );

    bitmap->pitch /= 3;
    bitmap->rows  *= 3;

    return error;
  }

#else   /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */

  /* initialize renderer -- init its raster */
  static FT_Error
  ft_smooth_init( FT_Renderer  render )
  {
    /* set up default LCD filtering */
    FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT );

    render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );

    return 0;
  }


  static FT_Error
  ft_smooth_raster_lcd( FT_Renderer  render,
                        FT_Outline*  outline,
                        FT_Bitmap*   bitmap )
  {
    FT_Error    error      = FT_Err_Ok;
    FT_Vector*  points     = outline->points;
    FT_Vector*  points_end = FT_OFFSET( points, outline->n_points );
    FT_Vector*  vec;

    FT_Raster_Params  params;


    params.target = bitmap;
    params.source = outline;
    params.flags  = FT_RASTER_FLAG_AA;

    /* implode outline */
    for ( vec = points; vec < points_end; vec++ )
      vec->x *= 3;

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

    /* deflate outline */
    for ( vec = points; vec < points_end; vec++ )
      vec->x /= 3;

    return error;
  }


  static FT_Error
  ft_smooth_raster_lcdv( FT_Renderer  render,
                         FT_Outline*  outline,
                         FT_Bitmap*   bitmap )
  {
    FT_Error    error      = FT_Err_Ok;
    FT_Vector*  points     = outline->points;
    FT_Vector*  points_end = FT_OFFSET( points, outline->n_points );
    FT_Vector*  vec;

    FT_Raster_Params  params;


    params.target = bitmap;
    params.source = outline;
    params.flags  = FT_RASTER_FLAG_AA;

    /* implode outline */
    for ( vec = points; vec < points_end; vec++ )
      vec->y *= 3;

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

    /* deflate outline */
    for ( vec = points; vec < points_end; vec++ )
      vec->y /= 3;

    return error;
  }

#endif  /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */

/* Oversampling scale to be used in rendering overlaps */
#define SCALE  ( 1 << 2 )

  /* This function averages inflated spans in direct rendering mode */
  static void
  ft_smooth_overlap_spans( int             y,
                           int             count,
                           const FT_Span*  spans,
                           TOrigin*        target )
  {
    unsigned char*  dst = target->origin - ( y / SCALE ) * target->pitch;
    unsigned short  x;
    unsigned int    cover, sum;


    /* When accumulating the oversampled spans we need to assure that  */
    /* fully covered pixels are equal to 255 and do not overflow.      */
    /* It is important that the SCALE is a power of 2, each subpixel   */
    /* cover can also reach a power of 2 after rounding, and the total */
    /* is clamped to 255 when it adds up to 256.                       */
    for ( ; count--; spans++ )
    {
      cover = ( spans->coverage + SCALE * SCALE / 2 ) / ( SCALE * SCALE );
      for ( x = 0; x < spans->len; x++ )
      {
        sum                           = dst[( spans->x + x ) / SCALE] + cover;
        dst[( spans->x + x ) / SCALE] = (unsigned char)( sum - ( sum >> 8 ) );
      }
    }
  }


  static FT_Error
  ft_smooth_raster_overlap( FT_Renderer  render,
                            FT_Outline*  outline,
                            FT_Bitmap*   bitmap )
  {
    FT_Error    error      = FT_Err_Ok;
    FT_Vector*  points     = outline->points;
    FT_Vector*  points_end = FT_OFFSET( points, outline->n_points );
    FT_Vector*  vec;

    FT_Raster_Params   params;
    TOrigin            target;


    /* Reject outlines that are too wide for 16-bit FT_Span.       */
    /* Other limits are applied upstream with the same error code. */
    if ( bitmap->width * SCALE > 0x7FFF )
      return FT_THROW( Raster_Overflow );

    /* Set up direct rendering to average oversampled spans. */
    params.target     = bitmap;
    params.source     = outline;
    params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
    params.gray_spans = (FT_SpanFunc)ft_smooth_overlap_spans;
    params.user       = &target;

    params.clip_box.xMin = 0;
    params.clip_box.yMin = 0;
    params.clip_box.xMax = bitmap->width * SCALE;
    params.clip_box.yMax = bitmap->rows  * SCALE;

    if ( bitmap->pitch < 0 )
      target.origin = bitmap->buffer;
    else
      target.origin = bitmap->buffer
                      + ( bitmap->rows - 1 ) * (unsigned int)bitmap->pitch;

    target.pitch = bitmap->pitch;

    /* inflate outline */
    for ( vec = points; vec < points_end; vec++ )
    {
      vec->x *= SCALE;
      vec->y *= SCALE;
    }

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

    /* deflate outline */
    for ( vec = points; vec < points_end; vec++ )
    {
      vec->x /= SCALE;
      vec->y /= SCALE;
    }

    return error;
  }

#undef SCALE

  static FT_Error
  ft_smooth_render( FT_Renderer       render,
                    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  = render->root.memory;
    FT_Pos       x_shift = 0;
    FT_Pos       y_shift = 0;


    /* check glyph image format */
    if ( slot->format != render->glyph_format )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    /* check mode */
    if ( mode != FT_RENDER_MODE_NORMAL &&
         mode != FT_RENDER_MODE_LIGHT  &&
         mode != FT_RENDER_MODE_LCD    &&
         mode != FT_RENDER_MODE_LCD_V  )
    {
      error = FT_THROW( Cannot_Render_Glyph );
      goto Exit;
    }

    /* release old bitmap buffer */
    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
    {
      FT_FREE( bitmap->buffer );
      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
    }

    if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) )
    {
      error = FT_THROW( Raster_Overflow );
      goto Exit;
    }

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

    /* allocate new one */
    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;
    y_shift = 64 * -slot->bitmap_top;
    if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V )
      y_shift += 64 * (FT_Int)bitmap->rows / 3;
    else
      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 );

    if ( mode == FT_RENDER_MODE_NORMAL ||
         mode == FT_RENDER_MODE_LIGHT  )
    {
      if ( outline->flags & FT_OUTLINE_OVERLAP )
        error = ft_smooth_raster_overlap( render, outline, bitmap );
      else
      {
        FT_Raster_Params  params;


        params.target = bitmap;
        params.source = outline;
        params.flags  = FT_RASTER_FLAG_AA;

        error = render->raster_render( render->raster, &params );
      }
    }
    else
    {
      if ( mode == FT_RENDER_MODE_LCD )
        error = ft_smooth_raster_lcd ( render, outline, bitmap );
      else if ( mode == FT_RENDER_MODE_LCD_V )
        error = ft_smooth_raster_lcdv( render, outline, bitmap );

#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING

      /* finally apply filtering */
      {
        FT_Byte*                 lcd_weights;
        FT_Bitmap_LcdFilterFunc  lcd_filter_func;


        /* Per-face LCD filtering takes priority if set up. */
        if ( slot->face && slot->face->internal->lcd_filter_func )
        {
          lcd_weights     = slot->face->internal->lcd_weights;
          lcd_filter_func = slot->face->internal->lcd_filter_func;
        }
        else
        {
          lcd_weights     = slot->library->lcd_weights;
          lcd_filter_func = slot->library->lcd_filter_func;
        }

        if ( lcd_filter_func )
          lcd_filter_func( bitmap, lcd_weights );
      }

#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */

    }

  Exit:
    if ( !error )
    {
      /* everything is fine; the glyph is now officially 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;
  }


  FT_DEFINE_RENDERER(
    ft_smooth_renderer_class,

      FT_MODULE_RENDERER,
      sizeof ( FT_RendererRec ),

      "smooth",
      0x10000L,
      0x20000L,

      NULL,    /* module specific interface */

      (FT_Module_Constructor)ft_smooth_init,  /* module_init   */
      (FT_Module_Destructor) NULL,            /* module_done   */
      (FT_Module_Requester)  NULL,            /* get_interface */

    FT_GLYPH_FORMAT_OUTLINE,

    (FT_Renderer_RenderFunc)   ft_smooth_render,     /* render_glyph    */
    (FT_Renderer_TransformFunc)ft_smooth_transform,  /* transform_glyph */
    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,   /* get_glyph_cbox  */
    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,   /* set_mode        */

    (FT_Raster_Funcs*)&ft_grays_raster               /* raster_class    */
  )


/* END */
