T168_111\appl\Text\Agfa:第25~32

comp_pix.c  //

/* 
 * Copyright (C) 2005 Monotype Imaging Inc. All rights reserved.
 */

/* $Header:   I:/BULL/URIP/RTS/COR/COMP_PIX.C_V   1.129   Dec 13 2004 18:23:06   galejss  $ */
/* $Log:   I:/BULL/URIP/RTS/COR/COMP_PIX.C_V  $ 
 * 
 *    Rev 1.129   Dec 13 2004 18:23:06   galejss
 * some DBG stmts were not correct for FPNUM
 * 
 *    Rev 1.128   Nov 15 2004 15:56:10   indreliunaiter
 * Backed out the MPR changes. 
 * 
 *    Rev 1.127   Sep 27 2004 16:11:04   dugganj
 * Added multithread support.
 * 
 *    Rev 1.126   Sep 08 2004 14:12:50   indreliunaiter
 * Joe changes for Bold/Normal embedded bitmaps.
 * 
 *    Rev 1.125   Sep 02 2004 14:12:40   indreliunaiter
 * Changed MPR code to support a Stroke data on the characters basis.
 * 
 *    Rev 1.124   Jul 16 2004 17:46:00   galejss
 * remove obsolete TTDEBUG test
 * 
 *    Rev 1.123   Jun 04 2004 16:04:38   GalejsS
 * for IF, set orThreshold to saved value (from if_init_glob)
 * 
 *    Rev 1.122   Aug 21 2003 17:03:32   Galejs
 * update copyright notice
 * 
 *    Rev 1.121   Aug 21 2003 13:57:42   IndrelR
 * Added feature for processing XL bitmaps.
 * 
 *    Rev 1.120   Jul 21 2003 17:27:08   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.119   Jun 19 2003 18:33:56   Galejs
 * get rid of NON_IF_FONT option
 * 
 *    Rev 1.118   Jan 07 2003 14:50:18   Joe
 * In comp_pix(), fixed "hanging" problem when switching from
 * plugins to STIK fonts.
 * 
 *    Rev 1.117   Dec 03 2002 16:53:22   Galejs
 * fix a conditional compile
 * 
 *    Rev 1.116   Nov 04 2002 08:40:22   Joe
 * Moved the setting of "if_state.BitmapManipulated" from
 * ttload_font() to comp_pix().
 * 
 *    Rev 1.115   Oct 23 2002 13:44:38   Joe
 * In matrix_to_scale(), calculate "lpm", "xlpm" and "ylpm"
 * (by awr and jfd)
 * 
 *    Rev 1.114   Oct 21 2002 18:15:46   Galejs
 * fix uninitialized-vbl warnings
 * 
 *    Rev 1.113   Oct 01 2002 16:24:26   Joe
 * In matrix_design(), removed the HP_4000 conditional compile directive surrounding
 * the test for modifying the transformation matrix, which happens when plugin fonts
 * have different scaling units than the TFS font.
 * 
 *    Rev 1.112   Sep 30 2002 14:10:48   WuQ
 * Changes for CCC font
 * 
 *    Rev 1.111   Sep 26 2002 20:07:00   Galejs
 * 
 *    Rev 1.110   Sep 26 2002 12:27:06   Joe
 * In comp_pix(), moved test for setting "update_reflines"
 * so that it is not compiled based on TT_TTPLUG.
 * 
 *    Rev 1.109   Sep 26 2002 11:00:34   Joe
 * Set up for extracting "HOxo" metrics for stroke fonts
 * 
 *    Rev 1.108   Sep 23 2002 19:24:56   Galejs
 * fix character scale problem with PS-based MT fonts (bug # 91) (for jfd)
 * 
 *    Rev 1.107   Sep 23 2002 17:46:18   Galejs
 * fix possibly-uninitialized-vbl warnings (part of bug # 76)
 * 
 *    Rev 1.106   31 Aug 2001 13:36:24   JOE
 * Use optionalThreshold (if present) for PostSCript missing-pixel
 * recovery (by slg).
 * 
 *    Rev 1.105   Jul 25 2001 13:38:54   Al
 * Backed out auto fast fill
 * 
 *    Rev 1.104   Jul 06 2001 15:14:42   Al
 * Fixed auto fast fill for MicroType
 * 
 *    Rev 1.103   Jul 03 2001 09:34:02   Al
 * Set NZW if above 51pt 300dpi; it's faster
 * 
 *    Rev 1.102   04 Jun 2001 10:00:50   JOE 
 * OpenType changes.
 * 
 *    Rev 1.101   May 03 2001 19:21:48   Galejs
 * data-type cleanup
 * 
 *    Rev 1.100   11 Feb 2000 13:20:04   JOE
 * Modified to support Design Space Master Point Size in 1-20ths (by aof).
 * 
 *    Rev 1.99   Jan 24 2000 12:53:46   galejs
 * vertical-writing changes (for keb)
 * 
 *    Rev 1.98   Dec 10 1999 16:34:18   galejs
 * get rid of TT_ROM1, include "sfntenum.h" and "cgmacros.h"
 * 
 *    Rev 1.97   Aug 13 1999 15:07:00   galejs
 * include-file changes
 * 
 *    Rev 1.96   29 Jul 1999 17:29:10   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.95   18 Jan 1999 17:30:18   GALEJS
 * move #endif to 1st column (not all compilers see it, otherwise)
 * 
 *    Rev 1.94   13 Jan 1999 14:21:00   MARTIN
 * Conditionally compile declaration for port.
 * 
 *    Rev 1.93   15 Dec 1998 14:41:32   JOE
 * Changed ASIANVERT1 to ASIANVERT in asian_adjust() (by keb).
 * 
 *    Rev 1.92   14 Dec 1998 08:30:00   JOE
 * Removed extra tabs (by keb).
 * 
 *    Rev 1.91   11 Dec 1998 11:33:50   JOE
 * Modified vertical writing code to work with matrix input (by keb).
 * 
 *    Rev 1.90   08 Dec 1998 10:47:54   JOE
 * Installed test in ROM portion of check_for_angle_adjustment()
 * to handle PCLETTO (by jwd).
 * 
 *    Rev 1.89   22 Jun 1998 19:10:36   GALEJS
 * reentrancy parm-passing for IF & TT too
 * 
 *    Rev 1.88   15 Jun 1998 16:37:06   GALEJS
 * reentrancy parm-passing changes (state becomes if_state again)
 * 
 *    Rev 1.87   15 Apr 1998 17:10:26   GALEJS
 * move chr_def_hdr into IF_STATE
 * 
 *    Rev 1.86   02 Apr 1998 19:14:50   GALEJS
 * move externs to if_state
 * 
 *    Rev 1.85   31 Mar 1998 19:50:10   GALEJS
 * add missing end-brace in splitVLCmatrix()
 * 
 *    Rev 1.84   27 Mar 1998 11:01:28   AL
 * Fixed PS MT to scale to 999pt 1200dpi
 * 
 *    Rev 1.83   27 Mar 1998 09:54:52   AL
 * Fixed Intellifont to go to 999pt 1200dpi
 * 
 *    Rev 1.82   24 Mar 1998 15:12:48   GALEJS
 * include-file changes
 * 
 *    Rev 1.81   12 Mar 1998 16:00:18   AL
 * fcoarbrot was not initialized
 * 
 *    Rev 1.80   12 Mar 1998 10:13:16   AL
 * Grayscale rotation bug and 128 and 256 graylevels and y-shear problem
 * 
 *    Rev 1.79   11 Mar 1998 13:39:52   GALEJS
 * don't use "long" type (64-bit problems)
 * 
 *    Rev 1.78   04 Mar 1998 16:51:36   JOE
 * Changed lines containing 2 argument declarations to 2 separate lines
 * to resolve SPARC compiler error.
 * 
 *    Rev 1.77   03 Mar 1998 16:11:16   JOE
 * Added ASIANVERT adjustment code (by dah).
 * 
 *    Rev 1.76   26 Feb 1998 11:48:50   DAVID
 * In matrix_design() added comments for HP4000 emulation.
 * 
 *    Rev 1.75   23 Feb 1998 15:04:38   AL
 * Removed unused if_state.qlob_ital_tan and added ASIANVERT
 * 
 *    Rev 1.74   20 Feb 1998 09:55:42   AL
 * Corrected VLC bug
 * 
 *    Rev 1.73   19 Feb 1998 09:45:04   AL
 * Corrected VLC limits.
 * 
 *    Rev 1.72   13 Feb 1998 12:35:04   AL
 * VLC support for CGIFbound_box()
 * 
 *    Rev 1.71   04 Feb 1998 14:22:18   DAVID
 * In matrix_design() added conditional code for HP4000 emulation.
 * 
 *    Rev 1.70   04 Feb 1998 08:27:52   AL
 * Improve conditional compile of VLCpower
 * 
 *    Rev 1.68   28 Jan 1998 13:04:24   AL
 * Very Large Character support and re-entrant
 * 
 *    Rev 1.67   09 Dec 1997 14:45:38   GALEJS
 * remove reference to obsolete graysscale mode GASUB
 * 
 *    Rev 1.66   09 Oct 1997 19:01:04   MIKE
 * Remove 1.65 change
 * 
 *    Rev 1.65   29 Sep 1997 19:14:20   MIKE
 * If fontcontext.ExtndFlags Bit 10 is set, disable TT Missing Pix Recovery
 * 
 *    Rev 1.64   04 Sep 1997 13:41:58   KEB
 * Removed all references to BJG_BOLD_P6.
 * 
 *    Rev 1.63   24 Jul 1997 15:43:50   JQZ
 * Got rid of 1 warning message for type mismatch.
 * 
 *    Rev 1.62   15 Jul 1997 12:51:34   AL
 * Pseudo bold via outlines
 * 
 *    Rev 1.61   14 Jul 1997 14:40:54   JOE
 * In fractional_output(), conditionally compile the 2 DBG2 statements
 * which reference "shift" and "shift_rnd" based on IF_RDR.
 * 
 *    Rev 1.60   23 Jun 1997 14:31:08   MIKE
 * Fixed warnings with (size_t) casts in checkAngle...()
 * 
 *    Rev 1.59   16 Jun 1997 19:14:04   GALEJS
 * fix SIGNEDCHAR NO compile
 * 
 *    Rev 1.58   10 Jun 1997 20:32:24   MIKE
 * Fixed compilation errors in check_for_angle_adjustment()
 * 
 *    Rev 1.57   05 Jun 1997 11:24:08   JOE
 * Added support for auto-rotating 90 degrees.
 * 
 *    Rev 1.56   01 May 1997 17:59:20   MIKE
 * Cleaned up matrix_design code to work with INT_FP=1
 * 
 *    Rev 1.55   25 Mar 1997 09:37:16   AL
 * Gray alignment is independent in x and y
 * 
 *    Rev 1.54   18 Mar 1997 16:31:18   PVCSADMN
 * Karen B. modified scale matrix for IF pluggins and Matrix input.
 * 
 *    Rev 1.53   14 Feb 1997 12:25:18   MIKE
 * Upgraded v.52 to include changes from v.49,50,51
 * 
 *    Rev 1.52   07 Feb 1997 16:16:10   MIKE
 * Degenerate matrix for MicroType, TrueType.
 * *** NOTE *** This version is a delta from v.48 (-v"UFST 3.3")
 * 
 *    Rev 1.51   13 Jan 1997 16:31:22   DAVID
 * Removed CONVERGENT_FONTS option as part of project to trim ufst.
 * 
 *    Rev 1.49   10 Jan 1997 11:29:50   DAVID
 * Removed SCREEN_FONTS option, ELASTIC_X, and ELASTIC_Y, and
 * comp_pix_changed() function as part of project to trim ufst.
 * 
 *    Rev 1.48   04 Oct 1996 09:17:44   JOE
 * Removed CTRL-Z at end of file.
 * 
 *    Rev 1.47   30 Aug 1996 14:28:14   MIKE
 * Changed PSEUDO_BOLD_FCO to BOLD_FCO
 * 
 *    Rev 1.45   15 Mar 1996 15:28:14   MIKE
 * #include "graymap.h" conditional on GRAYSCALING=1.
 * 
 *    Rev 1.44   23 Feb 1996 10:07:26   MERRILL
 * add test for status
 * 
 *    Rev 1.43   09 Jan 1996 18:39:00   MIKE
 * Fixed errors if DEBUG or NOT1200DPI are defined.
 * 
 *    Rev 1.42   09 Jan 1996 12:57:32   MERRILL
 * quiet warnings (r+s)
 * 
 *    Rev 1.41   05 Jan 1996 11:49:14   MERRILL
 * isolate use of am2, am3
 * 
 *    Rev 1.40   21 Dec 1995 15:11:38   MERRILL
 * spelling change gray
 * 
 *    Rev 1.39   18 Dec 1995 14:34:14   MERRILL
 * remove isolation of am3...
 * 
 *    Rev 1.38   12 Dec 1995 13:20:36   MERRILL
 * remove warns for am2/3,bucket
 * 
 *    Rev 1.37   01 Dec 1995 09:50:50   AL
 * Fixed GRAY test for internal floating point
 * 
 *    Rev 1.36   04 Oct 1995 17:24:08   AL
 * Grayscaling
 * 
 *    Rev 1.35   22 Sep 1995 10:50:30   JOE
 * In comp_pix(), changed conditional compile directive surrounding
 * loading of tt fontcontext to resolve compiler error.
 * 
 *    Rev 1.34   08 Aug 1995 15:47:26   JOE
 * Return no more than 4 frac_bits to prevent overflow in DRAS.
 * 
 *    Rev 1.33   06 Jul 1995 08:20:04   JOE
 * Basic 1200 dpi support.
 * 
 *    Rev 1.32   06 Apr 1995 15:10:52   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.31   27 Feb 1995 17:52:24   MIKE
 * In matrix_em_world(), code change 2-22-95 must be conditional on FCO_RDR.
 * 
 *    Rev 1.30   25 Feb 1995 13:20:36   MIKE
 * MAT0 scaling, nonsquare resolutions; see comments 2-24, 2-25-95
 * 
 *    Rev 1.29   22 Feb 1995 18:33:32   MIKE
 * For matrix input, change "inches_per_point" in matrix_em_world().
 * 
 *    Rev 1.28   14 Feb 1995 20:46:56   MIKE
 * For FCO_RDR removed "ERRmatrix_range", changed "max_design".
 * 
 *    Rev 1.27   25 Jan 1995 16:56:18   JOE
 * In matrix_to_scale(), changed the conditional compile statement which
 * surrounds the setting of the threshold value to include FCO_RDR.
 * 
 *    Rev 1.26   16 Jan 1995 15:38:44   MARTIN
 * Added FCO_RDR around fractional_output routine and in matrix_to_scale, arou
 * 
 *    Rev 1.25   11 Jan 1995 09:45:24   JOE
 * In matrix_to_scale(), added code to calculate "frac_places" for
 * FCO input.
 * 
 *    Rev 1.24   30 Nov 1994 18:34:36   MIKE
 * In matrix_to_scale(), use fpsqrt() to calculate pixel_size.
 * 
 *    Rev 1.23   21 Nov 1994 10:28:46   JOE
 * Added support for 1200 DPI output.
 * 
 *    Rev 1.22   16 Nov 1994 13:40:04   MIKE
 * Pass transformation matrix to fco code. Handle both 72 pt/in & 72.307 pt/in
 * 
 *    Rev 1.21   19 Oct 1994 16:47:54   MIKE
 * pixel_size for FCOs can be either IF or TT compatible.
 * 
 *    Rev 1.20   14 Oct 1994 14:48:44   MIKE
 * Added "orThreshold" to comp_pix_context for FCO processing.
 * 
 *    Rev 1.19   10 Oct 1994 12:34:44   MIKE
 * In comp_pix() resolved fontcontext matching problem.
 * 
 *    Rev 1.18   21 Sep 1994 18:28:42   MIKE
 * Add code to the beginning of comp_pix() to support FCO plugins.
 * 
 *    Rev 1.17   09 Sep 1994 17:13:00   JOE
 * In comp_pix(), moved "else" statement to line following "#if FCO_RDR"
 * block so that "comp_pix_context" settings are not overwritten for
 * PS or TT (if !FCO_RDR).
 * 
 *    Rev 1.16   11 Aug 1994 09:58:50   JOE
 * In matrix_to_scale(), corrected calculations for xpixel_size,
 * ypixel_size, if_state.x.orig_Pixel and if_state.y.orig_pixel to
 * resolve compiler error which occurs if INT_FP is enabled.
 * 
 *    Rev 1.15   10 Aug 1994 13:25:44   MIKE
 * Fix bug; "else if (FCO_ISFCO(fc))..." has to be conditionalized.
 * 
 *    Rev 1.14   05 Aug 1994 21:09:50   MIKE
 * Added FCO changes from 1.9.1.3
 * 
 *    Rev 1.13   27 Apr 1994 11:30:28   MIKE
 * Set if_state.shear in matrix_to_scale().
 * 
 *    Rev 1.12   22 Apr 1994 09:28:22   LISA
 * Modified copyright/disclaimer notice for 1994.
 * 
 *    Rev 1.11   06 Mar 1994 14:12:18   MIKE
 * Do pseudo obliquing for Convergent Fonts, only if CONVERGENT_FONTS == 1
 * 
 *    Rev 1.10   03 Feb 1994 14:53:06   MIKE
 * Put Convergent Font italic angle into transformation matrix.
 * 
 *    Rev 1.9   14 Jan 1994 08:43:46   JOE
 * In matrix_to_scale(), added missing ";" to resolve compiler error.
 * 
 *    Rev 1.8   13 Jan 1994 17:10:38   JOE
 * In matrix_to_scale(), when calculating "if_state.or_on", do not set
 * based on "if_state.non_z_wind" because it is not needed.
 * 
 *    Rev 1.7   24 Aug 1993 15:31:16   LISA
 * Added line for truetype spotsize.
 * 
 *    Rev 1.6   09 Jul 1993 10:57:50   MAIB
 * set making_bold and non_z_wind independently
 * 
 *    Rev 1.5   01 Jul 1993 14:26:04   MAIB
 * changed making_bold to non_z_wind
 * 
 *    Rev 1.4   12 Feb 1993 11:41:14   JOE
 * VXWorks support.
 * 
 *    Rev 1.3   07 Jan 1993 11:19:00   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.2   15 Dec 1992 18:23:12   MIKE
 * Fixed bug in comp_pix() when switching between Intellifont and TrueType
 * 
 *    Rev 1.1   14 Dec 1992 09:34:24   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:37:22   LISA
 * Initial revision.
*/
/* $Date:   Dec 13 2004 18:23:06  $ */
/* to do
    - move PS and TT values for "frac_places" to UFST-specific routines 
*/

/*  comp_pix.c  */

