T168_111\appl\Text\Agfa:第95~104

memory.txt、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/rac/MEMORY.C_V   1.17   Aug 22 2003 09:22:06   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/rac/MEMORY.C_V  $
 * 
 *    Rev 1.17   Aug 22 2003 09:22:06   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.16   Jun 20 2003 14:22:02   Galejs
 * get rid of asserts; clean up debug; size_t becomes UL32
 * 
 *    Rev 1.15   Sep 09 2002 18:49:22   Galejs
 * extra chars after #endif (part of bug # 76)
 * 
 *    Rev 1.14   Jun 29 2001 17:37:44   Galejs
 * const should be CONST (for portability)
 * 
 *    Rev 1.13   May 03 2001 20:43:34   Galejs
 * data-type cleanup
 * 
 *    Rev 1.12   Oct 16 2000 15:46:36   Al
 *  
 *    Rev 1.11   Sep 21 2000 14:01:38   galejs
 * change ACT error handling (no setjmp / longjmp)
 * 
 *    Rev 1.10   Feb 07 2000 15:52:50   galejs
 * unsigned long -> UL32, long ->SL32
 * 
 *    Rev 1.9   Jan 27 2000 18:17:28   galejs
 * use act_alloc/realloc/freemem() directly in code
 * 
 *    Rev 1.8   Jan 24 2000 15:52:30   galejs
 * remove unused field "mem_numNewCalls"
 * 
 *    Rev 1.7   May 24 1999 15:10:16   galejs
 * make ACT reentrant
 * 
 *    Rev 1.6   13 Oct 1997 15:36:54   MARTIN
 * Renamed memory.h to ra_mem.h to fix name conflict on some compilers.
 * 
 *    Rev 1.5   04 Sep 1997 17:04:50   MARTIN
 * Modified references to AGFA Compressed TrueType (ACT).
 * 
 *    Rev 1.4   29 Aug 1997 09:05:42   JOE
 * Revised last change to assert() calls for portability.
 * 
 *    Rev 1.3   28 Aug 1997 15:11:00   JOE
 * In ACT_mem_malloc() and ACT_mem_realloc(), removed "return" statements
 * at end of each function because it was unreachable code.
 * 
 *    Rev 1.2   15 Aug 1997 15:02:32   JOE
 * Added non-ANSI function declarations.
 * Changed the include filenames to lowercase.
 * Moved compiler directives to column 1.
 * 
 *    Rev 1.1   30 Jun 1997 20:17:42   MIKE
 * Fixed line endings with unix2dos utility
 * 
 *    Rev 1.0   04 Jun 1997 11:05:44   MARTIN
 * Initial revision.
 */


/*
 * File:                        MEMORY.CPP
 * First Version:                March 8, 1996
 * Added mem_realloc:            September 29, 1996
 * First pure ANSI C version:     October 28, 1996
 *
 *    07-Feb-00  slg    Don't use "long" dcls (incorrect if 64-bit platform).
 *
 */
#include "cgconfig.h"

#if TT_ROM_ACT    /* conditional compile entire module */ 

#include <stdio.h>
#include <stdlib.h>  /* 08-07-97 jfd */

#include "ufstport.h"
#include "shareinc.h"

#include "ra_mem.h"


#ifdef CHECK_MEMORY_ACT  /* 08-07-97 jfd */
CONST SL32 overWriteExtraSpace        = sizeof(SL32) + sizeof(SL32) + sizeof(SB8); /* 4-byte Stamp, length, data, 1-byte Stamp */
CONST SL32 overWriteOffsetToData    = sizeof(SL32) + sizeof(SL32); /* 4-byte Stamp, length */
#endif  /* 08-07-97 jfd */


#ifdef CHECK_MEMORY_ACT
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
static void validateAllMemory( ACT_MemHandler *t )
#else
static void validateAllMemory(t)
ACT_Memhandler *t;
#endif
{
    register SL32 i, limit;
    register void **pointers = t->mem_pointers;
    void *object;

    limit = t->mem_maxPointers;
    for ( i = 0; i < limit; i++ ) {
        if ( (object = pointers[i]) != NULL ) {
            if ( ((SL32 *)object)[0] != 0x12345678 )
            { 
                t->err = ERR_array_start_thrashed;
                return;
            }
            if ( ((UB8 *)object)[((SL32 *)object)[1]-1] != 0xa5 )
            { 
                t->err = ERR_array_end_thrashed;
                return;
            }
        }
    }
}
#endif


/* Our malloc */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
void *ACT_mem_malloc(FSP ACT_MemHandler *t, UL32 size)
#else
void *ACT_mem_malloc(t, size)
ACT_MemHandler *t;
UL32 size;
#endif
{
    register SL32 i, limit;
    void *babyObject;
    register void **pointers;
    
    if ( size == 0 ) 
        return NULL; /****** Added September 23, 1996 */
    
#ifdef CHECK_MEMORY_ACT
        size += overWriteExtraSpace;
        babyObject = act_allocmem( FSA size );
        ((SL32 *)babyObject)[0] = 0x12345678;
        ((SL32 *)babyObject)[1] = size;
        ((UB8 *)babyObject)[size-1] = 0xa5;
#else
        babyObject = act_allocmem ( FSA size );
#endif
    if ( babyObject == NULL )
    { 
        t->err = ERR_no_more_memory;
        return NULL;
    }
    if ( t->mem_numPointers >= t->mem_maxPointers ) {
        SL32 oldMaxPointers = t->mem_maxPointers;
        /* We need to allocate more space for pointers */
        t->mem_maxPointers = t->mem_maxPointers + t->mem_maxPointers/4 + 128;
        if ( t->mem_pointers != NULL ) {
            t->mem_pointers = (void **)act_reallocmem( FSA t->mem_pointers, t->mem_maxPointers * sizeof( void *) );
        } else { 
            t->mem_pointers = (void **)act_allocmem( FSA t->mem_maxPointers * sizeof( void *) );
        }
        if ( t->mem_pointers == NULL )
        { 
            t->err = ERR_no_more_memory;
            return NULL;
        }
        /* Zero out the new entries; */
        for ( i = oldMaxPointers; i < t->mem_maxPointers; i++ ) {
            t->mem_pointers[i] = NULL;
        }
    }
    /* OK, now we have a space to store the pointers, so go find it ! */
    limit = t->mem_maxPointers;
    pointers = t->mem_pointers;
    for ( i = 0; i < limit; i++ ) {
        if ( pointers[i] == NULL ) {
            pointers[i] = babyObject;
            /*callNumber[i] = t->mem_numPointers; */
            t->mem_numPointers++;
#ifdef CHECK_MEMORY_ACT
                validateAllMemory(t);
                if (t->err)
                    return NULL;
                return (void *)((SB8 *)babyObject + overWriteOffsetToData); /******/
#else
                return babyObject; /******/
#endif
        }
    }
    t->err = ERR_new_logical;
    return NULL;
}

/* Added September 29, 1996 */
/* Our realloc */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
void *ACT_mem_realloc(FSP ACT_MemHandler *t, void *p, UL32 size)
#else
void *ACT_mem_realloc(t, p, size)
ACT_MemHandler *t;
void *p;
UL32 size;
#endif
{
    register SL32 i, limit;
    register void **pointers = t->mem_pointers;
    void *new_p;

    if ( p == NULL ) {
        return ACT_mem_malloc( FSA t, size ); /******/
    }
    if ( size == 0 ) {
        ACT_mem_free( FSA t, p );
        return NULL; /****** Added October 7, 1996 */
    }
#ifdef CHECK_MEMORY_ACT    
        size += overWriteExtraSpace;
        p = (void *)((SB8 *)p - overWriteOffsetToData);
#endif
    /* See if we can find it */
    limit = t->mem_maxPointers;
    for ( i = 0; i < limit; i++ ) {
        if ( pointers[i] == p ) {
#ifdef CHECK_MEMORY_ACT
                if ( ((SL32 *)p)[0] != 0x12345678 )
                { 
                    t->err = ERR_array_start_thrashed;
                    return NULL;
                }
                if ( ((UB8 *)p)[((SL32 *)p)[1]-1] != 0xa5 )
                { 
                    t->err = ERR_array_end_thrashed;
                    return NULL;
                }
#endif
            new_p = act_reallocmem( FSA p, size );
            if ( new_p == NULL ) 
            {
                t->err = ERR_realloc_failed;
                return NULL;
            }
            pointers[i] = new_p;
#ifdef CHECK_MEMORY_ACT
                if ( ((SL32 *)new_p)[0] != 0x12345678 )
                { 
                    t->err = ERR_array_start_thrashed;
                    return NULL;
                }
                ((SL32 *)new_p)[1]            = size;
                ((UB8 *)new_p)[size-1]        = 0xa5;
                validateAllMemory(t); 
                if (t->err)
                    return NULL;
                return (void *)((SB8 *)new_p + overWriteOffsetToData); /******/
#else
                return new_p; /******/
#endif
        }
    }
    t->err = ERR_realloc_bad_pointer;
    return NULL;
}


/* Our free */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
void ACT_mem_free(FSP ACT_MemHandler *t, void *deadObject)
#else
void ACT_mem_free(t, deadObject)
ACT_MemHandler *t;
void *deadObject;
#endif
{
    register SL32 i, limit;
    register void **pointers = t->mem_pointers;
    if ( deadObject == NULL ) 
        return; /*****/ /* This is OK by definition */
#ifdef CHECK_MEMORY_ACT  /* 08-07-97 jfd */
        deadObject = (void *)((SB8 *)deadObject - overWriteOffsetToData);
#endif /* 08-07-97 jfd */
    /* See if we can find it */
    limit = t->mem_maxPointers;
    for ( i = 0; i < limit; i++ ) {
        if ( pointers[i] == deadObject ) {
#ifdef CHECK_MEMORY_ACT  /* 08-07-97 jfd */
                if ( ((SL32 *)deadObject)[0] != 0x12345678 )
                { 
                    t->err = ERR_array_start_thrashed;
                    return;
                }
                if ( ((UB8 *)deadObject)[((SL32 *)deadObject)[1]-1] != 0xa5 )
                { 
                    t->err = ERR_array_end_thrashed;
                    return;
                }
                validateAllMemory(t);
                if (t->err)
                    return;
#endif  /* 08-07-97 jfd */
            act_freemem( FSA deadObject );
            pointers[i] = NULL;
            t->mem_numPointers--;
            return; /******/
        }
    }
    t->err = ERR_delete_bad_pointer;
}

/* Call mem_FreeAllMemory insted on an abnormal (exception) exit */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
void ACT_mem_FreeAllMemory( FSP ACT_MemHandler *t )
#else
void ACT_mem_FreeAllMemory(t)
ACT_MemHandler *t;
#endif
{
    register SL32 i;

    if ( t->mem_pointers != NULL ) {
        for ( i = 0; i < t->mem_maxPointers; i++ ) {
            if ( t->mem_pointers[i] != NULL ) {
#ifdef CHECK_MEMORY_ACT  /* 08-07-97 jfd */
                    void *deadObject = t->mem_pointers[i];
                    if ( ((SL32 *)deadObject)[0] != 0x12345678 ) printf("%s\n", "ERR_array_start_thrashed ");
                    if ( ((UB8 *)deadObject)[((SL32 *)deadObject)[1]-1] != 0xa5 ) printf("%s\n", "ERR_array_end_thrashed ");
#endif  /* 08-07-97 jfd */
                act_freemem( FSA t->mem_pointers[i] );
                t->mem_pointers[i] = NULL;
                t->mem_numPointers--; 
            }
        }
        act_freemem( FSA t->mem_pointers );  
        t->mem_pointers = NULL;
    }
}

/* Call mem_CloseMemory on normal exit */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
void ACT_mem_CloseMemory( FSP ACT_MemHandler *t )
#else
void ACT_mem_CloseMemory(t)
ACT_MemHandler *t;
#endif
{
    if ( t->mem_numPointers != 0 )
    { 
        t->err = ERR_mem_dangling_pointers;
        return;
    }
    if ( t->mem_pointers != NULL  )
    { 
        act_freemem( FSA t->mem_pointers ); 
        t->mem_pointers = NULL;
    }
}


/* Constructor */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
ACT_MemHandler *ACT_mem_Create(FSP0)
#else
ACT_MemHandler *ACT_mem_Create()
#endif
{
    ACT_MemHandler *t    = (ACT_MemHandler *)act_allocmem( FSA sizeof( ACT_MemHandler ) );
    if ( t == NULL ) 
        return NULL; /*****/
    
    t->mem_pointers        = NULL;
    t->mem_maxPointers    = 0;
    t->mem_numPointers     = 0; /* Number of non-zero pointers */

    t->err = 0;        /* no errors yet */

    return t; /******/
}

/* Destructor */
#if defined (ANSI_DEFS)  /* 08-07-97 jfd */
void ACT_mem_Destroy(FSP ACT_MemHandler *t)
#else
void ACT_mem_Destroy(t)
ACT_MemHandler *t;
#endif
{
    act_freemem( FSA t );
}

#endif /* TT_ROM_ACT */
 

merge.txt   、、、、、、、、、、、、、、、、、、、、、、、

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

/* $Header:   I:/BULL/URIP/RTS/BMP/MERGE.C_V   1.15   Aug 21 2003 16:47:46   Galejs  $ */
/* $Log:   I:/BULL/URIP/RTS/BMP/MERGE.C_V  $ 
 * 
 *    Rev 1.15   Aug 21 2003 16:47:46   Galejs
 * update copyright notice
 * 
 *    Rev 1.14   Jul 21 2003 17:13:54   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.13   Jun 23 2003 14:27:20   Galejs
 * ufstport.h
 * 
 *    Rev 1.12   Aug 10 1999 14:41:20   galejs
 * include-file changes
 * 
 *    Rev 1.11   22 Jun 1998 18:49:48   GALEJS
 * tidying - remove unused defines / includes
 * 
 *    Rev 1.10   24 Mar 1998 14:48:28   GALEJS
 * include-file changes
 * 
 *    Rev 1.9   06 Apr 1995 15:08:26   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.8   22 Apr 1994 09:20:44   LISA
 * Modified copyright/disclaimer notice.
 * 
 *    Rev 1.7   07 Jan 1994 10:57:28   JOE
 * In merge(), fixed shifting process if !LEFT_TO_RIGHT_BIT_ORDER.
 * 
 *    Rev 1.6   19 May 1993 14:53:56   JOE
 * More changes for RASTER_ORG support.
 * 
 *    Rev 1.5   18 May 1993 17:50:34   JOE
 * Added support for RASTER_ORG != EIGHT_BIT_CHUNK.
 * 
 *    Rev 1.4   17 May 1993 18:03:30   JOE
 * In merge(), when calculating "ps" and "pd", cast "src->bm" and "dst->bm"
 * as LPUB8 due to change made in IFBITMAP structure.
 * 
 *    Rev 1.3   12 Feb 1993 11:14:22   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   05 Jan 1993 16:06:42   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:30:10   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:33:08   LISA
 * Initial revision.
*/
/* $Date:   Aug 21 2003 16:47:46  $ */
/* merge.c */


/*---------------------------------------------------------------------
     11-22-90   awr   Fixed bug in merge, rewrote bitblt portion based
                      on bg's if2.2 version.
     4-Feb-91   awr   Split off from maker.c
     9-Jun-91   awr   changed merge() parameter types to WORDVECTOR
     25-Jun-91   awr   changed merge() parameters
    17-Jun-91   jfd   Moved "debug.h" after "port.h".
                      Moved "cgconfig.h" before "port.h".
     1-Sep-91   awr   Included "bitmap.h"
    25-Oct-91   jfd   Conditionally compiling entire module based on
                      (CACHE | CHAR_HANDLE | CHAR_SIZE) instead of CGBITMAP.
    03-Apr-92   rs    Portability cleanup (see port.h).
    17-Apr-92   awr   Improved comments
    21-Jun-92   awr   Conditionally compile on IF_RDR
    05-Jan-93   jfd   ANSI C function declaration changes.
    08-Feb-93   jfd   VXWorks support.
    17-May-93   jfd   In merge(), when calculating "ps" and "pd", cast
                      "src->bm" and "dst->bm" as LPUB8 due to change made 
                      in IFBITMAP structure.
    18-May-93   jfd   Added support for RASTER_ORG !== EIGHT_BIT_CHUNK.
    19-May-93   jfd   More changes for RASTER_ORG support.
    07-Jan-94   jfd   In merge(), fixed shifting process if 
                      !LEFT_TO_RIGHT_BIT_ORDER.
-----------------------------------------------------------------------*/

#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"


/*----------------------*/
/*   merge              */
/*----------------------*/
/*  Merge the bitmap in the source buffer into the destination buffer
 *  so that the two origins coincide.  It is assumed that the src bitmap
 *  will fit in the destination.  There is no error checking.
 *
 *  Fields in the IFBITMAP structure that must be valid:
 *
 *    src                dst
 *    _________________________
 *    width              width
 *                       depth
 *    left_indent
 *    top_indent
 *    black_width
 *    black_depth
 *
 */
#if defined (ANSI_DEFS)
GLOBAL VOID  merge(FSP PIFBITMAP src, PIFBITMAP dst, SW16VECTOR org)
#else
GLOBAL VOID
merge(src, dst, org)
    PIFBITMAP  src;  /* Source      buffer                                */
    PIFBITMAP  dst;  /* Destination buffer                                */
    SW16VECTOR org;  /* source pixel origin (0,0) in destination bitmap   */
#endif
{
    SW16   ddx, ddy;  /* pixel address of blackbox in destination bitmap */
    LPCHUNK ps, pd;    /* pointers used to merge the bitmaps.             */
    SW16   sstart;    /* SB8 offset to starting SB8 of src blackbox    */
    SW16   dstart;    /* SB8 offset to starting SB8 of dst blackbox    */
    SW16   sw;        /* SB8 width of src blackbox                      */
    SW16   dw;        /* SB8 width of dst blackbox                      */
    UW16  i,j;
    UW16  mid_src_ct;
    UW16  sbit0, dbit0;
    UW16  sbit1, dbit1;
    SW16   n, nb;

    SW16   num_bytes;

    DBG2("\nmerge(org in destination = (%d, %d)", org.x, org.y);


  /*  Compute pixel address of blackbox in destination space. Address
   *  is upper left corner of pixel with origin at upper left of bitmap.
   */
    ddx = org.x;
    ddy = dst->depth - (org.y + src->black_depth);
    DBG2("    ddx, ddy  %d, %d\n", ddx, ddy);

  /*  Compute overhangs. Sbit0 and dbit0 are the number of white chunks
   *  to the left of the black box in the left most chunks that intersect
   *  the black box.
   *  Sbit1 and dbit1 are the number of black bits in the right most
   *  chunks that intersect the black box.
   */
    sbit0 = src->left_indent & (UW16)CHUNK_MASK;
    dbit0 = ddx & (UW16)CHUNK_MASK;
    sbit1 = (sbit0 + src->black_width) & (UW16)CHUNK_MASK;  if(!sbit1) sbit1 = (UW16)CHUNK_MASK + 1;
    dbit1 = (dbit0 + src->black_width) & (UW16)CHUNK_MASK;  if(!dbit1) dbit1 = (UW16)CHUNK_MASK + 1;
    DBG2("    sbit0 = %d    dbit0 = %d\n", sbit0, dbit0);
    DBG2("    sbit1 = %d    dbit1 = %d\n", sbit1, dbit1);

  /*  Compute starting chunk offset along a raster and the number
   *  of chunks that covers the black width in a raster. Note that
   *  sw and dw can vary from each other by as much as 1 depending
   *  on overhangs.
   */

    sstart = src->left_indent >> CHUNK_SHIFT;
    dstart = ddx >> CHUNK_SHIFT;
    sw    = ((src->left_indent + src->black_width + (UW16)CHUNK_MASK) >> CHUNK_SHIFT) - sstart;
    dw    = ((ddx + src->black_width + (UW16)CHUNK_MASK) >> CHUNK_SHIFT) - dstart;

  /*  Set pointers */

    ps = (LPCHUNK)((LPUB8)src->bm + (src->top_indent * src->width)) + sstart;  /* 5-17-93 */
    pd = (LPCHUNK)((LPUB8)dst->bm + (ddy * dst->width)) + dstart; /* 5-17-93 */

  /*  Special case if no shifting is required */

    if(sbit0 == dbit0)
    {
        for(i=0; i<src->black_depth; i++)
        {
            for(j=0; j<sw; j++)
                *pd++ |= *ps++;

            ps += (src->width >> (CHUNK_SHIFT - 3)) - sw;
            pd += (dst->width >> (CHUNK_SHIFT - 3)) - dw;
        }
        return;
    }

  /*  Shifting case. Transfer each raster in (up to) three steps:
   *    1. If src overhangs on left, then shift src and or into dst.
   *    2. Transfer all "middle" src chunks that overlap two dst
   *       chunks (if any).
   *    3. If src overhangs on right, then shift src and or into dst.
   */

  /* number of source chunks to transfer in the middle loop, step 2 */

    mid_src_ct = sw;  /* Assume no overhangs, all src chunks are in step 2 */
    if(sbit0 > dbit0) /* Source overhangs on left  */
        mid_src_ct--;
    if(sbit1 < dbit1) /* Source overhangs on right */
        mid_src_ct--;

    DBG1("    mid_src_ct = %u\n", mid_src_ct);

  /*  Shifting values. Each source overlaps two dst chunks.
   *  Shift src chunk >> n  before oring into left  dst chunk
   *  Shift src chunk << nb before oring into right dst chunk
   */

    n  = dbit0 - sbit0;   /* calculate n. Assume no left overhang        */
    if(n<0)               /* If n < 0, then left overhnag and we really  */
        n = (SW16)CHUNK_MASK + 1 + n;        /* calculated -nb, so convert to n.            */

    nb = (SW16)CHUNK_MASK + 1 - n;
    DBG2("    n = %u   nb = %u\n", n, nb);

  /*  For each raster in the black box shift and transfer the data from
   *  the source to the destination
   */

    for(i=0; i<src->black_depth; i++)
    {

      /*  Step 1. Take care of the case that the source overhangs the
       *  destination on the left. In this case, this first source chunk only
       *  contributes to one destination chunk.
       */
        if(sbit0 > dbit0)
#if LEFT_TO_RIGHT_BIT_ORDER
            *pd |= *ps++ << nb;
#else
            *pd |= *ps++ >> nb;
#endif

      /*  Step 2. Transfer the middle data. For each source chunk, put
       *  a piece in each of the two destination chunk that it overlaps.
       */
        for(j=0; j<mid_src_ct; j++)
        {
#if LEFT_TO_RIGHT_BIT_ORDER
            *pd++ |= *ps   >> n;
            *pd   |= *ps++ << nb;
#else
            *pd++ |= *ps   << n;
            *pd   |= *ps++ >> nb;
#endif
        }

              /*  Rule for pointers after each of these three steps:
               *      ps now points to the next src chunk to be processed.
               *      pd now points to the last dest chunk processed.
               */

      /*  Step 3. Take care of the case that the source overhangs the
       *  destination on the right. In this case, this last source chunk only
       *  contributes to one destination chunk.
       */

        if(sbit1 < dbit1)
#if LEFT_TO_RIGHT_BIT_ORDER
            *pd |= *ps++ >> n;
#else
            *pd |= *ps++ << n;
#endif

      /* On to the next raster */

        num_bytes = src->width - (sw * sizeof(CHUNK));
        ps += (num_bytes / sizeof(CHUNK));

        num_bytes = sizeof(CHUNK) + dst->width - (dw * sizeof(CHUNK));
        pd += (num_bytes / sizeof(CHUNK));
    }
}
#endif    /* IF_RDR */


