/****************************************************************************
 *
 * ftcsbits.c
 *
 *   FreeType sbits manager (body).
 *
 * Copyright (C) 2000-2024 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/ftcache.h>
#include "ftcsbits.h"
#include <freetype/internal/ftobjs.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/fterrors.h>

#include "ftccback.h"
#include "ftcerror.h"

#undef  FT_COMPONENT
#define FT_COMPONENT  cache


  /*************************************************************************/
  /*************************************************************************/
  /*****                                                               *****/
  /*****                     SBIT CACHE NODES                          *****/
  /*****                                                               *****/
  /*************************************************************************/
  /*************************************************************************/


  static FT_Error
  ftc_sbit_copy_bitmap( FTC_SBit    sbit,
                        FT_Bitmap*  bitmap,
                        FT_Memory   memory )
  {
    FT_Error  error;
    FT_Int    pitch = bitmap->pitch;
    FT_ULong  size;


    if ( pitch < 0 )
      pitch = -pitch;

    size = (FT_ULong)pitch * bitmap->rows;

    if ( !FT_QALLOC( sbit->buffer, size ) )
      FT_MEM_COPY( sbit->buffer, bitmap->buffer, size );

    return error;
  }


  FT_LOCAL_DEF( void )
  ftc_snode_free( FTC_Node   ftcsnode,
                  FTC_Cache  cache )
  {
    FTC_SNode  snode  = (FTC_SNode)ftcsnode;
    FTC_SBit   sbit   = snode->sbits;
    FT_UInt    count  = snode->count;
    FT_Memory  memory = cache->memory;


    for ( ; count > 0; sbit++, count-- )
      FT_FREE( sbit->buffer );

    FTC_GNode_Done( FTC_GNODE( snode ), cache );

    FT_FREE( snode );
  }


  FT_LOCAL_DEF( void )
  FTC_SNode_Free( FTC_SNode  snode,
                  FTC_Cache  cache )
  {
    ftc_snode_free( FTC_NODE( snode ), cache );
  }


  /*
   * This function tries to load a small bitmap within a given FTC_SNode.
   * Note that it returns a non-zero error code _only_ in the case of
   * out-of-memory condition.  For all other errors (e.g., corresponding
   * to a bad font file), this function will mark the sbit as `unavailable'
   * and return a value of 0.
   *
   * You should also read the comment within the @ftc_snode_compare
   * function below to see how out-of-memory is handled during a lookup.
   */
  static FT_Error
  ftc_snode_load( FTC_SNode    snode,
                  FTC_Manager  manager,
                  FT_UInt      gindex,
                  FT_ULong    *asize )
  {
    FT_Error          error;
    FTC_GNode         gnode  = FTC_GNODE( snode );
    FTC_Family        family = gnode->family;
    FT_Face           face;
    FTC_SBit          sbit;
    FTC_SFamilyClass  clazz;


    if ( gindex - gnode->gindex >= snode->count )
    {
      FT_ERROR(( "ftc_snode_load: invalid glyph index" ));
      return FT_THROW( Invalid_Argument );
    }

    sbit  = snode->sbits + ( gindex - gnode->gindex );
    clazz = (FTC_SFamilyClass)family->clazz;

    error = clazz->family_load_glyph( family, gindex, manager, &face );
    if ( error )
      goto BadGlyph;

    {
      FT_Int        temp;
      FT_GlyphSlot  slot   = face->glyph;
      FT_Bitmap*    bitmap = &slot->bitmap;
      FT_Pos        xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */


      if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
      {
        FT_TRACE0(( "ftc_snode_load:"
                    " glyph loaded didn't return a bitmap\n" ));
        goto BadGlyph;
      }

      /* Check whether our values fit into 8/16-bit containers! */
      /* If this is not the case, our bitmap is too large       */
      /* and we will leave it as `missing' with sbit.buffer = 0 */

#define CHECK_CHAR( d )  ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d )
#define CHECK_BYTE( d )  ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d )
#define CHECK_SHRT( d )  ( temp = (FT_Short)d, (FT_Int)temp == (FT_Int) d )

      /* horizontal advance in pixels */
      xadvance = ( slot->advance.x + 32 ) >> 6;
      yadvance = ( slot->advance.y + 32 ) >> 6;

      if ( !CHECK_BYTE( bitmap->rows  )     ||
           !CHECK_BYTE( bitmap->width )     ||
           !CHECK_SHRT( bitmap->pitch )     ||
           !CHECK_CHAR( slot->bitmap_left ) ||
           !CHECK_CHAR( slot->bitmap_top  ) ||
           !CHECK_CHAR( xadvance )          ||
           !CHECK_CHAR( yadvance )          )
      {
        FT_TRACE2(( "ftc_snode_load:"
                    " glyph too large for small bitmap cache\n"));
        goto BadGlyph;
      }

      sbit->width     = (FT_Byte)bitmap->width;
      sbit->height    = (FT_Byte)bitmap->rows;
      sbit->pitch     = (FT_Short)bitmap->pitch;
      sbit->left      = (FT_Char)slot->bitmap_left;
      sbit->top       = (FT_Char)slot->bitmap_top;
      sbit->xadvance  = (FT_Char)xadvance;
      sbit->yadvance  = (FT_Char)yadvance;
      sbit->format    = (FT_Byte)bitmap->pixel_mode;
      sbit->max_grays = (FT_Byte)( bitmap->num_grays - 1 );

      if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
      {
        /* take the bitmap ownership */
        sbit->buffer = bitmap->buffer;
        slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
      }
      else
      {
        /* copy the bitmap into a new buffer -- ignore error */
        error = ftc_sbit_copy_bitmap( sbit, bitmap, manager->memory );
      }

      /* now, compute size */
      if ( asize )
        *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height;

    } /* glyph loading successful */

    /* ignore the errors that might have occurred --   */
    /* we mark unloaded glyphs with `sbit.buffer == 0' */
    /* and `width == 255', `height == 0'               */
    /*                                                 */
    if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) )
    {
    BadGlyph:
      sbit->width  = 255;
      sbit->height = 0;
      sbit->buffer = NULL;
      error        = FT_Err_Ok;
      if ( asize )
        *asize = 0;
    }

    return error;
  }


  FT_LOCAL_DEF( FT_Error )
  FTC_SNode_New( FTC_SNode  *psnode,
                 FTC_GQuery  gquery,
                 FTC_Cache   cache )
  {
    FT_Memory   memory = cache->memory;
    FT_Error    error;
    FTC_SNode   snode  = NULL;
    FT_UInt     gindex = gquery->gindex;
    FTC_Family  family = gquery->family;

    FTC_SFamilyClass  clazz = FTC_CACHE_SFAMILY_CLASS( cache );
    FT_UInt           total;
    FT_UInt           node_count;


    total = clazz->family_get_count( family, cache->manager );
    if ( total == 0 || gindex >= total )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    if ( !FT_QNEW( snode ) )
    {
      FT_UInt  count, start;


      start = gindex - ( gindex % FTC_SBIT_ITEMS_PER_NODE );
      count = total - start;
      if ( count > FTC_SBIT_ITEMS_PER_NODE )
        count = FTC_SBIT_ITEMS_PER_NODE;

      FTC_GNode_Init( FTC_GNODE( snode ), start, family );

      snode->count = count;
      for ( node_count = 0; node_count < count; node_count++ )
      {
        snode->sbits[node_count].width  = 255;
        snode->sbits[node_count].height = 0;
        snode->sbits[node_count].buffer = NULL;
      }

      error = ftc_snode_load( snode,
                              cache->manager,
                              gindex,
                              NULL );
      if ( error )
      {
        FTC_SNode_Free( snode, cache );
        snode = NULL;
      }
    }

  Exit:
    *psnode = snode;
    return error;
  }


  FT_LOCAL_DEF( FT_Error )
  ftc_snode_new( FTC_Node   *ftcpsnode,
                 FT_Pointer  ftcgquery,
                 FTC_Cache   cache )
  {
    FTC_SNode  *psnode = (FTC_SNode*)ftcpsnode;
    FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;


    return FTC_SNode_New( psnode, gquery, cache );
  }


  FT_LOCAL_DEF( FT_Offset )
  ftc_snode_weight( FTC_Node   ftcsnode,
                    FTC_Cache  cache )
  {
    FTC_SNode  snode = (FTC_SNode)ftcsnode;
    FT_UInt    count = snode->count;
    FTC_SBit   sbit  = snode->sbits;
    FT_Int     pitch;
    FT_Offset  size;

    FT_UNUSED( cache );


    FT_ASSERT( snode->count <= FTC_SBIT_ITEMS_PER_NODE );

    /* the node itself */
    size = sizeof ( *snode );

    for ( ; count > 0; count--, sbit++ )
    {
      if ( sbit->buffer )
      {
        pitch = sbit->pitch;
        if ( pitch < 0 )
          pitch = -pitch;

        /* add the size of a given glyph image */
        size += (FT_Offset)pitch * sbit->height;
      }
    }

    return size;
  }