/*-----------------------------------------------------------------
  20-Mar-90  jfd  Added check for tangent already computed
                  in routine COMP_PIX()
  05-May-90  awr  Added landscape. Set new variable d.quadrant to indicate
                  rotation type. Eliminated rotate_on. Swap x and y
                  resolution and spot size for 90 and 270 degree rotation.
  07-Jul-90  awr  removed above swapping.
  10-Sep-90  awr  changed computations for arbitrary rotation and shear to
                  produce a rotated pixel size and spot size.
  25-Sep-90  dET  made 'fpix' and 'fnew_pix' MLOCAL to prevent protection
                  violations under windows 3.0. This is an obscure bug!
  11-Nov-90  dET  Added check in comp_pix to limit  ( -45 < shear < 45 )
                  as does IF 2.2.
  10-Dec-90  awr  Changed to compute output pixel sizes same as IF2.
  03-Jan-91  jfd  Including file "cgconfig.h".
  28-Jan-91  jfd  Handling point sizes in 16ths of a point if specified
                  in pix_calc() and comp_pix().
                  
                  Performing error checking on returns from pix_calc() in
                  comp_pix().

                  Calculating point size units flag in comp_pix() and
                  checking it for 16ths. Also, added it as an argument
                  to pix_calc() where it is checked.
  30-Jan-91  dET  Modify for MSC multi-model compilation.
   3-Feb-91  awr  added error return codes for comp_pix()
                  Removed include imath.h- not needed,
                  updated copyright.
  23-Feb-91  awr  Changed bucket sub-segment handles to offsets.
  13-May-91  jfd  Changed routine "comp_pix_change()" to "comp_pix_changed()"
  19-May-91  awr  corrected compiler warnings
  05-Jun-91  jfd  In typographer(), when calling pix_calc(), check first if
                  rotating 90 or 270 degrees. If so, pass point_size
                  when calculating "xmax" and set_size when calculating
                  "ymax". (FIX FROM EARLIER VERSION)
   9-Jun-91  awr  renamed and moved function is_qual() to maker.c
  17-Jun-91  jfd  Moved "debug.h" after "port.h".
  21 Jun 91  ss   Added prototypes for fpabs().
                  Moved prototype for fgseg() from ix.h.
   4-Jul-91  awr  Moved ERRdu_pix_range to cgif.h
                  Removed xy->max_des. No longer used
                  Removed translation from matrix
                  Added Wrong reading.
                  All now goes through matrix_to_scale().
   8-Jul-91  tbh  Added elasticity.
   1-Aug-91  tbh  Removed unreferenced variables.
                  Coerced face.orThreshold to WORD for pixel size comparison
  11-Aug-91  awr  Changed quadrant testing code in matrix_to_scale() to 
                  set pseudo bold as arbitrary rotation (d.quadrant=0).
  15 Aug 91  ss   Added mirror_matrix() & related code to support mirrored
                  characters.
  16-Aug-91  jfd  Removed function prototype for "fpabs" since it is done
                  in FPMATH.H .
  22-Aug-91  jfd  Conditionally compiling comb_des_world() based on
                  (SCALE_MATRIX & (MAT1_SCALE_MATRIX | MAT2_SCALE_MATRIX))
  28-Aug-91  jfd  Changed 3rd parameter in function prototype for
                  matrix_pt_world() from WORD to FPNUM to resolve a
                  compiler warning.
  29-Aug-91  jfd  In comp_pix(), replaced call to structs_are_equal() with
                  call to FCis_equal().
   1-Sep-91  awr  Removed extra fpmath_error resets and corrected
                  comp_pix_changed() switch statement.
   3-Sep-91  awr  removed scale.tt0 code and references to scale.m[4..5]
   12-Oct-91 awr  Missing pixel recovery and pseudo bold are no 
                  longer mutually exclusive.
    4 Dec 91 ss   Added more things to test for comp_pix() context changed.
                  Inspired by problem with plugin character requested as
                  a proofer pcleo.  Running thru comp_pix() makes sure that
                  all scaling and resolution info set correctly in d.
   11-Jan-92 awr  Fixed bug in comp_pix_changed().
   23-Jan-92 awr  removed unused constant eight_k in matrix_to_scale()
   26-Jan-92 awr  Added call to ttset_trans()
   29-Jan-92 jfd  In matrix_to_scale(), now declaring "fst_frac_bits"
                  conditionally based on (PST1I || TT_RDR).
                  Changed "FC_TT_RDR" to "FC_ISTT".
   07-Feb-92 jfd  In matrix_to_scale(), hard-wiring "if_state.or_on" to
                  TRUE for IF, PS and TT (for now!)
   24-Feb-92 jfd  In matrix_em_world(), changed EXTERN to EXTERN_FONT and
                  corrected typo "com_pix_context" to "comp_pix_context".
    4 Mar 92 ss   In comp_pix(), put back in test for COMP_PIX_CONTEXT_CHGD
                  to make sure comp_pix() is executed when changing to/from
                  mirrored characters.
    7-Mar-92 awr  matrix_to_scale(): Corrected dbg statement for ypixel_size.
   03-Apr-92 rs   Portability cleanup (see port.h).
   08-Apr-92 jfd  In matrix_to_scale(), only hard-wiring "if_state.or_on"
                  TRUE (for missing pixel recovery) for PST1I and TT_RDR.
   08-Apr-92 rs   Add conditionals for some declarations:
                  'mirror_matrix()', 'matrix_pt_world()', 'matrix_em_world()',
                  'comb_des_world()', 'matrix_design()'.
   12 May 92 ss   Changed conditional compiles from EXTERN_FONT to NON_IF_FONT
                  since EXTERN_FONT is used elsewhere to mean PCLEO.
                  NON_IF_FONT signifies that one or more PS/TT options are
                  enabled.
    2 Jun 92 jfd  In matrix_to_scale(), setting "if_state.quality" if
                  PS or TT for PS and TT outlines (I'm not sure if this is
                  really needed!!)
   17-Jun-92 awr  Changed if_state.?.grid_align to INTR
    3-Jul-92 awr  Moved structs_are_equal() from bmputl.c
   21-Jul-92 awr  Conditional compile changes
   05-Aug-92 det  Included "mixmodel.h" and "string.h".
                  Replaced calls to FCis_equal() and structs_are_equal()
                  with MEMCMP for optimation.
                  Disabled structs_are_equal().
                  Added missing pixel recovery cut-in check for PS and TT.
   06-Aug-92 jfd  In matrix_to_scale(), store original matrix elements
                  in m0, m1, m2 and m3 for PS. When calculating "orig_pixel",
                  scale result to make it bigger so that missing pixel
                  recovery cut-in check will work.
   07-Aug-92 jfd  Compatability w/WINDOWS 3.1 (FIXED-->CGFIXED,
                  POINTFX-->CGPOINTFX)
   10-Aug-92 jfd  Changed missing pixel recovery cut-in threshold for PS and
                  TT from 18pt @ 96dpi to 18pt @ 300dpi.
   16-Sep-92 jfd  Changed declaration for "gaso_pn" from EXTERN to GLOBAL.
                  It is now declared EXTERN in bmputl.c
                  Changed declaration for "if_state" from EXTERN to GLOBAL.
                  Conditionally compiled routines fractional_output() and 
                  fill_in_design_data() based on IF_RDR.
   15-Oct-92 mby  Added yet another test in comp_pix() for fontcontext change
                  -- for TrueType fonts if TT_TTPLUGIN is on.
   02-Dec-92 mby  Fixed bug introduced by the 10/15 change - when switching
                  between Intellifont and TrueType.
   07-Jan-93 jfd  ANSI C function declaration changes.
   08-Feb-93 jfd  VXWorks support.
   01-Jul-93 maib  Changed making_bold to non_z_wind
   09-Jul-93 maib Added making_bold back, and set independently from
                  non_z_wind
   13-Jan-94 jfd  In matrix_to_scale(), when calculating "if_state.or_on",
                  do not set based on "if_state.non_z_wind" because it
                  is not needed.
   02-Feb-94 mby  Incorporate Convergent Font oblique angle into transformation
                  matrix in matrix_to_scale() and modify comp_pix() logic so
                  this code is executed when necessary.
   06-Mar-94 mby  Execute above change only if CONVERGENT_FONTS == 1.
   26-Apr-94 mby  Set if_state.shear in matrix_to_scale() based on orthogonal
                  rotation and nonzero shear.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 FCO Changes from 1.9.1.3:
   14-Mar-94 mby  For FCO reader, matrix_to_scale() sets up if_state and
                  calls fco_set_trans(). In typographer() hard-coded master
                  point size and resolution to 250, 2540.
   28-Mar-94 mby  Defined FCO_THRESHOLD for drop control, 18 Pt @ 300 dpi.
   20-Jun-94 mby  Added 'unitsPerEm' to comp_pix_context. Used in
                  matrix_to_scale() to compute pixel_size.
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   10-Aug-94 mby  In comp_pix(), conditionalize "else if (FC_ISFCO(fc)) ..."
                  for comp_pix_context structure.
   11-Aug-94 jfd  In matrix_to_scale(), corrected calculations for
                  xpixel_size, ypixel_size, if_state.x.orig_pixel and
                  if_state.y.orig_pixel to resolve compiler error which
                  occurs if INT_FP is enabled.
   09-Sep-94 jfd  In comp_pix(), moved "else" statement to line following
                  "#if FCO_RDR" block so that "comp_pix_context" settings
                  are not overwritten for PS or TT (if !FCO_RDR).
   21-Sep-94 mby  In comp_pix() for FCO plugin support, added code to compare
                  current fc to fc stored in BUCKET.p.fco.
   06-Oct-94 mby/jfd
                  In comp_pix(), set "if_state.cur_loc_fc.font_hdr = 0" to
                  resolve fontcontext switching problem.
   13-Oct-94 mby  Added "comp_pix_context.orThreshold", used to set
                  value of "if_state.orThreshold".
   19-Oct-94 mby  Added "comp_pix_context.compositionFlag", 1 for TT,
                  0 for IF. Pixel_size computation depends on this in
                  matrix_to_scale() and comp_pix().
   16-Nov-94 mby  For FCO_RDR, changed comp_pix_context parameters in
                  comp_pix() and matrix_to_scale() to handle 72 pt/in scaling
                  for TT compatible faces and 72.307 pt/in scaling for IF
                  compatible faces.
                  Added transformation matrix args to fco_set_trans() call.
                  Removed 'unitsPerEm' from comp_pix_context.
   21-Nov-94 jfd  Added support for 1200 DPI output.
   28-Nov-94 mby  In matrix_to_scale changed calculation of [xy]pixel_size
                  to use fpsqrt().
   09-Jan-95 jfd/mby  In matrix_to_scale(), added code to calculate 
                  "frac_places" for FCO input.
   16-Jan-95 SBM  In matrix_to_scale(), added | FCO_RDR around definition
                  of frac_places and fo_pix.Added |FCO_RDR around routine
                  fractional_output.
   23-Jan-95 jfd  In matrix_to_scale(), changed the conditional compile
                  statement which surrounds the setting of the threshold
                  value to include FCO_RDR.
   14-Feb-95 mby  For FCO_RDR in matrix_to_scale() removed 'ERRmatrix_range',
                  Changed calculation of "max_design".
                  Made fill_in_design_data() conditional only on IF_RDR.
   22-Feb-95 mby  In matrix_em_world(), fix "inches_per_point" computation
                  for FCO Intellifont-derived faces.
   24-Feb-95 mby  Added conditional pseudobold code in matrix_to_scale() for
                  FCO_RDR; compile with PSEUDO_BOLD_FCO. Not enabled for 3.0 release!
   25-Feb-95 mby  Need to preserve compatibility at the user interface for
                  MAT0 scaling between TrueType PCLETTO's and TT-derived FCO
                  fonts. In matrix_scale(), scale the matrix by the design
                  resolution to accomplish this.
   25-Feb-95 mby  Fixed scaling problem for nonsquare resolutions. In
                  matrix_to_scale() fixed typo that set an incorrect value for
                  "if_state.y.p_pixel".
   27-Feb-95 mby  In matrix_em_world(), code change from 2/22/95 must be
                  conditional on FCO_RDR.
   06-Jul-95 mac  Basic 1200 dpi support.
   06-Aug-95 mac  Return no more than 4 frac_bits to prevent overflow in DRAS.
   11-Sep-95 awr  if grayscaling, turn off or_on and turn on non_z_wind
   09-Jan-96 mby  Fixed errors if DEBUG or NOT1200DPI defined.
   15-Mar-96 mby  Make #include "graymap.h" conditional on GRAYSCALING=1.
   21-Aug-96 mby  Changed PSEUDO_BOLD_FCO to BOLD_FCO.
   10-Jan-97 dlk  Removed SCREEN_FONTS option, and ELASTIC_X, and ELASTIC_Y
                  as part of project to trim ufst.
                  This resulted in removal of function definition and code for
                  com_pix_changed.
   13-Jan-97 dlk  Removed CONVERGENT_FONTS option as part of project to trim
                  ufst.
   06-Feb-97 mby  Make it work for degenerate scaling matrix (PCL6 emulation)
                  in matrix_to_scale() - MicroType & TrueType only.
                  IF & PS just return error 608.
   17-Mar-97 keb  Scale matrix 0 values to avoid blow-up with 8782 type plugins
   25-Mar-97 awr  Independent gray alignement in x and y
   18-Apr-97 mby  Couple of changes for MIPS native compiler.
   29-Apr-97 mby  Cleaned up matrix_design() - correct use of FP routines,
                  to fix errors with INT_FP=1.
   06-Jun-97 jfd  Added support for auto-rotating 90 degrees.
   10-Jun-97 mby  In check_for_angle_adjustment() fixed compilation problem
                  in assignment of pGTTBase
   16-Jun-97 slg  Add LPSB8 cast to fix "SIGNEDCHAR NO" compile
   14-Jul-97 jfd  In fractional_output(), conditionally compile the 2 DBG2
                  statements which reference "shift" and "shift_rnd" based
                  on IF_RDR.
   03-Sep-97 keb  Removed references to BJG_BOLD_P6
   29-Sep-97 mby  In matrix_to_scale(), used bit 10 of FONTCONTEXT.ExtndFlags 
                  to disable TrueType Missing Pixel Recovery by setting
                  if_state.orThreshold to a huge value. This is to fix
                  rasterization problems in TT fonts with "wrong-way" curves,
                  though at the cost of pixel dropouts at small sizes.
   29-Sep-97 mby  Remove 9/29/97 changes (restore Rev 1.64).
   09-Dec-97 slg  Remove reference to obsolete grayscalemode GASUB
   20-Dec-97 awr  Removed unused and dangerously defined SWAPWINC macro
                  Moved call to check_for_angle_adjustment() eliminating
                  global variable adjust_angle.
   23-Dec-97 awr  Removed over-loaded version of matrix_scale() resulting
                  in fewer lines of source code and run time code and
                  more legibility.
   28-Jan-98 awr  Very large character support
   04-Feb-98 dlk  In matrix_design() added check for HP4000 emulation.
   07-Feb-98 awr  Added VLC support for CGIFbound_box() and comments
   23-Feb-98 awr  Removed (unused) if_state.glob_ital_tan
   26-Feb-98 dlk  In matrix_design() added more comments for HP4000 emulation.
   02-Mar-98 dah  Added pitalic ASIANVERT adjustment code
   04-Mar-98 jfd  Changed lines containing 2 argument declarations to
                  2 separate lines to resolve SPARC compiler error.
   09-Mar-98 slg  don't use "long" dcls (64-bit-compile problems)
   08-Mar-98 awr  Removed grayscale test in if_set_text_transform() since
                  we can't make Intellifont graymaps anyway.
                  Make selection of fop sizes big enough for graymap
                  subpixels in  fco_set_text_transform() to support 128
                  and 256 gray levels.
   31-Mar-98 slg  Add missing end-brace in what I THINK is the right place.
   17-Sep-98 jwd  Installed test in ROM portion of check_for_angle_adjustment()
                  to handle PCLETTO
   11-Dec-98 keb  Modified vertical writing code to work with Matrix input
   15-Dec-98 keb  Changed ASIANVERT1 to ASIANVERT in asian_adjust()
   28-Jul-99 ks      Changed DEBUG compiler directive to AGFADEBUG. 
   18-Jan-00 slg  Vertical-writing changes (for keb): modify asian_adjust();
                  get rid of check_for_angle_adjustment(); remove #if-ASIANVERT
                  tests; add test for vert-write mode at start of comp_pix().
   11-Feb-00 aof  Modified to support Design Space Master Point Size in 1/20ths.  
   23-May-01 jfd  OpenType changes:
                  In ps_set_text_transform(), point to correct bucket.
                  In matrix_to_scale(), call ps_set_text_transform() for OpenType
                  CFF fonts.
   30-Aug-01 slg  For Type1 / CFF / OpenType CFF: if new FONTCONTEXT field 
                     "UL32 optionalThreshold" is nonzero, use that value in place
                     of the hardcoded PS_THRESHOLD value to determine when 
                     missing-pixel recovery kicks in (useful for problematic fonts
                     or fonts with lots of hairline strokes)
   25-Sep-02 jfd   In comp_pix(), if processing a stroke font and the pixel size has been recomputed,
                         set the "update_reflines" flag so that the metrics for "HOxo" can be retrieved for
                         autohint_stik().
   01-Oct-02 jfd   In matrix_design(), removed the HP_4000 conditional compile directive surrounding
                         the test for modifying the transformation matrix, which happens when plugin fonts
                         have different scaling units than the TFS font.
   23-Oct-02 awr/jfd
                         In matrix_to_scale(), calculate "lpm", "ylpm" and "xlpm".
   04-Nov-02 jfd  Moved the setting of "if_state.BitmapManipulated" from ttload_font()
                  to comp_pix().
   07-Jan-03 jfd  In comp_pix(), fixed "hanging" problem when switching from plugins
                  to STIK fonts.

---------------------------------------------------------------------------*/

#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include <stdio.h>
#include <string.h>

#include "cgconfig.h"
#include "ufstport.h"
#include "dbg_ufst.h"

#include "shareinc.h"

#include "segments.h"
#include "mixmodel.h"

#include <math.h>   /* 06-05-97 jfd */

#ifdef LINT_ARGS

#if IF_RDR
MLOCAL UW16   fill_in_design_data(FSP PCOORD_DATA, FPNUM, FPNUM);
#endif
#if IF_RDR|FCO_RDR
MLOCAL SW16    fractional_output(FSP SW16);
#endif
MLOCAL UW16   matrix_to_scale(FSP0);
#if SCALE_MATRIX
MLOCAL VOID   matrix_scale(PFPNUM, LPSL32, SW16);
#endif  /* SCALE_MATRIX */
#if (SCALE_MATRIX & MAT0_SCALE_MATRIX)
MLOCAL UW16   matrix_design(FSP0);
#endif
#if (!SCALE_MATRIX || (SCALE_MATRIX & TYPO_SCALE_MATRIX))
MLOCAL UW16   typographer(FSP FPNUM);
#endif
#if (SCALE_MATRIX & (MAT1_SCALE_MATRIX | MAT2_SCALE_MATRIX))
MLOCAL UW16   comb_des_world(FSP FPNUM, FPNUM, LPSL32, SW16);
#endif
#if (SCALE_MATRIX & MAT1_SCALE_MATRIX)
MLOCAL UW16   matrix_em_world(FSP0);
#endif
#if (SCALE_MATRIX & MAT2_SCALE_MATRIX)
MLOCAL UW16   matrix_pt_world(FSP FPNUM);
#endif
#if SLIM_FONTS
MLOCAL SW16    mirror_matrix( FSP PFPNUM );
#endif

MLOCAL VOID    asian_adjust( FSP0 );

#if EMBEDDED_BITMAPS && CGBITMAP
MLOCAL BOOLEAN                bitmap_manipulated(FSP0);
MLOCAL BOOLEAN                bitmap_rotated(FSP0);
MLOCAL BOOLEAN                bitmap_sheared(FSP0);
#endif

#else     /*  else !LINT_ARGS  */

#if SLIM_FONTS
MLOCAL SW16    mirror_matrix();
#endif

MLOCAL VOID    asian_adjust();

#if EMBEDDED_BITMAPS && CGBITMAP
MLOCAL BOOLEAN                bitmap_manipulated();
MLOCAL BOOLEAN                bitmap_rotated();
MLOCAL BOOLEAN                bitmap_sheared();
#endif

#endif       /* LINT_ARGS  */


/*------------------------------------------------------------*/


#if SLIM_FONTS
#define COMP_PIX_CONTEXT_CHGD()   \
   ( (display->masterPointSize     != if_state.comp_pix_context.masterPt) \
     || (display->scanResolutionX  != if_state.comp_pix_context.xRes)     \
     || (display->scanResolutionX  != if_state.comp_pix_context.yRes)     \
     || (if_state.comp_pix_context.mirflags != if_state.chr_def_hdr.mirror_flags) )
#else
#define COMP_PIX_CONTEXT_CHGD()   \
   ( (display->masterPointSize    != if_state.comp_pix_context.masterPt) \
     || (display->scanResolutionX != if_state.comp_pix_context.xRes)     \
     || (display->scanResolutionX != if_state.comp_pix_context.yRes) )
#endif


#if PST1_RDR
#define    PS_THRESHOLD    13     /* PS pix size for 18pt @ 300dpi */
#endif

#if TT_RDR
#define    TT_THRESHOLD    13     /* TT pix size for 18pt @ 300dpi */
#endif


/*------------------------------------------------------------*/
/*--------------------*/
/*     frac_bits      */
/*--------------------*/
/*  Returns the number of fractional bits allowed for representing output
 *  pixels. The parameter v is the largest pixel value we will ever have.
 *  The number of fractional bits allowed is half the number of remaining
 *  bits in a 14 bit "word" after accounting for v itself. The reason for
 *  the half is that we multiply fractional pixel size by a fractional
 *  pixel coordiate in raster and want the result to fit into 14 bits.
 *  The reason for 14 bits and not 15 is because that's the way if2
 *  does it.
 */
#if defined (ANSI_DEFS)
GLOBAL SW16  frac_bits(SL32 v)
#else
GLOBAL SW16
frac_bits(v)
    SL32 v;
#endif
{
    SL32 c;
#if (!defined(NOT1200DPI))
    SL32 r;
#endif

  /* Count the number of bits in v */

    c=0;
    while(v>0)
    {
        v >>= 1;
        c++;
    }

  /*  return half of the bits v doesn't use in a 14 bit "word" */
#ifdef NOT1200DPI
    return (SW16)((14-c)>>1);
#else
/*
    For the time being this turned out to be the best solution for a Q&D
    version of UFST for 1200 dpi that does not require extensive revision
    of the code to avoid overflow.
*/
    if ( c > 14 ) {
        r = 0;
    } else if ( c > 4 ) {
        r = ( 14 - c )/2;
    } else {
        r = 4;
    }
   return( (SW16)r );
#endif  /* NOT1200DPI */
}

/*---------------------------------------------------------------*/
/*                 F C O    a n d    I n t e l l i f o n t       */

#if IF_RDR|FCO_RDR
/*--------------------*/
/*  fractional_output */
/*--------------------*/
/*  Compute the sizes of fractional output pixels. The parameters
 *  xmax and ymax are largest output xoordinates in pixels that will
 *  ever be used. We see how many bits xmax and ymax don't use in a SW16
 *  and then make the fractional size as large as possible. Both x and y
 *  fractional pixel sizes are made the same.
 *
 *  We also calculate a shift value used in transforming from design units
 *  to fractional output units. These values are used by tx() and ty()
 *  in imath.c.
 *
 *  This functions fills in the sc.x and sc.y fields:
 *
 *      pixel_size    output fractional pixel size, power of 2
 *      half_pixel    pixel_size / 2
 *      grid_shift    ammount to shift x to obtain x/pixel_size
 *      grid_align    x & grid_align is a whole number of pixels
 *
 *      shift
 *      shift_rnd
 *
 *  Returns the output pixel size.
 */
#if defined (ANSI_DEFS)
MLOCAL SW16  fractional_output(FSP SW16 frac_places)
#else
MLOCAL SW16
fractional_output(frac_places)
    SW16 frac_places;
#endif
{
    SW16 frac_pixel;

    DBG1("fractional_output(frac_places=%d\n", frac_places);

    frac_pixel = 1<<frac_places;

    if_state.x.pixel_size = if_state.y.pixel_size = frac_pixel;
    if_state.x.half_pixel = if_state.y.half_pixel = frac_pixel >> 1;
    if_state.x.grid_shift = if_state.y.grid_shift = frac_places;
    if_state.x.grid_align = if_state.y.grid_align = ~((INTR)frac_pixel
                                                                 -(INTR)1);

#if IF_RDR  /* IF only */
    if_state.x.shift = 16 - if_state.x.bin_places - if_state.x.grid_shift;
    if_state.x.shift_rnd = 1<<(if_state.x.shift-1);

    if_state.y.shift = 16 - if_state.y.bin_places - if_state.y.grid_shift;
    if_state.y.shift_rnd = 1<<(if_state.y.shift-1);
#endif


    DBG2("    pixel_size = %d  half_pixel = %d\n", if_state.x.pixel_size,
                                                   if_state.x.half_pixel);
#if INTR_SIZE == 16
    DBG2("    grid_align = %x  grid_shift = %d\n", if_state.x.grid_align,
                                                   if_state.x.grid_shift);
#else
    DBG2("    grid_align = %lx  grid_shift = %d\n", if_state.x.grid_align,
                                                   if_state.x.grid_shift);
#endif

#if IF_RDR  /* IF only */
    DBG2("    x.shift = %d, x.shift_rnd = %d\n",   if_state.x.shift,
                                                   if_state.x.shift_rnd);
    DBG2("    y.shift = %d, y.shift_rnd = %d\n",   if_state.y.shift,
                                                   if_state.y.shift_rnd);
#endif
    return frac_pixel;
}
#endif  /* IF_RDR|FCO_RDR */

/*                 F C O    a n d    I n t e l l i f o n t       */
/*---------------------------------------------------------------*/
/*                 I n t e l l i f o n t                         */

#if IF_RDR
#define CON_SIZE 2
/*---------------------*/
/* fill_in_design_data */
/*---------------------*/
/*  Fill in the design unit pixel data used for grid aligning. */
#if defined (ANSI_DEFS)
MLOCAL UW16  fill_in_design_data(FSP PCOORD_DATA xy, FPNUM pixel_size, FPNUM bias)
#else
MLOCAL UW16
fill_in_design_data(xy, pixel_size, bias)
    PCOORD_DATA xy;
    FPNUM       pixel_size;
    FPNUM       bias;