metrics.c      、、、、、、、、、、、、、、、、、、、、、、、、

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

/* $Header:   I:/BULL/URIP/RTS/BMP/METRICS.C_V   1.52   Aug 26 2004 14:33:06   wuq  $ */
/* $Log:   I:/BULL/URIP/RTS/BMP/METRICS.C_V  $ 
 * 
 *    Rev 1.52   Aug 26 2004 14:33:06   wuq
 * Removed GET_VERTICAL_METRICS conditional
 * from non output structure.
 * 
 *    Rev 1.51   Oct 09 2003 12:57:38   IndrelR
 * Changes for Vertical Writing 
 * 
 *    Rev 1.50   Aug 21 2003 16:47:48   Galejs
 * update copyright notice
 * 
 *    Rev 1.49   Jun 19 2003 18:26:34   Galejs
 * get rid of NON_IF_FONT
 * 
 *    Rev 1.48   Jun 28 2001 19:01:16   Galejs
 * fix minor compiler warning
 * 
 *    Rev 1.47   10 Jul 2000 09:41:14   JOE
 * Modified calculation of vertical_metric (no /2) for TT Disk/ROM (by keb).
 * 
 *    Rev 1.46   19 Apr 2000 11:11:54   JOE
 * For TT_ROM or TT_DISK, added code to metrics() to replace escapement
 * with advanceHeight, if advanceHeight exists and is different from
 * escapement, and vertical writing is enabled (by keb).
 * 
 *    Rev 1.45   Mar 24 2000 17:10:48   galejs
 * fix unused-vbl compiler warnings
 * 
 *    Rev 1.44   Mar 22 2000 15:22:26   galejs
 * more vertical-writing changes (for keb)
 * 
 *    Rev 1.43   Jan 24 2000 12:44:14   galejs
 * vertical-writing changes (for keb)
 * 
 *    Rev 1.42   Dec 10 1999 16:29:12   galejs
 * remove redundant define MASK_ASIAN_ENC
 * 
 *    Rev 1.41   Aug 17 1999 17:59:04   galejs
 * fix compiler warnings about unknown #pragmas
 * 
 *    Rev 1.40   Aug 10 1999 14:50:20   galejs
 * include-file changes
 * 
 *    Rev 1.39   24 Feb 1999 13:12:28   JOE
 * Conditionally compiled test to set 'mkchg' in metrics() (by keb).
 * 
 *    Rev 1.38   11 Feb 1999 13:45:16   JOE
 * Modified the code in metrics() that adjusts the x and y origin for
 * vertical writing with XL soft fonts (by keb).
 * 
 *    Rev 1.37   13 Jan 1999 14:19:10   MARTIN
 * Removed declarations for rot_in_deg and rot_in_rad.
 * 
 *    Rev 1.36   15 Dec 1998 14:36:14   JOE
 * Modified metrics(). No divide by 2 for "adjx" and "adjy" (by keb)
 * 
 *    Rev 1.35   15 Dec 1998 10:44:24   JOE
 * Fixed comment delimiters (by ks).
 * 
 *    Rev 1.34   15 Dec 1998 09:44:46   JOE
 * In metrics(), conditionally compiled code which referenced "XLfont",
 * "yDescender" and "top_bearing" based on TT_PCLEOI to resolve
 * compiler errors.
 * 
 *    Rev 1.33   14 Dec 1998 08:37:24   JOE
 * Removed extra tabs (by keb).
 * 
 *    Rev 1.32   11 Dec 1998 11:42:40   JOE
 * Added code to support ASIANVERT for XLfonts (by keb).
 * 
 *    Rev 1.31   22 Jun 1998 18:51:06   GALEJS
 * mkae Intellifont reentrant too
 * 
 *    Rev 1.30   15 Jun 1998 16:47:50   GALEJS
 * reentrancy parameter-passing changes
 * 
 *    Rev 1.29   15 Apr 1998 16:54:34   GALEJS
 * move chr_def_hdr to IF_STATE
 * 
 *    Rev 1.28   14 Apr 1998 18:57:50   GALEJS
 * move "special_case" to IF_STATE
 * 
 *    Rev 1.27   02 Apr 1998 18:47:10   GALEJS
 * move externs to if_state
 * 
 *    Rev 1.26   24 Mar 1998 14:50:08   GALEJS
 * include-file changes
 * 
 *    Rev 1.25   03 Mar 1998 16:10:10   JOE
 * Added ASIANVERT metrics adjustments (by dah).
 * 
 *    Rev 1.24   23 Feb 1998 15:03:50   AL
 * Added ASIANVERT
 * 
 *    Rev 1.23   13 Jan 1997 16:25:58   DAVID
 * Removed CONVERGENT_FONTS option as part of project to
 * trim ufst.
 * 
 *    Rev 1.22   10 Jan 1997 14:01:32   DAVID
 * Removed ELASTIC_X and ELASTIC_Y as part of project to trim ufst.
 * 
 *    Rev 1.21   20 Mar 1996 12:10:10   MERRILL
 * quiet sig warns
 * 
 *    Rev 1.20   05 Jan 1996 09:42:18   MERRILL
 * consolidate pixelwidth, disc
 * 
 *    Rev 1.19   15 Dec 1995 13:14:40   MERRILL
 * remove cast to 32 of shift amount in calls to fp_to_16
 * 
 *    Rev 1.18   04 Dec 1995 13:03:02   MERRILL
 * 
 * added conditionalon IF_RDR to variable definitions.
 * 
 *    Rev 1.17   06 Apr 1995 15:08:16   LISA
 * 
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.16   11 Dec 1994 17:31:26   MIKE
 * 
 * Changed if_state.cs.origin to "origin_cs".
 * 
 *    Rev 1.15   02 May 1994 11:49:04   MIKE
 * Conditionally compile 1.14 change based on SLIM_FONTS.
 *
 *    Rev 1.14   27 Apr 1994 17:08:04   MIKE
 * Add new special case for mirror, oblique for rotation 90.
 * 
 *    Rev 1.13   27 Apr 1994 10:58:02   MIKE
 * In metrics(), handle special case of mirrored, obliqued characters.
 * 
 *    Rev 1.12   22 Apr 1994 10:31:14   JOE
 * Added missing comment delimiter at start of line prior to "History".
 * 
 *    Rev 1.11   22 Apr 1994 09:20:44   LISA
 * 
 * Modified copyright/disclaimer notice.
 * 
 *    Rev 1.10   08 Mar 1994 15:52:06   JOE
 * Corrected external declaration for variable "special_case".
 * Was missing type "SW16".
 * 
 *    Rev 1.9   06 Mar 1994 14:11:18   MIKE
 * 
 * Adjust character's horizontal position only if CONVERGENT_FONTS == 1.
 * 
 *    Rev 1.8   03 Feb 1994 14:22:48   MIKE
 * Adjust character horizontal position for Convergent Fonts.
 * 
 *    Rev 1.7   22 Sep 1993 16:06:10   JOE
 * In metrics(), conditionally compiled block of code which checks for
 * mirrored character before distributing alternate width based on
 * SLIM_FONTS.
 * 
 *    Rev 1.6   07 Sep 1993 17:15:34   MIKE
 * 
 * Fix bug in x-origin for mirrored characters using alternate widths.
 * 
 *    Rev 1.5   14 Jun 1993 09:17:54   JOE
 * In metrics(), in calls to fp_to_16() for calculating bm->yorigin, cast each
 * member of expression for first argument to SL32 to prevent SW16 calculation.
 * 
 *    Rev 1.4   12 Feb 1993 11:16:34   JOE
 * VXWorks support.
 * 
 *    Rev 1.3   29 Jan 1993 09:25:24   JOE
 * In metrics(), saved em box size in IFBITMAP structure for IF, PS and TT.
 * 
 *    Rev 1.2   05 Jan 1993 16:10:00   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:29:58   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:32:56   LISA
 * Initial revision.
*/
/* $Date:   Aug 26 2004 14:33:06  $ */
/* metrics.c */
/*
 * History
 *
 *    03-27-90   jfd     In "metrics()", instead of splitting the difference
 *                       between the alternate width and the real width
 *                       and applying that value to both "x0" and "x1",
 *                       apply it only to "x0" and set "x1" equal to "x0"
 *                       plus the alternate width. This will ensure the
 *                       proper escapement. It was off by 1 design unit
 *                       in some cases.
 *    05-22-90   awr     Corrected yorigin calculation to use the grid
 *                       alligned baseline (d.aBaselnVal) instead of the
 *                       the unaligned version.
 *    05-22-90   awr     Added metric calculations for quadrant rotations
 *    09-04-90   awr     Declared des2wrkbm() to fix compiler warning,
 *                       removed rot90() declaration.
 *    05-Oct-90  awr     Added connecting character side bearing calculation
 *    28-Jan-91  jfd     Conditionally compiling fp_to_16() based on
 *                       (MAX_BM_BITS > 16)
 *                       Including "cgconfig.h".
 *    30-Jan-91  dET     Added function prototyping for MSC
 *    31-Jan-91  dET     Added support for multi-model MSC compilation
 *     3-Feb-91  awr     Removed include imath.h- not needed,
 *                       updated copyright.
 *     8-Feb-91  awr     Moved inv_des2wrkbm() to scale.c
 *                       Changed name des2wrkbm() to des2bm()
 *                       and inv_des2wrkbm() to inv_des2bm().
 *    11-Mar-91  awr     Changed return value of des2bm() and inv_des2bm
 *                       to PWORDVECTOR
 *    05-Jun-91  jfd     In metrics(), in case of 90 or 270 degree rotation,
 *                       when calculatin lb.y, use bm->depth instead of
 *                       d.bmdepth (FIX FROM EARLIER VERSION)
 *     9-Jun-91  awr     changed metrics() parameters
 *    17-Jun-91  jfd     Moved "debug.h" after "port.h".
 *     4-Jul-91  awr     Removed SCALE fields "px" and "py".
 *     8-Jul-91  bjg     Added Elasticity.
 *     5-Aug-91  tbh     Cleaned up Elasticity.
 *    10 Aug 91  ss      Added code to support mirrored chars and -ROTs.
 *    24-Aug-91  awr     Changed calling sequence of des2bm()
 *    27-Aug-91  bjg     Add special case handling for mirrored chars 
 *     1-Sep-91  awr     Included "bitmap.h"
 *    17-Sep-91  jfd     Changed fp_to_16() to LONG instead of WORD.
 *                       In metrics(), calling DBG2() unconditionally now.
 *    20-Sep-91  jfd     In metrics(), when calculating xorigin and yorigin,
 *                       cast operands as LONG due to change in type to LONG
 *                       for xorigin and yorigin.
 *    30-Oct-91  awr     Corrected lsb calculations for connecting chars.
 *     5-Feb-92  awr     In short_metrics(), changed the way x and y origins
 *                       are calculated.
 *     7-Mar-92  awr     Changed metrics() to read design bounding box from
 *                       if_state
 *    03-Apr-92  rs      Portability cleanup (see port.h).
 *    10 Apr 92  ss      Don't reset special_case flag here any more.
 *    09-Jun-92  jfd     In metrics(), load "org" with contents of
 *                       "if_state.cs.dorigin", not "if_state.cs.origin".
 *    21-Jun-92  awr     Conditionally compiled
 *    28-Jun-92  awr     Changed TT & PS for 16bit scan conversion
 *    08-Jul-92  rs      Code cleanup.
 *    21-Jul-92  awr     Conditional compile changes
 *    11-Aug-92  jfd     Trying macro MDES2BM for optimization.
 *                       Included imath.h.
 *    05-Jan-93  jfd     ANSI C function declaration changes.
 *    25-Jan-93  jfd     In metrics(), store size of em box ("du_emx" and 
 *                       "du_emy") into IFBITMAP structure for IF, PS and TT.
 *    08-Feb-93  jfd     VXWorrks support.
 *    14-Jun-93  jfd     In metrics(), in calls to fp_to_16() for calculating
 *                       bm->yorigin, cast each member of expression for first
 *                       argument to SL32 to prevent truncation to SW16.
 *    01-Sep-03  mby     In metrics() if if_state.alt_width is on and the character
 *                       is mirrored in X, adjust the x-origin in the opposite
 *                       direction, because of a previous reflection.
 *    22-Sep-93  jfd     In metrics(), conditionally compiled block of code
 *                       which checks for mirrored character before distribu-
 *                       ting alternate width based on SLIM_FONTS.
 *    25-Jan-94  mby     Adjust character position by lsb_adj in metrics()
 *                       for Convergent Fonts.
 *    06-Mar-94  mby     Use lsb_adj only if CONVERGENT_FONTS == 1.
 *    08-Mar-94  jfd     Corrected external declaration for variable 
 *                       "special_case". Was missing type "SW16".
 *    22-Apr-94  jfd     Added missing comment delimiter at start of line
 *                       prior to "History".
 *    26-Apr-94  mby/    In metrics() for special_case of mirrored, obliqued
 *               bjg     characters, (1) set origin to character baseline;
 *                       (2) adjust bm->xorigin,yorigin.
 *    27-Apr-94  mby/    In metrics() add new special case for p0 for
 *               bjg     rotation of 0 and rotation of 90.
 *    02-May-94  mby     Conditionally compile above change to SLIM_FONTS.
 *    11-Dec-94  mby     Change if_state.cs.origin to "origin_cs".
 *    10-Jan-97  dlk     Removed ELASTIC_X and ELASTIC_Y as part of project
 *                       to trim ufst.
 *    13-Jan-97  dlk     Removed CONVERGENT_FONTS option as part of project to
 *                       trim ufst.
 *    02-Mar-98  dah     Added ASIANVERT metric adjustments
 *    11-Dec-98  keb     Added code to support ASIANVERT for XLfonts
 *    15-Dec-98  jfd     In metrics(), conditionally compiled code which
 *                       references the fields "XLfont", "yDescender" and
 *                       "top_bearing" based on TT_PCLEOI to resolve compiler
 *                       error.
 *    15-Dec-98  keb     Modified metrics(). No divide by 2 for "adjx" and
 *                       adjy.
 *    11-Feb-99  keb     Modified the code in metrics() that adjusts the x and y origin
 *                       for vertical writing with XL soft fonts
 *    24-Feb-99  keb     Conditionally compile the test to set mkchg in metrics()
 *      18-Jan-00  slg     Vertical-writing changes (for keb) - replace big
 *                         #if-ASIANVERT section with if-FC_ISUFSTVERT() section.
 *    21-Mar-00  keb     added back code to process format16 fonts in vertwrit mode
 *    14-Apr-00  keb     For TT_ROM or TT_DISK added code to metrics() to replace escapement 
 *                       with advanceHeight, if advanceHeight exists and is different from 
 *                       escapement, and vertical writing is enabled
 *    06-Jul-00  keb     modified calculation of vertical_metric (no /2) for TT Disk/Rom
 */

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

#include <stdio.h>
#include <math.h>  

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

#include "shareinc.h"

#include "imath.h"


#ifdef LINT_ARGS
MLOCAL SL32 fp_to_16(SL32, PCOORD_DATA);
#else /* no LINT_ARGS */
MLOCAL SL32 fp_to_16();
#endif /* LINT_ARGS */


/*----------------------*/
/*    fp_to_16()        */
/*----------------------*/
/*  Convert working bitmap space fractional pixels to 16ths of a pixel */
#if defined (ANSI_DEFS)
MLOCAL SL32  fp_to_16(SL32 v, PCOORD_DATA xy)
#else
MLOCAL SL32
fp_to_16(v, xy)
    SL32 v;
    PCOORD_DATA xy;
#endif
{
    SL32 val;

    val = LABS(v);
    val = (val * 16 + xy->half_pixel) >> xy->grid_shift;

    if(v<0)
        return -val;
    else
        return val;
}

/*----------------------*/
/*    metrics           */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID  metrics(FSP PIFBITMAP bm)
#else
GLOBAL VOID
metrics(bm)
    PIFBITMAP  bm;
#endif
{
    SW16VECTOR org;
    SW16       escx;
    SW16 adj_width;

#if IF_RDR
    SW16 orig_black_width;
    SW16 new_black_width;
    SW16 orig_lsb;
    SW16 new_lsb;
    SW16VECTOR lb, rb;     /* left & right bound (fractional pixels) */
    SW16VECTOR dlb, drb;   /* left & right bound (design units)      */
    SW16VECTOR new_org;    /* character origin (design units)        */
    SW16VECTOR p0;         /* character origin (fractional pixels)   */
#endif
    SL32VECTOR p;

    DBG("metrics()\n");
    org  = if_state.cs.dorigin;  /* 6-9-92 */
    escx = if_state.cs.escapement;

  /*  Adjust escape box for alternate width (if any) */

    
    if(if_state.alt_width > 0)  /* not supposed to be negative, ignore if < 0 */
    {
      /*  Distribute the alternate width change equally (not proportionately)
       *  over each side bearing.
       */

        DBG1("    alternate width = %d\n", if_state.alt_width);
        adj_width = (if_state.alt_width - escx) / 2;
#if SLIM_FONTS
        if (if_state.chr_def_hdr.mirror_flags & MIRROR_X_MASK)   /* mby 9-01-93 */
            org.x += adj_width;
        else
#endif
            org.x -= adj_width;
        escx = if_state.alt_width;
        DBG3("    alt origin (%d, %d)  escapement %d\n",
                                          org.x, org.y, escx);
    }


    bm->escapement   = escx;

if(if_state.fst_type != FC_IF_TYPE)
{
    DBG("short_metrics()\n");
    p.x = ((SL32)if_state.cs.origin_cs.x + (SL32)if_state.xlate.x)
                                                  >>if_state.right_shift;
    p.y = ((SL32)if_state.cs.origin_cs.y + (SL32)if_state.xlate.y)
                                                   >>if_state.right_shift;
    bm->xorigin = - fp_to_16(p.x, &if_state.x);

    bm->yorigin =   fp_to_16((SL32)((SL32)bm->depth << log_ypix) - p.y, &if_state.y);


    /* keb */
    if ( FC_ISUFSTVERT(&if_state.fcCur) )
    {
    if ( if_state.CharVertWrit )
    {
#if TT_RDR
       SW16 dx, dy, vertical_metric;
       FPNUM fdx, fdy, em;
#endif
       SL32 adjx, adjy;

        adjx = 0;
        adjy = 0;
        
#if TT_RDR
        if(FC_ISXLFONT(&if_state.fcCur)) 
        {
          vertical_metric = if_state.pbucket->p.tt.FontBBox[1]; 
          dx = vertical_metric; 
          dy = -(if_state.cs.du_emx + vertical_metric);
          em = fpint2fp ((SL32) if_state.cs.du_emx);
          fdx = fpint2fp((SL32)dx);
          fdy = fpint2fp((SL32)dy);
          fdx = fpdiv (fdx, em);
          fdy = fpdiv (fdy, em);
          adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
                               fpmul (fdy, if_state.m[2] ) ) );
          adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
                               fpmul (fdy, if_state.m[3] ) ) );
                  
          adjx = (adjx << 4) ;
          adjy = (adjy << 4) ;
        }
     
        if ((FC_ISTT(&if_state.fcCur)) & (if_state.pbucket->extern_font == 0))  
        {
/* #if GET_VERTICAL_METRICS 08-20-04 qwu */ 
          /* keb 4/00 */
          if ((if_state.cs.escapement != if_state.cs.advanceHeight) & (if_state.cs.advanceHeight != 0))
          {
              if_state.cs.escapement = if_state.cs.advanceHeight;
              bm->escapement = if_state.cs.advanceHeight;
          }
/* #endif  08-20-04 qwu */ 

          vertical_metric = if_state.cs.yDescender;
          dx = vertical_metric;
          dy = -(if_state.cs.du_emx + vertical_metric);
          em = fpint2fp ((SL32) if_state.cs.du_emx);
          fdx = fpint2fp((SL32)dx);
          fdy = fpint2fp((SL32)dy);
          fdx = fpdiv (fdx, em);
          fdy = fpdiv (fdy, em);
          adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
                               fpmul (fdy, if_state.m[2] ) ) );
          adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
                               fpmul (fdy, if_state.m[3] ) ) );
                  
          adjx = (adjx << 4) ;
          adjy = (adjy << 4) ;
        }

        if (FC_ISTTFMT16(&if_state.fcCur))
        {   
          vertical_metric = if_state.cs.yDescender;      
          dx = vertical_metric;
          dy = -(if_state.cs.du_emx + vertical_metric);
          em = fpint2fp ((SL32) if_state.cs.du_emx);
          fdx = fpint2fp((SL32)dx);
          fdy = fpint2fp((SL32)dy);
          fdx = fpdiv (fdx, em);
          fdy = fpdiv (fdy, em);
          adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
                               fpmul (fdy, if_state.m[2] ) ) );
          adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
                               fpmul (fdy, if_state.m[3] ) ) );
                  
          adjx = (adjx << 4) ;
          adjy = (adjy << 4) ;
        }
