/****************************************************************************
 *
 * ftsmooth.c
 *
 *   Anti-aliasing renderer interface (body).
 *
 * Copyright (C) 2000-2022 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.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.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 */