#endif
{
    UL32       t;          /* precise pixel size = t >> s */
    SW16        s;
    SL32        phpix;
    SL32        tbias;

  /*  Constrained dimension limit = pixel_size * CON_SIZE.
   *  (CON_SIZE = 2)
   */

    xy->con_size = fp2word(fpmul(pixel_size, fpint2fp((SL32)CON_SIZE)));

  /* Fractional pixel values used in skeletal processing */

    t = (UL32)fp2intel(FSA pixel_size, (LPSW16)&s);
#ifdef NOT1200DPI
    if(s<0 || s>14)  /* Minimum pixel size is 1.058333 = 0.529167*2^1 */
#else
    if(s<0 || s>15)  /* Minimum pixel size is 0.529167 = 0.529167*2^0 */
#endif  /* NOT1200DPI */
        return ERRdu_pix_range;

    /* tbias = fp2long(fpmul(bias,fplongexp(1L, -s))); 
                                          OffWarningMsg by jqz */

    tbias = fp2long(fpmul(bias,fplongexp(1L, (SW16)-s)));

    xy->p_pixel    = (SW16)t;
    phpix          = t >> 1;      /* precise half pixel */
    xy->p_half_pix = (SW16)phpix;
    xy->bin_places = s;

    xy->round[0] = phpix - tbias;
    xy->round[1] = phpix + tbias;
    xy->round[2] = phpix;
    xy->round[3] = phpix;

    DBG2("    p_pixel = %d  bin_places = %d\n", xy->p_pixel, xy->bin_places);
    DBG1("    con_size = %d\n", xy->con_size);
    DBG4("    round  %ld  %ld  %ld  %ld\n", xy->round[0], xy->round[1],
                                            xy->round[2], xy->round[3]);

  /* Standard dimension */

    xy->stand_value = 0;   /* to indicate that it must be recomputed */

    return SUCCESS;
}


/*-----------------------*/
/* if_set_text_transform */
/*-----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  if_set_text_transform(FSP FPNUM xpixel_size,
                                                    FPNUM ypixel_size)
#else
MLOCAL UW16  if_set_text_transform(xpixel_size, ypixel_size)
    FPNUM xpixel_size;
    FPNUM ypixel_size;
#endif
{
    PFONTCONTEXT fc;
    FPNUM xover, yover;             /* overhang in pixels: spot size - 1 */
    FPNUM xoverhang, yoverhang;     /* overhang in design units          */
    FPNUM xbias, ybias;
    SW16  min_pix;
    PFPNUM m;   /* if_state.m[] */
    FPNUM am0, am1, am2, am3;
    FPNUM det;
    UW16 status;
    SW16  frac_places;
    FPNUM fo_pix;               /* fractional output pixel size */
    SL32   i;

#ifdef AGFADEBUG
    DBG("    pixel_size: "); fpprint(FSA xpixel_size); fpprint(FSA ypixel_size);
    DBG("\n");
#endif
    m = &if_state.m[0];
    fc = &if_state.cur_loc_fc;

    am0 = fpabs(m[0]); am1 = fpabs(m[1]);
    am2 = fpabs(m[2]); am3 = fpabs(m[3]);
    det = fpabs(fpsub(fpmul(m[0], m[3]), fpmul(m[1], m[2])));

  /*  Determine spot size overhang in design space
   *      xoverhang = (yover*am0 + xover*am1)/det;
   *      yoverhang = (yover*am2 + xover*am3)/det;
   */

    xover = fpfixed2fp(fc->xspot - F_ONE);  /* overhang in output space */
    yover = fpfixed2fp(fc->yspot - F_ONE);
    xoverhang = fpdiv(fpadd(fpmul(yover, am2), fpmul(xover, am3)), det);
    yoverhang = fpdiv(fpadd(fpmul(yover, am0), fpmul(xover, am1)), det);

  /*  Determine bias:     bias = overhang - bold
   */

#if BOLD
    xbias = fpsub(xoverhang, fpint2fp((SL32)fc->xbold));
    ybias = fpsub(yoverhang, fpint2fp((SL32)fc->ybold));
#else
    xbias = xoverhang;
    ybias = yoverhang;
#endif

    DBG("x design data\n");
    if((status = fill_in_design_data(FSA &if_state.x, xpixel_size, xbias)) != SUCCESS)
        return status;

    DBG("y design data\n");
    if((status = fill_in_design_data(FSA &if_state.y, ypixel_size, ybias)) != SUCCESS)
        return status;

  /* compute baseline */

  /* Grid aligned baseline in design space */
    pixel_align(FSAvoid if_state.origBaseline, &if_state.y, 2);
    if_state.aBaselnVal  = if_state.value;

    DBG1("\n    orig baseline = %d\n", if_state.origBaseline);
    DBG1("    grid aligned in design space: %d \n", if_state.aBaselnVal);

  /* Set quality level */

    if_state.quality = fc->format >> 14;
    if(!if_state.quality)
    {
        min_pix = MIN(if_state.x.orig_pixel, if_state.y.orig_pixel);
        if(min_pix < 66)       if_state.quality = 3; /*  > 30 pt at 300dpi */
        else if(min_pix < 211) if_state.quality = 2; /* between 10 and 30  */
        else                   if_state.quality = 1; /*  < 10 pt           */
    }

    DBG1("    quality = %d\n", if_state.quality);

  /*________________fop stuff__________________________*/

      /*  Determine xmax and ymax in output space. A one x one box when
       *  transformed by m[] has a bounding box of r x s.
       */
        {
            FPNUM max_design;
            FPNUM xmax, ymax;

#ifdef NOT1200DPI
            FPNUM r, s;
            r = fpadd(am0, am2);
            s = fpadd(am1, am3);
            if(fplt(one, r) || fplt(one, s))   /* Can only scale down */
                return ERRmatrix_range;
            max_design = fpint2fp((SL32)MAX_DESIGN);
            xmax = fpmul(r, max_design);
            ymax = fpmul(s, max_design);
#else
            max_design = fpint2fp((SL32)8782); /* Q&D hardcoded upem value */
            xmax = fpdiv( max_design, xpixel_size );
            ymax = fpdiv( max_design, ypixel_size );
#endif  /* NOT1200DPI */

            frac_places = MIN(frac_bits(fp2long(xmax)),
                              frac_bits(fp2long(ymax)));

#ifdef NOT1200DPI
            if (frac_places < 0)
               return ERR_ov_16_bit_value;
#else
            if (frac_places < 0)
               return ERR_ov_16_bit_value;
#endif  /* NOT1200DPI */

            fo_pix = fpint2fp((SL32)fractional_output(FSA frac_places));
        }

      /*  Scale all elements of matrix by output pixel size. */

        for(i=0; i<4; i++, m++)       
            *m = fpmul(fo_pix, *m);

    return SUCCESS;

} /* if_set_text_transform() */
#endif  /* IF_RDR */

/*-----------------------*/
/*    mirror_matrix      */
/*-----------------------*/
#if SLIM_FONTS
#if defined (ANSI_DEFS)
MLOCAL SW16  mirror_matrix( FSP PFPNUM m )
#else
MLOCAL SW16
mirror_matrix( m )
    PFPNUM m;
#endif
{
    FPNUM  m0, m1, m2, m3;
    FPNUM  n0, n1, n2, n3;

    n0 = n1 = n2 = n3 = fpint2fp(0);
    
    m0 = *m;
    m1 = *(m+1);
    m2 = *(m+2);
    m3 = *(m+3);

    switch( if_state.chr_def_hdr.mirror_flags )
    {
      case MIRROR_ROT0:  /*  Identity - NOP                             */
                         /*   | 1  0 |  *  | m0 m1 |  =  | m0  m1 |     */
                         /*   | 0  1 |     | m2 m3 |     | m2  m3 |     */
          n0 =  m0;
          n1 =  m1;
          n2 =  m2;
          n3 =  m3;
          break;
      case MIRROR_ROT90: /*  rotate 90?                                */
                         /*   |  0  1 |  *  | m0 m1 |  =  |  m2  m3 |   */
                         /*   | -1  0 |     | m2 m3 |     | -m0 -m1 |   */
          n0 =  m2;
          n1 =  m3;
          n2 = fpneg(m0);
          n3 = fpneg(m1);
          break;
      case MIRROR_ROT180:/*  rotate 180? mirror in X and Y             */
                         /*   | -1   0 |  *  | m0 m1 |  =  | -m0 -m1 |  */
                         /*   |  0  -1 |     | m2 m3 |     | -m2 -m3 |  */
          n0 = fpneg(m0);
          n1 = fpneg(m1);
          n2 = fpneg(m2);
          n3 = fpneg(m3);
          break;
      case MIRROR_ROT270:/*  rotate 270?                               */
                         /*   | 0  -1 |  *  | m0 m1 |  =  | -m2 -m3 |   */
                         /*   | 1   0 |     | m2 m3 |     |  m0  m1 |   */
          n0 = fpneg(m2);
          n1 = fpneg(m3);
          n2 =  m0;
          n3 =  m1;
          break;

      case MIRROR_NEGROT0:/*  mirror in X direction                     */
                         /*   | -1  0 |  *  | m0 m1 |  =  | -m0 -m1 |   */
                         /*   |  0  1 |     | m2 m3 |     |  m2  m3 |   */
          n0 = fpneg(m0);
          n1 = fpneg(m1);
          n2 =  m2;
          n3 =  m3;
          break;
      case MIRROR_NEGROT90:/*  mirror across the line y = -x            */
                         /*   |  0 -1 |  *  | m0 m1 |  =  | -m2 -m3 |   */
                         /*   | -1  0 |     | m2 m3 |     | -m0 -m1 |   */
          n0 = fpneg(m2);
          n1 = fpneg(m3);
          n2 = fpneg(m0);
          n3 = fpneg(m1);
          break;
      case MIRROR_NEGROT180: /*  mirror in Y direction                  */
                         /*   |  1   0 |  *  | m0 m1 |  =  |  m0  m1 |  */
                         /*   |  0  -1 |     | m2 m3 |     | -m2 -m3 |  */
          n0 =  m0;
          n1 =  m1;
          n2 = fpneg(m2);
          n3 = fpneg(m3);
          break;
      case MIRROR_NEGROT270: /*  mirror across the line y = x           */
                         /*   | 0   1 |  *  | m0 m1 |  =  |  m2  m3 |   */
                         /*   | 1   0 |     | m2 m3 |     |  m0  m1 |   */
          n0 = m2;
          n1 = m3;
          n2 = m0;
          n3 = m1;
          break;
      default:
          break;
   }  /* end - switch */
   /* copy changes for return  */
   *m     = n0;
   *(m+1) = n1;
   *(m+2) = n2;
   *(m+3) = n3;

   return SUCCESS;
}   /*  end - mirror_matrix  */
#endif  /*  SLIM_FONTS  */
/*                 I n t e l l i f o n t                         */
/*---------------------------------------------------------------*/
/*                     F C O                                     */
/*------------------------*/
/* fco_set_text_transform */
/*------------------------*/
#if FCO_RDR
#if defined (ANSI_DEFS)
MLOCAL UW16  fco_set_text_transform(FSP PFONTCONTEXT fc,
                     FPNUM xpixel_size, FPNUM ypixel_size)
#else
MLOCAL UW16  fco_set_text_transform(fc, xpixel_size, ypixel_size)
    PFONTCONTEXT fc;
    FPNUM xpixel_size;
    FPNUM ypixel_size;
#endif
{
    FPNUM fo_pix;               /* fractional output pixel size */
    SW16  frac_places;
    SL32   i;
    FPNUM fst_frac_bits;
    SL32 emres;
    PFPNUM m;                   /* if_state.m[] */
    FPNUM m0, m1, m2, m3;       /* Matrix */
    FPNUM am0, am1;             /* Absolute values of matrix elements */
    FPNUM am2, am3;

    m = &if_state.m[0];
    am0 = fpabs(m[0]); am1 = fpabs(m[1]);
    am2 = fpabs(m[2]); am3 = fpabs(m[3]);

    if_state.x.p_pixel = fp2intel(FSA xpixel_size, &(if_state.x.bin_places));
    if_state.x.p_half_pix = if_state.x.p_pixel >> 1;
    if_state.y.p_pixel = fp2intel(FSA ypixel_size, &(if_state.y.bin_places));
    if_state.y.p_half_pix = if_state.y.p_pixel >> 1;

    /* Final format will be 16.16 fixed point interger */
    fst_frac_bits = fpint2fp(65536L);
    m0 = fpmul(m[0], fst_frac_bits);
    m1 = fpmul(m[1], fst_frac_bits);
    m2 = fpmul(m[2], fst_frac_bits);
    m3 = fpmul(m[3], fst_frac_bits);

  /*________________fop stuff__________________________*/

      /*  Determine xmax and ymax in output space. A one x one box when
       *  transformed by m[] has a bounding box of r x s.
       */
        {
            FPNUM max_design;
            FPNUM xmax, ymax;

#ifdef NOT1200DPI
            FPNUM r, s;
            r = fpadd(am0, am2);
            s = fpadd(am1, am3);

            if ((emres = if_state.pbucket->p.fco.design_EmRes) == 8782)
               max_design = fpint2fp((SL32)MAX_DESIGN);
            else  /* frac_places must never be < 0; must work for 1000 point, 600 dpi */
               max_design = fpint2fp((SL32)(emres + (emres>>1) - (emres>>3)));

            xmax = fpmul(r, max_design);
            ymax = fpmul(s, max_design);
#else
            emres = if_state.pbucket->p.fco.design_EmRes;
            max_design = fpint2fp((SL32)emres);

            xmax = fpdiv( max_design, xpixel_size );
            ymax = fpdiv( max_design, ypixel_size );
#endif  /* NOT1200DPI */

            frac_places = MIN(frac_bits(fp2long(xmax)),
                              frac_bits(fp2long(ymax)));
            if (frac_places < 0)
               return ERR_ov_16_bit_value;

#if GRAYSCALING
            if(FC_ISGRAY(fc))
            {
                if(if_state.grayfilter.lognumXpix > frac_places)
                    frac_places = if_state.grayfilter.lognumXpix;
                if(if_state.grayfilter.lognumYpix > frac_places)
                    frac_places = if_state.grayfilter.lognumYpix;
            }
#endif
            fo_pix = fpint2fp((SL32)fractional_output(FSA frac_places));
        }

      /*  Scale all elements of matrix by output pixel size. */

        for(i=0; i<4; i++)       
            m[i] = fpmul(fo_pix, m[i]);

#if BOLD_FCO
        if_state.pbucket->p.fco.xbold = fc->xbold;
        if_state.pbucket->p.fco.ybold = fc->ybold;
#endif

      /* Divide out the x and y scaling from the transformation matrix. */
    return fco_set_trans(FSA if_state.pbucket,
                                    fp2long(fpmul(m0, xpixel_size)),
                                    fp2long(fpmul(m1, xpixel_size)),
                                    fp2long(fpmul(m2, ypixel_size)),
                                    fp2long(fpmul(m3, ypixel_size)) );
}
#endif /* FCO_RDR */
/*                     F C O                                     */
/*---------------------------------------------------------------*/
/*                 T R U E T Y P E                               */

/* This function fiddles with the final matrix
 *
 *   [sx   0]    [1    0]    [ cos    sin ]    [xoutres      0  ]   [r   0]
 *   [      ]  o [      ]  o [            ]  o [                ] o [     ]
 *   [ 0  sy]    [ t   1]    [-sin    cos ]    [  0      youtres]   [0   1]
 *
 *
 * It rotates 90 degrees counter clockwise plus the shear angle and
 * then negates the shear angle. 
 *
 */
#if defined (ANSI_DEFS)
MLOCAL VOID  asian_adjust(FSP0)
#else
MLOCAL VOID  asian_adjust()
#endif

{
    /* keb 7/99 */
    PFPNUM m;
    FPNUM a;

    DBG(" in asian_adjust() ROTATING CHARACTER \n");

    m  = &if_state.m[0];
    a = m[0]; m[0] = m[2]; m[2] = fpneg(a);
    a = m[1]; m[1] = m[3]; m[3] = fpneg(a);
    return;
}

#if TT_RDR
/*-----------------------*/
/* tt_set_text_transform */
/*-----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  tt_set_text_transform(FSP0)
#else
MLOCAL UW16  tt_set_text_transform()
#endif
{
    FPNUM fst_frac_bits = fpint2fp(65536L);
    return ttset_trans(FSA if_state.pbucket,
                  fp2long(fpmul(if_state.m[0], fst_frac_bits)),
                  fp2long(fpmul(if_state.m[1], fst_frac_bits)),
                  fp2long(fpmul(if_state.m[2], fst_frac_bits)),
                  fp2long(fpmul(if_state.m[3], fst_frac_bits)) );
}
#endif /* TT_RDR */
/*                     T r u e T y p e                           */
/*---------------------------------------------------------------*/
/*                     P o s t S c r i p t                       */
#if PST1_RDR
/*-----------------------*/
/* ps_set_text_transform */
/*-----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  ps_set_text_transform(FSP0)
#else
MLOCAL UW16  ps_set_text_transform()
#endif
{
    FPNUM m0, m1, m2, m3;       /* Matrix */
    FPNUM fst_frac_bits;
    PFPNUM m, fm;
    PBUCKET pb = GET_pBUCKET(if_state.pbucket);    /* 05-23-01 jfd */

    /* concatenate with the fontmatrix (nominally scale by .001) */
    m = &if_state.m[0];
    fm = &pb->p.ps.fontmatrix[0];        /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
    m0 = fpadd(fpmul(fm[0], m[0]),
               fpmul(fm[1], m[2]));
    m1 = fpadd(fpmul(fm[0], m[1]),
               fpmul(fm[1], m[3]));
    m2 = fpadd(fpmul(fm[2], m[0]),
               fpmul(fm[3], m[2]));
    m3 = fpadd(fpmul(fm[2], m[1]),
               fpmul(fm[3], m[3]));

  /*  Pipeline seems to want matrix operating on left of vector so
   *  send transpose of concatenated matrix.
   */
    fst_frac_bits = fpint2fp(32768L);   /* scale by 2**15 */
    return psset_trans(FSA pb,            /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                           fp2long(fpmul(m0, fst_frac_bits)),
                           fp2long(fpmul(m2, fst_frac_bits)),
                           fp2long(fpmul(m1, fst_frac_bits)),
                           fp2long(fpmul(m3, fst_frac_bits)));
}
#endif /* PST1_RDR */
/*                     P o s t S c r i p t                       */
/*---------------------------------------------------------------*/
/*           V e r y    L a r g e    C h a r a c t e r s         */

#if defined (ANSI_DEFS)
MLOCAL FPNUM fpmax (FPNUM a, FPNUM b )
#else
MLOCAL FPNUM fpmax (a, b )
    FPNUM a;
    FPNUM b;
#endif
{
    if(fplt(a,b))
        return b;
    else
        return a;
}

/*--------------------*/
/*   splitVLCmatrix   */
/*--------------------*/
/* Very Large Character support.
   If the matrix if_state.m[4] scales beyond the capacity of a
   particular fst, then split the matrix into the largest one that the
   fst can handle concatenated with a scaling (up) matrix of a power of 2.
   The scale factor is stored in if_state.cs.VLCpower as the power of two to
   scale the coordinate values.

   The idea is that all of the fst's will continue to produce output within
   well tested limits and a further scaling will be done after the fst
   output.
*/
#if defined (ANSI_DEFS)
MLOCAL UW16  splitVLCmatrix(FSP 
      BOOLEAN allowsplit, /*  For most output types, eg bitmaps, we don't
                              allow real large scaling  */
      UW16 fsttype)       /*  TrueType, MicroType, PostScript, Intellifont */
#else
MLOCAL UW16 splitVLCmatrix(allowsplit, fsttype )
    BOOLEAN allowsplit;
    UW16 fsttype;                   
#endif
{
    PFPNUM m;
    FPNUM one;
    FPNUM m0, m1, m2, m3;
    FPNUM am0, am1, am2, am3;
    FPNUM orig_scale;
    FPNUM maxout;

    orig_scale = fpint2fp(0);
    m = &if_state.m[0];

    /* Values and absolute values of matrix */
    m0  = m[0];      m1  = m[1];       m2  = m[2];      m3  = m[3];
    am0 = fpabs(m0); am1 = fpabs(m1);  am2 = fpabs(m2); am3 = fpabs(m3);

#ifdef AGFADEBUG
    DBG("   am[] = ");   fpprint(FSA am0);   fpprint(FSA am1);  DBG("\n");
    DBG("          ");   fpprint(FSA am2);   fpprint(FSA am3);  DBG("\n");
#endif

    /* Compute maxout which is the larger of the width and depth of a unit
     * box scaled by the matrix. The width can be shown to be am0+am2 and
     * the depth is am1 +am3
     */
    maxout = fpmax(fpadd(am0, am2), fpadd(am1, am3));
    /* Compute "orig_scale" a the ratio of the output pixel image with
       the max allowable for the font scaling technology. If the ratio is
       greater than 1, then we must scale the matrix down.
     */
    if(fsttype  == FC_PST1_TYPE || fsttype  == FC_TT_TYPE)
    {
        /* The members of the matrix for PostScript and TrueType represent
           the pixel sizes of a scaled em box.
           1000 pt at 1200 dpi at 1/72 in/pt = 16,666.67 pixels */
        orig_scale = fpdiv(maxout, fpint2fp(16666L));
    }
#if IF_RDR
    else if(fsttype  == FC_IF_TYPE)
    {
        FPNUM limit;
        /* limit = 1.88976 */
        limit =  fpdiv(fpint2fp(188976L),fpint2fp(100000L));
        orig_scale=fpdiv(maxout, limit);
    }
#endif /* IF_RDR */
#if FCO_RDR
    else if(fsttype  == FC_FCO_TYPE)
    {
        FPNUM limit;
        if (if_state.comp_pix_context.compositionFlag) /* PS or TT MicroType ? */
        {
            if(if_state.comp_pix_context.masterPt == 1000)
                /* limit = 16.65 */
                limit = fpdiv(fpint2fp(1665), fpint2fp(100L));
            else /* must be TT MicroType */
                /* limit = 8.138 */
                limit = fpdiv(fpint2fp(8138), fpint2fp(1000L));
        } 
        else   /* == 0 means Intellifont MicroType */
            /* limit = 1.88976 */
            limit =  fpdiv(fpint2fp(188976L),fpint2fp(100000L));
        orig_scale=fpdiv(maxout, limit);
    }
#endif /* FCO_RDR */

    /* Scale down matrix if necessary and set VLCpower */
#if VLCOUTPUT
    if_state.cs.VLCpower = 0;
#endif
    one = fpint2fp(1L);
    if(fplt(one,orig_scale)) /* if too large for fst ... */
#if VLCOUTPUT
    {                         /* ... VLCOUTPUT scales back into fst range
                                        we have to scale the matrix down
                                        by VLCpower, that power of two
                                        that makes orig_scale <= 2**VLCpower
                               */
        FPNUM two, scale;
        COUNTER i;

        /* Only let outline types go on. Bitmaps and graymaps are not
           allowed to get this large.
        */
        if ( !allowsplit )
            return ERRmatrix_range;

        two = fpint2fp(2L);  scale = one;
        while(fplt(scale,orig_scale))
        {
            scale = fpmul(two, scale);
            if_state.cs.VLCpower++;
        }
        /* Scale down input matrix */
        for(i=0; i<4; i++, m++)       
            *m = fpdiv(*m, scale);
    }
#else                         /* ... not VLCOUTPUT, we're too big so fail */
      return ERRmatrix_range;
#endif /* VLCOUTPUT */
    return SUCCESS;
}

/*           V e r y    L a r g e    C h a r a c t e r s         */
/*---------------------------------------------------------------*/