#endif
 
        bm->xorigin += adjx;
        bm->yorigin += adjy;
    
    }
    
}/* if ISUFSTVERT end */

    /* Store size of em box */

    bm->du_emx  =   if_state.cs.du_emx;
    bm->du_emy  =   if_state.cs.du_emy;

    return;
}
#if IF_RDR
  /*  Compute vector (xorigin, yorign) in 16ths of an output pixel.
   *      step 1. Compute (p0.x, p0.y) the character origin in working
   *              bitmap space.
   *      step 2. Compute (xorigin, yorigin).
   */

/*---------step 1-------------------------*/

  /*  If arbitrary rotation, simply transfer the design origin to
   *   working bitmap space. If special 90 degree rotation, then we
   *   take into account the change in the character's black width
   *   and distribute this change equally over both side bearings.
   */

    if(!if_state.quadrant)      /* arbitrary rotation */
    {
        DBG("    Arbitrary rotate: ");

      /* Transform character origin to working bitmap space */

#if defined MDES2BM
        p0 = MDES2BM(org);
#else
        p0 = des2bm(FSA org);
#endif /* defined MDES2BM */
#if SLIM_FONTS          /* mby, 4/26 - 5/1/94 */
        if (if_state.special_case && if_state.shear == ROT0)
        {                   /* rotation is 0/180 and shear is nonzero */
            SW16 savex = p0.x;
            org.y = if_state.escape_box.ll.y;
#if defined MDES2BM
            p0 = MDES2BM(org);  /* p0 is the transform of the character    */
#else                           /* origin in X, and the character baseline */
            p0 = des2bm(FSA org);   /* in Y. */
#endif /* defined MDES2BM */
            p0.x = savex;
        }
        else if (if_state.special_case && if_state.shear == ROT90)
        {
            SW16 savey = p0.y;
            org = if_state.escape_box.ll;    /* x and y */
#if defined MDES2BM
            p0 = MDES2BM(org);
#else
            p0 = des2bm(FSA org);
#endif /* defined MDES2BM */
            p0.y = savey;
        }
#endif  /* SLIM_FONTS */
    }
    else                /* special 0, 90, 180, or 270 degree rotation */
    {
      /*  Intellifont is on.
       */
    SW16 tmp;

        if(if_state.quadrant==ROT0 || if_state.quadrant==ROT180
                        /* added -ss */
         || if_state.quadrant == -ROT0 || if_state.quadrant == -ROT180)
        {
            lb.y = rb.y = 0;

          /* assume ROT0, swap if ROT180 */

            lb.x = bm->left_indent << log_xpix;
            rb.x = lb.x + (bm->black_width << log_xpix);
            if( if_state.quadrant == ROT180
             || if_state.quadrant == -ROT0 )
            {
                tmp = lb.x;
                lb.x = rb.x;
                rb.x = tmp;
            }
        }
        else
        {
            lb.x = rb.x = 0;

          /* Assume ROT270, swap if ROT90 */

            lb.y = (bm->depth - bm->top_indent) << log_ypix;
            rb.y = lb.y - (bm->black_depth << log_ypix);
            if( if_state.quadrant == ROT90
             || if_state.quadrant == -ROT270 )
            {
                tmp = lb.y;
                lb.y = rb.y;
                rb.y = tmp;
            }
        }

        dlb = inv_des2bm(FSA lb);
        drb = inv_des2bm(FSA rb);

        DBG2("lb = (%d, %d)\n", lb.x, lb.y);
        DBG2("rb = (%d, %d)\n", rb.x, rb.y);
        DBG2("dlb = (%d, %d)\n", dlb.x, dlb.y);
        DBG2("drb = (%d, %d)\n", drb.x, drb.y);

        orig_lsb = if_state.cs.dxmin - org.x;

        if(if_state.ConnectingChar)
        {
            pixel_align (FSAvoid org.x, &if_state.x, R_TWO_I);
            new_lsb = dlb.x - if_state.value;
            DBG("     ConnectingChar:\n");
            DBG2("    orig_lsb %d    new_lsb %d\n", orig_lsb, new_lsb);
        }
        else
        {
            orig_black_width = if_state.cs.dxmax - if_state.cs.dxmin;
            new_black_width  = drb.x - dlb.x;

            new_lsb = orig_lsb + (orig_black_width - new_black_width)/2;
            DBG2("    orig_lsb %d    new_lsb %d\n", orig_lsb, new_lsb);
        }

        new_org.x = dlb.x - new_lsb;
        new_org.y = if_state.aBaselnVal;

        /*  Fix for one part compound char with nonzero offset.           */
        /*  There may still be a bug for multiple part chars with nonzero */
        /*  offset in first part.                        -ss,bjg 7/23/91  */
        if( if_state.chr_def[0].offset.y )
           new_org.y -= if_state.chr_def[0].offset.y;

        DBG2("new_org = (%d, %d)\n", new_org.x, new_org.y);

#if defined MDES2BM
        p0 = MDES2BM(new_org);
#else
        p0 = des2bm(FSA new_org);
#endif /* defined MDES2BM */
    }    

    DBG2("    (p0.x, p0.y) = (%d, %d)\n", p0.x, p0.y);

/*---------step 2-------------------------*/

      bm->xorigin = - fp_to_16((SL32)p0.x, &if_state.x);
    /* IF_RDR dependent */
    bm->yorigin =   fp_to_16((SL32)(((SL32)bm->depth << log_ypix)  - p0.y),
                             &if_state.y);

#if SLIM_FONTS
#if defined(__BORLANDC__)
#pragma warn -sig   /* Conversion may lose significant digits */
#endif
    /*  handle special case of mirrored characters */
    if( if_state.special_case &&
        (if_state.quadrant==ROT0 || if_state.quadrant==ROT180
          || if_state.quadrant == -ROT0 || if_state.quadrant == -ROT180
          || if_state.shear == ROT0) )       /* test for shear -mby 4-26-94 */
       bm->yorigin = (SL32)((SL32)bm->top_indent<<5L) +
                     (SL32)((SL32)bm->black_depth<<4L) -
                     bm->yorigin;

    if( if_state.special_case &&
        (if_state.quadrant==ROT90 || if_state.quadrant==ROT270
          || if_state.quadrant == -ROT90 || if_state.quadrant == -ROT270
          || if_state.shear == ROT90) )      /* test for shear */
       bm->xorigin = - (SL32)((SL32)bm->left_indent<<5L) -
                     (SL32)((SL32)bm->black_width<<4L) -
                     bm->xorigin;

    /**  don't reset this here, its used again later. -ss 4/10/92 **
    if_state.special_case = 0;
    **/
#ifdef __BORLANDC__
#pragma warn +sig
#endif
#endif    /* SLIM_FONTS */

    /* Store size of em box */

    bm->du_emx  =   if_state.cs.du_emx;
    bm->du_emy  =   if_state.cs.du_emy;

#endif /* IF_RDR  */
}
 

mixmodel.h   、、、、、、、、、、、、、、、、、、、、、、、、、、

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

/* $Header:   I:/BULL/URIP/RTS/INC/MIXMODEL.H_V   1.20   Aug 21 2003 17:10:20   Galejs  $ */
/* $Log:   I:/BULL/URIP/RTS/INC/MIXMODEL.H_V  $ 
 * 
 *    Rev 1.20   Aug 21 2003 17:10:20   Galejs
 * update copyright notice
 * 
 *    Rev 1.19   Sep 20 2002 20:14:50   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.18   Jun 12 2001 17:40:26   Galejs
 * data-type cleanup - use INTG type for int, for safety's sake
 * 
 *    Rev 1.17   17 Mar 2000 11:55:50   JOE
 * Added '#define MEMSET ulongmemset' (by ks).
 * 
 *    Rev 1.16   Aug 12 1999 15:58:28   galejs
 * add GCCx86 case (for GNU compiler under Windows)
 * 
 *    Rev 1.15   06 Aug 1998 15:56:18   AL
 * CFF_ROM support
 * 
 *    Rev 1.14   30 Mar 1998 11:36:30   GALEJS
 * add O_RDONLY define for OS-9000 compile
 * 
 *    Rev 1.13   20 Mar 1998 12:00:08   GALEJS
 * 64-bit port
 * 
 *    Rev 1.12   02 Jan 1997 14:42:20   DAVID
 * No change.
 * 
 *    Rev 1.11   23 Sep 1996 14:01:32   PVCSADMN
 * Provided change for MicroSoft Visual C 4.x MSVC.
 * 
 *    Rev 1.10   20 Mar 1996 10:28:22   MERRILL
 * included <mem.h> @ln 160 for memset prototypes
 * 
 *    Rev 1.9   07 Apr 1995 08:45:18   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.8   21 Apr 1994 15:48:44   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.7   09 Feb 1994 13:34:16   JOE
 * _AM29K changes.
 * 
 *    Rev 1.6   08 Dec 1993 18:58:02   ROB
 * General cleanup for MSDOS, FLAT, OS2.
 * 
 *    Rev 1.5   09 Jun 1993 16:47:06   JOE
 * Changed all references to "char" to "SB8" for transportability.
 * 
 *    Rev 1.4   22 Feb 1993 11:04:52   JOE
 * Added conditional compile for O_READFLAGS define (VXWORKS) to resolve
 * compiler error for OPEN call.
 * 
 *    Rev 1.3   12 Feb 1993 14:33:30   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   15 Jan 1993 09:35:28   LISA
 * Removed CtrlZ character from end of file
 * 
 *    Rev 1.1   14 Dec 1992 09:42:16   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 09:11:32   LISA
 * Initial revision.
*/
/* $Date:   Aug 21 2003 17:10:20  $ */
/************************************************************************/
/*
 *                      Function definitions                            
 *
 *
 */
/************************************************************************/
                /* special Borland C++ version - 3-7-92 - rs */
/* 
 * History:
 *
 * 03-DEC-90  dET - original
 *
 *
 * The common problem of mapping various I/O and string functions to the
 * respective operating system/compilers is partialy addressed forthwith.
 * Three cases exist.  MSDOS, MS WINDOWS, and standard 'C'.  We map various
 * functions to other functions because of the stdio differences.  In the 
 * SMALL, MEDIUM, and TINY models of the MSC and MS WINDOWS compilation,
 * these functions take far pointers to arguments rather than near pointers. 
 * 
 * 
 *   24 Jun 91  ss    Deleted O_BINARY from default O_READFLAGS & O_WRITEFLAGS.
 *                    Changed define SEEK to LSEEK for default.
 *   19-Jul-91  jfd   Changed "MSWINDOWS" to "_WINDOWS".
 *   26-Jul-91  jfd   Added STRCAT and SPRINTF.
 *   07-Aug-91  jfd   Added function prototype for _fstrcat() and wsprintf().
 *                    Changed conditional compile statement so that the
 *                    section of code that was meant to be run only if
 *                    !MSC && !_WINDOWS does not run if MSC.
 *   24-Sep-91  jfd   Added #define for QSORT.
 *   03-Mar-92  rs    Add '_fstrcmp()'.
 *   04-Mar-92  rs    Add STRSTR = '_fstrstr()'.
 *   07-Mar-92  rs     Add support for Borland C++ compiler. Make 'MSC'
 *                    more like 'MSDOS' where appropriate.
 *   15-Mar-92  rs    Move Borland specific things to 'port.h'.
 *   03-Apr-92  rs    Portability cleanup (see port.h).
 *   11-Jun-92  rs    wsprintf fix for Borland C++.
 *   05-Aug-92  jfd   Added MEMCMP and MEMSET.
 *   08-Aug-92  rs    Changes for Watcom C386 compiler.
 *   08-Feb-93  jfdf  Changed READ to READF and WRITE to WRITEF due to
 *                    conflict with VXWorks.
 *   17-Feb-93  jfd   Resolve VXWORKS compiler error when calling OPEN by 
 *                    changing #define for O_READFLAGS to "O_RDONLY, 0x644".
 *   09-Jun-93  jfd   Changed all references to "char" to "SB8" for
 *                    transportability.
 *   08-Dec-93  rs    General cleanup - MSDOS & WATCOMC -> CGFLAT32.
 *   09-Feb-94  jfd/dbk _AM29K changes.
 *   12-Sep-96  dbk   Provided change for MicroSoft Visual C 4.x(MSVC)
 *   09-Mar-98  slg   Don't use "long" dcls (incorrect if 64-bit platform)
 *   30-Mar-98    slg      Add O_RDONLY define for OS-9000 compile
 *   05-Aug-98    awr   Changed !ROM to DISK_FONTS
 *     12-Aug-99    slg      Add GCCx86 case, to fix premature end-of-read problem
 *                        when using GNU compiler in a Windows environment.
 *   16-Mar-00  ks    Add #define MEMSET ulongmemset() to handle sizes > 64K
 *                    on system with 16 bit ints.
 *
 */

#ifndef __MIXMODEL__
#define __MIXMODEL__

/*
Borland compiler decisions depend upon the following manifest constants:

    __BORLANDC__
    _Windows

if Borland C++ compiler - fake out the system to make it appear as
if we are running the Microsoft 6.0 compiler as follows:

NON-WINDOWS

MODEL    \    MSC    _WINDOWS    M_I86TM    M_I86SM    M_I86MM    M_I86CM M_I86LM    _MSC_VER
-----------------------------------------------------------------------------
SMALL         +             -          -             +            -            -            -          600
MEDIUM     +             -          -             -            +            -            -          600
COMPACT      +             -          -             -            -            +            -          600
LARGE         +             -          -             -            -            -            +          600

WINDOWS

MODEL    \    MSC    _WINDOWS    M_I86TM    M_I86SM    M_I86MM    M_I86CM M_I86LM    _MSC_VER
-----------------------------------------------------------------------------
SMALL         -             +          -             +            -            -            -          600
MEDIUM     -             +          -             -            +            -            -          600
COMPACT      -             +          -             -            -            +            -          600
LARGE         -             +          -             -            -            -            +          600

These definitions are taken care of in 'port.h'
*/


/* if small or medium (tiny?) MS `C' model then define pointers as far */

#if USING_16_BIT_DOS

#if (defined(UFST_MSDOS) && !defined(_WINDOWS))
#define O_READFLAGS   O_BINARY | O_RDONLY
#define O_WRITEFLAGS  O_BINARY | O_WRONLY| O_CREAT

#if (defined(M_I86SM) || defined(M_I86MM) || defined(M_I86TM))
#define STRLEN    _fstrlen
#define STRCPY    _fstrcpy
#define STRNCPY   _fstrncpy
#define STRNCMP   _fstrncmp
#define STRCMP    _fstrcmp
#define MEMCPY    _fmemcpy
#define STRCAT    _fstrcat
#define OPEN       open
#define READF      MMread
#define LSEEK      lseek
#define WRITEF     MMwrite
#define CLOSE      close
#define SPRINTF    sprintf
#define QSORT     _fqsort
#define STRSTR    _fstrstr
#define MEMCMP    _fmemcmp
#define MEMSET    _fmemset
#else                              /* large model (all pointers are far) */
//#include <mem.h>
#define STRLEN     strlen
#define STRCPY     strcpy
#define STRNCPY    strncpy
#define STRNCMP    strncmp
#define STRCMP     strcmp
#define STRCAT     strcat
#define MEMCPY     memcpy
#define OPEN       open
#define READF      read
#define LSEEK      lseek
#define WRITEF     write
#define CLOSE      close
#define SPRINTF    sprintf
#define QSORT      qsort
#define STRSTR     strstr
#define MEMCMP     memcmp
#define MEMSET     memset
#endif    /* defined(M_I86SM) || defined(M_I86MM) || defined(M_I86TM) */

#else   /* defined(UFST_MSDOS) && !defined(_WINDOWS) */

#define O_READFLAGS   0    /* OF_READ  as defined in windows.h */
#define O_WRITEFLAGS  1    /* OF_WRITE */

#if (defined(M_I86LM))
#define STRNCPY   strncpy
#define STRNCMP   strncmp
#define MEMCPY    memcpy
#define QSORT     qsort
#define STRSTR    strstr
#define MEMCMP    memcmp
#define MEMSET    memset
#else /* WINDOWS, not large model */
#define STRNCPY   _fstrncpy
#define STRNCMP   _fstrncmp
#define MEMCPY    _fmemcpy
#define QSORT     _fqsort
#define STRSTR    _fstrstr
#define MEMCMP    _fmemcmp
#define MEMSET    _fmemset
#endif /* WINDOWS & M_I86LM */

/*
Windows, all models
*/
#define STRLEN     lstrlen
#define STRCPY     lstrcpy
#define STRCMP     lstrcmp
#define STRCAT     lstrcat
#define OPEN      _lopen
#define READF     _lread
#define LSEEK     _llseek
#define WRITEF    _lwrite
#define CLOSE     _lclose
#if defined (__BORLANDC__) /* add 6/11/92 - rs */
#define wsprintf   WSPRINTF
#endif /* __BORLANDC__ */
#define SPRINTF    wsprintf

#endif

#else        /* not USING_16_BIT_DOS, i.e. the code we actually use now...  */

#if defined (MSVC)
#define O_READFLAGS   O_BINARY | O_RDONLY
#define O_WRITEFLAGS  O_BINARY | O_WRONLY| O_CREAT
#elif defined (GCCx86)
#define O_READFLAGS   O_BINARY | O_RDONLY
#define O_WRITEFLAGS  O_BINARY | O_WRONLY| O_CREAT
#elif defined (__WATCOMC__)
#define O_READFLAGS   O_BINARY | O_RDONLY
#define O_WRITEFLAGS  O_BINARY | O_WRONLY| O_CREAT
#elif defined (__i960)
#define O_READFLAGS   O_BINARY | O_RDONLY
#define O_WRITEFLAGS  O_BINARY | O_WRONLY| O_CREAT
#elif defined (VXWORKS)
#define O_READFLAGS   O_RDONLY,0x644
#define O_WRITEFLAGS  WRITE
#else

/*** This default case won't work if your environment's file system has the 
Text/Binary distinction (e.g. Windows/DOS). If this is the case, you will need
to clone a new case using BINARY, to prevent premature end-of-read. ***/

#define O_READFLAGS   O_RDONLY           /* deleted O_BINARY  -ss 6/24/91   */
#define O_WRITEFLAGS  O_WRONLY | O_CREAT /* deleted O_BINARY  -ss 6/24/91   */
#endif    /* MSVC */

#if defined _AM29K   /* 2-7-94 jfd,dbk */
#define OPEN       _open
#define CLOSE      _close
#define LSEEK      _lseek
#define READF      _read
#else
#define OPEN       open
#define CLOSE      close
#define LSEEK      lseek    /* correct define from SEEK to LSEEK -ss 6/24/91 */
#define READF      read
#endif  /* AM29K*/

#define STRLEN     strlen
#define STRCPY     strcpy
#define STRNCPY    strncpy
#define STRNCMP    strncmp
#define STRCMP     strcmp
#define MEMCPY     memcpy
#define STRCAT     strcat
#define WRITEF     write
#define SPRINTF    sprintf
#define QSORT      qsort
#define STRSTR     strstr
#define MEMCMP     memcmp
#define MEMSET     memset

#endif        /* USING_16_BIT_DOS */

/* function prototypes for MSC  */

#if (USING_16_BIT_DOS && !defined(_WINDOWS))
#if (defined(M_I86SM) || defined(M_I86MM) || defined(M_I86TM))
#if (defined(_MSC_VER) && (_MSC_VER >= 600)) /* includes Borland */
/* nothing */
#else /* MSC 5.10, etc */
EXTERN SW16  _fstrlen(LPSB8);
EXTERN LPSB8 _fstrcpy(LPSB8, LPSB8);
EXTERN LPSB8 _fstrncpy(LPSB8, LPSB8, SW16);
EXTERN SW16  _fstrncmp(LPSB8, LPSB8, SW16);
EXTERN SW16  _fstrcmp(LPSB8, LPSB8);
EXTERN LPSB8 _fmemcpy(LPSB8, LPSB8, SW16);
EXTERN LPSB8 _fstrcat(LPSB8, LPSB8);
EXTERN LPSB8 _fstrstr(LPSB8, LPSB8);
EXTERN SW16  _fmemcmp(LPSB8, LPSB8, UW16);
EXTERN LPSB8 _fmemset(LPSB8, SB8, INTG);
#endif
EXTERN SW16   MMread(SW16, LPSB8, SW16);
EXTERN SW16   MMwrite(SW16, LPSB8, SW16);
#endif
#endif /* USING_16_BIT_DOS && !defined(_WINDOWS) */ 

/* Added ulongmemset() to handle sizes > 64K on system
   with 16 bit ints. - Mar 16, 2000                   */
#if defined( _OSK )

#ifdef MEMSET
#undef MEMSET
#endif
#define MEMSET _ulongmemset

#endif  /* _OSK */

#ifdef _WINDOWS
EXTERN SW16  far pascal lstrlen( LPSB8 );
EXTERN LPSB8 far pascal lstrcpy( LPSB8, LPSB8);
EXTERN LPSB8 far pascal lstrcat( LPSB8, LPSB8);
EXTERN INTG far pascal lstrcmp(LPSB8, LPSB8);   /* add 3/4/92 rs */
INTG  far pascal _lopen( SB8 far *, INTG );
SL32 far pascal _llseek( INTG, SL32, INTG );
SW16 far pascal _lread( INTG, SB8 far *, INTG );
INTG  far pascal _lclose( INTG );
SW16 far pascal _lwrite( INTG, SB8 far *, INTG );
INTG  far cdecl wsprintf(SB8 far *, SB8 far *,...);
#endif    /* _WINDOWS */

