/****************************************************************************
 *
 * afloader.c
 *
 *   Auto-fitter glyph loading routines (body).
 *
 * Copyright (C) 2003-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 "afglobal.h"
#include "afloader.h"
#include "afhints.h"
#include "aferrors.h"
#include "afmodule.h"

#include <freetype/internal/ftcalc.h>


  /* Initialize glyph loader. */

  FT_LOCAL_DEF( void )
  af_loader_init( AF_Loader      loader,
                  AF_GlyphHints  hints )
  {
    FT_ZERO( loader );

    loader->hints = hints;
  }


  /* Reset glyph loader and compute globals if necessary. */

  FT_LOCAL_DEF( FT_Error )
  af_loader_reset( AF_Loader  loader,
                   AF_Module  module,
                   FT_Face    face )
  {
    FT_Error  error = FT_Err_Ok;


    loader->face    = face;
    loader->globals = (AF_FaceGlobals)face->autohint.data;

    if ( !loader->globals )
    {
      error = af_face_globals_new( face, &loader->globals, module );
      if ( !error )
      {
        face->autohint.data =
          (FT_Pointer)loader->globals;
        face->autohint.finalizer =
          (FT_Generic_Finalizer)af_face_globals_free;
      }
    }

    return error;
  }


  /* Finalize glyph loader. */

  FT_LOCAL_DEF( void )
  af_loader_done( AF_Loader  loader )
  {
    loader->face    = NULL;
    loader->globals = NULL;
    loader->hints   = NULL;
  }


#define af_intToFixed( i ) \
          ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) )
#define af_fixedToInt( x ) \
          ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