/*--------------------*/
/*   matrix_to_scale  */
/*--------------------*/
/*
Computes the grid alignment and scaling transformations from a matrix
that represents:
   for MicroType and Intellifont
                   the transformation from design units to output pixels.
   for PostScript and TrueType
                   the transformation from 1 unit em box to output pixels.
*/

#if defined (ANSI_DEFS)
MLOCAL UW16  matrix_to_scale(FSP0)
#else
MLOCAL UW16
matrix_to_scale()
#endif
{
    PFPNUM m;             /*  matrix */
    PFONTCONTEXT fc;
    FPNUM one;
    FPNUM m0, m1, m2, m3;       /* Matrix */
    FPNUM am0, am1;             /* Absolute values of matrix elements */
    FPNUM am2, am3;
    FPNUM det;                  /* determinate */
    UW16 status;
    SL32 matrDegen = 0;          /* Degenerate matrix flag */
    FPNUM xpixel_size, ypixel_size;

    DBG("matrix_to_scale()\n");

    m = &if_state.m[0];
    fc = &if_state.cur_loc_fc;

    one        = fpint2fp(1L);

/* Step: make last minute adjustments to the matrix if_state.m[]. */

#if SLIM_FONTS
    /* check for mirror flags and mirror matrix if necessary */
    if( if_state.chr_def_hdr.mirror_flags )
       mirror_matrix( FSA m );
#endif  /* SLIM_FONTS  */

/* keb 7/99 */
if ( FC_ISUFSTVERT(&if_state.fcCur) && if_state.CharVertWrit == 1)
    asian_adjust(FSA0);

#if GRAYSCALING
    /* If we are grid aligning to subpixels, then increase the output
     * resolution to account for the number of x and y sub-pixels
     */
    if(FC_ISGRAY(fc))
    {
        if(fc->alignment == GAPP )
        {
            *(m  ) = fpmul(fpint2fp((SL32)fc->numXsubpixels),*(m  ));
            *(m+2) = fpmul(fpint2fp((SL32)fc->numXsubpixels),*(m+2));
            *(m+1) = fpmul(fpint2fp((SL32)fc->numYsubpixels),*(m+1));
            *(m+3) = fpmul(fpint2fp((SL32)fc->numYsubpixels),*(m+3));
        }
        else if ( fc->alignment == GAPG || fc->alignment == GAPH )
        {
            *(m  ) = fpmul(fpint2fp((SL32)fc->numXsubpixels),*(m  ));
            *(m+2) = fpmul(fpint2fp((SL32)fc->numXsubpixels),*(m+2));
        }
        else if ( fc->alignment == GAGP || fc->alignment == GAHP )
        {
            *(m+1) = fpmul(fpint2fp((SL32)fc->numYsubpixels),*(m+1));
            *(m+3) = fpmul(fpint2fp((SL32)fc->numYsubpixels),*(m+3));
        }
    }
#endif
/* All last minute changes to the matrix have been done at this point */
/*====================================================================*/
/*                  Step: Extract matrix charactistics               */

    /* Values and absolute values of matrix elements */
    m0  = m[0];       m1 = m[1];       m2 = m[2];       m3 = m[3];   
    am0 = fpabs(m0); am1 = fpabs(m1); am2 = fpabs(m2); am3 = fpabs(m3);

    /*  Determinant */
    det = fpsub(fpmul(m0, m3), fpmul(m1, m2));

    /* Still need to take care of the non-square aspect ratio case. */
    if_state.lpm = fp2word(fpsqrt(fpadd(fpmul(m0, m0), fpmul(m1, m1))));
    if_state.xlpm = fp2word(m0);
    if_state.ylpm = fp2word(m3);

    if (fpiszero(det))
        matrDegen = 1;

#if FCO_RDR || TT_RDR
    if(!FC_ISFCO(fc) && !FC_ISTT(fc))
#endif                      /* for MT & TT, det == 0 is OK (but weird!) */
    {
        if (matrDegen)
            return ERRsingular_matrix;
    }

    if_state.wrong_read = fpisneg(det);
    det = fpabs(det);        /* we only need absolute value from here on */

   /* +++ if_state.quadrant +++ Determine quadrant rotation */
    if_state.quadrant = 0; /* assume arbitrary rotation or pseudo-italic */
    if (!matrDegen) {
        if(fpiszero(m1) && fpiszero(m2))
        {
            if(fpisneg(m3))
                if_state.quadrant = ROT180;
            else
                if_state.quadrant = ROT0;
        }
        else if(fpiszero(m0) && fpiszero(m3))
        {
            if(fpisneg(m2))
                if_state.quadrant = ROT90;
            else
                if_state.quadrant = ROT270;
        }
    }

  /* if_state.shear = ROT0 for 0 or 180 rotation + nonzero shear
   *                = ROT90 for 90 or 270 rotation + nonzero shear
   *                = 0 otherwise (if .quadrant is 1, then .shear is 0)
   *
   * M = a 0  for 0/180 rotation      M = 0 b  for 90/270 rotation
   *     c d  and shear != 0              c d  and shear != 0
   *
   * 17-Feb-98 awr: Is only used by Intellifont in metrics.c and quadra.c
   */
    if_state.shear = 0;
    if (!if_state.quadrant)
    {
        if (fpiszero(m1))
            if_state.shear = ROT0;
        if (fpiszero(m0))
            if_state.shear = ROT90;
    }

    if(if_state.wrong_read)
        if_state.quadrant = - if_state.quadrant;

/*              Step: Extract matrix charactistics           */
/*===========================================================*/
/*            If the matrix scales too large, scale down the
              matrix by a power of 2. This power of 2 is returned in
              if_state.cs.VLCpower.
*/
    status = splitVLCmatrix(FSA
                (BOOLEAN)(FC_ISOUTLINE(fc)), /* only allow split if outline */
         (UW16)(fc->format & FC_FONTTYPE_MASK) );
    if(status)
        return status;
#if VLCOUTPUT
    DBG1("VLCpower %d\n", if_state.cs.VLCpower);
#endif
/*===========================================================*/
/*              Step: Compute design unit pixel size         */
    /* Compute design unit pixel size. For Intellifont and MicroType
     * these are the dimensions of a box that will be scaled to a box
     * in output space that is one by one pixel
     */
{
    FPNUM xout, yout;
    BOOLEAN fcoarbrot = FALSE;

    /* Values and absolute values of matrix. Must load them again in case
       splitVLCmatrix() changed them. */
    m0  = m[0];      m1  = m[1];       m2  = m[2];      m3  = m[3];
    am0 = fpabs(m0); am1 = fpabs(m1);  am2 = fpabs(m2); am3 = fpabs(m3);

#ifdef AGFADEBUG
    DBG("   am[] = ");   fpprint(FSA am0);   fpprint(FSA am1);  DBG("\n");
    DBG("          ");   fpprint(FSA am2);   fpprint(FSA am3);  DBG("\n");
#endif

    if (fpiszero(am1) || fpiszero(am2))
    {  /* no rotation, possible x or y shear */
        xout = am0;
        yout = am3;
    }
    else if (fpiszero(am0) || fpiszero(am3))
    {
        xout = am1;
        yout = am2;
    }
    else  /* Else arbitrary rotation */
    {
        fcoarbrot = FC_ISFCO(fc); /* fco arbitrary rotation flag */
            xout = fpsqrt(fpadd(fpmul(am0,am0), fpmul(am1,am1)));
            if(fpiszero(xout)) 
                xout = one;
            yout = fpdiv(fpabs(fpsub(fpmul(m0,m3), fpmul(m1,m2))), xout);
    }
  /* MicroType & TrueType support degenerate matrices (determinant = 0).
     This can result in xout or yout being 0. Detect this case and
     set to benign values to avoid division by 0 by FCO user of these
     values.
   */
    if (fpiszero(xout) || fpiszero(yout))
        xout = yout = one;
    xpixel_size = fpdiv(one, xout);
    ypixel_size = fpdiv(one, yout);
  /*  Original pixel size with no fractional precision. Used to
   *  compare with typeface or-on threshold.
   */

#if (PST1_RDR || TT_RDR || FCO_RDR)
    if(FC_ISPST1(fc) || FC_ISTT(fc))
    {
       if_state.x.orig_pixel = fp2word(fpmul(fpint2fp(1000L),xpixel_size));
       if_state.y.orig_pixel = fp2word(fpmul(fpint2fp(1000L),ypixel_size));
    }
    else
#endif /* PST1_RDR || TT_RDR || FCO_RDR */
    {
        if_state.x.orig_pixel = fp2word(xpixel_size);
        if_state.y.orig_pixel = fp2word(ypixel_size);
    }
    if(fcoarbrot)
          /* FCO is Arbitrary rotation. The xpixel_size and ypixel_size
            are used by MicroType Intelliflator to
            reconstruct the segment end points fed into putsegs()
            which will in this case call the slowest most general of
            the three MicroType scalers, that hits each
            coordinate point with the full matrix if_state.m[] (after
            pixel size was divided out which is moot in this case).
           */
        xpixel_size = ypixel_size = one;
}
/*===========================================================*/
#if PST1_RDR
    if(FC_ISPST1(fc))     /* if PostScript font */
    {
        status = ps_set_text_transform(FSA0);
        if(status)
            return status;
        if (fc->optionalThreshold > 0)
            if_state.orThreshold = fc->optionalThreshold;  /* use user-specified threshold */
        else
            if_state.orThreshold = PS_THRESHOLD;  /* PS pix size for 18pt @ 300dpi */
    }
#endif
#if TT_RDR && CFF_RDR    /* 05-23-01 jfd */
    if(B_ISOTCFF(if_state.pbucket))                      /* if OTCFF font */
    {
        status = ps_set_text_transform(FSA0);
        if(status)
            return status;
        if (fc->optionalThreshold > 0)
            if_state.orThreshold = fc->optionalThreshold;  /* use user-specified threshold */
        else
            if_state.orThreshold = PS_THRESHOLD;  /* PS pix size for 18pt @ 300dpi */
    }
    else
#endif    /* TT_RDR && CFF_RDR */
#if TT_RDR
    if(FC_ISTT(fc))     /* if TrueType font */
    {
        if_state.pbucket->p.tt.spotsize = fc->xspot;
        status = tt_set_text_transform(FSA0);
        if(status)
            return status;
        if_state.orThreshold = TT_THRESHOLD;  /* TT pix size for 18pt @ 300dpi */
    }
#endif /* TT_RDR */
#if FCO_RDR
    if(FC_ISFCO(fc))
    {
        status = fco_set_text_transform(FSA fc,
                                           xpixel_size, ypixel_size);
        if(status)
            return status;
        if_state.orThreshold = if_state.comp_pix_context.orThreshold;
    }
#endif  /* FCO_RDR */

#if IF_RDR
    if(FC_ISIF(fc))     /* Intellifont specific scaling data */
    {
        status = if_set_text_transform(FSA xpixel_size, ypixel_size);
        if(status)
            return status;
        if_state.orThreshold = if_state.orThresholdIF;    /* restore IF threshold (saved in if_init_glob) */  
    }
#endif /* IF_RDR */


  /* Set bold and or_on flags */

/* if_state.non_z_wind is true when fontcontext format field specifies
 * non-zero winding, or when bold is specified.
 */
#if BOLD || BOLD_FCO
    if_state.making_bold =  ((fc->xbold | fc->ybold) != 0L);
#else
    if_state.making_bold = FALSE;
#endif
    if_state.non_z_wind  = (if_state.making_bold || (FC_ISNONZWIND(fc) ));

    if_state.or_on = (
            (if_state.x.orig_pixel > (SW16)if_state.orThreshold) ||
            (if_state.y.orig_pixel > (SW16)if_state.orThreshold) ||
            matrDegen
                     );

#if GRAYSCALING
    if(FC_ISGRAY(fc))
    {
        if_state.or_on = FALSE;
        if_state.non_z_wind = TRUE;
    }
#endif
#if BOLD_P6
    if ( fc->pcl6bold )
        if_state.non_z_wind = TRUE;
#endif
#if BOLD_HORIZONTAL
    if ( fc->bold_horizontal )
        if_state.non_z_wind = TRUE;
#endif

    DBG4("orThreshold %d  orig pixel  %d,%d    or_on = %d\n",
            if_state.orThreshold, if_state.x.orig_pixel,
                              if_state.y.orig_pixel, if_state.or_on);
/*--------------------------------------------------------*/
#if FCO_RDR
if_state.savenzw = if_state.non_z_wind; /* because compound chars change this */
#endif

    /*Backed out the MPR changes. In a future if you need to put the MPR*/ 
    /*changes back, please  search for the comments / * jwd, 06/29/04. */  
    /*in comp_pix.c, stikoutl.c, maker.c and IF_TYPE.H files.*/
    /*Changed MPR code to support a Stroke data on the characters basis*/

    /*if_state.save_or_on = if_state.or_on; */  /* jwd, 06/29/04 */


    return if_state.fpmath_error;

} /* matrix_to_scale */

#if SCALE_MATRIX
/*--------------------*/
/*  matrix_scale      */
/*--------------------*/
/*  Convert a matrix from fixed point to floating point */
#if defined (ANSI_DEFS)
MLOCAL VOID  matrix_scale(PFPNUM mdst, LPSL32 msrc, SW16 numbits)
#else
MLOCAL VOID
matrix_scale(mdst, msrc, numbits)
    PFPNUM mdst;          /* destination matrix                 */
    LPSL32  msrc;          /* source matrix of fixed point SL32s */
    SW16   numbits;       /* number of bits after binary point  */
#endif
{
    SL32    i;

    for(i=0; i<4; i++)
        *mdst++ = fplongexp(*msrc++, numbits);
}
#endif  /* SCALE_MATRIX */

#if (SCALE_MATRIX & MAT0_SCALE_MATRIX)

/* -----------------------------------------------
 * ---------------- matrix_design ----------------
 * -----------------------------------------------
 *
 * Description: matrix_design() is called for MAT0_SCALE_MATRIX input.
 *              Passes matrix parameters to common code in matrix_scale().
 *              There is a block of code to modify the transformation matrix,
 *              happens when plugin fonts have different scaling units
 *              than the TFS font.
 * Parameters:  fc - FONTCONTEXT structure
 * Called by:   comp_pix()
 */
#if defined (ANSI_DEFS)
MLOCAL UW16  matrix_design(FSP0)
#else
MLOCAL UW16
matrix_design()
#endif
{
    PFONTCONTEXT  fc;
    fc = &if_state.cur_loc_fc;
    matrix_scale(&if_state.m[0], fc->s.m0.m, fc->s.m0.matrix_scale);

#if FCO_RDR
{
    SW16 emres;
    if (FC_ISFCO(fc) && if_state.comp_pix_context.compositionFlag)
        emres = if_state.comp_pix_context.masterPt;
    else
        emres = 0;

    /* This code block is for PCL6 emulation when MicroType (FCO) is enabled,
     *  and / or when HP_4000 is enabled.
     *  If a TrueType or an FCO/TrueType font is selected and it accesses
     *  one of the *Intellifont* plugin buckets, the transformation matrix
     *  fc->s.m0 has to be changed to reflect a change from 2048 to 8782
     *  design units. Also, keep in mind that the 2048 factor is "hidden",
     *  i.e. not part of the matrix, whereas the matrix must be divided by
     *  the 8782 factor.  keb, mby  3/97.
     *  This conversion must also occur if an FCO/PostScript font is selected
     *  and it accessed one of the *Intellifont* plugin buckets
     */
    if (if_state.buck_SearchLvl > 0 &&
         (if_state.fst_type_Lvl0 == FC_TT_TYPE ||
            if_state.fst_type_Lvl0 == (FC_FCO_TYPE | 1) ||  /* MT PostScript */
            if_state.fst_type_Lvl0 == (FC_FCO_TYPE | 2)) && /* MT TrueType */
         if_state.pbucket->fst_type == FC_FCO_TYPE &&
         if_state.pbucket->p.fco.design_EmRes == IFDESIGNUNITS)
    {
        COUNTER i;
        FPNUM fp8782;
        fp8782 = fpint2fp(8782L);
        for(i=0; i<4; i++)
            if_state.m[i] = fpdiv(if_state.m[i], fp8782);
    }

    if (emres)
    {
        FPNUM scale;
        COUNTER i;
        scale = fplongexp((SL32)emres, (SW16)0);
        for(i=0; i<4; i++)
            if_state.m[i] = fpdiv(if_state.m[i], scale);
    }
}
#endif /* FCO_RDR */

    return matrix_to_scale(FSA0);
}
#endif  /* matrix_design() */

#if (SCALE_MATRIX & (MAT1_SCALE_MATRIX | MAT2_SCALE_MATRIX))
/*--------------------*/
/*  comb_des_world    */
/*--------------------*/
/*  Combine desgin to world transform and world to output transforms
 *  and then compute the SCALE parameters
 */
#if defined (ANSI_DEFS)
MLOCAL UW16  comb_des_world(FSP FPNUM xscale, FPNUM yscale,
                                             LPSL32 w,     SW16 w_scale)
#else
MLOCAL UW16
comb_des_world(xscale, yscale, w, w_scale)
    FPNUM  xscale, yscale;     /* scale:  design to world */
    LPSL32  w;                  /* matrix: world to output */
    SW16   w_scale;
#endif
{
    PFPNUM m = &if_state.m[0];

  /* Convert fixed point matrix to floating point */
    matrix_scale(m, w, w_scale);

  /* Build matrix from design space to output space */
    m[0] = fpmul(xscale, m[0]);
    m[1] = fpmul(xscale, m[1]);
    m[2] = fpmul(yscale, m[2]);
    m[3] = fpmul(yscale, m[3]);

  /* Compute the SCALE parameters */

    return matrix_to_scale(FSA0);
}
#endif


#if (SCALE_MATRIX & MAT1_SCALE_MATRIX)
/*--------------------*/
/*  matrix_em_world   */
/*--------------------*/
/*  Computes the scaling paramters */
#if defined (ANSI_DEFS)
MLOCAL UW16  matrix_em_world(FSP0)
#else
MLOCAL UW16
matrix_em_world()
#endif
{
    PFONTCONTEXT fc;
    FPNUM inches_per_point;         /* a CG point is 0.01383 inches    */
    FPNUM masterpt;                 /* master point size in CG points  */
    FPNUM inches_per_dem;           /* inches per design em            */
    FPNUM dem_width, dem_depth;
    FPNUM wem_width, wem_depth;
    FPNUM xscale, yscale;

    fc = &if_state.cur_loc_fc;

  /* Compute design unit em box */

#if FCO_RDR
    if (FC_ISIF(fc) || (FC_ISFCO(fc) && !if_state.comp_pix_context.compositionFlag))
        inches_per_point = fpdiv(fpint2fp(1383L), fpint2fp(100000L));
    else
        inches_per_point = fpdiv(fpint2fp(1L), fpint2fp(72L));
#else  /* !FCO_RDR */
    if(!FC_ISIF(fc))   /* PostScript and TrueType use 1/72 inch = point */
        inches_per_point = fpdiv(fpint2fp(1L), fpint2fp(72L));
    else
    inches_per_point = fpdiv(fpint2fp(1383L), fpint2fp(100000L));
#endif
    masterpt = fpdiv(fpint2fp((SL32)if_state.comp_pix_context.masterPt), fpint2fp(8L));
    inches_per_dem = fpmul(masterpt, inches_per_point);
    dem_width=fpmul(inches_per_dem, fpint2fp((SL32)if_state.comp_pix_context.xRes));
    dem_depth=fpmul(inches_per_dem, fpint2fp((SL32)if_state.comp_pix_context.yRes));

  /* Compute scale factors from design space to world space */

    wem_width = fplongexp(fc->s.m1.em_width, fc->s.m1.em_scale);
    wem_depth = fplongexp(fc->s.m1.em_depth, fc->s.m1.em_scale);
    xscale = fpdiv(wem_width, dem_width);
    yscale = fpdiv(wem_depth, dem_depth);

  /*  Combine the design to world transform and the world to output
   *  transform and compute the SCALE parameters.
   */

    return comb_des_world(FSA xscale, yscale, fc->s.m1.m,
                                          fc->s.m1.matrix_scale);
}
#endif


#if (SCALE_MATRIX & MAT2_SCALE_MATRIX)
/*--------------------*/
/*  matrix_pt_world   */
/*--------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  matrix_pt_world(FSP FPNUM masterpt)
#else
MLOCAL UW16
matrix_pt_world(masterpt)
    FPNUM masterpt;
#endif
{
    PFONTCONTEXT  fc;
    FPNUM set, pnt;

    FPNUM meters_per_inch;
    FPNUM xworld_res, yworld_res;   /*  world resolution in pixels/inch */
    FPNUM xscale, yscale;           /*  scale: design to world          */

    fc = &if_state.cur_loc_fc;

  /*  Compute first tranform matrix:
   *  scale outline by point and set size.
   *
   *    ( set   0  )
   *    (  0   pnt )
   *
   */
    set = fpdiv( fpint2fp((SL32)fc->s.m2.set_size),    masterpt);
    pnt = fpdiv( fpint2fp((SL32)fc->s.m2.point_size),  masterpt);

#ifdef AGFADEBUG
    DBG("\n    masterpt ");  fpprint(FSA masterpt);
    DBG("\n    set   pnt  ");  fpprint(FSA set); fpprint(FSA pnt);
#endif


  /* world space resolution in pixels per inch */

    xworld_res = fplongexp(fc->s.m2.xworld_res, fc->s.m2.world_scale);
    yworld_res = fplongexp(fc->s.m2.yworld_res, fc->s.m2.world_scale);

    if(!(fc->format & FC_INCHES_TYPE))
    {
      /* Convert pixels/meter to pixels/inch */
        meters_per_inch = fpdiv(fpint2fp((SL32)254), fpint2fp((SL32)10000));
        xworld_res = fpmul(xworld_res, meters_per_inch);
        yworld_res = fpmul(yworld_res, meters_per_inch);
    }

  /* Compute scale transform from design space to world space */

    xscale = fpdiv(fpmul(set, xworld_res),
                               fpint2fp((SL32)if_state.comp_pix_context.xRes));
    yscale = fpdiv(fpmul(pnt, yworld_res),
                               fpint2fp((SL32)if_state.comp_pix_context.yRes));

  /*  Combine the design to world transform and the world to output
   *  transform and compute the SCALE parameters.
   */

    return comb_des_world(FSA xscale, yscale, fc->s.m2.m,
                                          fc->s.m2.matrix_scale);
}
#endif

#if (!SCALE_MATRIX || (SCALE_MATRIX & TYPO_SCALE_MATRIX))
/*--------------------*/
/*    typographer     */
/*--------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  typographer(FSP FPNUM masterpt)
#else
MLOCAL UW16
typographer(masterpt)
    FPNUM      masterpt;
#endif
{
    PFONTCONTEXT fc;

  /* Rotate and Shear */
    CGFIXED fcos, fsin;
    CGFIXED fscos, fssin;

    FPNUM one;
    FPNUM meters_per_inch;

    FPNUM xscanres, yscanres;   /* Design space resolution in pixels/inch */
    FPNUM xoutres, youtres;     /* Output space resolution in pixels/inch */
    FPNUM set_size, point_size;

    FPNUM set, pnt;
    FPNUM cos, sin, tan;
    FPNUM xout, yout;


  /* Step 1. Load parameters from fc and if_state.comp_pix_context */
  /* Design space resolution in pixels / inch */

    xscanres = fpint2fp((SL32)if_state.comp_pix_context.xRes);
    yscanres = fpint2fp((SL32)if_state.comp_pix_context.yRes);

  /* Point and set_size and output space resolution in pixels / inch */

    fc = &if_state.cur_loc_fc;