#if defined(_OS9000) && DISK_FONTS
/* just for compilation purposes...*/
#define O_RDONLY 0x0001
#endif

#if defined(AGFA_FS) && DISK_FONTS
#define O_RDONLY (1 << 0)
EXTERN INTG    open(FILECHAR *, INTG);
EXTERN INTG    close(INTG);
EXTERN SL32    lseek(INTG, SL32, INTG);
EXTERN INTG    read(INTG, VOID *, UINTG);
#else
#define    open(path, access)                    (-1)
#define    close(handle)                        (-1)
#define    lseek(handle, offset, fromwhere)    (-1)
#define    read(handle, buf, len)                (-1)
#endif

#endif    /* __MIXMODEL__ */
 

mmdebug.h     、、、、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
#ifndef __MMDEBUG__
#define __MMDEBUG__

#ifdef MMDECODE_DEBUG
GLOBAL_EXTERN FILE   *OUFILE;
#define GENERATE_STATEMENTS(statements) statements
#else
#define GENERATE_STATEMENTS(statements)  ;
#endif

#define MMDBG(user_text) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text))

#define MMDBG1(user_text,a1) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1))

#define MMDBG2(user_text,a1,a2) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2))

#define MMDBG3(user_text,a1,a2,a3) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3))

#define MMDBG4(user_text,a1,a2,a3,a4) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4))

#define MMDBG5(user_text,a1,a2,a3,a4,a5) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4,a5))

#define MMDBG6(user_text,a1,a2,a3,a4,a5,a6) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4,a5,a6))

#define MMDBG8(user_text,a1,a2,a3,a4,a5,a6,a7,a8) \
    GENERATE_STATEMENTS(if (mmdecode_trace_sw) fprintf(OUFILE, user_text,a1,a2,a3,a4,a5,a6,a7,a8))


#if defined(MMDECODE_DEBUG) || ( ( FCO_STANDALONE == 1 ) && defined(MERGER_ON) )
UB8 *
printIntellNodes( MODELTYPE *LBmodel, UB8 *local, SL32 *Ysyntell, SL32 *Xsyntell );
#endif

#endif    /* __MMDEBUG__ */
 

modes.h   、、、、、、、、、、、、、、、、、、、、、、、、、、

空文件

nzwind.c   、、、、、、、、、、、、、、、、、、、、、、、

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

/* $Header:   I:/BULL/URIP/RTS/BMP/NZWIND.C_V   1.38   Sep 09 2004 17:02:42   galejss  $ */
/* $Log:   I:/BULL/URIP/RTS/BMP/NZWIND.C_V  $ 
 * 
 *    Rev 1.38   Sep 09 2004 17:02:42   galejss
 * allocate temporary areas for FIX_CONTOURS and WINDCOMP from 3rd memory pool
 * 
 *    Rev 1.37   Jun 04 2004 15:33:18   GalejsS
 * 16-bit-fix in nz_open_run(); undo experimental TT_SCREENRES code
 * 
 *    Rev 1.36   Oct 17 2003 16:29:08   Galejs
 * reentrant fixes for NZ_WIND option
 * 
 *    Rev 1.35   Sep 25 2003 13:40:08   Joe
 * Replaced "memset" with "MEMSET".
 * Replaced "memcpy" with "MEMCPY".
 * 
 *    Rev 1.34   Aug 21 2003 16:47:48   Galejs
 * update copyright notice
 * 
 *    Rev 1.33   Jul 21 2003 17:16:00   Galejs
 * reentrancy / debugs fixes
 * 
 *    Rev 1.32   Jun 23 2003 14:41:00   Galejs
 * debug cleanup; VOID
 * 
 *    Rev 1.31   Sep 25 2002 14:39:40   Galejs
 * FIX_CONTOURS changes (bug # 73) (for awr)
 * 
 *    Rev 1.30   Sep 23 2002 15:26:56   Galejs
 * fix possibly-uninitialized-vbl warnings (part of bug # 76)
 * 
 *    Rev 1.29   Aug 15 2002 10:51:06   Joe
 * In nz_set_trans(), for !NATORDER case, change last
 * "chunkcount" test from default case to (chunkcount > 0)
 * to resolve stroke font stray lines bug.
 * 
 *    Rev 1.28   25 Jul 2001 16:37:08   JOE
 * In nz_set_trans(), resolved stray run bug (by swp).
 * 
 *    Rev 1.27   Jul 06 2001 15:21:32   Al
 * Added larger chunk sizes to fast fill
 * 
 *    Rev 1.26   Jun 14 2001 16:27:44   Al
 * Added fast fill
 * 
 *    Rev 1.25   Jun 11 2001 20:00:06   Galejs
 * use UFST types rather than SHORT, CHAR, etc
 * 
 *    Rev 1.24   May 09 2001 19:50:12   Galejs
 * data-type cleanup
 * 
 *    Rev 1.23   Apr 23 2001 15:58:28   Al
 * Fixed bug in contour checking code
 * 
 *    Rev 1.22   Apr 19 2001 16:05:48   Al
 * Added logic to detect badly wound contours
 * 
 *    Rev 1.21   Nov 09 2000 18:48:44   Galejs
 * fix reentrant build for WINDCOMP with CHARalloc()
 * 
 *    Rev 1.20   17 Mar 2000 11:51:36   JOE
 * Fixed comment (by ks).
 * 
 *    Rev 1.19   15 Feb 2000 10:21:54   AL
 * Hooked CHARalloc() into WINDCOMP's nzwinding code
 * 
 *    Rev 1.18   Feb 03 2000 16:08:22   galejs
 * remove use of "long" type
 * 
 *    Rev 1.17   03 Feb 2000 15:34:38   AL
 * Changed SWP799 to WINDCOMP
 * 
 *    Rev 1.16   04 Oct 1999 08:35:02   JOE
 * Conditionally compiled two functions based on GRAYSCALING (by swp).
 * 
 *    Rev 1.15   17 Sep 1999 08:44:42   JOE
 * Replaced all nzwinding code, enabled with SWP799 (by swp).
 * 
 *    Rev 1.14   23 Aug 1999 15:39:14   JOE
 * Removed 'size_t' cast - fixes truncation of int from 32 bit to 16 bit (ks).
 * 
 *    Rev 1.13   Aug 10 1999 15:12:08   galejs
 * include-file changes
 * 
 *    Rev 1.12   Jun 29 1999 14:28:56   galejs
 * add missing-pixel recovery code (experimental)
 * 
 *    Rev 1.11   21 Jan 1999 14:03:18   GALEJS
 * fix compiler warning (add CGBITMAP || GRAYSCALING condition)
 * 
 *    Rev 1.10   15 Jun 1998 17:02:08   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.9   02 Apr 1998 18:49:38   GALEJS
 * move externs to if_state
 * 
 *    Rev 1.8   24 Mar 1998 14:52:02   GALEJS
 * include-file changes
 * 
 *    Rev 1.7   22 Jan 1998 17:57:38   GALEJS
 * fix for GAGP/GAHP grayscale alignment modes
 * 
 *    Rev 1.6   09 Dec 1997 15:10:54   GALEJS
 * change special-case test from obsolete GASUB to GAPP
 * 
 *    Rev 1.5   24 Jul 1997 16:19:16   JOE
 * Removed two unreferenced local variables (by Jimmy).
 * 
 *    Rev 1.4   15 Jul 1997 15:06:24   GALEJS
 * fix bug in nz_set_trans() when CGBITMAP=off
 * 
 *    Rev 1.3   15 Jul 1997 12:34:58   AL
 * removed debug dump
 * 
 *    Rev 1.2   15 Jul 1997 12:25:30   AL 
 * Better error handling if too many tran runs
 * 
 *    Rev 1.1   23 Jun 1997 16:05:32   MIKE
 * Fixed 16-bit code warnings w/ (size_t) casts
 * 
 *    Rev 1.0   16 Jun 1997 15:19:50   AL
 * Initial revision.
 * This code broken off from raster.c to enable grayscaling with cgbitmap off.
 * 
*/
/* $Date:   Sep 09 2004 17:02:42  $ */


/*  Change History
 *
 *  16-Jun-97  awr  This code broken off from raster.c to enable grayscaling 
 *                  with cgbitmap off.
 *  23-Jun-97  mby  Fixed 16-bit code warning with (size_t) casts.
 *  15-Jul-97  awr  Better error handling if tran_run_ct is overflowed
 *  15-Jul-97  slg    Outlines-have-crossed case in nz_set_trans() wasn't quite
 *                    right when CGBITMAP=off    (if-then-else mismatch)
 *    09-Dec-97  slg    Change test of obsolete alignment mode (GASUB => GAPP)
 *    22-Jan-98  slg    Extend above test to GAGP & GAHP modes
 *    29-Jun-99  slg    Put Steven's missing-pixel-recovery code into nz_set_trans():
 *                    experimental, so only enabled if TT_SCREENRES set in cgconfig.h
 *  23-Aug-99  ks   Removed (size_t) cast - Fix truncation of int from 32 bit to 16 bit
 *     Jul-99  swp  replaced all nzwinding code, enabled with existance of SWP799
 *  03-Feb-00  awr  Changed SWP799 to WINDCOMP
 *  15-Feb-00  awr  Hooked CHARalloc() into WINDCOMP nzwinding code
 *  19-Apr-01  awr  Added check for badly wound contours in nz_set_trans()
 *  23-Apr-01  awr  Fixed bug in above.
 *  12-Sep-02  awr  FIX_CONTOUR changes for CHAR_SIZE
 */

#include "cgconfig.h"

#if NON_Z_WIND && (CGBITMAP || GRAYSCALING)    /* conditionally-compile entire file */

#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"

#ifdef WINDCOMP
/****************************************************************/
/****************************************************************/
/****************************************************************/

/* forward declaration */
VOID dump_trans(FILECHAR *, NZTRANS *);

/****************************************************************/
/* allocate a NZTRANS object with <num+1> slots */
NZTRANS *new_trans(FSP SW16 num)
{
    MEM_HANDLE htrans;
    NZTRANS *trans;
    SL32 i,n;

    n = sizeof(NZTRANS);
    htrans = TEMPCHARalloc(FSA n);
    if (0 == htrans)
        return 0;
    trans = (NZTRANS*)MEMptr(htrans);
    MEMSET(trans,0,n);
    trans->htrans = htrans;

    /* there are <num+1> slots: <0...num> -- only use <1..num> (I think) */
    trans->num = ++num;
    n = (SL32)num * sizeof(SL32);
    trans->hindices = TEMPCHARalloc(FSA n);
    if (0 == trans->hindices)
        {
        delete_trans(FSA trans);
        return 0;
        }
    trans->indices = (SL32*)MEMptr(trans->hindices);

    /* all slots initially unused */
    for (i=0; i<num; i++)
        trans->indices[i] = -1;

    /* start with 4 nodes per slot */
    n = (SL32)num << 2;
    trans->stop_index = n;
    trans->next_index = 0;
    trans->hnodes = TEMPCHARalloc(FSA n* sizeof(NZNODE));
    if (trans->hnodes == 0)
        {
        delete_trans(FSA trans);
        return 0;
        }
    trans->nodes = (NZNODE*)MEMptr(trans->hnodes);
    return trans;
}

/****************************************************************/
/* add a transition coordinate x to the y-th row */
/* nznodes are maintained in increasing order within a row */
UW16 add_trans(FSP NZTRANS *trans, FS_FIXED x, SW16 y)
{
    SL32 index,next;
    NZNODE *nodes = trans->nodes;

    /* starting index is */
    if (y<0 || y>=trans->num)
        {
        /* printf("add_trans: y=%d trans->num=%d\n",y,trans->num); */
        /*** might be more usefull to simply IGNORE this error ***/
        return SUCCESS;
        /*** return ERR_nz_bad_slot; ***/
        }
    index = trans->indices[y];

    /* out of NZNODES?  ... get more */
    if (trans->next_index == trans->stop_index)
        {
        MEM_HANDLE h;
        trans->stop_index += trans->num;
        h = TEMPCHARalloc(FSA sizeof(NZNODE)*trans->stop_index);
        if (0 == h)
            {
            /***/ /* printf("add_trans: reallocation failed\n"); */
            return ERR_nz_realloc;
            }
        nodes = (NZNODE*)MEMptr(h);
        MEMCPY(nodes, trans->nodes, trans->next_index* sizeof(NZNODE));
        TEMPCHARfree(FSA trans->hnodes);
        trans->hnodes = h;
        trans->nodes = nodes;
        }

    /* add the element to the list */
    if (index<0 || nodes[index].x > x)
        {
        /* prepend new node to list, store new head */
        nodes[trans->next_index].x = x;
        nodes[trans->next_index].next = index;
        trans->indices[y] = trans->next_index++;
        }
    else
        {
        /* move to the proper <index> */
        while ((next=nodes[index].next) >= 0 && nodes[next].x <= x)
            index = next;

        /* insert new node after <index> */
        nodes[index].next = trans->next_index;
        nodes[trans->next_index].x = x;
        nodes[trans->next_index].next = next;
        trans->next_index++;
        }

    return SUCCESS;
}

/****************************************************************/
VOID delete_trans(FSP NZTRANS *trans)
{
    if (trans)
        {
        TEMPCHARfree(FSA trans->hindices);
        TEMPCHARfree(FSA trans->hnodes);
        TEMPCHARfree(FSA trans->htrans);
        trans = 0;
        }
}
/****************************************************************/
/* print the TRANS in ASCII */
#if 0
VOID dump_trans(FILECHAR *s, NZTRANS *trans)
{
    SL32 i,index,x;

    printf("dump_trans: %s\n",s);
    printf("next_index=%d stop_index=%d num=%d\n",trans->next_index, trans->stop_index, trans->num);

    for (i=0; i<trans->num; i++)
        {
        printf("%d:",i);
        index = trans->indices[i];
        while (index >= 0)
            {
            x = trans->nodes[index].x;
            printf("%c%f ",(x & 1)?'U':'D',(x >> 1) / 65536.0);
            index = trans->nodes[index].next;
            }
        printf("\n");
        }
    fflush(stdout);
}
#endif
/****************************************************************/
#if GRAYSCALING
/* grab a row of transitions, send off to the GRAY machinery */
static VOID grab_trans_i(FSP SW16 i)
{
    NZTRANS *trans = if_state.ras.trans;
    NZNODE  *nodes = trans->nodes;
    SL32    *indices = trans->indices;
    SL32 winding = 0;
    SL32 index;
    FS_FIXED t,x0,x1;
    SW16 on,off,num,*p;

    index = indices[i];
    num = 0;
    p = (SW16 *) &if_state.grayfilter.transition;

    while (index >= 0)
        {
        x0 = x1 = 0x7FFFFFFF;
        if (if_state.non_z_wind)
            {
            /* get the nzw pair */
            while (winding==0 && index>=0)
                {
                t = nodes[index].x;
                index = nodes[index].next;
                x0 = t >> 1;
                winding += (t & 1) ? 1 : -1;
                }
            while (winding!=0 && index>=0)
                {
                t = nodes[index].x;
                index = nodes[index].next;
                x1 = t >> 1;
                winding += (t & 1) ? 1 : -1;
                }
            }
        else 
            {
            /* get the parity pair */
            x0 = nodes[index].x >> 1;
            index = nodes[index].next;
            if (index >= 0)
                {
                x1 = nodes[index].x >> 1;
                index = nodes[index].next;
                }
            }

        /* add a matched pair of integer subpixels */
        if (x0 != 0x7FFFFFFF && x1 != 0x7FFFFFFF)
            {
            /* round to nearest int */
            on = (x0 + 0x00008000) >> 16;    
            off = (x1 + 0x00008000) >> 16;

            /* crude dropout protection */
            if (on==off)
                {
                if (on>0)
                    on--;
                else
                    off++;
                }

            *p++ = on;
            *p++ = off;
            num+=2;
            }
        }

    /* hand them off to GRAY machinery */
    if_state.grayfilter.numtrans = num;
    gs_endsubrast(FSA &if_state.grayfilter);
}
/****************************************************************/
/* package transitions for GRAY machinery */
VOID grab_trans(FSP0)
{
    SW16 row,a = if_state.grayfilter.alignment;
    NZTRANS *trans = if_state.ras.trans;

    /*** again ... don't seem to use row 0 ??? ***/
    if (a==GAPP || a==GAGP || a==GAHP)
        row = 1;
    else
        row = 1+if_state.grayfilter.startoffset.y;

    for (/**/; row < trans->num; row++)
        grab_trans_i(FSA row);

    /* we're done with this now */
    delete_trans(FSA if_state.ras.trans);
}
#endif /* GRAYSCALING */
/****************************************************************/
/****************************************************************/
/****************************************************************/
#else /* ! WINDCOMP */

/*==================================================================*/
/*                     Non zero winding                             */


#if CGBITMAP
#define    nz_raster_bot_row()    if_state.ras.toff =  if_state.ras.tsize - (SL32)if_state.ras.bmdim.x;
                                   /* bottom row in bitmap */
#define    nz_raster_next_row()   if_state.ras.toff -= if_state.ras.bmdim.x;
#endif

#ifdef LINT_ARGS
#if NZ_DUMP
MLOCAL VOID nz_dump_list(FSP PNZ_NODE);
#endif

MLOCAL UW16 analyzeContours( FSP PNZ_INSTANCE nz );
MLOCAL VOID nz_insert_pending( FSP PNZ_NODE, PNZ_NODE);
MLOCAL VOID nz_insert_active(FSP PNZ_NODE, PNZ_NODE);
MLOCAL VOID nz_sort(FSP PNZ_NODE);
#else
#if NZ_DUMP
MLOCAL VOID nz_dump_list();
#endif
MLOCAL UW16 analyzeContours( );
MLOCAL VOID nz_insert_pending( );
MLOCAL VOID nz_insert_active();
MLOCAL VOID nz_sort();
#endif

#if GRAYSCALING
#define writetran(xx)  if(if_state.grayfilter.numtrans >= MAXTRANS) \
                           if_state.grayfilter.error = TRUE;        \
                       else                                \
                           if_state.grayfilter.transition[if_state.grayfilter.numtrans++] = xx;
#endif  /* GRAYSCALING */

#if NZ_DUMP
#if defined (ANSI_DEFS)
MLOCAL VOID nz_dump_list( FSP PNZ_NODE list )
#else
MLOCAL VOID nz_dump_list( list )
PNZ_NODE list;
#endif
{
    PNZ_NODE  p;
    PNZCOUNTER  pv;
    NZCOUNTER   i,j;

    DBG("nz_dump_list()\n");

    for(j=0; j<if_state.ras.nz_instance.cur_node; j++)
    {
        p = &if_state.ras.nz_instance.nodes[j];
        DBG1("%d  -------next NZ_NODE--------\n", j);
        DBG1("Node address: %lx\n", p);
#if FIX_CONTOURS
        DBG1("Contour   %d\n", p->contourNum);
#endif
        DBG1("lowRow    %d\n", p->lowRow);
        DBG1("onoff     %d\n", p->onoff);
        DBG1("valCount  %d\n", p->valCount);
        pv = p->pval;
        DBG1("value list address: %lx\n", pv);
        for(i=0; i<p->valCount; i++)
        {
            DBG1("    %d\n", *pv++);
        }
        p = p->link;
    }
}
#endif
/*-------------------*/
/*      nz_init      */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID nz_init( FSP PNZ_INSTANCE nz, LPUB8 nzw_buf,
                   NZCOUNTER tran_run_ct, SW16 blackdepth)
#else
GLOBAL VOID nz_init( nz, nzw_buf, tran_run_ct, blackdepth )
PNZ_INSTANCE nz;
LPUB8 nzw_buf;
NZCOUNTER tran_run_ct;
SW16 blackdepth;
#endif
{
    DBG("nz_init()\n");

    nz->nodes    = (PNZ_NODE)nzw_buf;
    nz->transition = (PNZCOUNTER)(&nz->nodes[tran_run_ct]); /* transition row buffer */
    nz->pvalues = &nz->transition[tran_run_ct];
    nz->tran_run_ct = tran_run_ct;
    nz->blackdepth  = blackdepth;
    nz->cur_node = 0;
    nz->pend_list.link = NULL;
    nz->overflow = 0;
    nz->done = 0;
#if FIX_CONTOURS
    nz->contourNum = 0;  /* For contour winding check to know what contour this run belongs to. */
#endif
}
/*-------------------*/
/* nz_insert_pending */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL VOID nz_insert_pending ( FSP PNZ_NODE list, PNZ_NODE p )
#else
MLOCAL VOID nz_insert_pending( list, p )
PNZ_NODE list;
PNZ_NODE p;
#endif
{
    PNZ_NODE pprev, pnext;
    NZCOUNTER  lowRow;

    DBG("nz_insert_pending()\n");

    lowRow = p->lowRow;
    pprev = list;
    pnext = pprev->link;

    while(pnext)
    {
        if(lowRow <= pnext->lowRow) break;
        pprev = pnext;
        pnext = pprev->link;
    }

    p->link     = pnext;    /* link p after pprev */
    pprev->link = p;
}
/*-------------------*/
/*    nz_open_run   */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID nz_open_run( PNZ_INSTANCE nz, NZCOUNTER start_row , SL32 ydir )
#else
GLOBAL VOID nz_open_run ( nz, start_row, ydir )
    PNZ_INSTANCE nz;
    NZCOUNTER start_row;
    SL32 ydir;
#endif
{
    nz->start_row = start_row;

    if ( nz->cur_node >= nz->tran_run_ct )
    {
      /* Arm for potential error. We've already produced as many tran runs
         as we allocated. We can still fool around a bit with non
         transition producing curve elements... but if we do produce
         transitions (detecteed at nz_close_run()) then we throw the error
      */
        nz->done = 1;  /* any more transitions set will flag error */
        /* overwrite last node if we overflow */
        nz->cur_node = nz->tran_run_ct - 1;
    }

    nz->valCount = 0;
    nz->pval = nz->pvalues + (UL32)((UL32)nz->cur_node * (UL32)nz->blackdepth);
    if ( ydir == -1 )  /* going down; point at end of array */
        nz->pval += nz->blackdepth - 1;
}
/*-------------------*/
/*    nz_close_run   */
/*-------------------*/
/*  Scan conversion has changed y direction.
 *
 *  Close out current run of transitions (if any) by creating an NZ_NODE
 *  to hold the just written transitions and link this new NZ_NODE into
 *  the list of pending transition lists.
 */