#define af_floatToFixed( f ) \
          ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) )


  static FT_Error
  af_loader_embolden_glyph_in_slot( AF_Loader        loader,
                                    FT_Face          face,
                                    AF_StyleMetrics  style_metrics )
  {
    FT_Error  error = FT_Err_Ok;

    FT_GlyphSlot           slot    = face->glyph;
    AF_FaceGlobals         globals = loader->globals;
    AF_WritingSystemClass  writing_system_class;

    FT_Size_Metrics*  size_metrics = &face->size->internal->autohint_metrics;

    FT_Pos  stdVW = 0;
    FT_Pos  stdHW = 0;

    FT_Bool  size_changed = size_metrics->x_ppem !=
                              globals->stem_darkening_for_ppem;

    FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
    FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );

    FT_Matrix  scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };


    /* Skip stem darkening for broken fonts. */
    if ( !face->units_per_EM )
    {
      error = FT_ERR( Corrupted_Font_Header );
      goto Exit;
    }

    /*
     * We depend on the writing system (script analyzers) to supply
     * standard widths for the script of the glyph we are looking at.  If
     * it can't deliver, stem darkening is disabled.
     */
    writing_system_class =
      af_writing_system_classes[style_metrics->style_class->writing_system];

    if ( writing_system_class->style_metrics_getstdw )
      writing_system_class->style_metrics_getstdw( style_metrics,
                                                   &stdHW,
                                                   &stdVW );
    else
    {
      error = FT_ERR( Unimplemented_Feature );
      goto Exit;
    }

    if ( size_changed                                               ||
         ( stdVW > 0 && stdVW != globals->standard_vertical_width ) )
    {
      FT_Fixed  darken_by_font_units_x, darken_x;


      darken_by_font_units_x =
        af_intToFixed( af_loader_compute_darkening( loader,
                                                    face,
                                                    stdVW ) );
      darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
                                       size_metrics->x_scale ),
                            em_ratio );

      globals->standard_vertical_width = stdVW;
      globals->stem_darkening_for_ppem = size_metrics->x_ppem;
      globals->darken_x                = af_fixedToInt( darken_x );
    }

    if ( size_changed                                                 ||
         ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) )
    {
      FT_Fixed  darken_by_font_units_y, darken_y;


      darken_by_font_units_y =
        af_intToFixed( af_loader_compute_darkening( loader,
                                                    face,
                                                    stdHW ) );
      darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
                                       size_metrics->y_scale ),
                            em_ratio );

      globals->standard_horizontal_width = stdHW;
      globals->stem_darkening_for_ppem   = size_metrics->x_ppem;
      globals->darken_y                  = af_fixedToInt( darken_y );

      /*
       * Scale outlines down on the Y-axis to keep them inside their blue
       * zones.  The stronger the emboldening, the stronger the downscaling
       * (plus heuristical padding to prevent outlines still falling out
       * their zones due to rounding).
       *
       * Reason: `FT_Outline_Embolden' works by shifting the rightmost
       * points of stems farther to the right, and topmost points farther
       * up.  This positions points on the Y-axis outside their
       * pre-computed blue zones and leads to distortion when applying the
       * hints in the code further below.  Code outside this emboldening
       * block doesn't know we are presenting it with modified outlines the
       * analyzer didn't see!
       *
       * An unfortunate side effect of downscaling is that the emboldening
       * effect is slightly decreased.  The loss becomes more pronounced
       * versus the CFF driver at smaller sizes, e.g., at 9ppem and below.
       */
      globals->scale_down_factor =
        FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ),
                   em_size );
    }

    FT_Outline_EmboldenXY( &slot->outline,
                           globals->darken_x,
                           globals->darken_y );

    scale_down_matrix.yy = globals->scale_down_factor;
    FT_Outline_Transform( &slot->outline, &scale_down_matrix );

  Exit:
    return error;
  }


  /* Load the glyph at index into the current slot of a face and hint it. */

  FT_LOCAL_DEF( FT_Error )
  af_loader_load_glyph( AF_Loader  loader,
                        AF_Module  module,
                        FT_Face    face,
                        FT_UInt    glyph_index,
                        FT_Int32   load_flags )
  {
    FT_Error  error;

    FT_Size           size          = face->size;
    FT_Size_Internal  size_internal = size->internal;
    FT_GlyphSlot      slot          = face->glyph;
    FT_Slot_Internal  slot_internal = slot->internal;
    FT_GlyphLoader    gloader       = slot_internal->loader;

    AF_GlyphHints          hints         = loader->hints;
    AF_ScalerRec           scaler;
    AF_StyleMetrics        style_metrics;
    FT_UInt                style_options = AF_STYLE_NONE_DFLT;
    AF_StyleClass          style_class;
    AF_WritingSystemClass  writing_system_class;


    if ( !size )
      return FT_THROW( Invalid_Size_Handle );

    FT_ZERO( &scaler );

    if ( !size_internal->autohint_metrics.x_scale                          ||
         size_internal->autohint_mode != FT_LOAD_TARGET_MODE( load_flags ) )
    {
      /* switching between hinting modes usually means different scaling */
      /* values; this later on enforces recomputation of everything      */
      /* related to the current size                                     */

      size_internal->autohint_mode    = FT_LOAD_TARGET_MODE( load_flags );
      size_internal->autohint_metrics = size->metrics;

#ifdef AF_CONFIG_OPTION_TT_SIZE_METRICS
      {
        FT_Size_Metrics*  size_metrics = &size_internal->autohint_metrics;


        /* set metrics to integer values and adjust scaling accordingly; */
        /* this is the same setup as with TrueType fonts, cf. function   */
        /* `tt_size_reset' in file `ttobjs.c'                            */
        size_metrics->ascender  = FT_PIX_ROUND(
                                    FT_MulFix( face->ascender,
                                               size_metrics->y_scale ) );
        size_metrics->descender = FT_PIX_ROUND(
                                    FT_MulFix( face->descender,
                                               size_metrics->y_scale ) );
        size_metrics->height    = FT_PIX_ROUND(
                                    FT_MulFix( face->height,
                                               size_metrics->y_scale ) );

        size_metrics->x_scale     = FT_DivFix( size_metrics->x_ppem << 6,
                                               face->units_per_EM );
        size_metrics->y_scale     = FT_DivFix( size_metrics->y_ppem << 6,
                                               face->units_per_EM );
        size_metrics->max_advance = FT_PIX_ROUND(
                                      FT_MulFix( face->max_advance_width,
                                                 size_metrics->x_scale ) );
      }
#endif /* AF_CONFIG_OPTION_TT_SIZE_METRICS */
    }

    /*
     * TODO: This code currently doesn't support fractional advance widths,
     * i.e., placing hinted glyphs at anything other than integer
     * x-positions.  This is only relevant for the warper code, which
     * scales and shifts glyphs to optimize blackness of stems (hinting on
     * the x-axis by nature places things on pixel integers, hinting on the
     * y-axis only, i.e., LIGHT mode, doesn't touch the x-axis).  The delta
     * values of the scaler would need to be adjusted.
     */
    scaler.face    = face;
    scaler.x_scale = size_internal->autohint_metrics.x_scale;
    scaler.x_delta = 0;
    scaler.y_scale = size_internal->autohint_metrics.y_scale;
    scaler.y_delta = 0;

    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
    scaler.flags       = 0;

    /* note that the fallback style can't be changed anymore */
    /* after the first call of `af_loader_load_glyph'        */
    error = af_loader_reset( loader, module, face );
    if ( error )
      goto Exit;

#ifdef FT_OPTION_AUTOFIT2
    /* XXX: undocumented hook to activate the latin2 writing system. */
    if ( load_flags & ( 1UL << 20 ) )
      style_options = AF_STYLE_LTN2_DFLT;
#endif

    /*
     * Glyphs (really code points) are assigned to scripts.  Script
     * analysis is done lazily: For each glyph that passes through here,
     * the corresponding script analyzer is called, but returns immediately
     * if it has been run already.
     */
    error = af_face_globals_get_metrics( loader->globals, glyph_index,
                                         style_options, &style_metrics );
    if ( error )
      goto Exit;

    style_class          = style_metrics->style_class;
    writing_system_class =
      af_writing_system_classes[style_class->writing_system];

    loader->metrics = style_metrics;

    if ( writing_system_class->style_metrics_scale )
      writing_system_class->style_metrics_scale( style_metrics, &scaler );
    else
      style_metrics->scaler = scaler;

    if ( writing_system_class->style_hints_init )
    {
      error = writing_system_class->style_hints_init( hints,
                                                      style_metrics );
      if ( error )
        goto Exit;
    }

    /*
     * Do the main work of `af_loader_load_glyph'.  Note that we never have
     * to deal with composite glyphs as those get loaded into
     * FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function.
     * In the rare cases where FT_LOAD_NO_RECURSE is set, it implies
     * FT_LOAD_NO_SCALE and as such the auto-hinter is never called.
     */
    load_flags |=  FT_LOAD_NO_SCALE         |
                   FT_LOAD_IGNORE_TRANSFORM |
                   FT_LOAD_LINEAR_DESIGN;
    load_flags &= ~FT_LOAD_RENDER;

    error = FT_Load_Glyph( face, glyph_index, load_flags );
    if ( error )
      goto Exit;

    /*
     * Apply stem darkening (emboldening) here before hints are applied to
     * the outline.  Glyphs are scaled down proportionally to the
     * emboldening so that curve points don't fall outside their
     * precomputed blue zones.
     *
     * Any emboldening done by the font driver (e.g., the CFF driver)
     * doesn't reach here because the autohinter loads the unprocessed
     * glyphs in font units for analysis (functions `af_*_metrics_init_*')
     * and then above to prepare it for the rasterizers by itself,
     * independently of the font driver.  So emboldening must be done here,
     * within the autohinter.
     *
     * All glyphs to be autohinted pass through here one by one.  The
     * standard widths can therefore change from one glyph to the next,
     * depending on what script a glyph is assigned to (each script has its
     * own set of standard widths and other metrics).  The darkening amount
     * must therefore be recomputed for each size and
     * `standard_{vertical,horizontal}_width' change.
     *
     * Ignore errors and carry on without emboldening.
     *
     */

    /* stem darkening only works well in `light' mode */
    if ( scaler.render_mode == FT_RENDER_MODE_LIGHT    &&
         ( !face->internal->no_stem_darkening        ||
           ( face->internal->no_stem_darkening < 0 &&
             !module->no_stem_darkening            ) ) )
      af_loader_embolden_glyph_in_slot( loader, face, style_metrics );

    loader->transformed = slot_internal->glyph_transformed;
    if ( loader->transformed )
    {
      FT_Matrix  inverse;


      loader->trans_matrix = slot_internal->glyph_matrix;
      loader->trans_delta  = slot_internal->glyph_delta;

      inverse = loader->trans_matrix;
      if ( !FT_Matrix_Invert( &inverse ) )
        FT_Vector_Transform( &loader->trans_delta, &inverse );
    }

    switch ( slot->format )
    {
    case FT_GLYPH_FORMAT_OUTLINE:
      /* translate the loaded glyph when an internal transform is needed */
      if ( loader->transformed )
        FT_Outline_Translate( &slot->outline,
                              loader->trans_delta.x,
                              loader->trans_delta.y );

      /* compute original horizontal phantom points */
      /* (and ignore vertical ones)                 */
      loader->pp1.x = hints->x_delta;
      loader->pp1.y = hints->y_delta;
      loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
                                 hints->x_scale ) + hints->x_delta;
      loader->pp2.y = hints->y_delta;

      /* be sure to check for spacing glyphs */
      if ( slot->outline.n_points == 0 )
        goto Hint_Metrics;

      /* now load the slot image into the auto-outline */
      /* and run the automatic hinting process         */
      if ( writing_system_class->style_hints_apply )
      {
        error = writing_system_class->style_hints_apply(
                  glyph_index,
                  hints,
                  &gloader->base.outline,
                  style_metrics );
        if ( error )
          goto Exit;
      }

      /* we now need to adjust the metrics according to the change in */
      /* width/positioning that occurred during the hinting process   */
      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT )
      {
        AF_AxisHints  axis  = &hints->axis[AF_DIMENSION_HORZ];


        if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
        {
          AF_Edge  edge1 = axis->edges;         /* leftmost edge  */
          AF_Edge  edge2 = edge1 +
                           axis->num_edges - 1; /* rightmost edge */

          FT_Pos  old_rsb = loader->pp2.x - edge2->opos;
          /* loader->pp1.x is always zero at this point of time */
          FT_Pos  old_lsb = edge1->opos;     /* - loader->pp1.x */
          FT_Pos  new_lsb = edge1->pos;

          /* remember unhinted values to later account */
          /* for rounding errors                       */
          FT_Pos  pp1x_uh = new_lsb    - old_lsb;
          FT_Pos  pp2x_uh = edge2->pos + old_rsb;


          /* prefer too much space over too little space */
          /* for very small sizes                        */

          if ( old_lsb < 24 )
            pp1x_uh -= 8;

          if ( old_rsb < 24 )
            pp2x_uh += 8;

          loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
          loader->pp2.x = FT_PIX_ROUND( pp2x_uh );

          if ( loader->pp1.x >= new_lsb && old_lsb > 0 )
            loader->pp1.x -= 64;

          if ( loader->pp2.x <= edge2->pos && old_rsb > 0 )
            loader->pp2.x += 64;

          slot->lsb_delta = loader->pp1.x - pp1x_uh;
          slot->rsb_delta = loader->pp2.x - pp2x_uh;
        }
        else
        {
          FT_Pos  pp1x = loader->pp1.x;
          FT_Pos  pp2x = loader->pp2.x;


          loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
          loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );

          slot->lsb_delta = loader->pp1.x - pp1x;
          slot->rsb_delta = loader->pp2.x - pp2x;
        }
      }
      /* `light' mode uses integer advance widths */
      /* but sets `lsb_delta' and `rsb_delta'     */
      else
      {
        FT_Pos  pp1x = loader->pp1.x;
        FT_Pos  pp2x = loader->pp2.x;


        loader->pp1.x = FT_PIX_ROUND( pp1x );
        loader->pp2.x = FT_PIX_ROUND( pp2x );

        slot->lsb_delta = loader->pp1.x - pp1x;
        slot->rsb_delta = loader->pp2.x - pp2x;
      }

      break;

    default:
      /* we don't support other formats (yet?) */
      error = FT_THROW( Unimplemented_Feature );
    }

  Hint_Metrics:
    {
      FT_BBox    bbox;
      FT_Vector  vvector;


      vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;
      vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;
      vvector.x = FT_MulFix( vvector.x, style_metrics->scaler.x_scale );
      vvector.y = FT_MulFix( vvector.y, style_metrics->scaler.y_scale );

      /* transform the hinted outline if needed */
      if ( loader->transformed )
      {
        FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
        FT_Vector_Transform( &vvector, &loader->trans_matrix );
      }

      /* we must translate our final outline by -pp1.x and compute */
      /* the new metrics                                           */
      if ( loader->pp1.x )
        FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );

      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );

      bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
      bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
      bbox.xMax = FT_PIX_CEIL(  bbox.xMax );
      bbox.yMax = FT_PIX_CEIL(  bbox.yMax );

      slot->metrics.width        = bbox.xMax - bbox.xMin;
      slot->metrics.height       = bbox.yMax - bbox.yMin;
      slot->metrics.horiBearingX = bbox.xMin;
      slot->metrics.horiBearingY = bbox.yMax;

      slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x );
      slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );

      /* for mono-width fonts (like Andale, Courier, etc.) we need */
      /* to keep the original rounded advance width; ditto for     */
      /* digits if all have the same advance width                 */
      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT                       &&
           ( FT_IS_FIXED_WIDTH( slot->face )                              ||
             ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
               style_metrics->digits_have_same_width                    ) ) )
      {
        slot->metrics.horiAdvance =
          FT_MulFix( slot->metrics.horiAdvance,
                     style_metrics->scaler.x_scale );

        /* Set delta values to 0.  Otherwise code that uses them is */
        /* going to ruin the fixed advance width.                   */
        slot->lsb_delta = 0;
        slot->rsb_delta = 0;
      }
      else
      {
        /* non-spacing glyphs must stay as-is */
        if ( slot->metrics.horiAdvance )
          slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
      }

      slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
                                             style_metrics->scaler.y_scale );

      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
      slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );

      slot->format  = FT_GLYPH_FORMAT_OUTLINE;
    }

  Exit:
    return error;
  }


  /*
   * Compute amount of font units the face should be emboldened by, in
   * analogy to the CFF driver's `cf2_computeDarkening' function.  See there
   * for details of the algorithm.
   *
   * XXX: Currently a crude adaption of the original algorithm.  Do better?
   */
  FT_LOCAL_DEF( FT_Int32 )
  af_loader_compute_darkening( AF_Loader  loader,
                               FT_Face    face,
                               FT_Pos     standard_width )
  {
    AF_Module  module = loader->globals->module;

    FT_UShort  units_per_EM;
    FT_Fixed   ppem, em_ratio;
    FT_Fixed   stem_width, stem_width_per_1000, scaled_stem, darken_amount;
    FT_Int     log_base_2;
    FT_Int     x1, y1, x2, y2, x3, y3, x4, y4;


    ppem         = FT_MAX( af_intToFixed( 4 ),
                           af_intToFixed( face->size->metrics.x_ppem ) );
    units_per_EM = face->units_per_EM;

    em_ratio = FT_DivFix( af_intToFixed( 1000 ),
                          af_intToFixed ( units_per_EM ) );
    if ( em_ratio < af_floatToFixed( .01 ) )
    {
      /* If something goes wrong, don't embolden. */
      return 0;
    }

    x1 = module->darken_params[0];
    y1 = module->darken_params[1];
    x2 = module->darken_params[2];
    y2 = module->darken_params[3];
    x3 = module->darken_params[4];
    y3 = module->darken_params[5];
    x4 = module->darken_params[6];
    y4 = module->darken_params[7];

    if ( standard_width <= 0 )
    {
      stem_width          = af_intToFixed( 75 ); /* taken from cf2font.c */
      stem_width_per_1000 = stem_width;
    }
    else
    {
      stem_width          = af_intToFixed( standard_width );
      stem_width_per_1000 = FT_MulFix( stem_width, em_ratio );
    }

    log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) +
                 FT_MSB( (FT_UInt32)ppem );

    if ( log_base_2 >= 46 )
    {
      /* possible overflow */
      scaled_stem = af_intToFixed( x4 );
    }
    else
      scaled_stem = FT_MulFix( stem_width_per_1000, ppem );

    /* now apply the darkening parameters */
    if ( scaled_stem < af_intToFixed( x1 ) )
      darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem );

    else if ( scaled_stem < af_intToFixed( x2 ) )
    {
      FT_Int  xdelta = x2 - x1;
      FT_Int  ydelta = y2 - y1;
      FT_Int  x      = stem_width_per_1000 -
                       FT_DivFix( af_intToFixed( x1 ), ppem );


      if ( !xdelta )
        goto Try_x3;

      darken_amount = FT_MulDiv( x, ydelta, xdelta ) +
                      FT_DivFix( af_intToFixed( y1 ), ppem );
    }

    else if ( scaled_stem < af_intToFixed( x3 ) )
    {
    Try_x3:
      {
        FT_Int  xdelta = x3 - x2;
        FT_Int  ydelta = y3 - y2;
        FT_Int  x      = stem_width_per_1000 -
                         FT_DivFix( af_intToFixed( x2 ), ppem );


        if ( !xdelta )
          goto Try_x4;

        darken_amount = FT_MulDiv( x, ydelta, xdelta ) +
                        FT_DivFix( af_intToFixed( y2 ), ppem );
      }
    }

    else if ( scaled_stem < af_intToFixed( x4 ) )
    {
    Try_x4:
      {
        FT_Int  xdelta = x4 - x3;
        FT_Int  ydelta = y4 - y3;
        FT_Int  x      = stem_width_per_1000 -
                         FT_DivFix( af_intToFixed( x3 ), ppem );


        if ( !xdelta )
          goto Use_y4;

        darken_amount = FT_MulDiv( x, ydelta, xdelta ) +
                        FT_DivFix( af_intToFixed( y3 ), ppem );
      }
    }

    else
    {
    Use_y4:
      darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem );
    }

    /* Convert darken_amount from per 1000 em to true character space. */
    return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) );
  }


/* END */