#if (!SCALE_MATRIX)
    if_state.wrong_read = (fc->set_size < 0);
    set_size   = fpint2fp((SL32)fc->set_size);
    point_size = fpint2fp((SL32)fc->point_size);
    xoutres = fpint2fp(fc->xres);
    youtres = fpint2fp(fc->yres);
#else
    if_state.wrong_read = (fc->s.t.set_size < 0);
    set_size   = fpint2fp((SL32)fc->s.t.set_size);
    point_size = fpint2fp((SL32)fc->s.t.point_size);
    xoutres = fpint2fp(fc->s.t.xres);
    youtres = fpint2fp(fc->s.t.yres);
#endif

    if(!(fc->format & FC_INCHES_TYPE))
    {
      /* Convert pixels/meter to pixels/inch */
        meters_per_inch = fpdiv(fpint2fp((SL32)254), fpint2fp((SL32)10000));
        xoutres = fpmul(xoutres, meters_per_inch);
        youtres = fpmul(youtres, meters_per_inch);
    }

#ifdef AGFADEBUG
    DBG("\n    masterpt ");  fpprint(FSA masterpt);
    DBG("\n    xscanres yscanres    ");  fpprint(FSA xscanres); fpprint(FSA yscanres);
    DBG("\n    xoutres  youtres     ");  fpprint(FSA xoutres); fpprint(FSA youtres);
    DBG("\n    set_size point_size  "); fpprint(FSA set_size);
                                        fpprint(FSA point_size);
    DBG("\n");
#endif

  /*  Rotation and shear  */

#if (!SCALE_MATRIX)
    fcos  = fc->rotate.x;        /*  rotation */
    fsin  = fc->rotate.y;
    fscos = fc->shear.y;         /*  shear    */
    fssin = fc->shear.x;
#else
    fcos  = fc->s.t.rotate.x;        /*  rotation */
    fsin  = fc->s.t.rotate.y;
    fscos = fc->s.t.shear.y;         /*  shear    */
    fssin = fc->s.t.shear.x;
#endif

    if(if_state.fpmath_error)
        return ERR_comp_pix;

  /* Step 2. Compute component matrices */
  /*  Compute first tranform matrix:
   *  scale outline by point and set size.
   *
   *    ( set   0  )
   *    (  0   pnt )
   *
   */

    set = fpdiv(set_size,   masterpt);
    pnt = fpdiv(point_size, masterpt);

#ifdef AGFADEBUG
    DBG("\n    set   pnt  ");  fpprint(FSA set); fpprint(FSA pnt);
#endif

  /*  Compute the second transform matrix: shear.
   *
   *      (  1   0  )
   *      ( tan  1  )
   *
   *  Compute the shear tangent and verify shear angle is between
   *  -45 to 45.
   */

    tan = fpdiv(fpfixed2fp(fssin), fpfixed2fp(fscos));
#ifdef AGFADEBUG
    DBG("\n   tan");   fpprint(FSA tan);
#endif

    one = fpint2fp((SL32)1);
    if(fplt(tan, fpneg(one)) || fplt(one, tan))  /* 11-19-90 dET */
       return ERR_comp_pix;


    if(if_state.fpmath_error)
    {
        DBG("***** fmath_error ***** tan, set, pnt compute\n");
        return if_state.fpmath_error;
    }

  /*  Next transform is rotation.
   *
   *      (  cos   sin  )
   *      ( -sin   cos  )
   *
   */

    cos = fpfixed2fp(fcos);
    sin = fpfixed2fp(fsin);
#ifdef AGFADEBUG
    DBG("\n    cos  sin");  fpprint(FSA cos);  fpprint(FSA sin);
#endif

  /*  Last transform is from design unit to output pixels.
   *
   *      ( xout   0   )
   *      (  0    yout )
   *
   *  xout = xoutres / xscanres
   *  yout = youtres / yscanres
   */

    xout = fpdiv(xoutres, xscanres);
    yout = fpdiv(youtres, yscanres);
#ifdef AGFADEBUG
    DBG("\n    xout yout  ");  fpprint(FSA xout);  fpprint(FSA yout);
    DBG("\n");
#endif


  /* Step 3. Combine component matrices and return matrix_to_scale() */
  /*  Combine the above four transforms in the order given to get:
   *
   *    ( set*cos*xout                 set*sin*yout              )
   *    ( pnt*(tan*cos - sin)*xout     pnt*(tan*sin + cos)*yout  )
   *
   */

    if_state.m[0] = fpmul(fpmul(set, cos), xout);
    if_state.m[1] = fpmul(fpmul(set, sin), yout);
    if_state.m[2] = fpmul(fpmul(pnt, fpsub(fpmul(tan, cos), sin)), xout);
    if_state.m[3] = fpmul(fpmul(pnt, fpadd(fpmul(tan, sin), cos)), yout);
#ifdef AGFADEBUG
    DBG("\n    m0 m1  ");  fpprint(FSA if_state.m[0]);  fpprint(FSA if_state.m[1]);
    DBG("\n    m2 m3  ");  fpprint(FSA if_state.m[2]);  fpprint(FSA if_state.m[3]);
    DBG("\n");
#endif
    if(if_state.fpmath_error)
    {
        DBG("***** fmath_error ***** mi compute\n");
        return if_state.fpmath_error;
    }

    return matrix_to_scale(FSA0);
}
#endif    /* (!SCALE_MATRIX || (SCALE_MATRIX & TYPO_SCALE_MATRIX)) */


/*  Computes the scaling paramters */
#if defined (ANSI_DEFS)
GLOBAL UW16  comp_pix(FSP PFONTCONTEXT fc, PBUCKET bucket)
#else
GLOBAL UW16
comp_pix(fc, bucket)
    PFONTCONTEXT  fc;
    PBUCKET       bucket;
#endif
{
    UW16     fstType;
    UW16     status;
    SL32      temp;
#if IF_RDR
    PDISPLAY display=NULL;
#endif
#if ((!SCALE_MATRIX)||(SCALE_MATRIX&(TYPO_SCALE_MATRIX|MAT2_SCALE_MATRIX)))
    FPNUM    masterpt;
#endif
#if STIK && (TT_DISK || TT_ROM || TT_ROM_ACT)
    fs_GlyphInfoType *fsg;
    if_state.update_reflines = FALSE;
#endif

    DBG("\n\n\ncomp_pix()\n");

    /*  Step 1. Check for need to change scaling parameters.
        Don't do anything unless the FONTCONTEXT has changed  
        or we're in asian vertical writing mode and we need to
        rotate a character 90 degrees or stop rotating characters
        90 degrees. have_adjusted_angle == 1 means that we are rotating
        characters. adjust_angle == 1 means that we need to rotate characters.
    */
    /* keb 7/99 */

    /* Don't need to progress any further if bitmap font, so let's exit. */
    /* jwd, 07/21/03.                                                    */

#if PCLEO_RDR
    if (if_state.DLBmpInProcess)
       return SUCCESS;
#endif

    if ( FC_ISUFSTVERT(&if_state.fcCur) )
    {
        temp = MEMCMP((LPSB8)fc, (LPSB8)&if_state.pserver->cur_loc_fc, sizeof(FONTCONTEXT))
                 || (if_state.CharVertWrit != if_state.have_adjusted_angle );
        
        if_state.have_adjusted_angle = if_state.CharVertWrit; /* to be ready for next time */
    }
    else
        temp = MEMCMP((LPSB8)fc, (LPSB8)&if_state.pserver->cur_loc_fc, sizeof(FONTCONTEXT));

    fstType = fc->format & FC_FONTTYPE_MASK;
    switch( fstType )
    {
#if IF_RDR
        case FC_IF_TYPE:
        {
            display = (PDISPLAY)(fgseg(FSA bucket) + bucket->p.in.odisplay);

          /* Need to check more than just fontcontext for Intellifont type */
          /* data. Especially for SLIMs, need to check mirror_flags.       */
            { 
                if( !temp && !COMP_PIX_CONTEXT_CHGD() ) 
                    return SUCCESS;  /* FONTCONTEXT is unchanged. Collect $200. */
            }
            break;
        }
#endif  /* IF_RDR */

#if FCO_RDR
        case FC_FCO_TYPE:
      /* Must also compare fc to the one stored in the FCO bucket. */
        {
#if 0    /* 09-04-02 jfd */
            if ( !temp && (!MEMCMP((LPSB8)fc, (LPSB8)&(bucket->p.fco.fcoFC),
                                   sizeof(FONTCONTEXT))) )
#else
            if ( !temp && (!MEMCMP((LPSB8)fc, (LPSB8)&(bucket->p.fco.fcoFC),
                                   sizeof(FONTCONTEXT)))
                        && (bucket->p.fco.design_EmRes == if_state.comp_pix_context.masterPt))
#endif    /* 09-04-02 jfd */
                return SUCCESS;
            break;
        }
#endif  /* FCO_RDR */

#if TT_RDR
        case FC_TT_TYPE:
        {
#if TT_TTPLUG   /* TT_PLUGINS == 2 (TrueType format) */
        /* Must also compare fc to the one stored in the TT bucket. */
            if ( !temp && (!MEMCMP((LPSB8)fc, (LPSB8)&(bucket->p.tt.TTfc),
                                   sizeof(FONTCONTEXT))) )
                return SUCCESS;
#else   /* For all other plugins */
            if (!temp)
                return SUCCESS;
            bucket=bucket;/* not used */
#endif
            break;
        }
#endif  /* TT_RDR */

#if PST1_RDR
        case FC_PST1_TYPE:
        {
            if (!temp)
                return SUCCESS;
            break;
        }
#endif  /* PST1_RDR */
    }       /* switch( fstType ) */

     /*
      * force FCis_equal() to fail so that
      * comp_pix() is called for first characters
      * of PostScript and TrueType fonts
      */

    if_state.cur_loc_fc.font_hdr =  (LPUB8)0;  /* 10-6-94 */
    if_state.cur_loc_fc.font_id = 0;  /* make invalid FONTCONTEXT */
#if SLIM_FONTS
  /* make invalid mirror flags copy -ss */
    if_state.comp_pix_context.mirflags = (UB8)0;
#endif

/* Step 2. Compute masterPt, xRes and yRes */
    switch( fstType )
    {
#if IF_RDR
        case FC_IF_TYPE:
        {
        /* Intellifont setup */
            if_state.origBaseline     = display->baselinePosition;
            if_state.comp_pix_context.masterPt = display->masterPointSize;
            if_state.comp_pix_context.xRes     = display->scanResolutionX;
            if_state.comp_pix_context.yRes     = display->scanResolutionY;
            break;
        }
#endif  /* IF_RDR */
#if FCO_RDR
        case FC_FCO_TYPE:
        {
            bucket->p.fco.fcoFC.format = FC_IF_TYPE;  /* invalid setting */
            if_state.comp_pix_context.orThreshold = bucket->p.fco.orThreshold;
            if_state.comp_pix_context.compositionFlag = bucket->p.fco.compositionFlag;
            if (!if_state.comp_pix_context.compositionFlag)
            {
                if_state.comp_pix_context.masterPt = 2000;  /* for IF scaling */
                if_state.comp_pix_context.xRes     = 2540;
                if_state.comp_pix_context.yRes     = 2540;
            }
            else /* For non-IF scaling, mby 11-16-94 */
            {    /* Don't multiply masterPt by 8 in case of 16-bit overflow.
                  * Instead, multiply xRes, yRes by 8.
                  */
                if_state.comp_pix_context.masterPt = bucket->p.fco.design_EmRes;
                if_state.comp_pix_context.xRes     = 576;  /*  (8)(72)  */
                if_state.comp_pix_context.yRes     = 576;
            }
            break;
        }
#endif  /* FCO_RDR */
#if TT_RDR
        case FC_TT_TYPE:
        {
#if TT_TTPLUG
            bucket->p.tt.TTfc.format  = FC_IF_TYPE;  /* invalid setting */
#endif
            if_state.comp_pix_context.masterPt = 8;   /* 1 point in eighths */
            if_state.comp_pix_context.xRes     = 72;
            if_state.comp_pix_context.yRes     = 72;
            break;
        }
#endif  /* TT_RDR */
#if PST1_RDR
        case FC_PST1_TYPE:
        {
      /*  We assume that after the fontmatrix has been concatenated, an
       *  original PS design unit maps to 1 unit in "user space".
       *  A "user space" pixel is defined to be 1 point square.
       */
            if_state.comp_pix_context.masterPt = 8;   /* 1 point in eighths */
            if_state.comp_pix_context.xRes     = 72;  /* 1 user space pixel = 1 point */
            if_state.comp_pix_context.yRes     = 72;
            break;
        }
#endif  /* PST1_RDR */
    }       /* switch( fstType ) */

#if IF_RDR
    if_state.gaso_pn = -1;
#endif
    if_state.fpmath_error = 0;  /*  fpmath error flag. Floating point operations
                        *  set to nonzero error code on error. */

#if ((!SCALE_MATRIX)||(SCALE_MATRIX&(TYPO_SCALE_MATRIX|MAT2_SCALE_MATRIX)))
  /*  Compute Design space master point size. Is in eighth points. Adjust
   *  in input point size is in sixteenth points.
   */
    /* AOF Feb. 11, 2000 added 1/20ths changes here and in cgif.h*/
     /* The default Design Space Master Point Size is in 8ths.    */
    masterpt = fpint2fp((SL32)if_state.comp_pix_context.masterPt);

    /* Design Space Master Point Size may have been set to 16ths.*/
    if (((fc->format) & FC_PSUNITS_MASK) == (SW16)FC_16THS_TYPE)
        masterpt = fpmul(masterpt, fpint2fp((SL32)2));

    /* Design Space Master Point Size may have been set to 20ths.*/
    if (((fc->format) & FC_PSUNITS_MASK) == (SW16)FC_20THS_TYPE)
        masterpt = fpdiv(fpmul(masterpt,fpint2fp((SL32)5)),
            fpint2fp((SL32)2));


    if(if_state.fpmath_error) return if_state.fpmath_error;
#endif

/* Step 3. Switch to typeographer(), matrix_design() etc. */

    if_state.cur_loc_fc = *fc; /* pass copy of incomming FONTCONTEXT to all
                                further levels and remember for next call
                                to comp_pix()
                              */
    if_state.pserver->cur_loc_fc = *fc;    /* save system copy of incoming FONTCONTEXT */
#if (!SCALE_MATRIX)
    if((status = typographer(FSA masterpt)) != SUCCESS)
        return status;
#else
    switch(fc->fc_type)
    {
#if (SCALE_MATRIX & TYPO_SCALE_MATRIX)
        case FC_TYPO_TYPE: status = typographer(FSA masterpt);
                           break;
#endif

#if (SCALE_MATRIX & MAT0_SCALE_MATRIX)
        case FC_MAT0_TYPE: status = matrix_design(FSA0);
                           break;
#endif
#if (SCALE_MATRIX & MAT1_SCALE_MATRIX)
        case FC_MAT1_TYPE: status = matrix_em_world(FSA0);
                           break;
#endif
#if (SCALE_MATRIX & MAT2_SCALE_MATRIX)
        case FC_MAT2_TYPE: status = matrix_pt_world(FSA masterpt);
                           break;
#endif
        default: return ERR_comp_pix;
    }
    if(status)
        return status;
#endif


#if STIK && (TT_DISK || TT_ROM || TT_ROM_ACT)
    if (FC_ISTT(fc))
    {
        fsg = (fs_GlyphInfoType *)MEMptr(bucket->p.tt.buffInfo);
        /* for CCC font */
        if (IS_STIK_FONT(fsg) && !if_state.update_reflines_flag_set)
                if_state.update_reflines = TRUE;
    }
#endif    /* STIK && (TT_DISK || TT_ROM || TT_ROM_ACT) */ 

#if TT_TTPLUG && TT_RDR
    if (FC_ISTT(fc))
        bucket->p.tt.TTfc = *fc;        /* -mby 10/15/92 */
#endif    /* TT_TTPLUG && TT_RDR */

#if FCO_RDR
    if (FC_ISFCO(fc))
        bucket->p.fco.fcoFC = *fc;      /* mby, 09-21-94 */
#endif

#if SLIM_FONTS
    if_state.comp_pix_context.mirflags = if_state.chr_def_hdr.mirror_flags;
#endif

#if EMBEDDED_BITMAPS && TT_RDR && CGBITMAP
     /*    Set flag which indicates whether a request has been made to manipulate the
      *    bitmap (embolden, rotate, shear, etc.). If so, the bitmap will be rasterized
      *    instead of retrieved from the embedded bitmap table.
      */
     /* also reuse this flag to force rasterization if the user requests it 
     (this is an override of the default behavior for testing purposes)    */
 
     if (bucket->fc_ExtndFlags & EF_TT_NOEMBED)
         if_state.BitmapManipulated = TRUE;
     else if (bitmap_manipulated(FSA0))
         if_state.BitmapManipulated = TRUE;
     else
         if_state.BitmapManipulated = FALSE;
#endif    /* EMBEDDED_BITMAPS && TT_RDR && CGBITMAP */

    return SUCCESS;
}

#if EMBEDDED_BITMAPS && CGBITMAP
#if defined (ANSI_DEFS)
MLOCAL    BOOLEAN    bitmap_rotated(FSP0)
#else
MLOCAL    BOOLEAN    bitmap_rotated()
#endif
    /* Checks if bitmap rotation is being requested. 
       If so, returns TRUE. Else, returns FALSE    */
{
#if (!SCALE_MATRIX)
    return (if_state.fcCur.rotate.x != (CGFIXED)F_ONE ||
            if_state.fcCur.rotate.y != (CGFIXED)0);
#else
    switch (if_state.fcCur.fc_type)
    {
#if (SCALE_MATRIX & TYPO_SCALE_MATRIX)
    case FC_TYPO_TYPE:
        return (if_state.fcCur.s.t.rotate.x != (CGFIXED)F_ONE ||
                if_state.fcCur.s.t.rotate.y != (CGFIXED)0);
        break;
#endif
#if (SCALE_MATRIX & MAT0_SCALE_MATRIX)
    case FC_MAT0_TYPE:
        return (if_state.fcCur.s.m0.m[1] != 0);
        break;
#endif
#if (SCALE_MATRIX & MAT1_SCALE_MATRIX)
    case FC_MAT1_TYPE:
        return (if_state.fcCur.s.m1.m[1] != 0);
        break;
#endif
#if (SCALE_MATRIX & MAT2_SCALE_MATRIX)
    case FC_MAT2_TYPE:
        return (if_state.fcCur.s.m2.m[1] != 0);
        break;
#endif
    default:
        return FALSE;
        break;
    }
#endif    /* !SCALE_MATRIX */
}

#if defined (ANSI_DEFS)
MLOCAL    BOOLEAN    bitmap_sheared(FSP0)
#else
MLOCAL    BOOLEAN    bitmap_sheared()
#endif
    /* Checks if bitmap shearing is being requested. 
       If so, returns TRUE. Else, returns FALSE    */
{
#if (!SCALE_MATRIX)
    return (if_state.fcCur.shear.x != (CGFIXED)0 ||
            if_state.fcCur.shear.y != (CGFIXED)F_ONE);
#else
    switch (if_state.fcCur.fc_type)
    {
#if (SCALE_MATRIX & TYPO_SCALE_MATRIX)
    case FC_TYPO_TYPE:
        return (if_state.fcCur.s.t.shear.x != (CGFIXED)0 ||
                if_state.fcCur.s.t.shear.y != (CGFIXED)F_ONE);
        break;
#endif
#if (SCALE_MATRIX & MAT0_SCALE_MATRIX)
    case FC_MAT0_TYPE:
        return (if_state.fcCur.s.m0.m[2] != 0);
        break;
#endif
#if (SCALE_MATRIX & MAT1_SCALE_MATRIX)
    case FC_MAT1_TYPE:
        return (if_state.fcCur.s.m1.m[2] != 0);
        return FALSE;
        break;
#endif
#if (SCALE_MATRIX & MAT2_SCALE_MATRIX)
    case FC_MAT2_TYPE:
        return (if_state.fcCur.s.m2.m[2] != 0);
        return FALSE;
        break;
#endif
    default:
        return FALSE;
        break;
    }
#endif    /* !SCALE_MATRIX */
}

#if defined (ANSI_DEFS)
MLOCAL    BOOLEAN    bitmap_manipulated(FSP0)
#else
MLOCAL    BOOLEAN    bitmap_manipulated()
#endif
    /* Checks if any type of bitmap manipulation (shearing, rotating,
       emboldening, banding, grayscaling, pcl6 emulation)
       is being requested. If so, returns TRUE. Else, returns FALSE    */


    /* 01-16-04 jfd
     * For bold and/or italic embedded bitmaps, we won't check for
     * shearing or emboldening with BOLD_HORIZONTAL
     */
{
    BOOLEAN status = FALSE;
    if (bitmap_rotated(FSA0))                            /* rotating    */
        return TRUE;
#if 0    /* 01-16-04 jfd */
    if (bitmap_sheared(FSA0))                            /* shearing    */
        return TRUE;
#endif    /* 01-16-04 jfd */

    return ( 
#if BOLD || BOLD_FCO
        if_state.fcCur.xbold != 0                    ||    /* bolding    */
        if_state.fcCur.ybold != 0                    ||    /* bolding    */
#endif

#if 0    /* 01-16-04 jfd */
#if BOLD_HORIZONTAL
        if_state.fcCur.bold_horizontal != 0            ||    /* bolding    */
#endif
#endif    /* 01-16-04 jfd */
#if BOLD_P6
        if_state.fcCur.pcl6bold != 0                ||    /* bolding    */
#endif
#if BANDING
        if_state.fcCur.band_top != 0                ||    /* banding    */
        if_state.fcCur.band_bot != 0                ||    /* banding    */
#endif
        FC_ISGRAY(&if_state.fcCur)                        /* grayscale        */
        );
}
#endif    /* EMBEDDED_BITMAPS && CGBITMAP */

 