#if defined (ANSI_DEFS)
GLOBAL VOID nz_close_run ( FSP PNZ_INSTANCE nz, SL32 newydir, BOOLEAN beam )
#else
GLOBAL VOID nz_close_run ( nz, newydir, beam )
    PNZ_INSTANCE nz;
    SL32 newydir;
    BOOLEAN beam;
#endif
{
    PNZ_NODE  pnew;

    DBG("nz_close_run()\n");

    if ( !nz->valCount )      /* haven't written any transitions yet */
    {
        DBG("   no transitions written-  no node created\n");

        /*  We changed direction without writing any transitions. */
        nz->start_row += newydir;
        nz->pval -= newydir * (nz->blackdepth - 1); /* pt to other end */
        return;
    }
    /* else we have produced transitions. */

    /*  Close off current NZ_NODE  */

    pnew = &nz->nodes[nz->cur_node];
    pnew->valCount = nz->valCount;

    if(beam)   pnew->onoff = -1;   /* we were making OFF trans */
    else           pnew->onoff = 1;   /* we were making ON trans */

    if ( newydir == 1 )  /* already changed- we were going down */
    {
        nz->start_row -= nz->valCount - 1;
        pnew->lowRow = nz->start_row;
        pnew->pval = nz->pval + 1;
    }
    else   /* We were going up */
    {
        pnew->lowRow = nz->start_row;
        nz->start_row += nz->valCount - 1;
        pnew->pval = nz->pval - nz->valCount;
    }
    DBG4("Node %d  onoff = %d  lowRow = %d   valCount = %d\n",
         nz->cur_node, pnew->onoff,   pnew->lowRow,  pnew->valCount);

#if FIX_CONTOURS
    pnew->contourNum = nz->contourNum;
    pnew->right = pnew->wrong = 0;
#endif
    /*  Link new node into the list; list is sorted by nz_start_row */
    if ( nz->done )
    {
        nz->overflow = 1;   /* we made an extra transition run */
        DBG("  overflow is set\n");
    }
    else
        nz_insert_pending ( FSA &nz->pend_list, pnew );

    nz->cur_node++;   /* set up for next node */
    nz_open_run ( nz, nz->start_row , newydir );
}
/*-------------------*/
/* nz_insert_active  */
/*-------------------*/
/*  Insert node p into list maintining sort from low to high
 *  of *pval
 */
#if defined (ANSI_DEFS)
MLOCAL VOID nz_insert_active ( FSP PNZ_NODE list, PNZ_NODE p )
#else
MLOCAL VOID nz_insert_active ( list, p )
PNZ_NODE list;
PNZ_NODE p;
#endif
{
    PNZ_NODE pprev, pnext;
    NZCOUNTER val;

    DBG("nz_insert_active()\n");

    val = *(p->pval);
    pprev = list;
    pnext = pprev->link;

    while(pnext)
    {
        if(val <= *(pnext->pval)) break;
        pprev = pnext;
        pnext = pprev->link;
    }

    p->link     = pnext;    /* link p after pprev */
    pprev->link = p;
}
/*-------------------*/
/*     nz_sort       */
/*-------------------*/
/*  Sort list on *pval fields low to high */
#if defined (ANSI_DEFS)
MLOCAL VOID nz_sort( FSP PNZ_NODE activelist )
#else
MLOCAL VOID nz_sort( activelist )
PNZ_NODE activelist;
#endif
{
    PNZ_NODE pcur, pnext;

    DBG("nz_sort()\n");

    pcur = activelist->link;
    activelist->link = NULL;

    while(pcur)
    {
        pnext = pcur->link;
        nz_insert_active ( FSA activelist, pcur );
        pcur = pnext;
    }    
}


#if CGBITMAP

#if NATORDER
#if LEFT_TO_RIGHT_BIT_ORDER
CONST UB8 Lbits[8] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01};
CONST UB8 Rbits[8] = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF};
#else
CONST UB8 Lbits[8] = {0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80};
CONST UB8 Rbits[8] = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
#endif
#else /* not NATORDER, we need to process the chunks */
#if RASTER_ORG == SIXTEEN_BIT_CHUNK
#if LEFT_TO_RIGHT_BIT_ORDER
CONST UW16 Lbits[16] = {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF, 0x0FFF, 0x07FF, 0x03FF, 0x01FF,
                        0x00FF, 0x007F, 0x003F, 0x001F, 0x000F, 0x0007, 0x0003, 0x0001};
CONST UW16 Rbits[16] = {0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00,
                        0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF};
#else
CONST UW16 Lbits[16] = {0xFFFF, 0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, 0xFFE0, 0xFFC0, 0xFF80,
                        0xFF00, 0xFE00, 0xFC00, 0xF800, 0xF000, 0xE000, 0xC000, 0x8000};
