/****************************************************************************
 *
 * afloader.c
 *
 *   Auto-fitter glyph loading routines (body).
 *
 * Copyright 2003-2018 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 FT_INTERNAL_CALC_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 */