config.h   ///

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/rac/CONFIG.H_V   1.12   Aug 22 2003 09:22:06   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/rac/CONFIG.H_V  $
 * 
 *    Rev 1.12   Aug 22 2003 09:22:06   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.11   Jul 21 2003 17:42:06   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.10   Jun 20 2003 15:05:54   Galejs
 * get rid of asserts
 * 
 *    Rev 1.9   Sep 23 2002 14:08:14   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.8   Dec 11 2000 18:27:02   Galejs
 * remove SIZEOF_LONG definition - this sort of thing belongs in port.h
 * 
 *    Rev 1.7   Dec 08 2000 18:06:22   Galejs
 * move SWP typedefs into port.h
 * 
 *    Rev 1.6   Oct 16 2000 15:46:34   Al
 * ACT 2 changes
 * 
 *    Rev 1.5   Sep 21 2000 14:01:38   galejs
 * change ACT error handling (no setjmp / longjmp)
 * 
 *    Rev 1.4   Jan 27 2000 17:33:54   galejs
 * remove ENABLE_MESSAGE option
 * 
 *    Rev 1.3   Dec 09 1999 15:21:26   galejs
 * all defines except debug-related are now obsolete
 * 
 *    Rev 1.2   29 Jul 1999 17:28:10   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.1   15 Aug 1997 15:00:58   JOE
 * Defined BIT_ENDIAN (by sm).
 * 
 *    Rev 1.0   04 Jun 1997 11:06:00   MARTIN
 * Initial revision.
 */
/*
 * File:                CONFIG.H
 * First Version:        December 18, 1996
 */
 
#ifndef __CONFIG__
#define __CONFIG__

/* the maximum length of a symbol ... must be <256
* values longer than 64 don't seem to help file size much 
* and add MUCH time to the compress phase
*/
#define MAX_SYMBOL_LENGTH 64


/* how many bits to use in the table -- 10 seems about right */
#define TABLE_BITS 10

/*** SOME BOOK KEEPING STUFF ... DON'T CHANGE ANYTHING BELOW ***/

#ifndef false
#define false 0
#endif

#ifndef true
#define true 1
#endif

#endif    /* __CONFIG__ */
 

cubic.h   

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/SYS/INC/CUBIC.H_V   1.7   Aug 22 2003 09:43:50   LynchR  $ */
/* $Log:   I:/BULL/URIP/SYS/INC/CUBIC.H_V  $ 
 * 
 *    Rev 1.7   Aug 22 2003 09:43:50   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.6   Sep 23 2002 14:27:30   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.5   11 Jan 1999 20:05:48   GALEJS
 * use CONST keyword for read-only data
 * 
 *    Rev 1.4   07 Apr 1995 11:31:32   LISA
 * Changed copyright information from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.3   22 Apr 1994 15:31:28   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.2   14 Jan 1993 11:14:08   LISA
 * Removed CntrlZ character
 * 
 *    Rev 1.1   14 Dec 1992 08:47:04   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 11:37:26   LISA
 * Initial revision.
*/
/* $Date:   Aug 22 2003 09:43:50  $ */
/*
**  
**  Process Block 1.6
**  File: cubic.h
 *
 *
 */
/************************************************************************/
/* Raster function include file of data type declarations and macro def */
/* History:                                                             */
/*    12-Apr-89 bjg created                                             */
/*    14-Mar-91 awr moved local variable declarations to cubic.c        */
/*    07-Mar-92 rs  Fix a million 'constant is long' warnings.               */
/*    02-Apr-92 rs  Portability cleanup (WORD, etc) (see port.h).       */
/************************************************************************/

#ifndef __CUBIC__
#define __CUBIC__

CONST SW16 atanlist[] = 
{  90,   93,   97,  100,  103,  105,  108,  110,  113,  115,
  117,  119,  121,  122,  124,  125,  127,  128,  130,  131,
  132,  133,  134,  135,  136,  137,  138,  139,  140,  141,
  142,  142,  143,  144,  145,  145,  146,  146,  147,  148,
  148,  149,  149,  150,  150,  151,  151,  151,  152,  152,
  153,  153,  154,  154,  154,  155,  155,  155,  156,  156,
  156,  157,  157,  157,  157,  158,  158,  158,  158,  159,
  159,  159,  159,  160,  160,  160,  160,  160,  161,  161,
  161,  161,  161,  162,  162,  162,  162,  162,  163,  163,
  163,  163,  163,  163,  163,  164,  164,  164,  164,  164,
  164,  164,  165,  165,  165,  165,  165,  165,  165,  165,
  166,  166,  166,  166,  166,  166,  166,  166,  166,  166,
  167,  167,  167,  167,  167,  167,  167,  167,  167,  167,
  167,  168,  168,  168,  168,  168,  168,  168,  168,  168,
  168,  168,  168,  169,  169,  169,  169,  169,  169,  169,
  169,  169,  169,  169,  169,  169,  169,  169,  169,  170,
  170,  170,  170,  170,  170,  170,  170,  170,  170,  170,
  170,  170,  170,  170,  170,  170,  170,  171,  171,  171,
  171,  171,  171,  171,  171,  171,  171,  171,  171,  171,
  171,  171,  171,  171,  171,  171,  171,  171,  171,  171,
  172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
  172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
  172,  172,  172,  172,  172,  172,  172,  172,  172,  172 };

CONST SL32 tanlist[] = 
  {    0L,     572L,    1144L,    1716L,    2289L,
    2861L,    3435L,    4008L,    4583L,    5158L,
    5734L,    6310L,    6888L,    7467L,    8047L,
    8628L,    9210L,    9794L,   10380L,   10967L,
   11556L,   12146L,   12739L,   13333L,   13930L,
   14529L,   15130L,   15734L,   16340L,   16949L,
   17560L,   18175L,   18792L,   19413L,   20036L,
   20663L,   21294L,   21928L,   22566L,   23207L,
   23853L,   24503L,   25157L,   25815L,   26478L,
   27146L,   27818L,   28496L,   29178L,   29866L,
   30560L,   31259L,   31964L,   32675L,   33392L,
   34116L,   34846L,   35583L,   36327L,   37078L,
   37837L,   38604L,   39378L,   40160L,   40951L,
   41751L,   42560L,   43377L,   44205L,   45042L,
   45889L,   46746L,   47615L,   48494L,   49385L,
   50287L,   51202L,   52130L,   53070L,   54024L,
   54991L,   55973L,   56970L,   57981L,   59009L,
   60053L,   61113L,   62191L,   63287L,   64402L,
   65536L,   66690L,   67864L,   69060L,   70279L,
   71520L,   72785L,   74075L,   75390L,   76733L,
   78103L,   79501L,   80930L,   82390L,   83882L,
   85408L,   86969L,   88567L,   90202L,   91878L,
   93595L,   95355L,   97161L,   99014L,  100916L,
  102871L,  104879L,  106945L,  109070L,  111258L,
  113511L,  115834L,  118230L,  120702L,  123255L,
  125893L,  128621L,  131445L,  134368L,  137399L,
  140542L,  143805L,  147196L,  150722L,  154393L,
  158217L,  162207L,  166372L,  170727L,  175283L,
  180058L,  185067L,  190330L,  195866L,  201698L,
  207853L,  214358L,  221245L,  228550L,  236314L,
  244583L,  253408L,  262849L,  272976L,  283866L,
  295612L,  308321L,  322118L,  337151L,  353598L,
  371671L,  391625L,  413775L,  438508L,  466309L,
  497791L,  533742L,  575196L,  623526L,  680608L,
  749069L,  832700L,  937191L, 1071482L, 1250471L,
 1500977L, 1876636L, 2502594L, 3754273L, 7508546L};

#endif    /* __CUBIC__ */
 

cubic.txt   

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/OUT/CUBIC.C_V   1.19   Aug 22 2003 09:09:58   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/OUT/CUBIC.C_V  $ 
 * 
 *    Rev 1.19   Aug 22 2003 09:09:58   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.18   Jun 23 2003 15:00:42   Galejs
 * ufstport.h
 * 
 *    Rev 1.17   Oct 21 2002 18:08:38   Galejs
 * fix uninitialized-vbl warnings
 * 
 *    Rev 1.16   Aug 09 1999 18:37:18   galejs
 * include-file changes
 * 
 *    Rev 1.15   21 Jan 1999 17:06:52   GALEJS
 * standardize #include tests
 * 
 *    Rev 1.14   12 Jan 1999 18:14:28   GALEJS
 * move EXTERN dcls
 * 
 *    Rev 1.13   22 Jun 1998 18:39:42   GALEJS
 * make Intellifont reentrant too
 * 
 *    Rev 1.12   01 Apr 1998 19:31:18   GALEJS
 * move all MLOCALs into IF_STATE
 * 
 *    Rev 1.11   24 Mar 1998 16:38:06   GALEJS
 * include-file changes
 * 
 *    Rev 1.10   16 Jul 1997 11:50:20   JOE
 * Got rid of 10 warning messages about type mismatches (by Jimmy).
 * 
 *    Rev 1.9   15 Jul 1997 10:39:12   AL
 * Pseudo bold via outlines
 * 
 *    Rev 1.8   15 Apr 1997 15:11:40   MIKE
 * LINT_ARGS replaces LINTARGS
 * 
 *    Rev 1.7   07 Apr 1995 09:17:10   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.6   01 Jun 1994 09:56:32   JOE
 * In get_angle(), moved code which adjust angle for polarity so that
 * it is executed only if the vector is neither horizontal nor vertical.
 * 
 *    Rev 1.5   22 Apr 1994 14:23:08   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.4   02 Feb 1994 08:59:26   JOE
 * Removed #include for "memory.h" .
 * 
 *    Rev 1.3   12 Feb 1993 14:47:18   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   05 Jan 1993 14:19:54   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:25:38   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:28:46   LISA
 * Initial revision.
*/
/* $Date:   Aug 22 2003 09:09:58  $ */
/*
**  Process Block 1.6
**  File: cubic.c
**  ----------------------------------------------------------
*  History:
*  ---------
*             bjg Version 2.2 release
*   12-Mar-91 awr started port to ufst
*   24-Mar-91 awr modified get_angle(). "Slope" was not always initialized.
*   19-May-91 awr LOOP structure changed
*    2-Jun-91 awr HQ4 changes
*    8-Jun-91 awr fixed two bugs in if_long_mult()
*   17-Jun-91 jfd Moved "debug.h" after "port.h".
*   17-Jun-91 bjg Fixed make_bezier when den == 0.
*   18-Jun-91 jfd In check_bezier(), changed "eps1" from 20 to 40.
*   19-Jun-91 jfd Attempted fix by bjg in make_bezier()
*   26 Jun 91 ss  Fixed prototype for cubic() in not LINT_ARGS.
*                 Added casts for SegmtPtr usage.
*   27-Jun-91 bjg In make_bezier(), to get rid of crossing contours,
*                 check if both "alpha1" and "alpha2" exceed 65536.
*             jfd In check_bezier(), changed "eps1" from 40 to 60.
*   06-Aug-91 jfd In cubic(), cast argument passed to CHARfree() as
*                 (HIFOUTLINE).
*   24-Aug-91 awr Moved function decls to include file
*    6-Sep-91 awr Changed HEADERSIZE to OLHEADERSIZE
*    7-Sep-91 awr Changed cubic output from IFOUTLINE to function calls
*    9-Sep-91 jfd  Including "outline.h".
*   10-Sep-91 jfd Changed naming convention of outline functions.
*   12-Sep-91 jfd In make_bezier(), changed name of olcurveto() call to
*                 olcubeto().
*    9-Nov-91 awr Moved if_long_mult() to q3.c
*   03-Apr-92 rs  Portability cleanup (see port.h).
*   21-May-92 jfd In cubic() and make_bezier(), changed argument lists for
*                 calls to olmoveto(), ollineto() and olcubeto() so as to
*                 match corresponding bitmap function calls. Replaced
*                 all direct outline function calls with calls via the
*                 function table.
*                 Added pointer to font function table "pras".
*   08-Jul-92 rs  Code cleanup.
*   30-Jul-92 jfd Removed "#include if_def.h" statement.
*   09-Aug-92 rs  Changes for Watcom C386 compiler (string.h).
*   23-Sep-92 jfd INTEL960 conditional compile changes.
*   05-Jan-93 jfd ANSI C function declaration changes.
*   08-Feb-93 jfd VXWorks support.
*   26-Jan-94 jfd Removed #include for memory.h .
*   01-Jun-94 jfd In get_angle(), moved code which adjusts angle for
*                 polarity so that it is executed only if the vector
*                 is neither horizontal nor vertical.
*   14-Apr-97 mby Replaced "LINTARGS" with "LINT_ARGS".
*   01-Apr-98 slg MLOCALs cleanup: make wb, finis, k local to cubic(), move
*                  all the other MLOCALs into IF_STATE.
*/

#include "cgconfig.h"

#if IF_RDR && CUBIC        /*  Entire module is conditionally compiled  */

#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include <stdio.h>
#include <string.h>

#include "ufstport.h"
#include "dbg_ufst.h"

#include "shareinc.h"

#include "mixmodel.h"
#include "q3.h"
#include "cubic.h"


#ifdef LINT_ARGS
MLOCAL SW16  if_break(FSP SW16, SW16, LPSW16, LPSW16);
MLOCAL UW16 make_bezier(FSP0);
MLOCAL VOID  check_bezier(FSP SW16, SW16, SW16,
                    SW16VECTOR, SW16VECTOR, SW16VECTOR, SW16VECTOR, LPSW16);
MLOCAL VOID  get_point(FSP SW16, SW16, SW16, PSW16VECTOR);
MLOCAL SW16  get_angle(PSW16VECTOR);

#else
MLOCAL SW16  if_break();
MLOCAL UW16 make_bezier();
MLOCAL VOID  check_bezier();
MLOCAL VOID  get_point();
MLOCAL SW16  get_angle();
#endif


/*--------------------------------------------------------------------*/

#define dot(A,B) ( ((SL32)(A.x)*(SL32)(B.x)) + ((SL32)(A.y)*(SL32)(B.y)) )
#define crs(A,B) ( ((SL32)(A.x)*(SL32)(B.y)) - ((SL32)(A.y)*(SL32)(B.x)) )
#define BYTEMASK1 ((UB8)1)
#define BYTEMASK2 ((UB8)2)

/* ----------------------------------------------------------------------- */
/* Routine: cubic                                                          */
/* Purpose: Generate a cubic outline for the output character              */
/* Input  : Grid aligned scaled outline- line and bi-arc                   */
/* Output : Function calls to start & end loop and draw lines and beziers  */
/* ----------------------------------------------------------------------- */
#if defined (ANSI_DEFS)
GLOBAL UW16  cubic(FSP INTR xtranslate, INTR ytranslate)
#else
GLOBAL UW16
cubic(xtranslate, ytranslate)
    INTR        xtranslate;
    INTR        ytranslate;
#endif
{
   BOOLEAN  linear_op;        /* TRUE = linear, FALSE = quadratic outline  */
   UW16    bstate,set_state = 1,i;
   BOOLEAN  vs,ve;       /*  TRUE if curve point */
   LPSB8    vptr;        /* vertex codes */
   LOOP     loop;        /* current loop */
   UW16    status;
   PSW16VECTOR  wb;
   SW16 finis, k;

   if_state.xt_cb = (SW16)(-xtranslate);
   if_state.yt_cb = (SW16)(-ytranslate);

   linear_op = (if_state.quality < 3);
   vs = ve = FALSE;     /* set for quality < 3 */

   first_loop(FSA0);
   for ( k = 0; k < if_state.num_loops; k++ ) {
      DBG("\n\n\nN e x t    L o o p\n");

      next_loop(FSA &loop);
      vptr  = loop.v;                           /* vertex codes */
      finis = loop.ncoords;
      if_state.coord_cb = wb = loop.cv;    /* start of loop in workbuffer */
      status = if_state.out.start_loop ( FSAvoid if_state.out_instance, loop.polarity );
      if (status)
         return status;

     /* Traverse contour foward (CCW direction) by outline segments */ 

      if_state.START_cb.x = wb->x - if_state.xt_cb;
      if_state.START_cb.y = wb->y - if_state.yt_cb;
      wb++;
      if(!linear_op)
          vs = V_CONTACT(*vptr++);
      if_state.bzstart = 0;

      if_state.stack_pntr = if_state.stack_cb;
      if_state.angle_pntr = if_state.angle_cb;
      bstate = set_state;
      status = if_state.out.moveto(FSAvoid if_state.out_instance,
                                           incr(if_state.START_cb.x), incr(if_state.START_cb.y));
      if (status)
         return status;

      for ( i = 1; i <= finis; i++ ) {
         if ( linear_op || (!vs) ) {
            if_state.END_cb.x = wb->x - if_state.xt_cb;
            if_state.END_cb.y = wb->y - if_state.yt_cb;
            wb++;
            if(!linear_op)
                ve = V_CONTACT(*vptr++);
            if_state.bzstart = i;
            if_state.angle_pntr = if_state.angle_cb;
            bstate = set_state = 1;
            status = if_state.out.lineto(FSAvoid if_state.out_instance,
                                              incr(if_state.END_cb.x), incr(if_state.END_cb.y));
            if (status)
               return status;
         } else {
            if_state.CONTACT_cb.x = wb->x - if_state.xt_cb;
            if_state.CONTACT_cb.y = wb->y - if_state.yt_cb;
            wb++;

            i++;
            if_state.END_cb.x = wb->x - if_state.xt_cb;
            if_state.END_cb.y = wb->y - if_state.yt_cb;
            wb++;
            ve = V_CONTACT(*vptr++);

            if( if_break(FSA if_state.bzstart,i,(LPSW16)&bstate,(LPSW16)&set_state) ) {

               if_state.bzend = i - 2;

               status = make_bezier(FSA0);
               if (status)
                   return status;

               if_state.bzstart = if_state.bzend;
               *(if_state.angle_cb+1) = *(--if_state.angle_pntr);
               *(if_state.angle_cb) = *(--if_state.angle_pntr);
               if_state.angle_pntr = if_state.angle_cb + 2;
               bstate = set_state;

           }  /* end if for discontinuity, inflection, extrema check */


            if(!ve || (i == finis)) {

               if_state.bzend = i;

               status = make_bezier(FSA0);
               if (status)
                   return status;

               if_state.bzstart = if_state.bzend;
               if_state.angle_pntr = if_state.angle_cb;
               bstate = set_state;

           }  /* end if next seg is line or end  */
            
       } /*  end else clause for curve segment */
      if_state.START_cb = if_state.END_cb; 
      vs = ve;
      } /* end for each segment */ 
      status = if_state.out.end_loop ( FSAvoid if_state.out_instance );
      if (status)
         return status;
   } /* end for each contour */ 
   return SUCCESS;  
}