CONST UW16 Rbits[16] = {0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
                       0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
#endif
#endif
#if RASTER_ORG == THIRTYTWO_BIT_CHUNK
#if LEFT_TO_RIGHT_BIT_ORDER
CONST UL32 Lbits[32] = {0xFFFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x1FFFFFFF,
                        0x0FFFFFFF, 0x07FFFFFF, 0x03FFFFFF, 0x01FFFFFF,
                        0x00FFFFFF, 0x007FFFFF, 0x003FFFFF, 0x001FFFFF,
                        0x000FFFFF, 0x0007FFFF, 0x0003FFFF, 0x0001FFFF,
                        0x0000FFFF, 0x00007FFF, 0x00003FFF, 0x00001FFF,
                        0x00000FFF, 0x000007FF, 0x000003FF, 0x000001FF,
                        0x000000FF, 0x0000007F, 0x0000003F, 0x0000001F,
                        0x0000000F, 0x00000007, 0x00000003, 0x00000001};
CONST UL32 Rbits[32] = {0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,
                        0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,
                        0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,
                        0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,
                        0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
                        0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,
                        0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,
                        0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF};
#else
CONST UL32 Lbits[32] = {0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
                        0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
                        0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
                        0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
                        0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
                        0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
                        0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
                        0xF0000000, 0xE0000000, 0xC0000000, 0x80000000};
CONST UW16 Rbits[32] = {0x00000001, 0x00000003, 0x00000007, 0x0000000F,
                        0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
                        0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
                        0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
                        0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
                        0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
                        0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
                        0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF};
#endif
#endif
#endif /* not NATORDER */

#endif /* CGBITMAP */


/*-------------------*/
/*   nz_set_trans    */
/*-------------------*/
/*  Set simple, even-odd transitions in the transition array according
 *  to the transition list.
 */
#if defined (ANSI_DEFS)
GLOBAL UW16 nz_set_trans( FSP PNZ_INSTANCE nz )
#else
GLOBAL UW16 nz_set_trans( nz )
PNZ_INSTANCE nz;
#endif
{
    PNZ_NODE   pprev, pnext;
    NZCOUNTER  row=0, hirow=0, pendRow, onCount, val, prevVal, beamIsOn;
    SW16 isgray;
#if CGBITMAP
    INTG tranct=0;
#endif

    DBG("nz_set_trans()\n");
#if NZ_DUMP
    nz_dump_list(FSA &nz->pend_list);
#endif
#if FIX_CONTOURS
    if(if_state.ras.nz_instance.checkingContours)
        return checkContours(FSA nz);
#endif
    if(nz->overflow) return ERRnzw_mem_overflow;

    isgray = FC_ISGRAY(&if_state.cur_loc_fc);

    /* Set starting row and hi row --------------------------------*/
#if GRAYSCALING
    if(isgray)
    {
        if_state.grayfilter.numtrans = 0;

/* following test is OBSOLETE - needs to be updated for new alignment modes */
/*         if(if_state.grayfilter.alignment == GASUB) */

/* the following three cases are NECESSARY (otherwise, lots of extraneous 
lines/gaps in glyphs with those alignment modes) - however, there still might 
be other cases that need special treatment... (Sandra, 22 Jan 98) */

        if((if_state.grayfilter.alignment == GAPP) ||
            (if_state.grayfilter.alignment == GAGP) ||
            (if_state.grayfilter.alignment == GAHP))
            row = 0;
        else
            row = if_state.grayfilter.startoffset.y;
        hirow = row + nz->blackdepth;
    }
#endif
#if CGBITMAP
    if(!isgray)
    {
        nz_raster_bot_row();                 /* bottom row in bitmap */
        row = 0;
        hirow = nz->blackdepth;
        tranct = 0;  /* for fast fill */
    }
#endif

    nz->active_list.link = NULL;
    pnext = nz->pend_list.link;
    if(!pnext) return SUCCESS;   /* no transitions produced */
    pendRow = pnext->lowRow;

    for( ; row < hirow ; row++)
    {
        DBG1 ("\nrow: %d\n", row);
        /*  Add any pending nodes ------------------------------------*/
        if(pendRow <= row)
        {
            pprev = &nz->pend_list;
            pnext = nz->pend_list.link;
            while(pnext)
            {
                pendRow = pnext->lowRow;
                if(pendRow <= row)
                {
                    pprev->link = pnext->link; /* remove from pending list */
                    nz_insert_active ( FSA &nz->active_list, pnext);
                    pnext = pprev->link;
                }
                else
                    break;
            }
            if(!pnext) pendRow = 32767;
        }
        /*  Set transitions -----------------------------------------*/
settrans:
        beamIsOn = 0;
        pnext = nz->active_list.link;
        if(pnext)
        {
            prevVal = *(pnext->pval);
            onCount = pnext->onoff;
            pnext   = pnext->link;
            
            while(pnext)
            {
                val = *(pnext->pval);
                if(val < prevVal)
                {
                    /* Outlines have crossed, re-sort, and clear bitmap row */
                    nz_sort( FSA &nz->active_list );
#if GRAYSCALING
                    if(isgray)
                    {
                        if_state.grayfilter.numtrans = 0;
                    }
#endif
#if CGBITMAP
                    if(!isgray)
                    {
                        MEMSET(if_state.ras.tran_buffer+if_state.ras.toff, (INTG)0, (INTG)if_state.ras.bmdim.x);
                        tranct = 0;  /* for fast fill */
                    }
#endif
                    goto settrans;   /* try again */
                }
/**** #if TT_SCREENRES ***/
/*** not a good idea after all - delete before 4.7 release ***/
                /*** swp - missing-pixel recovery (experimental) ***/
                /*** part 2 of change is in graymap.c ***/
/***                else if(val >= prevVal)    ***/
/*** #else ***/
                else if(val > prevVal)
/*** #endif ***/
                {
                    if((beamIsOn && onCount == 0) || (!beamIsOn && onCount !=  0))
                    {
#if GRAYSCALING  /* 10-27-95, mby */
                        if(isgray)
                        {
                            writetran ( prevVal );
                        }
#endif
#if CGBITMAP
                        if(!isgray)
                            nz->transition[tranct++] = prevVal;
#endif
                        beamIsOn = 1 - beamIsOn;
                    }
                    
                    prevVal = val;
                }
                onCount += pnext->onoff;
                pnext = pnext->link;
            }  /*  for each NZ_NODE in the active list  */
            if((beamIsOn && onCount == 0) || (!beamIsOn && onCount != 0))
            {
#if GRAYSCALING  /* 10-27-95, mby */
                if(isgray)
                {
                    writetran ( prevVal );
                }
#endif
#if CGBITMAP
                if(!isgray)
                    nz->transition[tranct++] = prevVal;
#endif
            }
        } /* endif (pnext) */

#if GRAYSCALING
        if(isgray)
        {
            UW16 status = gs_endsubrast(FSA &if_state.grayfilter);
            if(status)
                return status;
        }
#endif
#if CGBITMAP
        if(!isgray)
        {
            INTG i;
            
            /* Write a row of pixels in the output bitmap */
            if(tranct & 1) /* gotta have an even number of pixels */
                return ERR_odd_transitions;
#if NATORDER
            {
                UB8 *rasStart, *p;
                rasStart = if_state.ras.tran_buffer+if_state.ras.toff;
                for(i=0; i<tranct;)
                {
                    INTG c0, c1, byte0, ct;
                    c0 = nz->transition[i++];       /* first bit on */
                    c1 = nz->transition[i++] - 1;   /* last bit on */

                    byte0 = c0 >> 3;
                    p = rasStart + byte0;       /* point to 1st changed byte */
                    ct = (c1>>3) - byte0 + 1;   /* number of bytes to change */
                    if(ct>2)
                    {
                        *p++ |= Lbits[c0 & 7];
                        MEMSET(p, 0xff, ct-2);
                        *(p+ct-2) |= Rbits[c1 & 7];
                    }
                    else if(ct>1)
                    {
                        *p++ |= Lbits[c0 & 7];
                        *p   |= Rbits[c1 & 7];
                    }
                    else if (ct > 0)
                        *p |= Lbits[c0 & 7] & Rbits[c1 & 7];
                }
            }
#else
            {
                LPCHUNK rasStart, p;
                rasStart = (LPCHUNK)(if_state.ras.tran_buffer+if_state.ras.toff);
                for(i=0; i<tranct;)
                {
                    INTG c0, c1, chunk0, chunkcount;

                    c0 = nz->transition[i++];       /* first bit on */
                    c1 = nz->transition[i++] - 1;   /* last bit on */
                    chunk0 = c0 >> CHUNK_SHIFT;
                    p = rasStart + chunk0;                /* point to 1st changed chunk */
                    chunkcount = (c1>>CHUNK_SHIFT) - chunk0 + 1; /* number of chunks to change */
                    
                    if(chunkcount>2)
                    {
                        *p++ |= Lbits[c0 & CHUNK_MASK];
                        MEMSET((UB8*)p, 0xff, (chunkcount-2)<<(CHUNK_SHIFT-3));
                        *(p+chunkcount-2) |= Rbits[c1 & CHUNK_MASK];
                    }
                    else if(chunkcount>1)
                    {
                        *p++ |= Lbits[c0 & CHUNK_MASK];
                        *p   |= Rbits[c1 & CHUNK_MASK];
                    }
                    else if (chunkcount > 0)
                        *p |= Lbits[c0 & CHUNK_MASK] & Rbits[c1 & CHUNK_MASK];
                }
            }
#endif
            tranct = 0;
            /*  move to next raster line in transition buffer  */
            nz_raster_next_row();
        }
#endif

        /*  Bump list to next row --------------------------------*/
        pprev = &nz->active_list;
        pnext = pprev->link;
        while(pnext)
        {
            if(--(pnext->valCount))   /* if any transitions left  */
            {
                pnext->pval++;   /* bump to next transition value */
                pprev = pnext;
            }
            else
                pprev->link = pnext->link;   /*  remove from active list */

            pnext = pprev->link;
        }
    }   /* for(each raster row of the bitmap */
#if FIX_CONTOURS
    if(if_state.ras.nz_instance.isWrong)    /* not NULL means 2nd time, need to free */
    {
        TEMPCHARfree(FSA if_state.ras.nz_instance.hisWrong);
        if_state.ras.nz_instance.isWrong = NULL;
        if_state.ras.nz_instance.hisWrong = NIL_MH;
    }

#endif
    return SUCCESS;
}


#if FIX_CONTOURS
/*-------------------*/
/*  analyzeContours  */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 analyzeContours( FSP PNZ_INSTANCE nz )
#else
MLOCAL UW16 analyzeContours( nz )
PNZ_INSTANCE nz;
#endif
{
    SL32 wrong, right;
    PNZ_NODE   node;
    SW16 numContours, curCn, i;

    DBG("\nanalyzeContours\n");
    /* Allocate array of flags indicating if a contour is wound wrong. */
    numContours = nz->contourNum + 1;
    nz->hisWrong = TEMPCHARalloc(FSA numContours);
    if(nz->hisWrong == NIL_MH)
        return ERRmem;
    nz->isWrong = (LPUB8)MEMptr(nz->hisWrong);
    /* Go through all the nzw nodes and add up how many transitions were right and wrong
     * Based on this "vote" set the isWrong flags. The reason we have to vote is that
     * little loops caused by emboldening or hint processing can cause some of the
     * contours in a transition run to be right and some to be wrong. The fact that these
     * loops are little means that they will not contribute much to the vote.
     */
    node = nz->nodes;
    curCn = 0;
    wrong = right = 0;
    for(i=0; i<nz->cur_node; i++)
    {
        /* Note that all nzw runs from a single contour are consecutive in nz->nodes. */
        if(node[i].contourNum !=curCn)
        {
            DBG3("contourNum  %d    right  %ld   wrong   %ld\n", curCn, right, wrong);
            nz->isWrong[curCn] = wrong>right?1:0;
            curCn = node[i].contourNum;
            wrong = right = 0;
        }
        wrong += node[i].wrong;
        right += node[i].right;
    }
    nz->isWrong[curCn] = wrong>right?1:0;
    return SUCCESS;
}
/*-------------------*/
/*   checkContours   */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  checkContours( FSP PNZ_INSTANCE nz )
#else
GLOBAL UW16  checkContours( nz )
PNZ_INSTANCE nz;
#endif
{
    PNZ_NODE   pprev, pnext;
    NZCOUNTER  row, hirow, pendRow, onCount, val, prevVal, beamIsOn;
    UW16 status;

    DBG("nz_set_trans()\n");

    if(nz->overflow) return ERRnzw_mem_overflow;

    /* Set starting row and hi row --------------------------------*/
#if CGBITMAP
    nz_raster_bot_row();                 /* bottom row in bitmap */
    row = 0;
    hirow = nz->blackdepth;
#endif

    nz->active_list.link = NULL;
    pnext = nz->pend_list.link;
    if(!pnext) return SUCCESS;   /* no transitions produced */
    pendRow = pnext->lowRow;

    for( ; row < hirow ; row++)
    {
        DBG1 ("\nrow: %d\n", row);
        /*  Add any pending nodes ------------------------------------*/
        if(pendRow <= row)
        {
            pprev = &nz->pend_list;
            pnext = nz->pend_list.link;
            while(pnext)
            {
                pendRow = pnext->lowRow;
                if(pendRow <= row)
                {
                    pprev->link = pnext->link; /* remove from pending list */
                    nz_insert_active ( FSA &nz->active_list, pnext);
                    pnext = pprev->link;
                }
                else
                    break;
            }
            if(!pnext) pendRow = 32767;
        }
        /*  Set transitions -----------------------------------------*/
settrans:
        beamIsOn = 0;
        pnext = nz->active_list.link;
        if(pnext)
        {
            prevVal = *(pnext->pval);
            onCount = pnext->onoff;
            pprev   = pnext;
            pnext   = pnext->link;

            if(if_state.ras.nz_instance.checkingContours)
            {
                while(pnext)
                {
                    val = *(pnext->pval);
                    if(val < prevVal)
                    {
                        /* Outlines have crossed, re-sort, and clear bitmap row */
                        nz_sort( FSA &nz->active_list );
                        goto settrans;   /* try again */
                    }
                    else if(val > prevVal)
                    {
                        if(beamIsOn && onCount == 0)
                        {
                            /* Writing an off transition */
                            if(pprev->onoff == 1)
                                pprev->wrong++;
                            else
                                pprev->right++;
                            beamIsOn = 1 - beamIsOn;
                        }
                        if(!beamIsOn && onCount !=  0)
                        {
                            /* Writing an on transition */
                            if(pprev->onoff == 1)
                                pprev->right++;
                            else
                                pprev->wrong++;

                            beamIsOn = 1 - beamIsOn;
                        }
                        
                        prevVal = val;
                    }
                    onCount += pnext->onoff;
                    pprev = pnext;
                    pnext = pnext->link;
                }  /*  for each NZ_NODE in the active list  */
                if(beamIsOn && onCount == 0)
                {
                    if(pprev->onoff == 1)
                        pprev->wrong++;
                    else
                        pprev->right++;
                }
                if(!beamIsOn && onCount !=0)
                {
                    if(pprev->onoff == 1)
                        pprev->right++;
                    else
                        pprev->wrong++;
                }
            }
        } /* endif (pnext) */

        /*  Bump list to next row --------------------------------*/
        pprev = &nz->active_list;
        pnext = pprev->link;
        while(pnext)
        {
            if(--(pnext->valCount))   /* if any transitions left  */
            {
                pnext->pval++;   /* bump to next transition value */
                pprev = pnext;
            }
            else
                pprev->link = pnext->link;   /*  remove from active list */

            pnext = pprev->link;
        }
    }   /* for(each raster row of the bitmap */
    status = analyzeContours(FSA nz);
    if(status)
        return status;
    else
        return ERR_nz_contours_wrong;
}
#endif /* FIX_CONTOURS */
#endif /* WINDCOMP */
#endif    /* NON_Z_WIND && (CGBITMAP || GRAYSCALING) */

outdata.txt     、、、、、、、、、、、、、、、、、、、、、、、、、、

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

/* $Header:   I:/BULL/URIP/RTS/OUT/OUTDATA.C_V   1.46   Dec 15 2004 12:22:42   galejss  $ */
/* $Log:   I:/BULL/URIP/RTS/OUT/OUTDATA.C_V  $ 
 * 
 *    Rev 1.46   Dec 15 2004 12:22:42   galejss
 * make all DBG calls 16-bit-compatible
 * 
 *    Rev 1.45   Sep 27 2004 15:16:22   galejss
 * "hisWrong" now allocated from NEW_POOL - needs TEMPCHARfree()
 * 
 *    Rev 1.44   Oct 09 2003 13:22:54   IndrelR
 * Changes for Vertical Writing .
 * 
 *    Rev 1.43   Oct 09 2003 13:21:26   IndrelR
 *  
 * 
 *    Rev 1.42   Aug 22 2003 09:09:58   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.41   Aug 13 2003 15:42:54   LynchR
 * Added error checking for memory allocation.
 * 
 *    Rev 1.40   Jul 21 2003 18:24:16   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.39   Jun 23 2003 14:59:40   Galejs
 * ufstport.h
 * 
 *    Rev 1.38   Dec 02 2002 18:05:50   Galejs
 * cast all calls to MEMptr()
 * 
 *    Rev 1.37   Sep 27 2002 18:33:50   Doolittl
 * Changes for TT_SCREENRES to return fractional pixel advance information.
 * 
 *    Rev 1.36   Sep 25 2002 15:32:20   Galejs
 * FIX_CONTOURS changes (bug # 73) (for awr)
 * 
 *    Rev 1.35   04 Jun 2001 10:12:44   JOE
 * 
 * OpenType changes.
 * 
 *    Rev 1.34   Nov 28 2000 18:31:46   Galejs
 * remove code for obsolete PST1 option
 * 
 *    Rev 1.33   Mar 22 2000 15:26:26   galejs
 * vertical-writing changes (for keb)
 * 
 *    Rev 1.32   Aug 09 1999 18:37:18   galejs
 * include-file changes
 * 
 *    Rev 1.31   29 Jul 1999 17:11:24   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.30   21 Jan 1999 17:04:26   GALEJS
 * standardize #include tests
 * 
 *    Rev 1.29   19 Jan 1999 18:39:16   GALEJS
 * LONGALIGN macro needs to handle 64-bit pointers correctly
 * 
 *    Rev 1.28   12 Jan 1999 17:34:48   GALEJS
 * use CONST for read-only data; move EXTERN dcls
 * 
 *    Rev 1.27   02 Sep 1998 17:30:44   GALEJS
 * "olcubeto" element of OUT_TBL not conditional on CUBIC now
 * 
 *    Rev 1.26   13 Aug 1998 15:10:02   GALEJS
 * undo my mistake
 * 
 *    Rev 1.24   22 Jun 1998 18:42:24   GALEJS
 * make Outline fully reentrant
 * 
 *    Rev 1.23   15 Jun 1998 11:12:16   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.22   16 Apr 1998 18:42:36   GALEJS
 * oops - put back q3.h include
 * 
 *    Rev 1.21   02 Apr 1998 19:24:00   GALEJS
 * move GLOBAL odata structure to IF_STATE
 * 
 *    Rev 1.20   25 Mar 1998 14:57:08   JOE
 * In odifbb(), changed reference to "origin.x" and "origin.y" to
 * "origin_cs.x" and "origin_cs.y" respectively.
 * 
 *    Rev 1.19   24 Mar 1998 16:55:14   GALEJS
 * include-file changes
 * 
 *    Rev 1.18   24 Mar 1998 16:01:48   JOE
 * In olstartchar(), if processing IF outlines, adjust "VLCpower"
 * by "powincr" since we bypass ifrender().
 * 
 *    Rev 1.17   04 Mar 1998 11:53:42   AL
 * Fixed VLCpower calculation
 * 
 *    Rev 1.16   13 Feb 1998 12:38:40   AL
 * Changed meaning of VLCpower to support CGIFbound_box()
 * 
 *    Rev 1.15   03 Feb 1998 09:35:20   AL
 * Conditional compile mixup in olquadto()
 * 
 *    Rev 1.14   30 Jan 1998 16:35:50   GALEJS
 * gaso_pn is in if_state now
 * 
 *    Rev 1.13   28 Jan 1998 11:46:20   AL
 * Moved towards re-entrant
 * 
 *    Rev 1.12   05 Dec 1997 11:42:36   MIKE
 * (1) VLC change in fix_cubic_ol  (2) Fixed cubic output bug in olcubeto()
 * 
 *    Rev 1.11   30 Jul 1997 08:33:32   KEB
 * Conditionally compiled calls to quadvectorize() and cubevectorize()
 * 
 *    Rev 1.10   24 Jul 1997 16:21:14   JIMMY
 * Added prototypes for quadvectorize() and cubevectorize() to
 * resolve warning messages.
 * 
 *    Rev 1.9   15 Jul 1997 10:35:26   AL
 * Pseudo bold via outlines
 * 
 *    Rev 1.8   07 Apr 1995 09:17:36   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.7   15 Feb 1995 16:36:00   MAC
 * Fixed printf's format specifiers in print_outline_data().
 * 
 *    Rev 1.6   22 Apr 1994 14:23:32   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.5   02 Feb 1994 08:43:14   JOE
 * Removed #include statement for "memory.h".
 * 
 *    Rev 1.4   12 Feb 1993 14:44:54   JOE
 * VXWorks support.
 * 
 *    Rev 1.3   29 Jan 1993 09:20:24   JOE
 * In olstartchar(), saved em box size in "odata.pol".
 * 
 *    Rev 1.2   05 Jan 1993 15:03:58   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:25:24   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:28:36   LISA
 * Initial revision.
*/
/* $Date:   Dec 15 2004 12:22:42  $ */
/* outdata.c */


/*---------------------------------------------------------------------
     09-11-90   bjg   Added quadratic outline support.
     12-01-90   awr   split off from maker.c. Removed unused parameters
                      from linear() and quadra().
     02-04-91   awr   Changed name des2wrkbm() to des2bm()
     02-04-91   tnc   In outline_metrics(), if compound character, store
                      "h_esc" as escapement instead of calculating it 
                      from bounding box.

                dET   In outline_metrics(), "is_compound" and "h_esc"
                      are part of structure "chr_def_hdr".
     03-06-91   jfd   In make_char_part(), corrected typeo in conditional
                      compile (#if QUADRA  was  #if QUADdRA)
                      In outline(), loaded "*phol" prior to calling
                      outline_metrics().
     03-10-91   awr   Corrected size calculations for outline memory
     19-May-91  awr   LOOP structure changed
      1-Jun-91  awr   HQ4 changes
      9-Jun-91  awr   added more output to print_outline_data()
                      changed chr_def_hdr structure
     17-Jun-91  jfd   Moved "debug.h" after "port.h".
                      Moved "profile.h" after "port.h".
                      Moved "cgconfig.h" before "port.h".
     29-Jun-91  awr   Removed d.tt- not needed.
     23-Aug-91  rs    make_char_part() & outline_metrics() -> GLOBAL
     24-Aug-91  awr   Moved function decls to include file
      6-Sep-91  awr   Changed HEADERSIZE to OLHEADERSIZE
      9-Sep-91  jfd   Changed routine names as follows:
                         OUTstartchar() --> odstartchar()
                         OUTendchar()--> odendchar()
                         OUTstartloop() --> odstartloop()
                         OUTendloop() --> odendloop()
                         OUTmoveto() --> odmoveto()
                         OUTlineto() --> odlineto()
                         OUTquadto() --> odquadto()
                         OUTcurveto() --> odcurveto()
                      In odstartloop(), was not declaring argument
                      "polarity".
                      Added function prototype for outdata().
     10-Sep-91  jfd   Changed naming convention of outline functions:
                         odstartchar() --> _olstartchar()
                         odendchar()   --> _olendchar()
                         odstartloop() --> _olstartloop()
                         odendloop()   --> _olendloop()
                         odmoveto()    --> _olmoveto()
                         odlineto()    --> _ollineto()
                         odquadto()    --> _olquadto()
                         odcurveto()   --> _olcurveto()
                      Added PWORDVECTOR argument to _olifbb.
     11-Sep-91  jfd   In _olendchar(), reduce size of outline by removing
                      unused space and update appropriate offsets and sizes.
                      Including "mixmodel.h" and <memory.h>.
      12-Sep-91 jfd   In _olendchar(), check if unused space exists before
                      trying to reclaim it.
                      Changed name of _olcurveto() to _olcubeto().
       8 Oct 91 ss    Added prototype for cpymem() in !LINT_ARGS case.
     12-Oct-91  awr   Removed unused #include "bitmap.h"
     07-Nov-91  jfd   In _olstartchar(), when calculating "odata.pntptr",
                      add 8 instead of 4 to accomodate changes in
                      OUTLINE_CHAR structure.
     12-Nov-91  jfd   In _olstartchar(), replaced constants with sizeof
                      operations for SUN/SPARC compatability.
                      In _olendchar(), did the same thing.
      22-Nov-91  rs    Modify odifbb() to not add translation to get bbox.
                       This bbox is NOT same as from CGIFCHAR_handle() - error
                      equals 1/2 of translation vector.
     03-Apr-92  rs    Portability cleanup (see port.h).
                      #ifdef'd out 'OLrealloc()', not used?
     10-Apr-92  jfd   In _olendchar(), applying translation to coordinates.
     21-May-92  jfd   In order to use the function table, the following
                      outline functions' argument lists were changed to
                      match those of the corresponding bitmap functions:
                        olmoveto: (SW16VECTOR) --> (SL32, SL32)
                        ollineto: (SW16VECTOR) --> (SL32, SL32)
                        olquadto: (SW16VECTOR, SW16VECTOR) -->
                                  (SL32, SL32, SL32, SL32)
                        olcubeto: (SW16VECTOR, SW16VECTOR, SW16VECTOR) -->
                                  (SL32, SL32, SL32, SL32, SL32, SL32)

                      The argument for olstartchar() was changed from
                      OLSTATS to PVOID.
     22-May-92  jfd   In _olendchar(), removed code which applied translation
                      to coordinates. Will do it in make_char_part().
     29-May-92  jfd   In "odata" structure and in _olstartchar(), changed 
                      type "OLSTATS" to "CHAR_STATS" due to change in
                      "ix.h".
     19-Jun-92  jfd   In outdata(), if processing space character, set
                      "est_size" to 0.
                      If outline() returns ERR_fixed_space, save handle
                      to outline and return.
                      In _olstartchar(), if processing a space character,
                      return ERR_fixed_space.
      1 Jul 92  ss    Added !LINT_ARGS prototypes.
      2-Jul-92  jfd   Added olcubequadto() for generating TT cubic outlines
                      from quadratic outlines.
      7-Jul-92  jfd   Re-enabled POSTSCRIPCONTOUR so that fix_cubic_ol()
                      is called to reverse contours if necessary.
     10 Jul 92 ss,awr Changed refs from OUTLINE_CHAR.bm to new item ol.
                      Long align beginning of vectors before setting.
     14-Jul-92  awr   Changed call to make_gaso().
     16-Jul-92 rs/jfd Fixed "fix_cubic_ol()" bug by making "temppnt"
                      (data at beginning of coordinate data section)
                      an MLOCAL instead of frame variable due to potential 
                      compiler bug in MSC.
     09-Aug-92 rs     Changes for Watcom C386 (string.h).
     15-Sep-92 jfd    COnditionally compiled odifbb() based on IF_RDR &&
                      PST1.
     23-Sep-92 jfd    INTEL960 conditional compile changes.
     15-Nov-92 rs     Port to Mac - rename outline() to cgoutline().
     05-Jan-93 jfd    ANSI C function declaration changes.
     27-Jan-93 jfd    In olstartchar(), store em box size in "odata.pol".
     08-Feb-93 jfd    VXWorks support.
     26-Jan-94 jfd    Removed #include statement for "memory.h".
     15-Feb-95 mac    Fixed printf's format specifiers in print_outline_data()
     30-Jul-97 keb    Conditionally compiled calls to quadvectorize()
                      and cubevectorize().
     01-Dec-97 mby    VLC support - in fix_cubic_ol() declare "UL32 i".
     04-Dec-97 mby    Fixed bug - conditional code in olcubeto() messed up
                      num_segmts if you wanted CUBIC output on a TRUETYPE
                      or MICROTYPE font.
      16-Jan-98 awr   Removed
                        EXTERN CHR_DEF_HDR chr_def_hdr;
                        EXTERN CHR_DEF chr_def[];
                        OUTDATA outdata;   on the way towards re-entrant
      30-Jan-98 slg   "gaso_pn" is now an element of "if_state"
       3-Feb-98 awr   fixed "PODATA p = (POUDATA)s;" conditional compile
                      mixup in olquadto()
       7-Feb-98 awr   Changed meaning of VLCpower to support CGIFbound_box()    
      24-Mar-98 jfd   In olstartchar(), if processing IF outlines,
                      adjust "VLCpower" by "powincr" since we are
                      bypassing ifrender().
      25-Mar-98 jfd   In odifbb(), changed reference to "origin.x" and
                      "origin.y" to "origin_cs.x" and "origin_cs.y"
                      respectively.
      02-Apr-98 slg   Move GLOBAL odata structure to if_state.
      02-Sep-98 slg      "olcubeto" element of OUT_TBL should not be conditionally
                      compiled #if-CUBIC - this causes stack-fault crashes when
                      using PostScript and LINEAR outlines with !CUBIC
      19-Jan-99 slg      LONGALIGN definition now conditional for 32-bit / 64-bit
                      longs (so that 64-bit pointers not truncated).
                      Also fix compiler warning in fix_cubic_ol().
      28-July-99 ks      Changed DEBUG compiler directive to AGFADEBUG.
      22-Mar-00  keb  changed char bbox calc. if vert writ is enabled
      28-Nov-00    slg      Remove odifbb() - only used with obsolete PST1 option.
      23-May-01  jfd  OpenType changes:
                      in out_setRender(), point to correct bucket.
      12-Sep-02  awr  Added logic to free the isWrong[] array to fix badly wound contours
-----------------------------------------------------------------------*/

#include "cgconfig.h"

#if OUTLINE && OLDATA     /* 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 "q3.h"
#include "mixmodel.h"


#ifdef LINT_ARGS
MLOCAL VOID      cpymem(LPSB8, LPSB8, UW16);
MLOCAL VOID      fix_cubic_ol(POUTLINE_CHAR);
#ifdef AGFADEBUG
MLOCAL VOID      print_outline_data(FSP PIFOUTLINE);
#endif

MLOCAL UW16     olstartchar(FSPvoid PVOID, PVOID);  /* 5-21-92 !!! */
MLOCAL UW16     olendchar(FSPvoid PVOID);
MLOCAL UW16     olstartloop(FSPvoid PVOID, UW16);
MLOCAL UW16     olendloop(FSPvoid PVOID);
MLOCAL UW16     olmoveto(FSPvoid PVOID, INTR, INTR);
MLOCAL UW16     ollineto(FSPvoid PVOID, INTR, INTR);
MLOCAL UW16     olquadto(FSPvoid PVOID, INTR, INTR, INTR, INTR);
MLOCAL UW16     olcubeto(FSPvoid PVOID, INTR, INTR, INTR, INTR, INTR, INTR);
MLOCAL UW16     olcubequadto(FSPvoid PVOID, INTR, INTR, INTR, INTR);

#else  /* !LINT_ARGS */
MLOCAL VOID      cpymem();
MLOCAL VOID      fix_cubic_ol();
#ifdef AGFADEBUG
MLOCAL VOID      print_outline_data();
#endif

MLOCAL UW16     olstartchar();  /* 5-21-92 !!! */
MLOCAL UW16     olendchar();
MLOCAL UW16     olstartloop();
MLOCAL UW16     olendloop();
MLOCAL UW16     olmoveto();
MLOCAL UW16     ollineto();
MLOCAL UW16     olquadto();
MLOCAL UW16     olcubeto();
MLOCAL UW16     olcubequadto();

#endif  /* LINT_ARGS */

#if (NAT_ALIGN == 8)    /* make sure not to truncate 64-bit pointers */
#define LONGALIGN( v )  (((SL64)(v)+7)&0xFFFFFFFFFFFFFFF8)
#else
#define LONGALIGN( v )  (((SL32)(v)+3)&0xFFFFFFFC)
#endif

#define POSTSCRIPTCONTOUR 1 /* use to reverse cubic outlines for PST1 */

#ifdef AGFADEBUG
#if defined (ANSI_DEFS)
MLOCAL VOID  print_outline_data(FSP PIFOUTLINE pol)
#else
MLOCAL VOID
print_outline_data(pol)
    PIFOUTLINE pol;
#endif
{
    POUTLINE_CHAR outchar;
    INTR x0,y0,x1,y1,x2,y2,x3,y3;
    SW16 num_contrs,num_segmts;
    LPSB8 segment;
    PINTRVECTOR points;
    SW16  i,j;

    DBG("\n\nprint_outline_data()\n");
    DBG1("    size\t%ld\n", pol->size);    /* size of header w/out metrics */
    DBG1("    depth\t%d\n", pol->depth);  /*  always 1                */
#if INTR_SIZE == 16
    DBG1("    left\t%d\n", pol->left);
    DBG1("    top\t\t%d\n", pol->top);
    DBG1("    right\t%d\n", pol->right);
    DBG1("    bottom\t%d\n", pol->bottom);
#else
    DBG1("    left\t%ld\n", pol->left);
    DBG1("    top\t\t%ld\n", pol->top);
    DBG1("    right\t%ld\n", pol->right);
    DBG1("    bottom\t%ld\n", pol->bottom);
#endif
#if VLCOUTPUT
    DBG1("    VLCpower\t%d\n", pol->VLCpower);
#else
    DBG1("    xscale\t%d\n", pol->xscale);
    DBG1("    yscale\t%d\n", pol->yscale);
#endif
    DBG1("    escapement\t%d\n", pol->escapement);
                      
    outchar = &pol->ol;
    num_contrs = outchar->num_loops;

    DBG1("\nNumber of loops %d\n", num_contrs);

    for(i=0; i<num_contrs; i++)
    {
        num_segmts = outchar->loop[i].num_segmts;
     
        segment = (LPSB8)((LPSB8)(outchar->loop)
                                         + outchar->loop[i].segmt_offset);
        points = (PINTRVECTOR)((LPSB8)(outchar->loop)
                                        + outchar->loop[i].coord_offset);

        DBG1("Next Contour  num_segmts = %d\n", num_segmts);
        DBG1("    polarity = %d\n", outchar->loop[i].polarity);
        for(j=0; j<num_segmts; j++)
        {
   
            if(*segment == 0x00)
            {
                x0 = points->x;
                y0 = points->y;    points++;

#if INTR_SIZE == 16
                DBG2("    MoveTo %6d %6d\n", x0, y0);
#else
                DBG2("    MoveTo %6ld %6ld\n", x0, y0);
#endif
            }
            else if (*segment == 0x01)
            {
                x1 = points->x;
                y1 = points->y;    points++;

#if INTR_SIZE == 16
                DBG2("    LineTo %6d %6d\n", x1, y1);
#else
                DBG2("    LineTo %6ld %6ld\n", x1, y1);
#endif
            }
            else if (*segment == 0x02)
            {
                x1 = points->x;
                y1 = points->y;    points++;

                x2 = points->x;
                y2 = points->y;    points++;

#if INTR_SIZE == 16
                DBG4("    QuadTo %6d %6d %6d %6d\n", x1, y1, x2, y2);
#else
                DBG4("    QuadTo %6ld %6ld %6ld %6ld\n", x1, y1, x2, y2);
#endif
            }
            else if (*segment == 0x03)
            {
                x1 = points->x;
                y1 = points->y;    points++;

                x2 = points->x;
                y2 = points->y;    points++;

                x3 = points->x;
                y3 = points->y;    points++;

#if INTR_SIZE == 16
                DBG6("    CurvTo %6d %6d %6d %6d %6d %6d\n",
                         x1, y1, x2, y2, x3, y3);
#else
                DBG6("    CurvTo %6ld %6ld %6ld %6ld %6ld %6ld\n",
                         x1, y1, x2, y2, x3, y3);
#endif
            }
            else
                DBG1("    INVALID SEGMENT CODE %d\n", *segment);

            segment++;
        }
    }
}
#endif

#define MOVETO  0
#define LINETO  1
#define QUADTO  2
#define CURVETO 3

#if POSTSCRIPTCONTOUR
/*----------------------*/
/*     fix_cubic_ol     */
/*----------------------*/
/*  reverse outline depending on fill rule and polarity */
/*
    Reverse outline depending on fill rule and polarity. PostScript
    follows a "fill to the left" rule. Outside contours are counter-clockwise
    and inside contours are clockwise.

    NOTE: This algorithm will only work if there are NO open paths within
            contours. The final point must end up at the start point.
          Only newly made loops in case of a compound character are reversed.
*/
#if defined (ANSI_DEFS)
MLOCAL VOID  fix_cubic_ol(POUTLINE_CHAR outcharptr)
#else
MLOCAL VOID
fix_cubic_ol(outcharptr)
    POUTLINE_CHAR outcharptr;
#endif
{
    INTRVECTOR temppnt;
    POUTLINE_LOOP oloop;
    LPSB8 segptr, bsegptr;
    PINTRVECTOR pntptr, bpntptr;
    SW16 k;
    SB8 tempseg;

    oloop = outcharptr->loop;
    for (k = 0; k<outcharptr->num_loops; k++, oloop++ )
    {
        /* Only reverse the points for polarity == 0 */
        if(!oloop->polarity)
        {
            SL32 i;    /* for a VLC, num_segmts could be > 64K */
            oloop->polarity = 1;

          /*  Reverse order of segments. Leave 1st moveto where it is.
           *  Point segptr just after the MOVETO segment. Point bsegptr
           *  to the bottom segment
           */

            segptr = (LPSB8)(outcharptr->loop) + oloop->segmt_offset + 1;
            bsegptr = (LPSB8)segptr + oloop->num_segmts - 2;

            for (i = 0; i < ((oloop->num_segmts - 1) >> 1); i++)
            {
                tempseg    = *segptr;
                *segptr++  = *bsegptr;
                *bsegptr-- = tempseg;
            }

          /* Reverse order of points using the same idea. */

            pntptr = (PINTRVECTOR)((LPSB8)(outcharptr->loop)
                                              + oloop->coord_offset);
            bpntptr = pntptr + oloop->num_coords - 1;

            for (i = 0; i < (oloop->num_coords >> 1); i++)
            {
                
                temppnt    = *pntptr;
                *pntptr++  = *bpntptr;
                *bpntptr-- = temppnt;
            }
        } /* if (polarity == 0) */
    }
}
#endif /* POSTSCRIPTCONTOUR */


/*----------------------*/
/*     olstartchar      */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olstartchar(FSPvoid PVOID s, PVOID pstats)
#else
MLOCAL UW16
olstartchar(s, pstats)
    PVOID s;
    PVOID pstats;  /* 5-21-92 !!! */
#endif
{
    PODATA p = (PODATA)s;

    FSPusevoid    /* converts optional PVOID parm to PIF_STATE */

    p->s = *(PCHAR_STATS)pstats;   /* keep copy of input CHAR_STATS */

    DBG("olstartchar()\n");
    DBG1("    p->s.format   %d\n", p->s.format  );
    DBG1("           .nloop    %d\n", p->s.nloop   );
    DBG1("           .est_pnts %d\n", p->s.est_pnts);
    DBG1("           .est_segs %d\n", p->s.est_segs);
    DBG1("           .est_size %ld\n", p->s.est_size);


  /*  Get memory for IFOUTLINE */

    if(p->pol)                       /* If using apps buffer           */
        p->hol = (HIFOUTLINE)NIL_MH; /* set to nil so we don't realloc */
    else                                /* else alloc and realloc at end  */
    {
        p->hol = CHARalloc(FSA (SL32)(OLHEADERSIZE+p->s.est_size));
        if(p->hol == (HIFOUTLINE)NIL_MH)
            return ERRoutline_mem;
        p->pol = (PIFOUTLINE)MEMptr(p->hol);
    }

  /* Special case:
   *      if space character, return ERR_fixed_space
   */
    if (!if_state.num_loops)  /* 6-19-92 */
       return ERR_fixed_space;

  /* Fill in IFOUTLINE header */

    p->pol->size             = p->s.est_size;
    p->pol->depth            = 1;

    p->pol->left             =  p->s.olbox.ll.x;
    p->pol->bottom           =  p->s.olbox.ll.y;
    p->pol->right            =  p->s.olbox.ur.x;
    p->pol->top              =  p->s.olbox.ur.y;


    /* keb 2/00 */
    if (FC_ISUFSTVERT(&if_state.fcCur))
    {
        if ( if_state.CharVertWrit )
        {
           p->pol->left = p->pol->left + if_state.cs.origin_cs.x;   
           p->pol->bottom = p->pol->bottom  + if_state.cs.origin_cs.y; 
           p->pol->right = p->pol->right + if_state.cs.origin_cs.x; 
           p->pol->top = p->pol->top + if_state.cs.origin_cs.y;
        }
    }

#if VLCOUTPUT
    /* Set VLCpower to the power of two to multiply the coordinates by
     * as they come out of the fst render() functions to convert them into
     * output pixels.
     */
    p->pol->VLCpower = if_state.cs.VLCpower - if_state.x.grid_shift;
#if IF_RDR
    if(if_state.fst_type == FC_IF_TYPE)
       p->pol->VLCpower -= (SW16)powincr;
#endif
#else
    p->pol->xscale           = p->s.xscale;
    p->pol->yscale           = p->s.yscale;
#endif

    p->pol->escapement       = p->s.escapement;

#if GET_VERTICAL_METRICS 
    p->pol->topSideBearing       = p->s.topSideBearing; 
    p->pol->advanceHeight        = p->s.advanceHeight; 
#endif /* R.I. 07/10/03 */

#if TT_SCREENRES            
    p->pol->pixelWidth       = p->s.pixelWidth;     /* jwd, 07/24/02 */
    p->pol->advanceWidth.x   = p->s.advanceWidth.x; /* jwd, 08/18/02 */
    p->pol->advanceWidth.y   = p->s.advanceWidth.y;  
#endif

    /* Store em box size   - 01/27/93 jfd */
    p->pol->du_emx           = p->s.du_emx;
    p->pol->du_emy           = p->s.du_emy;

    p->outcharptr            = &p->pol->ol;
    p->outcharptr->size      = p->s.est_size;
    p->outcharptr->num_loops = p->s.nloop;

  /* point to first loop and start of data area */

    p->oloop = p->outcharptr->loop;
    p->pntptr = (PINTRVECTOR)
         ((LPSB8)p->outcharptr
                                              /*  VVV only have one now */
                    + (sizeof(OUTLINE_CHAR) - sizeof(OUTLINE_LOOP))
                    + sizeof(OUTLINE_LOOP) * p->s.nloop);

     /* make sure vectors start on long aligned address -ss,awr 7/10/92 */
    p->pntptr = (PINTRVECTOR)LONGALIGN( p->pntptr );

    p->segptr = (LPSB8)(p->pntptr + p->s.est_pnts);
    p->tot_segs = 0;
    p->tot_pnts = 0;

    return SUCCESS;
}


/*----------------------*/
/*      olendchar       */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olendchar(FSPvoid PVOID s)
#else
MLOCAL UW16
olendchar(s)
    PVOID s;
#endif
{
    PIFOUTLINE pol;
    POUTLINE_CHAR outchar;
    SW16 i;
    SW16 wasted_point_space;
    SW16 wasted_segmt_space;
    SW16 wasted_total_space;
    LPSB8 segment;
    LPSB8 src;
    LPSB8 dst;
    MEM_HANDLE nh;
    SW16 new_size;
    PIFOUTLINE dol;

    PODATA p = (PODATA)s;

    FSPusevoid    /* converts optional PVOID parm to PIF_STATE */

#ifdef AGFADEBUG
    print_outline_data(FSA p->pol);
#endif

    DBG2("est_segs = %d   actual segs = %d\n",
                                  p->s.est_segs, p->tot_segs);
    DBG2("est_pnts = %d   actual pnts = %d\n",
                                  p->s.est_pnts, p->tot_pnts);
    DBG1("   wasted space = %d\n",  4*(p->s.est_pnts-p->tot_pnts)
                                     + p->s.est_segs-p->tot_segs);

#if POSTSCRIPTCONTOUR
    /*
        changed from '=' to '==' - 4/3/92 - rs
    */
    if(p->s.format == FC_CUBIC_TYPE)
        fix_cubic_ol(p->outcharptr);
#endif /* POSTSCRIPTCONTOUR */

    if(p->hol != (HIFOUTLINE)NIL_MH)
    {
        /* if linear or cubic,  quality level == 3 and */
        /* unused space exists, remove unused space    */

        wasted_point_space = sizeof(INTRVECTOR) *
            (p->s.est_pnts - p->tot_pnts);  /* 11-12-91 jfd */
        wasted_segmt_space = p->s.est_segs - p->tot_segs;
        wasted_total_space = wasted_point_space + wasted_segmt_space;

        if ((if_state.quality == 3)
                       && (p->s.format == (SW16)FC_LINEAR_TYPE ||
          p->s.format == (SW16)FC_CUBIC_TYPE) && (wasted_total_space > 0))
        {
           pol = p->pol;
           outchar = &pol->ol;
           new_size = OLHEADERSIZE + (SW16)(pol->size - (SL32)wasted_total_space);
              /* 11-07-91 jfd */

           /* try to allocate new smaller block */

           nh = CHARalloc(FSA (SL32)new_size); /* else leave big one */
           if (nh != NIL_MH)
           {       
              src = (SB8*)MEMptr(p->hol); /* de-reference source outline */
              dst = (SB8*)MEMptr(nh);        /* de-reference reduced outline */
              dol = (PIFOUTLINE)dst;

              /* get rid of unused space in source outline */

              segment = (LPSB8)((LPSB8)(outchar->loop) + 
                    outchar->loop[0].segmt_offset);
              cpymem(segment - wasted_point_space, segment, p->tot_segs);

              for (i=0; i<outchar->num_loops; i++)
                 outchar->loop[i].segmt_offset -= wasted_point_space;

              /* copy into smaller outline */

              cpymem(dst, src, new_size);

              /* update appropiate sizes */

              dol->size -= wasted_total_space;
              outchar = &dol->ol;
              outchar->size -= wasted_total_space;

              /* free old outline */

              CHARfree(FSA p->hol);  /* free old outline */

              /* update odata pointers */

              p->hol = nh;
              p->pol = (PIFOUTLINE)MEMptr(p->hol);

           }
           else    /* Added error handling */ /* rjl 8/4/2003 - */
           {
               CHARfree(FSA p->hol);  /* free old outline */
               return ERRoutline_mem;
           }
        }

    }
#if FIX_CONTOURS
    if(if_state.ras.nz_instance.isWrong)    /* not NULL means 2nd time, need to free */
    {
        TEMPCHARfree(FSA if_state.ras.nz_instance.hisWrong);
        if_state.ras.nz_instance.isWrong = NULL;
        if_state.ras.nz_instance.hisWrong = NIL_MH;
    }
#endif

    return SUCCESS;
}
/*----------------------*/
/*     olstartloop      */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olstartloop(FSPvoid PVOID s, UW16 polarity)
#else
MLOCAL UW16
olstartloop(s, polarity)
    PVOID s;
    UW16 polarity;
#endif
{
    PODATA p = (PODATA)s;

    p->oloop->num_segmts = 0;
    p->oloop->num_coords = 0;

    p->oloop->segmt_offset =
         (LPSB8)p->segptr - (LPSB8)p->outcharptr->loop;
    p->oloop->coord_offset =
         (LPSB8)p->pntptr - (LPSB8)p->outcharptr->loop;
    p->oloop->polarity = polarity;
    return SUCCESS;
}
/*----------------------*/
/*     olendloop        */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olendloop(FSPvoid PVOID s)
#else
MLOCAL UW16
olendloop(s)
    PVOID s;
#endif
{
    PODATA p = (PODATA)s;
    p->oloop++;
    return SUCCESS;
}
/*----------------------*/
/*     olmoveto         */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olmoveto(FSPvoid PVOID s, INTR vx, INTR vy)
#else
MLOCAL UW16
olmoveto(s, vx, vy)
    PVOID s;
    INTR vx;
    INTR vy;
#endif
{
    PODATA p = (PODATA)s;

    p->oloop->num_segmts++;
    p->oloop->num_coords++;

    p->tot_segs++;
    p->tot_pnts++;
    if((p->tot_segs > p->s.est_segs)
                                || (p->tot_pnts > p->s.est_pnts))
        return ERRoutline_mem;

    *p->segptr++ = MOVETO;
    p->pntptr->x = vx;
    p->pntptr->y = vy;
    p->pntptr++;
    p->p0x = vx;
    p->p0y = vy;
    return SUCCESS;
}
/*----------------------*/
/*     ollineto         */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  ollineto(FSPvoid PVOID s, INTR vx, INTR vy)
#else
MLOCAL UW16
ollineto(s, vx, vy)
    PVOID s;
    INTR vx;
    INTR vy;
#endif
{
    PODATA p = (PODATA)s;
    p->oloop->num_segmts++;
    p->oloop->num_coords++;

    p->tot_segs++;
    p->tot_pnts++;
    if((p->tot_segs > p->s.est_segs)
                                || (p->tot_pnts > p->s.est_pnts))
        return ERRoutline_mem;

    *p->segptr++ = LINETO;
    p->pntptr->x = vx;
    p->pntptr->y = vy;
    p->pntptr++;  /* 5-21-92 !!! */
    p->p0x = vx;
    p->p0y = vy;
    return SUCCESS;
}
/*----------------------*/
/*     olquadto         */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olquadto(FSPvoid PVOID s, INTR cx, INTR cy, INTR vx, INTR vy)
#else
MLOCAL UW16
olquadto(s, cx, cy, vx, vy)
    PVOID s;
    INTR cx, cy, vx, vy;
#endif
{
    PODATA p = (PODATA)s;

    FSPusevoid    /* converts optional PVOID parm to PIF_STATE */

#if LINEAR 
    if(if_state.cs.format == FC_LINEAR_TYPE)
/*keb*/
#if ((TT_RDR || FCO_RDR) && (CGBITMAP || LINEAR || SMEAR_BOLD || GRAYSCALING))
        return quadvectorize ( FSA s, ollineto, p->p0x, p->p0y,
                                             cx, cy, vx, vy );
#endif
#endif /* LINEAR */
    p->oloop->num_segmts++;
    p->oloop->num_coords += 2;

    p->tot_segs++;
    p->tot_pnts += 2;
    if((p->tot_segs > p->s.est_segs)
                                || (p->tot_pnts > p->s.est_pnts))
        return ERRoutline_mem;

    *p->segptr++ = QUADTO;
    p->pntptr->x = cx;
    p->pntptr->y = cy;
    p->pntptr++;
    p->pntptr->x = vx;
    p->pntptr->y = vy;
    p->pntptr++;

    p->p0x = vx;
    p->p0y = vy;
    return SUCCESS;
}
/*----------------------*/
/*     olcubeto         */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olcubeto(FSPvoid PVOID s, INTR c0x, INTR c0y, INTR c1x, INTR c1y,
                                                   INTR vx,  INTR vy)
#else
MLOCAL UW16
olcubeto(s, c0x, c0y, c1x, c1y, vx, vy)
    PVOID s;
    INTR c0x, c0y, c1x, c1y, vx, vy;
#endif
{
    PODATA p = (PODATA)s;

    FSPusevoid    /* converts optional PVOID parm to PIF_STATE */

#if ((PST1_RDR) && (CGBITMAP || LINEAR || SMEAR_BOLD || GRAYSCALING))
    if(if_state.cs.format == FC_LINEAR_TYPE)
        return cubevectorize ( FSA s, ollineto, p->p0x, p->p0y,
                                             c0x, c0y, c1x, c1y, vx, vy );
#endif

    p->oloop->num_segmts++;
    p->oloop->num_coords += 3;

    p->tot_segs++;
    p->tot_pnts +=3;
    if((p->tot_segs > p->s.est_segs)
                                || (p->tot_pnts > p->s.est_pnts))
        return ERRoutline_mem;

    *p->segptr++ = CURVETO;
    p->pntptr->x = c0x;
    p->pntptr->y = c0y;
    p->pntptr++;
    p->pntptr->x = c1x;
    p->pntptr->y = c1y;
    p->pntptr++;
    p->pntptr->x = vx;
    p->pntptr->y = vy;
    p->pntptr++;

    p->p0x = vx;
    p->p0y = vy;
    return SUCCESS;
}
/*----------------------*/
/*     olcubequadto     */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  olcubequadto(FSPvoid PVOID s, INTR cx, INTR cy, INTR vx, INTR vy)
#else
MLOCAL UW16
olcubequadto(s, cx, cy, vx, vy)
    PVOID s;
    INTR cx, cy, vx, vy;
#endif
{
    INTR cx0, cy0, cx1, cy1;
    UW16 status;
    PODATA p = (PODATA)s;

    FSPusevoid    /* converts optional PVOID parm to PIF_STATE */
 
    cx0 = (INTR)(((SL32)p->p0x + ((SL32)cx << 1)) / 3L);
    cy0 = (INTR)(((SL32)p->p0y + ((SL32)cy << 1)) / 3L);

    cx1 = (INTR)((((SL32)cx << 1) + (SL32)vx) / 3L);
    cy1 = (INTR)((((SL32)cy << 1) + (SL32)vy) / 3L);

    status = olcubeto ( FSAvoid s, cx0, cy0, cx1, cy1, vx, vy );
    return status;
}

/*----------------------*/
/*    cpymem            */
/*----------------------*/
/*  Like memcpy() only copies from front to back (for sure). It's here so we
 *  don't have to use memmove()
 */
#if defined (ANSI_DEFS)
MLOCAL VOID  cpymem(LPSB8 dest, LPSB8 src, UW16 count)
#else
MLOCAL VOID
cpymem(dest, src, count)
    LPSB8 dest;
    LPSB8 src;
    UW16 count;
#endif
{
    while(count--)
        *dest++ = *src++;
}


/*----------------------*/
/*      outdata         */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  outdata(FSP PHIFOUTLINE phol)
#else
GLOBAL UW16
outdata(phol)
    PHIFOUTLINE phol;         /* Final result goes here */
#endif
{
    UW16 status;

    DBG("\n\n\n\no u t d a t a()\n");

    if_state.odata.pol = (PIFOUTLINE)0;   /* to signal no outline memory buffer */

    /* Special case:
     *   if space character, set "est_size" to 0 because 
     *   "make_gaso_and_stats()" has not been called to
     *   calculate this value
     */
    if (!if_state.num_loops)  /* 6-19-92 */
       if_state.odata.s.est_size = 0L;

    status = cgoutline(FSA0);

    /* Special case:
     *   if space character, store handle before returning
     */

    if (status == ERR_fixed_space)  /* 6-19-92 */
       *phol = if_state.odata.hol;

    if (status)
       return status;
    *phol = if_state.odata.hol;
    return SUCCESS;
}
/*----------------------*/
/*      outbuffer       */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  outbuffer(FSP PIFOUTLINE pol)
#else
GLOBAL UW16
outbuffer(pol)
    PIFOUTLINE pol;         /* Final result goes here */
#endif
{
    if_state.odata.pol = pol;
    return cgoutline(FSA0);
}

CONST OUT_TBL olout_tbl = {
    olstartchar,
    olendchar,
    olstartloop,
    olendloop,
    olmoveto,
    ollineto,
    olquadto,
    olcubeto
};

/*----------------------*/
/*      out_setRender   */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID  out_setRender( FSP0 )
#else
GLOBAL VOID
out_setRender()
#endif
{
    PBUCKET pb;    /* 05-23-01 jfd */
    if_state.out_instance = &if_state.odata;
    if_state.out = olout_tbl;

    pb = GET_pBUCKET(if_state.pbucket);        /* 05-23-01 jfd */

#if (TT_RDR || FCO_RDR)
  /* Substitute TT cubequadto() function for cubeto() */
    if ((pb->fst_type == FC_TT_TYPE ||        /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
         pb->fst_type == FC_FCO_TYPE) &&    /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
        (if_state.cs.format == FC_CUBIC_TYPE))
    {
#if OLDATA
        if_state.out.quadto = olcubequadto;
#endif
    }
#endif /* TT_RDR || FCO_RDR */
}

#endif  /* OUTLINE && OLDATA */
 

outline.txt   、、、、、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2004 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/OUT/OUTLINE.C_V   1.39   Aug 26 2004 14:40:26   wuq  $ */
/* $Log:   I:/BULL/URIP/RTS/OUT/OUTLINE.C_V  $ 
 * 
 *    Rev 1.39   Aug 26 2004 14:40:26   wuq
 * Removed GET_VERTICAL_METRICS conditional
 * from non output structure.
 * 
 * 
 *    Rev 1.38   Jun 08 2004 18:34:54   GalejsS
 * fix positioning of outlines in vertical writing (make consistent with bitmaps)
 * 
 *    Rev 1.37   Oct 09 2003 13:25:46   IndrelR
 * Changes for Vertical Writing .
 * 
 *    Rev 1.36   Aug 22 2003 09:09:58   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.35   Jun 20 2003 14:02:22   Galejs
 * get rid of NON_IF_FONT
 * 
 *    Rev 1.34   Dec 02 2002 18:06:28   Galejs
 * fix uninit-vbl warnings
 * 
 *    Rev 1.33   04 Jun 2001 10:14:04   JOE
 * OpenType changes.
 * 
 *    Rev 1.32   May 03 2001 20:37:46   Galejs
 * data-type cleanup
 * 
 *    Rev 1.31   19 Apr 2000 11:14:10   JOE
 * For TT_ROM or TT_DISK, added code to metrics() to replace escapement
 * with advanceHeight, if advanceHeight exists and is different from
 * escapemenet, and vertical writing is enabled (by keb).
 * 
 *    Rev 1.30   Jan 24 2000 14:52:58   galejs
 * vertical-writing changes (for keb), edited to remove FCO-specific code
 * 
 *    Rev 1.29   Aug 09 1999 18:37:18   galejs
 * include-file changes
 * 
 *    Rev 1.28   22 Apr 1999 13:40:10   BEHRINGE
 * Modified so Vert Writ works with pseudo bolds
 * 
 *    Rev 1.27   31 Mar 1999 11:49:50   JOE
 * Added code to support Vertical Writing feature (by keb).
 * 
 *    Rev 1.26   12 Jan 1999 18:16:42   GALEJS
 * move EXTERN dcls
 * 
 *    Rev 1.25   22 Jun 1998 18:43:46   GALEJS
 * make Intellifont reentrant too
 * 
 *    Rev 1.24   15 Jun 1998 11:15:38   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.23   15 Apr 1998 17:00:28   GALEJS
 * move chr_def_hdr to IF_STATE
 * 
 *    Rev 1.22   24 Mar 1998 16:56:44   GALEJS
 * include-file changes
 * 
 *    Rev 1.21   28 Jul 1997 13:58:34   JOE
 * In make_char_part(), calling quadra() if LINEAR || QUADRA || CGBITMAP ||
 * GRAYSCALING to resolve "ERRinvalid_outproc_type" error when emboldening
 * IF bitmap using BOLD_P6.
 * 
 *    Rev 1.19   22 Jul 1997 14:54:08   AL
 * Also conditionally compile on non zero winding with bold
 * 
 *    Rev 1.18   22 Jul 1997 08:22:30   AL
 * Also conditionally compile on non zero winding and bold
 * 
 *    Rev 1.17   21 Jul 1997 15:12:12   JOE
 * Removed PVOID as first argument for quadra() and cubic() (prototypes
 * and calls).
 * 
 *    Rev 1.16   15 Jul 1997 10:40:20   AL
 * Pseudo bold via outlines
 * 
 *    Rev 1.15   14 Jan 1997 21:40:28   DAVID
 * Removed DRAS_QUAD option as part of project to trim ufst.
 * 
 *    Rev 1.14   25 Aug 1995 11:18:04   MIKE
 * Changed last 2 args of ttrender() call (can be nonzero).
 * 
 *    Rev 1.13   07 Apr 1995 09:17:34   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.12   02 Feb 1995 13:36:32   JOE
 * In make_char_part(), fixed computation of "half pixel" sizes (by mac).
 * 
 *    Rev 1.11   12 Dec 1994 08:12:58   JOE
 * Conditionally compiled prototype for bmras_quad_flat() based on FCO_RDR.
 * In outline(), corrected typo in conditional compile statement
 * (FC_RDR is changed to FCO_RDR) (by dbk)
 * 
 *    Rev 1.10   11 Dec 1994 17:24:18   MIKE
 * Replace "cs.origin" with "cs.origin_cs".
 * 
 *    Rev 1.9   17 Nov 1994 13:38:52   JOE
 * More FCO outline changes (by bjg).
 * 
 *    Rev 1.8   15 Nov 1994 14:19:48   JOE
 * In outline(), added FCO support (by bjg).
 * 
 *    Rev 1.7   03 Aug 1994 16:01:42   MIKE
 * Added FCO changes for 1.5.1.1
 * 
 *    Rev 1.6   22 Apr 1994 14:23:30   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.5   03 Sep 1993 11:06:28   JOE
 * In cgoutline(), substitute proper "...quadto()" function in
 * "if_state.out" table.
 * Added function prototype for "bmras_quad_flat()".
 * 
 *    Rev 1.4   13 Apr 1993 13:19:16   JOE
 * In cgoutline(), conditionally compiled calls to psrender() and ttrender()
 * if !USE_JUMP_TABLES.
 * 
 *    Rev 1.3   12 Feb 1993 14:57:24   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   05 Jan 1993 14:23:58   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:24:48   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:28:40   LISA
 * Initial revision.
*/
/* $Date:   Aug 26 2004 14:40:26  $ */
/* outline.c */


/*---------------------------------------------------------------------
     09-11-90   bjg   Added quadratic outline support.
     12-01-90   awr   split off from maker.c. Removed unused parameters
                      from linear() and quadra().
     02-04-91   awr   Changed name des2wrkbm() to des2bm()
     02-04-91   tnc   In outline_metrics(), if compound character, store
                      "h_esc" as escapement instead of calculating it 
                      from bounding box.

                dET   In outline_metrics(), "is_compound" and "h_esc"
                      are part of structure "chr_def_hdr".
     03-06-91   jfd   In make_char_part(), corrected typeo in conditional
                      compile (#if QUADRA  was  #if QUADdRA)
                      In outline(), loaded "*phol" prior to calling
                      outline_metrics().
     03-10-91   awr   Corrected size calculations for outline memory
     19-May-91  awr   LOOP structure changed
      1-Jun-91  awr   HQ4 changes
      9-Jun-91  awr   added more output to print_outline_data()
                      changed chr_def_hdr structure
     17-Jun-91  jfd   Moved "debug.h" after "port.h".
                      Moved "profile.h" after "port.h".
                      Moved "cgconfig.h" before "port.h".
     29-Jun-91  awr   Removed d.tt- not needed.
     24-Aug-91  awr   Moved function decls to include file
      6-Sep-91  awr   Changed HEADERSIZE to OLHEADERSIZE
     10-Sep-91  jfd   Changed naming convention of outline functions.
     12-Oct-91  awr   Removed unused #include "bitmap.h"
     03-Apr-92  rs    Portability cleanup (see port.h).
     13-Apr-92  awr   In outline(), added braces inside "for" loop.
     21-May-92  jfd   In outline(), replaced direct outline function calls
                      with calls via the function table. Cast argument
                      for ras_start_char() to PVOID.
                      Added pointer to font function table "pras".
     27-May-92  jfd   In make_char_part(), when passing translations "xt" 
                      and "yt" to quadra() and cubic(), add additional
                      translation "if_state.xlate.x" and "if_state.xlate.y".
     29-May-92  jfd   Changed type "OLSTATS" to "CHAR_STATS" due to change 
                      in "ix.h".
      4 Jun 92  jfd   In outline(), if PS or TT, call "render()" with
                      zero translation.
      8-Jun-92  jfd   Replaced all references to "olstats" with
                     "if_state.cs".
      9-Jun-92  jfd   In outline(), call "render()" if requested character
                      is in PS or TT bucket (i.e., check "pbucket->fst_type"
                      rather than "format").
     23-Jun-92  jfd   In outline(), moved statement which copied "olout_tbl"
                      into "if_state.out" from beginning of routine to
                      two different places: after check for linear and
                      at end of routine.
     24-Jun-92  jfd   In make_char_part(), restore "if_state.tbound" 
                      before returning.
      6-Jul-92  jfd   In outline(), if generating a TT cubic outline,
                      substitute "olcubequadto()" function for "olquadto()".
     14-Jul-92  awr   Changed call to make_gaso().
     21-Jul-92  awr   Conditional compile changes.
     14-Sep-92  jfd   In outline(), moved braces outside of #if IF_RDR 
                      conditional compile.
     10-Oct-92  rs    Implement USE_JUMP_TABLES feature for overlays.
     15-Nov-92  rs    Port to Mac -> rename outline() to cgoutline().
     05-Jan-93  jfd   ANSI C function declaration changes.
     08-Feb-93  jfd   VXWorks support.
     13-Apr-93  jfd   In cgoutline(), conditionally compiled calls to 
                      psrender() and ttrender() if !USE_JUMP_TABLES.
     31-Aug-93  jfd   In cgoutline(), substitute proper "...quadto()"
                      function in if_state.out table.
                      Added function prototypes for "bmras_quad_flat()".
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  FCO Changes from 1.5.1.1:
     14-Mar-94  mby   If FCO is enabled, cgoutline() calls fco_render().
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     15-Nov-94  bjg   In outline(), added FCO support.
     11-Dec-94  mby   Replace "cs.origin" with "cs.origin_cs".
     12-Dec-94  dbk   Conditionally compiled prototype for bmras_quad_flat()
                      based on FCO_RDR.
                      In outline(), corrected typo in conditional compile
                      statement (FC_RDR is changed to FCO_RDR).
     02-Feb-95  mac   In make_char_part(), fixed computation of "half pixel"
                      sizes.
     24-Aug-95  mby   In cgoutline, last two args to ttrender() are nonzero if
                      the character's LSB != xmin. This caused the outline to
                      lie in the wrong position. Disabled USE_JUMP_TABLES.
     14-Jan-97  dlk   Removed DRAS_QUAD option as part of project to trim ufst.
     21-Jul-97  jfd   Removed PVOID argument as first argument in quadra()
                      and cubic() (prototypes and calls).
     22-Jul-97  awr   Conditionally compiled entire file also on NON_Z_WIND
                      and BOLD_P6 or BOLD_HORIZONTAL
     28-Jul-97  jfd   In make_char_part(), calling quadra() if
                      LINEAR || QUADRA || CGBITMAP || GRAYSCALING to resolve
                      "ERRinvalid_outproc_type" error when emboldening
                      IF bitmap using BOLD_P6.
     31-Mar-99  keb   Added code to support Vertical Writing Feature. It adjusts 
                      outline's origin (TrueType data only
     22-Apr-99  keb   Modified ASIANVERT code for Pseudo Bold Bitmaps
     18-Jan-00  slg   Vertical-writing changes (for keb) - pretty much a
                rewrite of cgoutline(), for TT and FCO cases. Note that
                the FCO_RDR-specific changes have NOT been checked in.
     14-Apr-00  keb   For TT_ROM or TT_DISK added code to metrics() to replace escapement 
                      with advanceHeight, if advanceHeight exists and is different from 
                      escapement, and vertical writing is enabled
     23-May-01  jfd   OpenType changes:
                      In cgoutline(), point to correct bucket.      

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

#include "cgconfig.h"

#if OUTLINE || (NON_Z_WIND && (BOLD_P6 || BOLD_HORIZONTAL))

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

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

#include "shareinc.h"

#include "q3.h"

#if IF_RDR
#ifdef LINT_ARGS
MLOCAL UW16      make_char_part(FSP UW16, PCHR_DEF);
#else
MLOCAL UW16      make_char_part();
#endif
#endif


#if IF_RDR
/*----------------------*/
/*   make_char_part     */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  make_char_part(FSP UW16 pn, PCHR_DEF cd)
#else
MLOCAL UW16
make_char_part(pn, cd)
    UW16 pn;
    PCHR_DEF cd;
#endif
{
    UW16    status;
    INTR    xt, yt;

    DBG("make_char_part()\n");

  /* Grid aligned scaled outline */

    status = make_gaso(FSA (SL32)pn, cd);
    if (status)
        return status;

  /*  Translate outline: 1. to postion this part within the whole
   *                     2. Position the whole so origin is at (0,0)
   */

    xt = (INTR)cd->bmorigin.x * (INTR)xpix - (INTR)if_state.cs.origin_cs.x;
    yt = (INTR)cd->bmorigin.y * (INTR)ypix - (INTR)if_state.cs.origin_cs.y;

    if_state.tbound.ll.x += xt;
    if_state.tbound.ll.y += yt - half_ypix;
    if_state.tbound.ur.x += xt;
    if_state.tbound.ur.y += yt - half_ypix;

    /*  Increase the fractional output pixel by powincr bits.  These values
     *  will be restored at the end of this function.  All coordinates
     *  will be multiplied by 2**powincr.
     */
    log_xpix   += powincr;
    log_ypix   += powincr;
    xpix      <<= powincr;
    ypix      <<= powincr;
    half_xpix = xpix >> 1;
    half_ypix = ypix >> 1;
    if_state.tbound.ll.x <<= powincr;
    if_state.tbound.ll.y <<= powincr;
    if_state.tbound.ur.x <<= powincr;
    if_state.tbound.ur.y <<= powincr;

  /* draw the character outline */

    switch(if_state.cs.format)
    {
#if (CGBITMAP || GRAYSCALING)   /* 07-28-97 jfd */
        case FC_BITMAP_TYPE:    /* 07-28-97 jfd */
#endif                          /* 07-28-97 jfd */
#if LINEAR 
        case FC_LINEAR_TYPE:    /* quadra() also makes linear outlines */
#endif
#if QUADRA
        case FC_QUAD_TYPE:
#endif
#if (LINEAR || QUADRA || CGBITMAP || GRAYSCALING)   /* 07-28-97 jfd */
                              status =  quadra(FSA if_state.cs.format, 
                                              xt + if_state.xlate.x, 
                                              yt + if_state.xlate.y);
                              break;
#endif
#if CUBIC
        case FC_CUBIC_TYPE:   status = cubic(FSA xt + if_state.xlate.x,
                                                yt + if_state.xlate.y);
                              break;
#endif
        default:              status = ERRinvalid_outproc_type;
    }

    /*  Restore original fractional output pixel size  */
    log_xpix   -= powincr;
    log_ypix   -= powincr;
    xpix      >>= powincr;
    ypix      >>= powincr;
    half_xpix = xpix >> 1;
    half_ypix = ypix >> 1;
    if_state.tbound.ll.x >>= powincr;
    if_state.tbound.ll.y >>= powincr;
    if_state.tbound.ur.x >>= powincr;
    if_state.tbound.ur.y >>= powincr;

    if_state.tbound.ll.x -= xt;
    if_state.tbound.ll.y -= yt - half_ypix;
    if_state.tbound.ur.x -= xt;
    if_state.tbound.ur.y -= yt - half_ypix;

    return status;
}
#endif  /* IF_RDR  */

/*----------------------*/
/*      cgoutline       */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  cgoutline(FSP0)
#else
GLOBAL UW16
cgoutline()
#endif
{
#if IF_RDR
    UW16     status, pn;
    PCHR_DEF cd;
#endif
    PBUCKET pb;    /* 05-23-01 jfd */

    DBG("\n\n\n\no u t l i n e()\n");

    pb = GET_pBUCKET(if_state.pbucket);    /* 05-23-01 jfd */

  if (pb->fst_type == FC_PST1_TYPE ||    /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
      pb->fst_type == FC_TT_TYPE ||        /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
      pb->fst_type == FC_FCO_TYPE)        /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
  {
   switch (pb->fst_type)                /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
   {
#if PST1_RDR
      case FC_PST1_TYPE:
       return (psrender ( FSA if_state.out_instance,
                          pb, 0L, 0L));    /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
       break;
#endif

/* keb 12/99 (modified heavily by sandra - vertical FCO case removed) */
#if TT_RDR
    case FC_TT_TYPE:

    if ( FC_ISOUTLINE(&if_state.fcCur) 
          && FC_ISUFSTVERT(&if_state.fcCur)
            && if_state.CharVertWrit )
    {
        SL32 adjx, adjy;
        SW16 dx, dy, vertical_metric;
        FPNUM fdx, fdy, em;

        fdx = fpint2fp(0);
        fdy = fpint2fp(0);

        adjx = 0;
        adjy = 0;

        if (FC_ISXLFONT(&if_state.fcCur)) 
        {
            vertical_metric = if_state.pbucket->p.tt.FontBBox[1]; 
            dx = vertical_metric; 
            dy = -(if_state.cs.du_emx + vertical_metric);
            em = fpint2fp ((SL32) if_state.cs.du_emx);
            fdx = fpint2fp((SL32)dx);
            fdy = fpint2fp((SL32)dy);
            fdx = fpdiv (fdx, em);
            fdy = fpdiv (fdy, em);
        }
 
         if ((FC_ISTT(&if_state.fcCur)) & (if_state.pbucket->extern_font == 0))  
        {
            /* keb 4/00 */ 
/*#if GET_VERTICAL_METRICS        08-20-04  qwu */ 
            if ((if_state.cs.escapement != if_state.cs.advanceHeight) & (if_state.cs.advanceHeight != 0))
              if_state.cs.escapement = if_state.cs.advanceHeight;
/*#endif        08-20-04 qwu */ 
            vertical_metric = if_state.cs.yDescender;
            /* dx = vertical_metric/2; */
            /* dy = -(if_state.cs.du_emx + vertical_metric/2); */ /* keb 4/14/04 */
            dx = vertical_metric;
            dy = -(if_state.cs.du_emx + vertical_metric);
            em = fpint2fp ((SL32) if_state.cs.du_emx);
            fdx = fpint2fp((SL32)dx);
            fdy = fpint2fp((SL32)dy);
            fdx = fpdiv (fdx, em);
            fdy = fpdiv (fdy, em);
        }

        if (FC_ISTTFMT16(&if_state.fcCur))
        {   
            vertical_metric = if_state.cs.yDescender;      
            dx = vertical_metric;
            dy = -(if_state.cs.du_emx + vertical_metric);
            em = fpint2fp ((SL32) if_state.cs.du_emx);
            fdx = fpint2fp((SL32)dx);
            fdy = fpint2fp((SL32)dy);
            fdx = fpdiv (fdx, em);
            fdy = fpdiv (fdy, em);
        }
        
        adjx = fp2long( fpadd ( fpmul (fdx, if_state.m[0] ),
                           fpmul (fdy, if_state.m[2] ) ) );
        adjy = fp2long( fpadd ( fpmul (fdx, if_state.m[1] ),
                           fpmul (fdy, if_state.m[3] ) ) );

         if_state.cs.origin_cs.x = (adjx * 64);
         if_state.cs.origin_cs.y = (adjy * 64);

        return (ttrender ( FSA if_state.out_instance,if_state.pbucket,
              if_state.cs.origin_cs.x, if_state.cs.origin_cs.y));
        
    
    }    /* ISOUTLINE && ISUFSTVERT && CharVertWrit */

    /* default case */
    return (ttrender ( FSA if_state.out_instance, if_state.pbucket,
                -if_state.cs.origin_cs.x, -if_state.cs.origin_cs.y));
    break;    
       
#endif    /* TT_RDR */
/* keb 12/99 end */

#if FCO_RDR
      case FC_FCO_TYPE:
       return (fco_render ( FSA if_state.out_instance,
                            if_state.pbucket, 0L, 0L));
       break;
#endif
      default:
         return (ERR_fst_type);
   }
  }

    else
    {
#if IF_RDR
        status = if_state.out.start_char ( FSA if_state.out_instance,
                                                     (PVOID)&if_state.cs );
        if (status)
           return status;

        for(pn=0, cd=if_state.chr_def; pn<if_state.chr_def_hdr.num_parts; pn++, cd++)
        {
            status = make_char_part(FSA pn, cd);
            if (status)
               return status;
        }
        return if_state.out.end_char ( FSA if_state.out_instance );
#endif
    }
    return SUCCESS;
}
#endif /* OUTLINE || (NON_Z_WIND && (BOLD_P6 || BOLD_HORIZONTAL)) */
 

path.c  、、、、、、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/DA/PATH.C_V   1.18   Aug 22 2003 08:53:40   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/DA/PATH.C_V  $ 
 * 
 *    Rev 1.18   Aug 22 2003 08:53:40   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.17   Jul 03 2003 18:33:30   Galejs
 * after all these years, you'd think I'd be able to copy a string on the first try...
 * 
 *    Rev 1.16   Jun 23 2003 16:25:52   Galejs
 * fix compiler warning; ufstport.h
 * 
 *    Rev 1.15   03 Mar 2000 11:50:48   JOE
 * Make PATH_DELIM '\\' and PATH_DELIM2 '\0' when _OSK is defined (by ks).
 * 
 *    Rev 1.14   Jan 28 2000 15:08:14   galejs
 * test for DISK_FONTS rather than !ROM
 * 
 *    Rev 1.13   Aug 16 1999 12:04:50   galejs
 * include-file changes
 * 
 *    Rev 1.12   20 Jan 1999 13:56:52   GALEJS
 * ALPHA becomes UFST_ALPHA_UNIX
 * 
 *    Rev 1.11   02 Apr 1998 18:26:52   GALEJS
 * ufst_path, type_path now in if_state
 * 
 *    Rev 1.10   20 Mar 1998 12:01:18   GALEJS
 * 64-bit port
 * 
 *    Rev 1.9   03 Sep 1997 17:37:36   GALEJS
 * paths are irrelevant if not DISK mode
 * 
 *    Rev 1.8   24 Oct 1996 15:24:28   PVCSADMN
 * DBK Cleaned up annoying MIPS compiler warnings.
 * 
 *    Rev 1.7   07 Dec 1995 14:36:02   MERRILL
 * wipe warnings
 * 
 *    Rev 1.6   27 Nov 1995 11:44:42   MIKE
 * _OSK & _OS9000 support
 * 
 *    Rev 1.5   06 Apr 1995 15:14:42   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.4   22 Apr 1994 13:55:08   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.3   12 Feb 1993 13:15:22   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   06 Jan 1993 14:59:28   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 15:57:46   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 15:38:36   LISA
 * Initial revision.
*/
/* $Date:   Aug 22 2003 08:53:40  $ */
/* path.c */
/*
 *
 *
 *  HISTORY:
 *
 *    22-Jul-90  awr   Initialized ufstPath = "" for multicaller.
 *    23-Jul-90  awr   Merged Blake's default typeface path code in
 *    18-Aug-90  awr   Correct buildpath() to not insert a "\" at the
 *                     beginning if source1 is null.
 *     4-Feb-91  awr   Split off from ix.c
 *    17-Jun-91   jfd  Moved "debug.h" after "port.h".
 *                     Moved "cgconfig.h" before "port.h".
 *    03-Apr-92   rs   Portability cleanup (see port.h).
 *    20-May-92   jfd  Changed buildpath() by adding a second delimiter
 *                     (":" if LAMIGA) to prevent an invalid path from being
 *                     returned.
 *   1 Jul 92  ss      Changed conditional on SUN to UNIX to be more general.
 *                     Changed conditional order of PATH_DELIM to resolve
 *                     problem on MIPS which is confused by #elif.
 *                     (? Bug in the preprocessor? )
 *  08-Jul-92  rs      Code cleanup.
 *  19-Nov-92  rs      Port to Macintosh -> path delimiters ":".
 *  06-Jan-93  jfd     ANSI C function declaration changes.
 *  08-Feb-93  jfd     VXWorks support.
 *  27-Nov-95  mby     _OSK and _OS9000 support.
 *  24-Oct-96  dbk     Cleaned up annoying MIPS Compiler Warnings.
 *    03-Sep-97  slg         Paths are irrelevant if ROM (spacesaving)
 *  11-Mar-98  slg        Integrate Jim's Alpha-port change
 *    02-Apr-98  slg        Move GLOBALs ufst_path[], type_path[] into IF_STATE.
 *    18-Jan-99  slg        ALPHA case becomes UFST_ALPHA_UNIX.
 *  01-Mar-00  ks        Make PATH_DELIM '\\' and PATH_DELIM2 '\0' when _OSK
 *                        is defined, for printronix.
 */

#include <stdio.h>
#include "cgconfig.h"

/* this file is only needed for disk-based code */
#if DISK_FONTS

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

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

#include "shareinc.h"

#include "mixmodel.h"

/* UNIX-style paths */
#if defined (UFST_UNIX) || defined (UFST_ALPHA_UNIX) || defined (_OS9000) || defined(MIPS)   /* 03-11-98 */
#define PATH_DELIM      '/'
#define PATH_DELIM2     '\0'
/* DOS-style paths */
#else
#define PATH_DELIM      '\\'
#define PATH_DELIM2     '\0'
#endif

/*------------------*/
/*  buildpath       */
/*------------------*/
/*  Build the a full pathname in dest.  Assume source2 is either a simple
 *  filename or already the full pathname. Use the presence of a "\" to
 *  determine. source1 if the default directory path.
 *  If source1 is null or source2 contains a slash, copy source2 to dest.
 *  Otherwise, concatinate source1 and source2 in dest making sure that
 *  there is a "\" between them.
 */
#if defined (ANSI_DEFS)
GLOBAL VOID  buildpath(LPSB8 dest, LPSB8 source1, LPSB8 source2)
#else
GLOBAL VOID
buildpath(dest, source1, source2)
   LPSB8  dest, source1, source2;
#endif
{
    LPSB8 p, q;

  /* See if source2 contains "\" */
    q = source2;
    while ((*q) && ((*q) != PATH_DELIM) && ((*q) != PATH_DELIM2) )
       ++q;

    p = dest;
    if(! *q)              /* It doesn't, so assume source2 filename only */
    {
        if(*source1)        /* copy default directory path */
        {
            while(*source1)
                *p++ = *source1++;

            --p;              /* make sure a '\' seperates */
            if(*p != PATH_DELIM && (*p != PATH_DELIM2) ) {
                p++;
                *p++ = PATH_DELIM;
            }
            else ++p;
       }
     }

    while(*source2)
        *p++ = *source2++;
    *p = 0;    /* null-terminated strings work better... */
}
#endif    /* DISK_FONTS */
 

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值