#if 0

  FT_LOCAL_DEF( FT_Offset )
  FTC_SNode_Weight( FTC_SNode  snode )
  {
    return ftc_snode_weight( FTC_NODE( snode ), NULL );
  }

#endif /* 0 */


  FT_LOCAL_DEF( FT_Bool )
  ftc_snode_compare( FTC_Node    ftcsnode,
                     FT_Pointer  ftcgquery,
                     FTC_Cache   cache,
                     FT_Bool*    list_changed )
  {
    FTC_SNode   snode  = (FTC_SNode)ftcsnode;
    FTC_GQuery  gquery = (FTC_GQuery)ftcgquery;
    FTC_GNode   gnode  = FTC_GNODE( snode );
    FT_UInt     gindex = gquery->gindex;
    FT_Bool     result;


    if ( list_changed )
      *list_changed = FALSE;
    result = FT_BOOL( gnode->family == gquery->family       &&
                      gindex - gnode->gindex < snode->count );
    if ( result )
    {
      /* check if we need to load the glyph bitmap now */
      FTC_SBit  sbit = snode->sbits + ( gindex - gnode->gindex );


      /*
       * The following code illustrates what to do when you want to
       * perform operations that may fail within a lookup function.
       *
       * Here, we want to load a small bitmap on-demand; we thus
       * need to call the `ftc_snode_load' function which may return
       * a non-zero error code only when we are out of memory (OOM).
       *
       * The correct thing to do is to use @FTC_CACHE_TRYLOOP and
       * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop
       * that is capable of flushing the cache incrementally when
       * an OOM errors occur.
       *
       * However, we need to `lock' the node before this operation to
       * prevent it from being flushed within the loop.
       *
       * When we exit the loop, we unlock the node, then check the `error'
       * variable.  If it is non-zero, this means that the cache was
       * completely flushed and that no usable memory was found to load
       * the bitmap.
       *
       * We then prefer to return a value of 0 (i.e., NO MATCH).  This
       * ensures that the caller will try to allocate a new node.
       * This operation consequently _fail_ and the lookup function
       * returns the appropriate OOM error code.
       *
       * Note that `buffer == NULL && width == 255' is a hack used to
       * tag `unavailable' bitmaps in the array.  We should never try
       * to load these.
       *
       */

      if ( !sbit->buffer && sbit->width == 255 )
      {
        FT_ULong  size;
        FT_Error  error;


        ftcsnode->ref_count++;  /* lock node to prevent flushing */
                                /* in retry loop                 */

        FTC_CACHE_TRYLOOP( cache )
        {
          error = ftc_snode_load( snode, cache->manager, gindex, &size );
        }
        FTC_CACHE_TRYLOOP_END( list_changed )

        ftcsnode->ref_count--;  /* unlock the node */

        if ( error )
          result = 0;
        else
          cache->manager->cur_weight += size;
      }
    }

    return result;
  }

/* END */