/*-------------------*/
/*   make_bezier     */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  make_bezier(FSP0)
#else
MLOCAL UW16
make_bezier()
#endif
{
   UW16 status;
   UW16 is,ie,u1,fit;
   SW16VECTOR B,C,D,E,Dnext,Enext;
   SW16VECTOR  P0 ,P1, P2, P3;
   SW16VECTOR chord;
   SL32 m1,m2,b1,b2,bx,by;
   SL32 mult,mult2,fac,den;
   SL32 alpha1,alpha2;
   SW16 shift,shift2;   
   SW16 u,tempang,chordang,minn;
   LPSW16 tempptr;

   SW16VECTOR CONTROL, V;

   if_state.bzptr = if_state.base_cb;
   *if_state.bzptr++ = if_state.bzstart;             
   *if_state.bzptr++ = if_state.bzend;

   get_point(FSA if_state.bzstart, (SW16)(if_state.bzstart+1), (SW16)(if_state.bzstart+2), &P1);
   get_point(FSA if_state.bzend,   (SW16)(if_state.bzend-1),   (SW16)(if_state.bzend-2),   &P2);

   D.x = (P1.x>>1) - if_state.coord_cb[if_state.bzstart].x+if_state.xt_cb;
   D.y = (P1.y>>1) - if_state.coord_cb[if_state.bzstart].y+if_state.yt_cb;
   E.x = (P2.x>>1) - if_state.coord_cb[if_state.bzend].x+if_state.xt_cb;
   E.y = (P2.y>>1) - if_state.coord_cb[if_state.bzend].y+if_state.yt_cb;
   
   *if_state.stack_pntr++ = D;
   *if_state.stack_pntr++ = E;

   while ( if_state.bzptr != if_state.base_cb ) {
     ie = *(--if_state.bzptr);
     is = *(--if_state.bzptr);

     fit = TRUE;
     P0.x = if_state.coord_cb[is].x-if_state.xt_cb;
     P0.y = if_state.coord_cb[is].y-if_state.yt_cb;
     P3.x = if_state.coord_cb[ie].x-if_state.xt_cb;
     P3.y = if_state.coord_cb[ie].y-if_state.yt_cb;

     C = E = *(--if_state.stack_pntr);
     B = D = *(--if_state.stack_pntr);

     den = crs(D,E);
     if(den == 0) {
       fit = 2;
         status = if_state.out.lineto(FSAvoid if_state.out_instance,
                                        incr(P3.x), incr(P3.y));
         if (status)
            return status;
         continue;
     }


     if(D.x == 0) {
        m2 = ((SL32)E.y << 16)/E.x;
        b2 = P3.y - (SW16)((m2 * P3.x)>>16);
        P1.x = P0.x;
        P1.y = (SW16)(b2 + ((m2 * P1.x)>>16));
     }
     else if (E.x == 0) {
        m1 = ((SL32)D.y << 16)/D.x;
        b1 = P0.y - (SW16)((m1 * P0.x)>>16);
        P1.x = P3.x;
        P1.y = (SW16)(b1 + ((m1 * P1.x)>>16));
     }
     else {
        m1 = ((SL32)D.y << 16)/D.x;
        m2 = ((SL32)E.y << 16)/E.x;
        if_long_mult(m1, P0.x, &mult, &shift);
           fac = mult>>(16-shift);
           b1 = P0.y - fac;
        if_long_mult(m2, P3.x, &mult, &shift);
           b2 = P3.y - (mult>>(16-shift));
        if_long_mult((b2-b1),0x4000,&mult,&shift);
        P1.x = (SW16)(mult/((m1-m2)>>(3+shift)));
        P1.x = (P1.x+1)>>1;

        if(D.y == 0)
          P1.y = P0.y;
        else if (E.y == 0)
          P1.y = P3.y;
        else {
          if_long_mult(m1, P1.x, &mult, &shift);
             fac = mult>>(16-shift);
             P1.y = (SW16)(b1 + fac);
        }
     }


     D.x = P1.x - P0.x;
     D.y = P1.y - P0.y;
     E.x = P1.x - P3.x;
     E.y = P1.y - P3.y;

     den = crs(D,E);
     if(den == 0) {
       fit = 2;
         status = if_state.out.lineto(FSAvoid if_state.out_instance,
                         incr(P3.x), incr(P3.y));
         if (status)
            return status;
         continue;
     }


     minn = 0x7fff;
     u1 = is;

     chord.x = P3.x - P0.x;
     chord.y = P3.y - P0.y;
     chordang = get_angle(&chord);

     tempptr = if_state.angle_cb + 2 + (is-if_state.bzstart);
     for (u=is+2; u<ie; u++) {
      tempang = *tempptr++;

       if(ABS(tempang-chordang) < minn) {
         minn = ABS(tempang-chordang);
         u1 = u;
       }
     }
     if(u1 == is)
       u1 = (is + ie)>>1;

     P1.x = if_state.coord_cb[u1].x-if_state.xt_cb;
     P1.y = if_state.coord_cb[u1].y-if_state.yt_cb;


     bx = ( ( ((SL32)P1.x<<3) - ((SL32)P0.x<<2)  
            - ((SL32)P3.x<<2))<<16)/3L;
     by = ( ( ((SL32)P1.y<<3) - ((SL32)P0.y<<2)
            - ((SL32)P3.y<<2))<<16)/3L;

     if_long_mult(bx,E.y,&mult,&shift);
     if_long_mult(by,E.x,&mult2,&shift2);
     if(shift > shift2) {
       mult2 = mult2>>(shift-shift2);
       fac = den >> shift;
     }
     else {
       mult = mult >>(shift2-shift);
       fac = den >> shift2;
       shift = shift2;
     }

     if( ((mult^mult2)&0x80000000L) &&
         ( (LABS(mult)&0x40000000L) || (LABS(mult2)&0x40000000L)) ) {
        shift += 1;
        mult = mult>>1;
        mult2 = mult2>>1;
     }
     alpha1 = (mult - mult2)/den;
     alpha1 = alpha1 << shift;


     if_long_mult(by,D.x,&mult,&shift);
     if_long_mult(bx,D.y,&mult2,&shift2);
     if(shift > shift2) {
       mult2 = mult2>>(shift-shift2);
       fac = den >> shift;
     }
     else {
       mult = mult >>(shift2-shift);
       fac = den >> shift2;
       shift = shift2;
     }
     if( ((mult^mult2)&0x80000000L) &&
         ( (LABS(mult)&0x40000000L) || (LABS(mult2)&0x40000000L)) ) {
        shift += 1;
        mult = mult>>1;
        mult2 = mult2>>1;
     }
     alpha2 = (mult - mult2)/den;
     alpha2 = alpha2 << shift;

     if((alpha1 < 0 || alpha2 < 0)) 
         fit = FALSE;
     if((alpha1 > 65536L && alpha2 > 65536L))
         fit = FALSE;
     P1.x = P0.x + (SW16)((alpha1 * D.x) >> 16);
     P1.y = P0.y + (SW16)((alpha1 * D.y) >> 16);
     P2.x = P3.x + (SW16)((alpha2 * E.x) >> 16);
     P2.y = P3.y + (SW16)((alpha2 * E.y) >> 16);
     if (fit == TRUE)
         check_bezier(FSA is, u1, ie, P0, P1, P2, P3, (LPSW16)&fit);
     if( fit == 2) {
        /************WRITE DATA************/
         status = if_state.out.lineto(FSAvoid if_state.out_instance,
                                           incr(P3.x), incr(P3.y));
         if (status)
            return status;
        /************WRITE DATA************/
     }

     else if ((fit != TRUE) && ((ie-is) > 2) ) {
        u1 = (is&1) ? u1|1 : u1&0xfffe;
        if(u1 == ie) u1 -= 2;
        *if_state.bzptr++ = u1;
        *if_state.bzptr++ = ie;
        *if_state.bzptr++ = is;
        *if_state.bzptr++ = u1;

        get_point(FSA u1, (SW16)(u1+1), (UW16)(u1+2), &P1);
        get_point(FSA u1, (SW16)(u1-1), (UW16)(u1-2), &P2);

        
        Dnext.x = (P1.x>>1) - if_state.coord_cb[u1].x+if_state.xt_cb;
        Dnext.y = (P1.y>>1) - if_state.coord_cb[u1].y+if_state.yt_cb;
        Enext.x = (P2.x>>1) - if_state.coord_cb[u1].x+if_state.xt_cb;
        Enext.y = (P2.y>>1) - if_state.coord_cb[u1].y+if_state.yt_cb;
        *if_state.stack_pntr++ = Dnext;
        *if_state.stack_pntr++ = C;
        *if_state.stack_pntr++ = B;
        *if_state.stack_pntr++ = Enext;
     }
     else if (fit != TRUE) {
        /************WRITE DATA************/
        CONTROL.x = P0.x+B.x;
        CONTROL.y = P0.y+B.y;
        V.x = if_state.coord_cb[u1].x - if_state.xt_cb;
        V.y = if_state.coord_cb[u1].y - if_state.yt_cb;
        status = if_state.out.cubeto(FSAvoid if_state.out_instance,
                                        incr(CONTROL.x), incr(CONTROL.y), 
                          incr(CONTROL.x), incr(CONTROL.y),
                          incr(V.x), incr(V.y));
        if (status)
           return status;
        /************WRITE DATA************/
        CONTROL.x = P3.x+C.x;
        CONTROL.y = P3.y+C.y;
        status = if_state.out.cubeto(FSAvoid if_state.out_instance,
                                     incr(CONTROL.x), incr(CONTROL.y),
                          incr(CONTROL.x), incr(CONTROL.y),
                          incr(P3.x), incr(P3.y));
        if (status)
           return status;
        /************WRITE DATA************/
     }
     else {
        /************WRITE DATA************/
        status = if_state.out.cubeto(FSAvoid if_state.out_instance,
                                        incr(P1.x), incr(P1.y), incr(P2.x),
                          incr(P2.y), incr(P3.x), incr(P3.y));
        if (status)
           return status;
        /************WRITE DATA************/
     }
   }  /*  end while(if_state.bzptr != if_state.base_cb) */
   return SUCCESS;
}


/*-------------------*/
/*     get_angle     */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL SW16  get_angle (PSW16VECTOR A)
#else
MLOCAL SW16
get_angle (A)
   PSW16VECTOR A;
#endif
{
   SW16 index,angA;
   SL32 slope;

   if (A->x == 0)
     angA = 180;
   else if (A->y == 0)
     angA = 0;
   else
   {
      if ( ABS(A->y) > ABS(A->x)) 
         slope = LABS(((SL32)A->y<<16)/A->x);
      else
         slope = LABS(((SL32)A->x<<16)/A->y);

      index = (SW16)((slope-63488L)>>12);
      if(index < 229)
        angA = atanlist[index];
      else if (index < 508) {
        if (index < 318) {
           if(index < 266)   angA = 173;
           else              angA = 174;
        }
        else if(index < 392) angA = 175;
        else                 angA = 176;
      }
      else if (index < 1207) {
        if(index < 718)      angA = 177;
        else                 angA = 178;
      }
      else if (index < 3651) angA = 179;
      else                   angA = 180;

      /* The following code was moved from outside the
       * if-else if -else loop
       *    5-31-94 jfd
       */

      if ( ABS(A->y) <= ABS(A->x)) 
        angA = 180 - angA;
      if(A->x < 0)
        angA = 360 - angA;
      if(A->y < 0) 
        angA = -angA;
   }
   return(angA);
}


/*-------------------*/
/*     if_break      */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL SW16  if_break(FSP SW16 bz_start, SW16 i, LPSW16 bstate, LPSW16 set_state)
#else
MLOCAL SW16
if_break(bz_start,i,bstate,set_state)
   SW16 bz_start;
   SW16 i;
   LPSW16 bstate;
   LPSW16 set_state;
#endif
{
#define angtol 10
   SW16VECTOR A,B,C;
   SW16 angA,angB,angC,angD,angE;
   SL32 AcrossB;

/*  this is the only other use of START, CONTACT, END 
 *  which are global variables other than in main. Think about passing
 *  as parameters.
 */

   A.x = if_state.END_cb.x - if_state.START_cb.x;
   A.y = if_state.END_cb.y - if_state.START_cb.y;
   B.x = if_state.CONTACT_cb.x - if_state.START_cb.x;
   B.y = if_state.CONTACT_cb.y - if_state.START_cb.y;
   C.x = if_state.END_cb.x - if_state.CONTACT_cb.x;
   C.y = if_state.END_cb.y - if_state.CONTACT_cb.y;

   angA = get_angle(&A);
   angB = get_angle(&B);
   angC = get_angle(&C);
 
   angD = angB + angB - angA;
   angE = angC + angC - angA;
   *if_state.angle_pntr++ = angD;
   *if_state.angle_pntr++ = angA;

   *set_state = 1;

   AcrossB = crs(A,B);

   if ( (i - bz_start) > 22) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(1);
   }

   if ( bz_start >= (i-2) ) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(0);
   }
   if(   /* inflection */
        (((AcrossB^if_state.AcrossBprev)&0x80000000L) != 0)  ||
      /* discontinuity */
         ( ABS(angD-if_state.angEprev) > angtol)  ) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(1);
    }

   *set_state = 0;

   if (  ( ABS(angD) >= 3 ) &&
         ( ABS(180 - ABS(angD)) >= 3 ) &&
         ( ABS(360 - ABS(angD)) >= 3 ) )  {
      *bstate = 1;
   }

   if( *bstate == 0) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(0);
   }

   if ( ABS(angE) < 3 || ABS(180 - ABS(angE)) < 3 ||
         ABS(360 - ABS(angE)) < 3) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(0);
   }
      /*  extrema  */
   if (  ( ABS(angD) < 3 ) ||
         ( ABS(180 - ABS(angD)) < 3 ) ||
         ( ABS(360 - ABS(angD)) < 3 ) ||
         ( ABS(if_state.angEprev) < 3 ) ||
         ( ABS(180 - ABS(if_state.angEprev)) < 3 ) ||
         ( ABS(360 - ABS(if_state.angEprev)) < 3 ) ) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(1);
     }

     if (( ((angD^angE)&0x8000) != 0 ) ||
         ( (((180-ABS(angD))^(180-ABS(angE)))&0x8000) != 0 ) ) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(1);
     }
     if (( ((angD^if_state.angEprev)&0x8000) != 0 ) ||
         ( (((180-ABS(angD))^(180-ABS(if_state.angEprev)))&0x8000) != 0 ) ) {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(1);
     }

     else {
         if_state.AcrossBprev = AcrossB;
         if_state.angEprev = angE;
         return(0);
     }
}


/*-------------------*/
/*    get_point      */
/*-------------------*/
/*  is, ic, ie are input indices of curve points. */
#if defined (ANSI_DEFS)
MLOCAL VOID  get_point(FSP SW16 is, SW16 ic, SW16 ie, PSW16VECTOR P)
#else
MLOCAL VOID
get_point(is, ic, ie, P)
  SW16 is,ic,ie;
  PSW16VECTOR P;
#endif
{
   SW16VECTOR A,B;
   SW16VECTOR P0;
   SL32 fac,den,mult;
   SW16 shift;

   A.x = if_state.coord_cb[ie].x - if_state.coord_cb[is].x;
   A.y = if_state.coord_cb[ie].y - if_state.coord_cb[is].y;
   B.x = if_state.coord_cb[ic].x - if_state.coord_cb[is].x;
   B.y = if_state.coord_cb[ic].y - if_state.coord_cb[is].y;
   P0.x = if_state.coord_cb[ic].x - if_state.xt_cb;
   P0.y = if_state.coord_cb[ic].y - if_state.yt_cb;
   fac = dot(B,B);
   den = dot(A,B);
   if ( den == 0 ) {
      P->x = ( P0.x << 1 );
      P->y = ( P0.y << 1 );
   } else {
      if_long_mult ( fac, A.x, &mult, &shift );
      den = den >> shift;
      P->x = ( P0.x << 1 ) - ( (SW16)(mult/den) );
      if_long_mult ( fac, A.y, &mult, &shift );
      den = den >> shift;
      P->y = ( P0.y << 1 ) - ( (SW16)(mult/den) );
   }

}


/*-------------------*/
/*    check_bezier   */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL VOID  check_bezier(FSP SW16 is, SW16 u1, SW16 ie, SW16VECTOR P0,
   SW16VECTOR P1, SW16VECTOR P2, SW16VECTOR P3, LPSW16 fit)
#else
MLOCAL VOID
check_bezier(is, u1, ie, P0, P1, P2, P3, fit)
   SW16 is;
   SW16 u1;
   SW16 ie;
   SW16VECTOR P0, P1, P2, P3;
   LPSW16 fit;
#endif
{

#define MAYBE 23
#define LONGMASK1 ((UL32)1)
#define bitpattern 0x00001327


   SW16 u,iz;
   SW16VECTOR F;
   SW16 dx=0, dy=0, dx1, dy1, dx2, dy2;
   SW16VECTOR v0={0,0}, v1, v2, v3;
   SW16 shift;
   SL32 m1,m2,mult,b1,b2,fac,bitpatt;
   SW16 first,last,ang1,ang2;
   LPSW16 tempptr;
   SW16 flip,eps1;
   PSW16VECTOR ptr;

   eps1 = 60;    /* controls curve fitting tolerance (was 20, then 40) 06-27-91 jfd */
 
   for (iz=0; iz<4; iz += 2) {


      if( iz == 0) {
         F.x = (SW16)((((SL32)P0.x<<5) - ((SL32)P0.x<<2) - (SL32)P0.x
                     + ((SL32)P1.x<<5) - ((SL32)P1.x<<2) - (SL32)P1.x
                     + ((SL32)P2.x<<3) + (SL32)P2.x + (SL32)P3.x)>>6);
         F.y = (SW16)((((SL32)P0.y<<5) - ((SL32)P0.y<<2) - (SL32)P0.y
                     + ((SL32)P1.y<<5) - ((SL32)P1.y<<2) - (SL32)P1.y
                     + ((SL32)P2.y<<3) + (SL32)P2.y + (SL32)P3.y)>>6);
         first = is+1;
         last = u1;
      }
      else {
         F.x = (SW16)((((SL32)P3.x<<5) - ((SL32)P3.x<<2) - (SL32)P3.x
                     + ((SL32)P2.x<<5) - ((SL32)P2.x<<2) - (SL32)P2.x
                     + ((SL32)P1.x<<3) + (SL32)P1.x + (SL32)P0.x)>>6);
         F.y = (SW16)((((SL32)P3.y<<5) - ((SL32)P3.y<<2) - (SL32)P3.y
                     + ((SL32)P2.y<<5) - ((SL32)P2.y<<2) - (SL32)P2.y
                     + ((SL32)P1.y<<3) + (SL32)P1.y + (SL32)P0.y)>>6);
         first = u1+1;
         last = ie;
      }
      ptr = &if_state.coord_cb[first-1];
      if ( ABS(F.x - ptr->x + if_state.xt_cb) < eps1 &&
           ABS(F.y - ptr->y + if_state.yt_cb) < eps1) {
           *fit = TRUE;
           continue;
      }
      *fit = FALSE;
      for(u = first; u <= last; u++) {
        v0.x = ptr->x - if_state.xt_cb;
        v0.y = ptr->y - if_state.yt_cb;
        ptr++;
        dx = ptr->x - v0.x - if_state.xt_cb;
        dy = ptr->y - v0.y - if_state.yt_cb;

        if( ABS(F.x-v0.x-dx) < eps1 &&
            ABS(F.y-v0.y-dy) < eps1) {
           *fit = TRUE;
           break;
        }
        if (dx > 0 ) {
           dx1 = 0;
           dx2 = dx;
        }
        else {
           dx1 = dx;
           dx2 = 0;
        }
        if (dy > 0 ) {
           dy1 = 0;
           dy2 = dy;
        }
        else {
           dy1 = dy;
           dy2 = 0;
        }
        if (F.x < v0.x + dx1 - eps1 ||
            F.y < v0.y + dy1 - eps1 ||
            F.x > v0.x + dx2 + eps1 ||
            F.y > v0.y + dy2 + eps1 ) {
                *fit = FALSE;
                continue;
        }
        *fit = MAYBE;
        break;
     }  /*  end for (u= ... */

     if(*fit == FALSE)
       break;
     if(*fit == TRUE)
       continue;
     
     tempptr = if_state.angle_cb + u - 1 - if_state.bzstart;
     ang1 = *tempptr++;
     ang2 = *tempptr;

     flip = 1;
     if(ang1 < 0) {
        ang1 = -ang1;
        flip = -1;
     }
     if(ang1 > 180) {
        ang1 = 360 - ang1;
        flip *= -1;
     }
     m1 = tanlist[ang1]*flip;
     flip = 1;
     if(ang2 < 0) {
        ang2 = -ang2;
        flip = -1;
     }
     if(ang2 > 180) {
        ang2 = 360 - ang2;
        flip *= -1;
     }
     m2 = tanlist[ang2]*flip;

     v1.x = v0.x + dx;
     v1.y = v0.y + dy;

     if(m1 == m2) {
       v2.x = (v0.x + v1.x)>>1;
       v2.y = (v0.y + v1.y)>>1;
     }
     else {
       if_long_mult(m1, v0.x, &mult, &shift);
            fac = mult>>(16-shift);
          b1 = v0.y - fac;
       if_long_mult(m2, v1.x, &mult, &shift);
          b2 = v1.y - (mult>>(16-shift));
       if_long_mult((b2-b1),0x4000,&mult,&shift);
       v2.x = (SW16)(mult/((m1-m2)>>(3+shift)));
       v2.x = (v2.x+1)>>1;
       if(m1 == MAX_LONG)
         v2.y = v0.y;
       else if (m2 == MAX_LONG)
         v2.y = v1.y;
       else {
         if_long_mult(m1, v2.x, &mult, &shift);
            fac = mult>>(16-shift);
            v2.y = (SW16)(b1 + fac);
       }
     }
     if_state.ptr2_cb = if_state.stack2_cb + 8;
     *if_state.ptr2_cb++ = v0;
     v0.x = v0.x<<1;
     v0.y = v0.y<<1;
     v3.x = v1.x<<1;
     v3.y = v1.y<<1;
     v1.x = v2.x<<1;
     v1.y = v2.y<<1;

    


    bitpatt = bitpattern;
    if_state.ptr1_cb = if_state.stack1_cb;
    if_state.ptr2_cb = if_state.stack2_cb;
    while ( TRUE ) {
       if ( bitpatt & LONGMASK1 ) {
          bitpatt = bitpatt >> 1;
          v2.x = (SW16)(( (SL32)v0.x + (SL32)v1.x )>>1);
          v2.y = (SW16)(( (SL32)v0.y + (SL32)v1.y )>>1);
          v1.x = (SW16)(( (SL32)v1.x + (SL32)v3.x )>>1);
          v1.y = (SW16)(( (SL32)v1.y + (SL32)v3.y )>>1);
          *++if_state.ptr1_cb = v2;
          *++if_state.ptr1_cb = v0;
          v0.x = (SW16)(( (SL32)v1.x + (SL32)v2.x )>>1);
          v0.y = (SW16)(( (SL32)v1.y + (SL32)v2.y )>>1);
       } else {
          bitpatt = bitpatt >> 1;
          v3.x >>= 1;
          v3.y >>= 1;
          *if_state.ptr2_cb++ = v3;
          v3 = v0;
          if ( if_state.ptr1_cb == if_state.stack1_cb ) break;
          v0 = *if_state.ptr1_cb--;
          v1 = *if_state.ptr1_cb--;
       }
    }  

      *fit = FALSE;
      if_state.ptr2_cb = if_state.stack2_cb;
      v1 = *if_state.ptr2_cb++;
      for(u = 1; u <= 8; u++) {
        v0 = v1;
        v1 = *if_state.ptr2_cb++;
        dx = v1.x - v0.x;
        dy = v1.y - v0.y;

        if( ABS(F.x-v0.x-dx) < eps1 &&
            ABS(F.y-v0.y-dy) < eps1) {
           *fit = TRUE;
           break;
        }
        if (dx > 0 ) {
           dx1 = 0;
           dx2 = dx;
        }
        else {
           dx1 = dx;
           dx2 = 0;
        }
        if (dy > 0 ) {
           dy1 = 0;
           dy2 = dy;
        }
        else {
           dy1 = dy;
           dy2 = 0;
        }
        if (F.x < v0.x + dx1 - eps1 ||
            F.y < v0.y + dy1 - eps1 ||
            F.x > v0.x + dx2 + eps1 ||
            F.y > v0.y + dy2 + eps1 ) {
                *fit = FALSE;
                continue;
        }

        if (dx == 0) {
          if(ABS(F.x-v0.x)<eps1) {
            *fit = TRUE;
            break;
          }
          else
            continue;
        }
        if (dy == 0) {
          if(ABS(F.y-v0.y)<eps1) {
            *fit = TRUE;
            break;
          }
          else
            continue;
        }

        else {
          m1 = ((SL32)dy<<16)/dx;

          if_long_mult (m1,(SW16)(F.x-v0.x),&mult,&shift);
          v2.y = v0.y + (SW16)(mult>>(16-shift));
          if(ABS(F.y-v2.y)<eps1) {
            *fit = TRUE;
            break;
          }
          m1 = ((SL32)dx<<16)/dy;

          if_long_mult (m1,(SW16)(F.y-v0.y),&mult,&shift);
          v2.x = v0.x + (SW16)(mult>>(16-shift));
          if(ABS(F.x-v2.x)<eps1) {
            *fit = TRUE;
            break;
          }
        }
      }  /*  end for (u= ... */
      if(*fit == FALSE) break;

  }   /*  end for(iz = ...  */
}

#endif   /*  IF_RDR && CUBIC  */

da.c    /

/* 
 * Copyright (C) 2004 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/DA/DA.C_V   1.32   Aug 10 2004 14:53:40   galejss  $ */
/* $Log:   I:/BULL/URIP/RTS/DA/DA.C_V  $ 
 * 
 *    Rev 1.32   Aug 10 2004 14:53:40   galejss
 * changes for runtime no-symset-mapping option
 * 
 *    Rev 1.31   Aug 22 2003 08:53:38   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.30   Jun 19 2003 18:47:52   Galejs
 * get rid of NON_IF_FONT
 * 
 *    Rev 1.29   Dec 03 2002 16:29:12   Galejs
 * fix compile warning (last stmt unreachable)
 * 
 *    Rev 1.28   Oct 01 2002 12:23:52   Galejs
 * add (UW16)chId cast
 * 
 *    Rev 1.27   Sep 30 2002 12:14:02   Galejs
 * 32-bit charcode support (for rjl)
 * 
 *    Rev 1.26   Jun 28 2001 18:48:00   Galejs
 * fix no-return-value compiler warning, tidy up preprocessor lines
 * 
 *    Rev 1.25   May 03 2001 19:33:58   Galejs
 * data-type cleanup
 * 
 *    Rev 1.24   Aug 16 1999 12:04:48   galejs
 * include-file changes
 * 
 *    Rev 1.23   12 Jan 1999 18:26:34   GALEJS
 * move EXTERN dcls
 * 
 *    Rev 1.22   21 Dec 1998 16:45:54   JOE
 * Mismatch in LIBmake_cd() call - 4th arg should be int and not UW16
 * (by jwd).
 * 
 *    Rev 1.21   22 Jun 1998 17:53:18   GALEJS
 * make Intellifont reentrant too
 * 
 *    Rev 1.20   17 Jun 1998 16:32:18   GALEJS
 * add arg to ...setchar() calls (for reentrancy)
 * 
 *    Rev 1.19   15 Jun 1998 15:19:24   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.18   15 Apr 1998 17:17:28   GALEJS
 * chr_def_hdr, symbolset in IF_STATE
 * 
 *    Rev 1.17   24 Mar 1998 15:44:30   GALEJS
 * include-file changes
 * 
 *    Rev 1.16   16 Jul 1997 16:43:52   JOE
 * Got rid of 1 warning message about type mismatch (by Jimmy).
 * 
 *    Rev 1.15   21 Feb 1996 12:56:34   MERRILL
 * move final return() up to remove warning
 * 
 *    Rev 1.14   08 Feb 1996 09:57:48   MERRILL
 * fix jump-table
 * 
 *    Rev 1.13   01 Dec 1995 13:39:12   MERRILL
 * Remove compiler warnings by using arguments.
 * 
 *    Rev 1.12   18 Apr 1995 16:48:14   JOE
 * In DAmake_cd(), added support for the removal of symbol set mapping.
 * 
 *    Rev 1.11   06 Apr 1995 15:14:56   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.10   08 Sep 1994 16:50:30   MIKE
 * Fixed typo: fcoset_char -> fco_set_char
 *
 *    Rev 1.9   03 Aug 1994 16:00:36   MIKE
 * Added FCO changes from 1.6.1.1
 * 
 *    Rev 1.8   22 Apr 1994 13:55:18   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.7   02 Feb 1994 08:57:14   JOE
 * 
 * Removed #include for "fcntl.h" .
 * 
 *    Rev 1.6   08 Dec 1993 18:59:50   ROB
 * General cleanup for MSDOS, FLAT, OS2.
 * 
 *    Rev 1.5   10 Aug 1993 15:30:36   JOE
 * 
 * In DAmake_cd(), conditionally compiled call to ifset_char() based
 * on IF_RDR.
 * 
 *    Rev 1.4   13 Apr 1993 13:21:56   JOE
 * In DAmake_cd(), conditionally compiled calls to psrender() and ttrender()
 * if !USE_JUMP_TABLES.
 * 
 *    Rev 1.3   12 Feb 1993 13:19:58   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   06 Jan 1993 15:05:20   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 15:58:20   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 15:38:56   LISA
 * Initial revision.
*/
/* $Date:   Aug 10 2004 14:53:40  $ */
/* da.c */
/*
 *
 *
 * History
 *
 *    19-Dec-90  jfd   IFB on a Printer changes:
 *                     2.) Replace CC elements with fields from CHR_DEF_HDR
 *                         structure.
 *     7 Jan 91  ss    Added PCLEO_RDR support
 *    30-Jan-91  dET   Added function prototyping for MSC
 *    31-Jan-91  dET   Modify for MSC multi-model compilation.
 *     7-Feb-91  jfd   Make sure that PCLascii2ptr() is declared correctly
 *     9-Feb-91  awr   Added #include "sym.h" to declare symbol set fncts.
 *    23-Feb-91  awr   Changed bucket sub-segment handles to offsets.
 *                     Split off as new module.
 *    04-Mar-91  jfd   Added function prototype for BUFfree() and
 *                     PCLload_font().
 *                     In DAmake_cd(), added missing ";" after call to
 *                     PCLEOmake_cd().
 *                     In DAload_font(), if PCLEO, store "b->tfnum" and
 *                     "b->bucket_num" from "ix".
 *    17-Jun-91  jfd   Moved "debug.h" after "port.h".
 *                     Moved "cgconfig.h" before "port.h".
 *    19 Jun 91  ss    Changed DAmak_cd() argument "i" to "buck_search_lvl".
 *    24 Jun 91  ss    Conditionally compile io.h based on system type.
 *    24-Aug-91  awr   IXclose_file() function prototype
 *    27-Aug-91  jfd   When calling PCLEOmake_cd(), no longer passing 
 *                     PBUCKET as first argument because it was never
 *                     getting referenced.
 *    17 Sep 91  ss    Added !ROM call to PCLload_font() in DAload_font() to 
 *                     support PCLEO_RDR w/ disk-based plugins.
 *    25 Nov 91  ss    In DAload_font(), set file_open to FALSE for PCLEOs.
 *     3-Jan-92  awr   Removed font_open field from BUCKET
 *    22-Jan-92  rs    Incorporate ptrs to external font functions.
 *    28-Jan-92  rs    Move external font func ptr to bucket.
 *     7-Mar-92  awr   cleaned up test ps stubs.
 *    30 Mar 92  ss    In DAmake_cd, reset chr_def_hdr.mirror_flags.
 *                     For IF data, it gets reset OK, but for PS & TT data
 *                     it was not resulting in non-mirrored characters being
 *                     mirrored if requested after a mirrored character.
 *    03-Apr-92  rs    Portability cleanup (see port.h).
 *    23 Apr 92  ss    In DAmake_cd(), restored test for only calling
 *                     PCLEOmake_cd() when typeface sensitive.
 *    21-Jul-92  awr   Conditional compile changes.
 *    31 Jul 92  ss    Special handling of ss_num == 0 for PCLEOs with symbol
 *                     sets not know to us, (not in IF.SS) in DAmake_cd().
 *    15-Sep-92  jfd   In DAmake_cd(), conditionally compiled test for IF
 *                     bucket type based on IF_RDR.
 *                     Conditionally compile function prototype for
 *                     LIBmake_cd().
 *    28-Sep-92  awr   Removed DAload_font() and DAunload_font().
 *                     Coded in line.  Changed parameter of DAmake_cd().
 *    10-Oct-92  rs    Implement USE_JUMP_TABLES feature for overlays.
 *    06-Jan-93  jfd   ANSI C function declaration changes.
 *    08-Feb-93  jfd   VXWorks support.
 *    13-Apr-93  jfd   In DAmake_cd(), conditionally compiled calls to 
 *                     psrender() and ttrender() if !USE_JUMP_TABLES.
 *    10-Aug-93  jfd   In DAmake_cd(), conditionally compile call to
 *                     ifset_char() based on IF_RDR.
 *    08-Dec-93  rs    General cleanup - MSDOS & OS2.
 *    26-Jan-94  jfd   Removed #include for fcntl.h .
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *  FCO Changes from 1.6.1.1:
 *    15-Mar-94  mby   Added fco_set_char() call from DAmake_cd().
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *    08-Sep-94  mby   Fixed typo: fcoset_char -> fco_set_char
 *    18-Apr-95  jfd   In DAmake_cd(), added support for the removal of
 *                     symbol set mapping.
 *    20-Dec-98  jwd   Mismatch in function LIBmake_cd() prototype and 
 *                     call; fourth parameter should be int rather than UW16.
 *
 */


#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include <stdio.h>

#include "cgconfig.h"
#include "ufstport.h"

#if MAYBE_IO_H
#include <io.h>
#endif

#include "dbg_ufst.h"

#include "shareinc.h"

#include "mixmodel.h"


/*-------------------*/
/*    DAmake_cd      */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  DAmake_cd(FSP PBUCKET bucket, UL32 chId, PCHR_DEF chr_def,
    SL32 buck_search_lvl)
#else
GLOBAL UW16
DAmake_cd(bucket, chId, chr_def, buck_search_lvl)
    PBUCKET  bucket;
    UL32    chId;
    PCHR_DEF chr_def;
    SL32      buck_search_lvl;
#endif
{
#if SLIM_FONTS  /** Is this the best place for this?? -ss 3/30/92 */
   if_state.chr_def_hdr.mirror_flags = (UB8)0;
#endif


#if !IF_RDR
    chr_def = chr_def; /* Quiet Compiler */
    buck_search_lvl = buck_search_lvl; /* Quiet Compiler */
#endif

#if IF_RDR
    if(bucket->fst_type == FC_IF_TYPE)
    {
#if PCLEO_RDR
        /* Only have IF pcleos at TFS level */
        if(bucket->extern_font && buck_search_lvl == TF_SENSITIVE)
            return PCLEOmake_cd(FSA (UW16)chId, chr_def, buck_search_lvl);

        if (FC_SSMAP(&if_state.fcCur) && (if_state.symbolset.curssnum == 0)) /* must have valid ssnum to map */
            return ERR_no_cgnum;                                               /* to cgnum.        -ss 7/31/92 */
#endif /* PCLEO_RDR */

        return LIBmake_cd(FSA bucket, (UW16)chId, chr_def, buck_search_lvl); /* jwd, 20-Dec-98 */   /* rjl 9/23/2002 - added cast for UW16*/
    }
    else
#endif /* IF_RDR */
    {
#if (USE_JUMP_TABLES)
        return ((*((PIF_FUNC_TBL)bucket->pft)->set_char) (FSA bucket, chId));
#else
           switch (bucket->fst_type) {
#if IF_RDR
        case FC_IF_TYPE:
            return ifset_char (FSA bucket, chId);
#endif
#if PST1_RDR
        case FC_PST1_TYPE:
            return psset_char (FSA bucket, chId);
#endif
#if TT_RDR
        case FC_TT_TYPE:
            return ttset_char (FSA bucket, chId);
#endif
#if FCO_RDR
        case FC_FCO_TYPE:
            return fco_set_char (FSA bucket, chId);
#endif
        default:
            return (ERR_fst_type);
     }
#endif /* USE_JUMP_TABLES */
    }
}

dbg_ufst.h    //

/* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved. */

/* $Header:   I:/BULL/URIP/RTS/INC/dbg_ufst.h_v   1.4   Aug 21 2003 17:10:18   Galejs  $ */
/* $Log:   I:/BULL/URIP/RTS/INC/dbg_ufst.h_v  $ 
 * 
 *    Rev 1.4   Aug 21 2003 17:10:18   Galejs
 * update copyright notice
 * 
 *    Rev 1.3   Jul 21 2003 17:47:04   Galejs
 * "trace_sw" now part of IF_STATE structure (rather than standalone global)
 * 
 *    Rev 1.2   Sep 20 2002 20:14:50   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.1   Aug 13 1999 16:17:18   galejs
 * DEBUG becomes AGFADEBUG (reintegrate debug.h change)
 * 
 *    Rev 1.0   Aug 09 1999 17:30:20   galejs
 *  
 *  
 *    Rev 1.5   29 Jul 1999 17:26:54   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.4   07 Apr 1995 08:45:20   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.3   21 Apr 1994 15:48:44   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.2   15 Jan 1993 09:35:16   LISA
 * Removed CtrlZ character from end of file
 * 
 *    Rev 1.1   14 Dec 1992 09:40:50   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 09:11:02   LISA
 * Initial revision.
*/
/* $Date:   Aug 21 2003 17:10:18  $ */
 /*----------------------------DEBUG.H--------------------------------------
  *  DEBUG.H  This header file contains the statements necessary for the
  *           conditional compilation of debug statements
  *
  *
  *  Modification History:
  *
  *  17-Jun-91  jfd   Changed trace_sw declaration to use port.h defines
  *                   (FIX FROM EARLIER VERSION)
  *  30-Sep-91  rs    Added 'DBG8()' for PostScript Type 1 output.
  *  03-Apr-92  rs    Portability cleanup (see port.h).
  *     28-July-99 ks    Changed DEBUG compiler directive to AGFADEBUG. 
  *     09-Aug-99    slg      Rename to "dbg_ufst.h", to avoid conflicts with
  *                        customer target-environment header files "debug.h"
  *
  *------------------------------------------------------------------------*/
#ifndef __DBG_UFST__
#define __DBG_UFST__

#ifdef AGFADEBUG
#define GENERATE_STATEMENTS(statements) statements
#else
#define GENERATE_STATEMENTS(statements)  ;   
#endif

//extern void SendPrintf(const char *fmt, ...);

//#define DBG        SendPrintf
//#define DBG1        SendPrintf
//#define DBG2        SendPrintf
//#define DBG3        SendPrintf
//#define DBG4        SendPrintf
//#define DBG5        SendPrintf
//#define DBG6        SendPrintf
//#define DBG8        SendPrintf

#define DBG(user_text) \
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text))

//Send_String(cTempBuffer,sprintf(cTempBuffer,user_text)

#define DBG1(user_text,a1) \
//         sprintf(cTempBuffer,user_text,a1);\
//         Send_String(cTempBuffer);
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1))

#define DBG2(user_text,a1,a2) \
//         sprintf(cTempBuffer,user_text,a1,a2);\
//         Send_String(cTempBuffer);
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1,a2))

#define DBG3(user_text,a1,a2,a3) \
//         sprintf(cTempBuffer,user_text,a1,a2,a3);\
//         Send_String(cTempBuffer);


//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1,a2,a3))

#define DBG4(user_text,a1,a2,a3,a4) \
//         sprintf(cTempBuffer,user_text,a1,a2,a3,a4);\
//         Send_String(cTempBuffer);
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1,a2,a3,a4))

#define DBG5(user_text,a1,a2,a3,a4,a5) 
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1,a2,a3,a4,a5))

#define DBG6(user_text,a1,a2,a3,a4,a5,a6)
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1,a2,a3,a4,a5,a6))

#define DBG8(user_text,a1,a2,a3,a4,a5,a6,a7,a8) 
//    GENERATE_STATEMENTS(if (UFST_get_debug(FSA0)) printf(user_text,a1,a2,a3,a4,a5,a6,a7,a8))

#endif    /* __DBG_UFST__    */

des2bm.txt   

/* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved. */

/* $Header:   I:/BULL/URIP/RTS/COR/DES2BM.C_V   1.13   Aug 21 2003 17:03:32   Galejs  $ */
/* $Log:   I:/BULL/URIP/RTS/COR/DES2BM.C_V  $ 
 * 
 *    Rev 1.13   Aug 21 2003 17:03:32   Galejs
 * update copyright notice
 * 
 *    Rev 1.12   Jun 23 2003 13:50:14   Galejs
 * ufstport.h
 * 
 *    Rev 1.11   Oct 21 2002 18:15:50   Galejs
 *  
 *    Rev 1.10   Aug 13 1999 15:07:00   galejs
 * include-file changes
 * 
 *    Rev 1.9   09 Feb 1999 15:22:36   GALEJS
 * fix warning when building with DEBUG on
 * 
 *    Rev 1.8   22 Jun 1998 18:58:20   GALEJS
 * make Intellifont reentrant too
 * 
 *    Rev 1.7   15 Jun 1998 16:06:04   GALEJS
 * include-file changes
 * 
 *    Rev 1.6   24 Mar 1998 15:14:32   GALEJS
 * include-file changes
 * 
 *    Rev 1.5   06 Apr 1995 15:11:02   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.4   22 Apr 1994 09:28:24   LISA
 * Modified copyright/disclaimer notice for 1994.
 * 
 *    Rev 1.3   12 Feb 1993 11:25:54   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   07 Jan 1993 10:42:38   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:35:02   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:37:50   LISA
 * Initial revision.
*/
/* $Date:   Aug 21 2003 17:03:32  $ */
/* des2bm.c */

/*---------------------------------------------------------------------
     05-05-90   awr   Added landscape. New function rot90(), changed
                      des2wrkbm() to rotate coords. Changed bitmpa_size()
                      to swap bmwidth and bmdepth and compute d.max_x
                      and d.max.y.

    11-Dec-90   awr   Changed inv_des2wrkbm() to account for the new
                      tx() and ty()- see imath.c.
     8-Feb-91   awr   Split off from maker.c and shortened names to
                      des2bm() nad inv_des2bm().
    11-Mar-91   awr   Changed return value of des2bm() and inv_des2bm
                      to PWORDVECTOR
    06-Apr-91   awr   Changed rotate calculations to floating point
    17-Jun-91   jfd   Moved "debug.h" after "port.h".
                      Moved "profile.h" after "port.h".
    29-Jun-91   awr   added tt0 to make des2bm() = matrix o translate
                      and other 4 transforms for mirroring
    14 Aug 91   ss    Fixed inv_des2bm() to use correct vars for -ROT cases.
    24-Aug-91   awr   Moved function decls to include file
                      Moved tx() and ty() inline in des2bm()
    11-Nov-91   rs    Broke 'cg_scale()' off from des2bm() - for performance.
    15-Nov-91   jfd   In des2bm(), removed local variables "xx" and "yy"
                      which were never referenced.
     7-Mar-92   awr   Reversed order in inv_des2bm(): rotate 1st, scale 2nd.
    03-Apr-92   rs    Portability cleanup (see port.h).
    11-Aug-92   jfd   Trying new version of des2bm() for optimization.
    15-Sep-92   jfd   Conditionally compiling entire module based on
                      IF_RDR.
    07-Jan-93   jfd   ANSI C function declaration changes.
    08-Feb-93   jfd   VXWorks support.
-----------------------------------------------------------------------*/

#include "cgconfig.h"

#if IF_RDR

#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include <stdio.h>
#include "ufstport.h"
#include "dbg_ufst.h"

#include "shareinc.h"

#include "imath.h"

/*----------------------*/
/*      des2bm          */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL SW16VECTOR des2bm(FSP SW16VECTOR v)
#else
GLOBAL SW16VECTOR
des2bm(v)
    SW16VECTOR v;
#endif
{
    SW16VECTOR new={0,0};

#if defined MDES2BM

    /* Always arbitrary rotation */
    new.x = ifpmul(v.x, if_state.m[0])
          + ifpmul(v.y, if_state.m[2]) + if_state.tt.x;
    new.y = ifpmul(v.x, if_state.m[1])
          + ifpmul(v.y, if_state.m[3]) + if_state.tt.y;
    return (new);

#else

    if(!if_state.quadrant)    /* arbitrary rotation */
    {
        new.x = ifpmul(v.x, if_state.m[0])
              + ifpmul(v.y, if_state.m[2]) + if_state.tt.x;
        new.y = ifpmul(v.x, if_state.m[1])
              + ifpmul(v.y, if_state.m[3]) + if_state.tt.y;
          return (new);
    }
    else return (cg_scale (FSA v));

#endif /* defined MDES2BM */

}

/*----------------------*/
/*    inv_des2bm        */
/*----------------------*/
/*  DOES NOT WORK FOR ARBITRARY ROTATION. Don't fix it either because
*  we don't need this function for arbitrary rotation. Fix it if
*  we ever do and save the space in the meantime.
*/
#if defined (ANSI_DEFS)
GLOBAL SW16VECTOR inv_des2bm(FSP SW16VECTOR v)
#else
GLOBAL SW16VECTOR
inv_des2bm(v)
   SW16VECTOR v;
#endif
{
   SW16 xx, yy;
   SW16VECTOR new;

   xx = v.x - if_state.tt.x;
   yy = v.y - if_state.tt.y;

   DBG2("    %d = inv_tx(%d)\n", xx, v.x);
   DBG2("    %d = inv_ty(%d)\n", v.y, v.y);

   if(if_state.quadrant == ROT0)
   {
      new.x = xx;
      new.y = yy;
   }
   else if(if_state.quadrant == ROT270)
   {
      new.x = - yy;
      new.y =   xx;
   }
   else if(if_state.quadrant == ROT180)
   {
      new.x =  - xx;
      new.y =  - yy;
   }
   else if(if_state.quadrant == ROT90)
   {
      new.x =   yy;
      new.y = - xx;
   }
   else if(if_state.quadrant == -ROT0)    /* Next 4: mirror about y axis first */
   {
      new.x = -xx;
      new.y =  yy;
   }
   else if(if_state.quadrant == -ROT90)
   {
      new.x = -yy;
      new.y = -xx;
   }
   else if(if_state.quadrant == -ROT180)
   {
      new.x =  xx;
      new.y = -yy;
   }
   else if(if_state.quadrant == -ROT270)
   {
      new.x = yy;
      new.y = xx;
   }


    if(new.x < 0)
        new.x = -(SW16)(  ( (   ((UL32)(-new.x)) << if_state.x.shift
                            )     * (UL32)if_state.x.p_pixel
                          ) >> 16
                       );
    else
        new.x =  (SW16)(  ( (   ((UL32)(new.x)) << if_state.x.shift
                            )     * (UL32)if_state.x.p_pixel
                          ) >> 16
                       );

    if(new.y < 0)
        new.y = -(SW16)(  (  (  ((UL32)(-new.y)) << if_state.y.shift
                             )    * (UL32)if_state.y.p_pixel
                          ) >> 16
                       );
    else
        new.y =  (SW16)(  (  (  ((UL32)(new.y)) << if_state.y.shift
                             )    * (UL32)if_state.y.p_pixel
                          ) >> 16
                       );

   return new;
}
#endif  /* IF_RDR */

 

dimmdsk.c  /

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */

/* $Header:   I:/BULL/URIP/RTS/TT/dimmdsk.c_v   1.6   Sep 25 2003 14:13:14   Joe  $ */
/* $Log:   I:/BULL/URIP/RTS/TT/dimmdsk.c_v  $
 * 
 *    Rev 1.6   Sep 25 2003 14:13:14   Joe
 * Replaced "memcpy" with "MEMCPY".
 * 
 *    Rev 1.5   Aug 22 2003 09:37:28   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.4   Jun 23 2003 15:35:04   Galejs
 * ufstport.h
 * 
 *    Rev 1.3   Nov 26 2002 18:30:08   Galejs
 * conditional include of unistd.h
 * 
 *    Rev 1.2   Sep 25 2002 18:28:02   Galejs
 * add DIMM_DISK conditional compiles 
 * 
 *    Rev 1.1   Sep 25 2002 14:05:22   Galejs
 * add PVCS Header / Log strings
 *
 */

/* dimmdsk.c 
 *  15-Aug-02  awr  File created to add DIMM_DISK support to TrueType - others later.
 *  25-Sep-03  jfd  Replaced "memcpy" with "MEMCPY".
 *
 */

#include <string.h>
#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include <stdio.h>

#include "cgconfig.h"
#include "ufstport.h"

#if MAYBE_FCNTL_H
#include <fcntl.h>
#endif

#if MAYBE_FCNTL_HIF_H
#include <fcntl.h>
#include <hif.h>  /* 2-7-94 jfd */
#endif

#if MAYBE_IO_H
#include <io.h>
#endif

#if MAYBE_UNISTD_H
#include <unistd.h>
#endif

#include "dbg_ufst.h"

#include "shareinc.h"

#include "mixmodel.h"
#include "segments.h"
#include "dll.h"


GLOBAL VOID dd_open(PBUCKET pb)
{
#if DIMM_DISK
    pb->curpos = 0;
#endif
    pb->fh = 1;     /* gets tested later, -1 means not open so set it to 1 */
}

GLOBAL SL32 dd_read(PBUCKET pb, VOID* buff, UL32 count)
{
#if DIMM_DISK
    if(pb->fc_ExtndFlags & EF_DIMM_DISK_TYPE)
    {
        MEMCPY(buff, pb->cur_font_hdr + pb->curpos, count);
        pb->curpos += count;
        return count;
    }
    else
#endif
        return READF(pb->fh, buff, count);
}

GLOBAL SL32 dd_lseek(PBUCKET pb, SL32 pos, SL32 type)
{
#if DIMM_DISK
    if(pb->fc_ExtndFlags & EF_DIMM_DISK_TYPE)
    {
        if(type == SEEK_END)
            return -1;    /* can't do this one */
        else if(type == SEEK_SET)
            pb->curpos = pos;
        else if(type == SEEK_CUR)
            pb->curpos += pos;
        return pb->curpos;
    }
    else
#endif
        return LSEEK(pb->fh, pos, type);
}

GLOBAL VOID dd_close(PBUCKET pb)
{
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值