T168_111\appl\Text\Agfa:第1~6个文件

adj_skel.h   、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/SYS/INC/ADJ_SKEL.H_V   1.9   Aug 22 2003 09:42:16   LynchR  $ */
/* $Log:   I:/BULL/URIP/SYS/INC/ADJ_SKEL.H_V  $ 
 * 
 *    Rev 1.9   Aug 22 2003 09:42:16   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.8   Sep 23 2002 14:27:28   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.7   22 Jun 1998 16:47:46   GALEJS
 * fn prototypes modified for reentrancy
 * 
 *    Rev 1.6   30 Mar 1998 11:39:04   GALEJS
 * move ADJUSTED_SKEL typedef into if_type.h
 * 
 *    Rev 1.5   10 Jan 1997 13:29:50   DAVID
 * Removed ELASTIC_X and ELASTIC_Y option as part of project to trim ufst.
 * 
 *    Rev 1.4   07 Apr 1995 11:30:46   LISA
 * Changed copyright information from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.3   22 Apr 1994 15:31:06   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.2   14 Jan 1993 11:04:52   LISA
 * Removed CntrlZ character
 * 
 *    Rev 1.1   14 Dec 1992 08:48:04   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 11:37:54   LISA
 * Initial revision.
*/
/* $Date:   Aug 22 2003 09:42:16  $ */
/*
*  adjust_skel.h
*
*
*

*  History:
*  ---------
*    1-Nov-87    Initial Release
*   23-Jan-88    incorporated intermed in adjust_skel_type struct (tbh)
*    4-Feb-88    changed num_seg_p_loop from UWORD to WORD (tbh)
*   31-Jan-91    Changed history order, added support for MSC multi-model
*                compilation.  change "adjusted_skel_type" to uppercase
*                "ADJUSTED_SKEL" to be consistent with the rest of the code.
*    8-Jul-91    Added elasticity
*    2-Apr-92 jfd  In structure ADJUSTED_SKEL, made the following changes:
*                  1.) Added field "baseproj".
*                  2.) Removed fields "pixel_grid_line", "processing_status"
*                      and "parent".
*                  3.) Conditionally compiled fields "remainder" and 
*                      "num_breaks" based on ELASTIC*.
*                These changes are in conjunction with changes made to IF 3.0
*   02-Apr-92    Portability cleanup (BYTE, WORD, LONG, etc) (see port.h).
*   14-Nov-92 rs Port to Mac - rename italic() to cgitalic(), bold() to cgbold().
*   10-Jan-97 dlk Removed ELASTIC_X and ELASTIC_Y as part of project to
*                trim ufst.  This droppie two fields from ADJUSTED_SKEL struct.
*    27-Mar-98 slg    Move ADJUSTED_SKEL typedef into "if_type.h"

*/

#ifndef __ADJ_SKEL__
#define __ADJ_SKEL__

#ifdef LINT_ARGS
EXTERN VOID    yclass(FSP PADJUSTED_SKEL);
EXTERN BOOLEAN skel_proc(FSP PSKEL, PDIMENSION, PCOORD_DATA,
                                            PADJUSTED_SKEL, SW16);
EXTERN VOID    cgitalic(FSP PADJUSTED_SKEL, PADJUSTED_SKEL);
EXTERN VOID    cgbold(FSP PADJUSTED_SKEL, PADJUSTED_SKEL);
EXTERN UW16   manipulate(FSP PADJUSTED_SKEL, PADJUSTED_SKEL);
EXTERN VOID    init_xy_tran(FSP PADJUSTED_SKEL, PADJUSTED_SKEL);
#else
EXTERN VOID    yclass();
EXTERN BOOLEAN skel_proc ();
EXTERN VOID    cgitalic();
EXTERN VOID    cgbold();
EXTERN UW16   manipulate();
EXTERN VOID    init_xy_tran();
#endif

#endif    /* __ADJ_SKEL__ */


 

AgfaText.c  //

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define AGFATEXT_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

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

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XComm.h"
#include "XFileSys.h"
#include "XText.h"
#include "XCodePage.h"

#include "..\FriBidi\fribidi.h"

#if defined(__HITACHI__)
#pragma section Font
#endif

#if defined(DPL)
#include "utt.h"
#include "umt.h"
#endif

#include "zbrplg.h"
#include "zbr___zg.h"

#if defined(DPL)
#include "tsc___za.h"
#endif

#if defined(__HITACHI__)
#pragma section 
#endif

#undef CONST

#include "cgconfig.h"        /* this must be first  */
#include "ufstport.h"        /* this must be second */
#include "shareinc.h"
#include "mixmodel.h"
#include "dbg_ufst.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#define MAX_OPEN_LIBRARIES    2    /* max # of open library files */

/*
 * Sizes of CACHE and BUFFER memory pools. These can be modified
 */

#define NUM_PAGES            3

#if DISK_FONTS
#define CACHE_SIZE            0x80000L
#define BUFFR_SIZE            0x100000L
#define CHARGEN_SIZE        0x40000L
#else
#define CACHE_SIZE            0x10000L
#define BUFFR_SIZE            0x8000L
#define CHARGEN_SIZE        0x8000L
#endif

/*
 * Set max size for saving character in cache.
 */

#if CACHE
#if !defined(GRAYBENCH)
#define CACHE_CHAR            0x4000
#else
#define CACHE_CHAR            1    /* disables caching */
#endif
#endif


/* Platform        Platform ID (PID) */
/*-----------------------------------*/
/* Apple Unicode        0            */
/* Macintosh            1            */
/* ISO                  2            */
/* Microsoft            3            */

#define PID_APPLE_UNICODE            0    // Apple Unicode
#define PID_MACINTOSH                1    // Macintosh
#define PID_ISO                        2    // ISO
#define PID_MICROSOFT                3    // Microsoft

/* Platform ID = 1                   */
/* Script          Encoding ID (EID) */
/*-----------------------------------*/
/* Roman                0            */
/* Japanese             1            */
/* Chinese              2            */
/* Korean               3            */
/* Arabic               4            */
/* Hebrew               5            */
/* Greek                6            */
/* Russian              7            */
/* Roman Symbol         8            */
/* Devanagari           9            */
/* Gurmukhi            10            */
/* Gujarati            11            */
/* Oriya               12            */
/* Bengali             13            */
/* Tamil               14            */
/* Telugu              15            */
/* Kannada             16            */
/* Malayalam           17            */
/* Sinhalese           18            */
/* Burmese             19            */
/* Khmer               20            */
/* Thai                21            */
/* Laotian             22            */
/* Georgian            23            */
/* Armenian            24            */
/* Maldivian           25            */
/* Tibetan             26            */
/* Mongolian           27            */
/* Geez                28            */
/* Slavic              29            */
/* Vietnamese          30            */
/* Sindhi              31            */
/* Uninterpreted       32            */

#define EID_ROMAN                    0    // Roman
#define EID_JAPANESE                1    // Japanese
#define EID_CHINESE                    2    // Chinese
#define EID_KOREAN                    3    // Korean
#define EID_ARABIC                    4    // Arabic
#define EID_HEBREW                    5    // Hebrew
#define EID_GREEK                    6    // Greek
#define EID_RUSSIAN                    7    // Russian
#define EID_ROMAN_SYMBOL            8    // Roman Symbol
#define EID_DEVANAGARI                9    // Devanagari
#define EID_GURMUKHI                10    // Gurmukhi
#define EID_GUJARATI                11    // Gujarati
#define EID_ORIYA                    12    // Oriya
#define EID_BENGALI                    13    // Bengali
#define EID_TAMIL                    14    // Tamil
#define EID_TELUGU                    15    // Telugu
#define EID_KANNADA                    16    // Kannada
#define EID_MALAYALAM                17    // Malayalam
#define EID_SINHALESE                18    // Sinhalese
#define EID_BURMESE                    19    // Burmese
#define EID_KHMER                    20    // Khmer
#define EID_THAI                    21    // Thai
#define EID_LAOTIAN                    22    // Laotian
#define EID_GEORGIAN                23    // Georgian
#define EID_ARMENIAN                24    // Armenian
#define EID_MALDIVIAN                25    // Maldivian
#define EID_TIBETAN                    26    // Tibetan
#define EID_MONGOLIAN                27    // Mongolian
#define EID_GEEZ                    28    // Geez
#define EID_SLAVIC                    29    // Slavic
#define EID_VIETNAMESE                30    // Vietnamese
#define EID_SINDHI                    31    // Sindhi
#define EID_UNINTERPRETED            32    // Uninterpreted

/* Platform ID = 2                   */
/* Encoding        Encoding ID (EID) */
/*-----------------------------------*/
/* ASCII                0            */
/* ISO 10646            1            */
/* ISO 8859-1           2            */

#define EID_ASCII                    0    // ASCII
#define EID_ISO_10646                1    // ISO 10646
#define EID_ISO_8859_1                2    // ISO 8859-1

/* Platform ID = 3                   */
/* Encoding        Encoding ID (EID) */
/*-----------------------------------*/
/* Symbol               0            */
/* Unicode 2.0          1            */
/* Shift JIS            2            */
/* GB 2312 (1980)       3            */
/* Big 5                4            */
/* KSC 5601 (Wansung)   5            */
/* KSC 5601 (Johab)     6            */

#define EID_SYMBOL                    0    // Symbol
#define EID_UNICODE                    1    // Unicode 2.0
#define EID_SJIS                    2    // Shift JIS
#define EID_GB2312                    3    // GB 2312 (1980)
#define EID_BIG5                    4    // Big 5
#define EID_KSC_WANSUNG                5    // KSC 5601 (Wansung)
#define EID_KSC_JOHAB                6    // KSC 5601 (Johab)

/*        Microsoft Encodings        */
/* PlatformID EncodingID Description */
/*-----------------------------------*/
/*    3           0        Symbol    */
/*    3           1        Unicode   */
/*    3           2        ShiftJIS  */
/*    3           3        PRC       */
/*    3           4        Big5      */
/*    3           5        Wansung   */
/*    3           6        Johab     */
/*    3           7        Reserved  */
/*    3           8        Reserved  */
/*    3           9        Reserved  */
/*    3          10        UCS-4     */


/* 00-FF */
#define TTF_TYPE_SINGLE_RAW            0
#define TTF_TYPE_SINGLE_ENCODE        1
#define TTF_TYPE_SINGLE_LEFT        2
#define TTF_TYPE_SINGLE_RIGHT        3
#define TTF_TYPE_SINGLE_REMAP        4

/* 0000-FFFF */
#define TTF_TYPE_DOUBLE_RAW            5
#define TTF_TYPE_DOUBLE_ENCODE        6

/* 00-7F, 8000-FFFF */
#define TTF_TYPE_MULTI_RAW            7
#define TTF_TYPE_MULTI_ENCODE        8
#define TTF_TYPE_MULTI_BIG5            9
#define TTF_TYPE_MULTI_GB            10
#define TTF_TYPE_MULTI_SJIS            11
#define TTF_TYPE_MULTI_KSC            12

#define TTF_TYPE_MULTI_UTF8            13
#define TTF_TYPE_MULTI_UTF16BE        14
#define TTF_TYPE_MULTI_UTF16LE        15

/* Some convenience macros */
#define IS_BIDI_TYPE(type) ( \
    type == TTF_TYPE_SINGLE_RIGHT  || \
    type == TTF_TYPE_DOUBLE_RAW    || \
    type == TTF_TYPE_DOUBLE_ENCODE || \
    type == TTF_TYPE_MULTI_RAW     || \
    type == TTF_TYPE_MULTI_ENCODE  || \
    type == TTF_TYPE_MULTI_UTF8    || \
    type == TTF_TYPE_MULTI_UTF16BE || \
    type == TTF_TYPE_MULTI_UTF16LE )

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    UW16 Unicode;
    UW16 Encode;
} ENCODE_INFO;

typedef struct
{
    CONST UW16 *Table;
    INTG Type;
} TT_CHAR_INFO;

typedef struct
{
    UW16    pool;    /* ufst memory pool that owns this page       */
    UL32    size;    /* size of page in bytes                      */
    LPSB8    ptr;    /* pointer to page                            */
    UW16    pg;        /* ufst handle of page returned by CGIFfund() */
} PAGE_INFO;

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

MLOCAL CONST TT_CHAR_INFO SingleRawCharInfo =
    { _NULL,                    TTF_TYPE_SINGLE_RAW        };    // 00-FF

MLOCAL CONST TT_CHAR_INFO DoubleRawCharInfo =
    { _NULL,                    TTF_TYPE_DOUBLE_RAW        };    // 0000-FFFF

MLOCAL CONST TT_CHAR_INFO MultiRawCharInfo =
    { _NULL,                    TTF_TYPE_MULTI_RAW        };    // 00-7F, 8000-FFFF

MLOCAL CONST TT_CHAR_INFO OtherCharInfo =
    { CodePage850ToUnicode,        TTF_TYPE_SINGLE_LEFT    };    // 850 = Multilingual

MLOCAL CONST TT_CHAR_INFO TsplCharInfo[] =
{
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // USA
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // BRI
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // GER
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // FRE
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // DAN
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // ITA
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // SPA
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // SWE
    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // SWI

    { CodePage437ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 437 = United States
    { CodePage850ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 850 = Multilingual
    { CodePage852ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 852 = Slavic
    { CodePage860ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 860 = Portuguese
    { CodePage863ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 863 = Canadian/French
    { CodePage865ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 865 = Nordic
    { CodePage857ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 857 = Turkish
    { CodePage861ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 861 = Iceland
    { CodePage862ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 862 = Hebrew
    { CodePage855ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 855 = Cyrillic
    { CodePage866ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 866 = Russian
    { CodePage737ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 737 = Greek
    { CodePage851ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 851 = Greek 1
    { CodePage869ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 869 = Greek 2

#if defined(TSPL_VER_2)
    { CodePage1252ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1252 = Latin I
    { CodePage1250ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1250 = Central Europe
    { CodePage1251ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1251 = Cyrillic
    { CodePage1253ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1253 = Greek
    { CodePage1254ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1254 = Turkish
    { CodePage1255ToUnicode,    TTF_TYPE_SINGLE_RIGHT    },    // 1255 = Hebrew
    { CodePage1256ToUnicode,    TTF_TYPE_SINGLE_RIGHT    },    // 1256 = Arabic
    { CodePage1257ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1257 = Baltic
    { CodePage1258ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 1258 = Vietnam
#endif

#if defined(ISO8859_CODEPAGE)
    { CodePage88591ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-1  = Latin 1
    { CodePage88592ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-2  = Latin 2
    { CodePage88593ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-3  = Latin 3
    { CodePage88594ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-4  = Baltic
    { CodePage88595ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-5  = Cyrillic
    { CodePage88596ToUnicode,    TTF_TYPE_SINGLE_RIGHT    },    // 8859-6  = Arabic
    { CodePage88597ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-7  = Greek
    { CodePage88598ToUnicode,    TTF_TYPE_SINGLE_RIGHT    },    // 8859-8  = Hebrew
    { CodePage88599ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-9  = Turkish
    { CodePage885910ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-10 = Nordic
    { CodePage885915ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 8859-15 = Nordic
#endif

#if defined(UNICODE_CODEPAGE)
    { _NULL,                    TTF_TYPE_MULTI_UTF8        },    // UTF-8 = Unicode Character Set
#endif

#if defined(AGFA_DBYTE)
    { BIG5ToUnicode,            TTF_TYPE_MULTI_BIG5        },    // 950
    { GBToUnicode,                TTF_TYPE_MULTI_GB        },    // 936
    { SJISToUnicode,            TTF_TYPE_MULTI_SJIS        },    // 932
    { KSCToUnicode,                TTF_TYPE_MULTI_KSC        },    // 949
#endif
};

#if defined(ZPL2)
MLOCAL CONST TT_CHAR_INFO ZplCharInfo[] =
{
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  0 = U.S.A. 1
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  1 = U.S.A. 2
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  2 = U.K.
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  3 = Holland
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  4 = Denmark/Norway
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  5 = Sweden/Finland
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  6 = Germany
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  7 = France 1
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  8 = France 2
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    //  9 = Italy
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    // 10 = Spain
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    // 11 = Miscellaneous
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    // 12 = Japan (ASCII with Yen symbol)
    { ZFontToUnicode,            TTF_TYPE_SINGLE_REMAP    },    // 13 = Zebra Code Page 850
    { _NULL,                    TTF_TYPE_DOUBLE_ENCODE    },    // 14 = Double Byte Asian Encodings
    { _NULL,                    TTF_TYPE_DOUBLE_ENCODE    },    // 15 = Shift-JIS
    { _NULL,                    TTF_TYPE_DOUBLE_RAW        },    // 16 = EUC-JP and EUC-CN
    { _NULL,                    TTF_TYPE_MULTI_UTF8        },    // 17 = Deprecated - UCS-2 Big Endian
    { _NULL,                    TTF_TYPE_SINGLE_RAW        },    // 18 = Reserved
    { _NULL,                    TTF_TYPE_SINGLE_RAW        },    // 19 = Reserved
    { _NULL,                    TTF_TYPE_DOUBLE_RAW        },    // 20 = Reserved
    { _NULL,                    TTF_TYPE_DOUBLE_RAW        },    // 21 = Reserved
#if defined(AGFA_DBYTE)
    { KSCToUnicode,                TTF_TYPE_MULTI_KSC        },    // 22 = Reserved (Force this character set to use KSC)
#else
    { _NULL,                    TTF_TYPE_MULTI_RAW        },    // 22 = Reserved
#endif
    { _NULL,                    TTF_TYPE_MULTI_RAW        },    // 23 = Reserved
    { _NULL,                    TTF_TYPE_SINGLE_ENCODE    },    // 24 = Single Byte Asian Encodings
    { CodePage850ToUnicode,        TTF_TYPE_SINGLE_LEFT    },    // 25 = Reserved
    { _NULL,                    TTF_TYPE_MULTI_ENCODE    },    // 26 = Multibyte Asian Encodings with ASCII
    { CodePage1252ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 27 = Zebra Code Page 1252
    { _NULL,                    TTF_TYPE_MULTI_UTF8        },    // 28 = UTF-8 encoding
    { _NULL,                    TTF_TYPE_MULTI_UTF16BE    },    // 29 = UTF-16 Big-Endian encoding
    { _NULL,                    TTF_TYPE_MULTI_UTF16LE    },    // 30 = UTF-16 Little-Endian encoding
    { CodePage1250ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 31 = Zebra Code Page 1250
    { _NULL,                    TTF_TYPE_SINGLE_RAW        },    // 32 = Reserved
    { CodePage1251ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 33 = Code Page 1251
    { CodePage1253ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 34 = Code Page 1253
    { CodePage1254ToUnicode,    TTF_TYPE_SINGLE_LEFT    },    // 35 = Code Page 1254
    { CodePage1255ToUnicode,    TTF_TYPE_SINGLE_RIGHT    },    // 36 = Code Page 1255
};
#endif

MLOCAL ENCODE_INFO *EncodingTable = _NULL;
MLOCAL INTG EncodeTabSize = 0;

MLOCAL UW16 fco_index = 0;

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

MLOCAL FONTCONTEXT fontcontext;    /* our local FONTCONTEXT */

MLOCAL SW16 fcHandleCGTBC;
MLOCAL SW16 fcHandleCGTC;
MLOCAL SW16 fcHandlePlug;

INTG InitUFST(VOID)
{
    PAGE_INFO page_info[NUM_PAGES];
    IFCONFIG config_block;
    UW16  status;

#if INT_MEM_MGT
    PAGE_INFO* pg;
    UW16       ii;
#endif /* INT_MEM_MGT */

#if ROM
    LPUB8 ss_addr[3];
    SB8   *iffnt_addr;
#endif /*  ROM  */

    /* Set up default library path and ufst file locations */

#if DISK_FONTS
    strcpy (config_block.ufstPath, "");
    strcpy (config_block.typePath, "");
    config_block.num_files = MAX_OPEN_LIBRARIES;    /* max open library files */
#endif

#if CACHE
    config_block.max_char_size = CACHE_CHAR;
#endif

    config_block.bit_map_width = (UW16)RASTER_ORG;
    page_info[0].pool = CACHE_POOL;
    page_info[0].size = CACHE_SIZE;
    page_info[1].pool = BUFFER_POOL;
    page_info[1].size = BUFFR_SIZE;
    page_info[2].pool = CHARGEN_POOL;
    page_info[2].size = CHARGEN_SIZE;

    status = CGIFinit (FSA0);
    if (status)
    {
        SendPrintf ("CGIFinit() error: %d\n", status);
        return FALSE;
    }

    /*
     * This function is used to set the current UFST environment
     * parameters to those in the IFCONFIG structure. It may be
     * called any time to change any of the config parameters.
     */
    status = CGIFconfig (FSA &config_block);
    if (status)
    {
        SendPrintf ("CGIFconfig() error: %d\n", status);
        return FALSE;
    }

    /* If using CG internal memory manager then
     * Get memory from malloc for each page and give it to
     * CGIFfund(), otherwise ignore this code.
     */
#if INT_MEM_MGT
    pg = page_info;
    for (ii = 0; ii < NUM_PAGES; ii++, pg++)
    {
        if ((pg->ptr = malloc(pg->size)) == _NULL)
        {
            SendPrintf("malloc() page memory failed\n");
            return FALSE;
        }
        status = CGIFfund(FSA pg->pool, pg->ptr, (UL32)pg->size, &pg->pg);
        if (status)
        {
            SendPrintf("CGIFfund() error: %u\n", status);
            return FALSE;
        }
    }
#endif /* INT_MEM_MGT */

#if ROM
    /*  Setup symbol set and font blocks as if they were in ROM. */
    /*  This must be done BEFORE the call to CGIFenter().        */

    iffnt_addr = _NULL;
    ss_addr[0] = _NULL;
    ss_addr[1] = _NULL;
    ss_addr[2] = _NULL;

#if defined(DPL)
    ss_addr[SYMBOLSET_TT] = (LPUB8)utt;
    ss_addr[SYMBOLSET_MT] = (LPUB8)umt;
#endif

    /* Pass the addresses of the IF.FNT and IF.SS contents into ufst.   */
    /* Also do special processing required for ROM support.             */
    if (status = CGIFinitRomInfo( FSA (UB8 *)iffnt_addr, ss_addr ))
    {
        SendPrintf("CGIFinitRomInfo() failure: %u\n", status);
        return FALSE;
    }
#endif  /*  ROM  */

    /*
     * This function is used to load (IF.FNT or BLOCK_IF.FNT) and (UIF.SS,
     * UMT.SS, and UTT.SS) from disk or ROM. This function must be called
     * before any font or character generation calls are attempted.
     */
    status = CGIFenter (FSA0);
    if (status)
    {
        SendPrintf ("CGIFenter() error: %u\n", status);
        return FALSE;
    }

    /*
     * This function is used to open a new MicroType Font Collection Object.
     * The data item fcfnt_addr is either a null-terminated pathname string if disk
     * input is used, or is a pointer to the FCO if embedded in a ROM environment.
     * A handle to the FCO is returned to the application. The data item fcHandle is
     * used by the UFST MicroType subsystem to identify which FCO is currently in
     * use, and is passed back to UFST in the uppermost 16 bits of the font_id member
     * of the FONTCONTEXT structure.
     */

    /* The first call is for the core FCO */
    status = CGIFfco_Open(FSA(LPUB8 )CGTBC, (LPSW16 )&fcHandleCGTBC);
    if (status)
    {
        SendPrintf("CGIFfco_Open error %d\n", status);
        return FALSE;
    }

#if defined(DPL)
    /* The first call is for the core FCO */
    status = CGIFfco_Open(FSA(LPUB8 )CGTC, (LPSW16 )&fcHandleCGTC);
    if (status)
    {
        SendPrintf("CGIFfco_Open error %d\n", status);
        return FALSE;
    }
#endif

    /* The second call is for the plugin fco */
    status = CGIFfco_Open(FSA(LPUB8 )CGTBCplg, (LPSW16 )&fcHandlePlug);
    if (status)
    {
        SendPrintf("CGIFfco_Open error %d\n", status);
        return FALSE;
    }

    /*
     * In addition, the application must also call the interface function
     * CGIFfco_Plugin() if the plugin characters are not contained in the typeface
     * sensitive FCO.
     */

    /* This call identifies which FCO is the plugin */
    status = CGIFfco_Plugin(FSA (SW16)fcHandlePlug);
    if (status)
    {
        SendPrintf("CGIFfco_Plugin error %d\n", status);
        return FALSE;
    }

    return TRUE;
}

VOID *InstallEncodingTable(VOID *Table, INTG Size)
{
    VOID *OldTab  = EncodingTable;
    EncodingTable = Table;
    EncodeTabSize = Size / sizeof(ENCODE_INFO);
    return OldTab;
}

MLOCAL INTG CheckUnicodeEncode(UB8 *pFont, UW16 *pPlatID, UW16 *pSpecID) 
{
    CMAP_QUERY CampQuery;
    INT i;

    *pPlatID = 0;
    *pSpecID = 0;
    if (CGIFtt_cmap_query(pFont, 0, &CampQuery) != 0)
        return FALSE;

    for (i = 0; i < CampQuery.numCmap; i++)
    {
        if ((CampQuery.entry[i].platId == PID_MICROSOFT) &&
            (CampQuery.entry[i].specId == EID_UNICODE))
            return TRUE;
    }

    for (i = 0; i < CampQuery.numCmap; i++)
    {
        if (CampQuery.entry[i].platId == PID_MICROSOFT)
            break;
    }
    if (i == CampQuery.numCmap)
        i = 0;

    *pPlatID = CampQuery.entry[i].platId;
    *pSpecID = CampQuery.entry[i].specId;
    return FALSE;
}

MLOCAL BOOLEAN set_up_fontcontext(_FontAttr *pFontAttr)
{
    UW16 PlatID, SpecID;

    /* Make sure all fields of FONTCONTEXT are set to zero initially */
    memset(&fontcontext, 0, sizeof(FONTCONTEXT));

    /* Set default fontcontext */

    fontcontext.font_id    = 0;
    fontcontext.xspot      = F_ONE;        /* 1.0 */
    fontcontext.yspot      = F_ONE;        /* 1.0 */
#if BOLD || BOLD_FCO
    fontcontext.xbold      = 0;            /* disabled */
    fontcontext.ybold      = 0;            /*   "      */
#endif
    fontcontext.ssnum      = UNICODE;
    fontcontext.format     = FC_FCO_TYPE | FC_ROM_TYPE;
    fontcontext.ExtndFlags = 0;
#if (PCLEO_RDR || PST1_RDR || TT_RDR)
    fontcontext.font_hdr   = (LPUB8)0;    /* pointer to PCLEO font header */
#endif

#if defined(DPL)
    if (pFontAttr->iFontType == AGFA_FONT_TYPE_CGT)
        fontcontext.font_id = fco_index | (fcHandleCGTC  << 16);
#endif
    if (pFontAttr->iFontType == AGFA_FONT_TYPE_CGT_BOLD)
        fontcontext.font_id = fco_index | (fcHandleCGTBC << 16);

    if (pFontAttr->iFontType == AGFA_FONT_TYPE_DOWNLOAD)
    {
        fontcontext.format = FC_TT_TYPE | FC_NON_Z_WIND;
#if DISK_FONTS
        strcpy(fontcontext.FileName, (CHAR *)pFontAttr->pFont);
        fontcontext.font_hdr = (LPUB8)fontcontext.FileName;
#elif ROM
        fontcontext.format  |= FC_ROM_TYPE;
        fontcontext.font_hdr = (LPUB8)pFontAttr->lpGetAddrPoint();
#endif
        fontcontext.ssnum = UNICODE;
        if (!CheckUnicodeEncode(fontcontext.font_hdr, &PlatID, &SpecID))
        {
            if (PlatID == 0 && SpecID == 0)
                return FALSE;
            fontcontext.ssnum       = USER_CMAP;
            fontcontext.user_platID = PlatID;
            fontcontext.user_specID = SpecID;
        }
    }

    if (pFontAttr->eLanguage == LANG_DPL)
        fontcontext.ssnum = (UW16)pFontAttr->iSymbolSet;

    fontcontext.fc_type = FC_MAT1_TYPE;

    switch (pFontAttr->iRotation)
    {
        case 0:
            fontcontext.s.m1.m[0] = 1;
            fontcontext.s.m1.m[1] = 0;
            fontcontext.s.m1.m[2] = 0;
            fontcontext.s.m1.m[3] = 1;
            break;
        case 90:
            fontcontext.s.m1.m[0] = 0;
            fontcontext.s.m1.m[1] = -1;
            fontcontext.s.m1.m[2] = 1;
            fontcontext.s.m1.m[3] = 0;
            break;
        case 180:
            fontcontext.s.m1.m[0] = -1;
            fontcontext.s.m1.m[1] = 0;
            fontcontext.s.m1.m[2] = 0;
            fontcontext.s.m1.m[3] = -1;
            break;
        case 270:
            fontcontext.s.m1.m[0] = 0;
            fontcontext.s.m1.m[1] = 1;
            fontcontext.s.m1.m[2] = -1;
            fontcontext.s.m1.m[3] = 0;
            break;
    }

    fontcontext.s.m1.em_width = pFontAttr->iHoriMulti * 256 * 4;
    fontcontext.s.m1.em_depth = pFontAttr->iVertMulti * 256 * 4;

    fontcontext.s.m1.matrix_scale = 2;
    fontcontext.s.m1.em_scale     = 8;

    return TRUE;
}

#if CHAR_HANDLE

MLOCAL UW16 make_char_bitmap(UL32 chId, _FontAttr *pFontAttr)
{
    _ImgBuf sImage;
    UW16 status;
    UL32 buffer;
    INTG X, Y;

    HIFBITMAP  hbm = NIL_MH;

    PIFBITMAP  pbm = NULL;
    PIFOUTLINE pol = NULL;

    status = CGIFFwidth(chId, 1, 4, &buffer);

    status = CGIFchar_handle(FSA chId, (PHIFBITMAP)&hbm, (SW16)0);
    if (status)
    {
        SendPrintf("CGIFchar_handle error %d\n", status);
        return status;
    }

    /* Need to de-reference the memory handle before use. */

    if (FC_ISBITMAP(&fontcontext) && !status)
    {
        pbm = (PIFBITMAP)MEMptr(hbm);
        X = pFontAttr->sCoord.iX;
        Y = pFontAttr->sCoord.iY;
        sImage.iWidth     = pbm->black_width;
        sImage.iByteWidth = pbm->width;
        sImage.iHeight    = pbm->depth;
        sImage.pBuffer    = (UB8 *)pbm->bm;    // be aware of CHUNK size(8 or 16)

        pFontAttr->sCoord.iX += pbm->xorigin; 
        PutImage(pFontAttr->psImageBuffer, &sImage, X, Y, pFontAttr->iRotation, pFontAttr->ePutWay);
        pFontAttr->sCoord.iX += (buffer&0xffff)*200*fontcontext.set_size/(72*8782*8*2) - pbm->xorigin;
    }
    else if (FC_ISOUTLINE(&fontcontext) && !status)
    {
        pol = (PIFOUTLINE)pbm;
    }

    /* Here, check for valid memory handle and free bitmap memory. */

    if(hbm)
    {
        CHARfree(FSA hbm);
        hbm = NIL_MH;
    }

    return 0;
}

#elif CACHE

MLOCAL UW16 make_char_bitmap(UL32 chId, _FontAttr *pFontAttr)
{
    UW16 status;
    UL32 advance;
    INTG orientation;

    PIFBITMAP  pbm = NULL;
    PIFOUTLINE pol = NULL;
    BOOL findChar = FALSE;

    while (1)
    {
           status = CGIFchar(chId, &pbm, (SW16)0);

        // character is a fixed space
        if (status == ERR_fixed_space)
            break;

        // can't find cgnum in char. index
        if (status == ERR_find_cgnum)
        {
            if (findChar == FALSE)
            {
                findChar = TRUE;
                chId = ' ';
                continue;
            }
        }

        // other error
        if (status)
        {
            SendPrintf("CGIFchar error %d\n", status);
            return status;
        }

        // make ok
        break;
    }

    orientation = (360 - pFontAttr->iRotation + pFontAttr->iDirection) % 360;

    if (pFontAttr->iFontType == AGFA_FONT_TYPE_DOWNLOAD)
        advance = (pFontAttr->iHoriMulti * pbm->escapement + (pbm->du_emx >> 1)) / pbm->du_emx;
    else
        advance = (pFontAttr->iHoriMulti * pbm->escapement + (8782 >> 1)) / 8782;

    if (orientation == 0 || orientation == 180)
    {
        pFontAttr->iTextWidth += advance;
        pFontAttr->iTextHeight = pFontAttr->iVertMulti;
    }
    else
    {
        pFontAttr->iTextWidth = pFontAttr->iHoriMulti;
        pFontAttr->iTextHeight += pFontAttr->iVertMulti;
        advance = pFontAttr->iVertMulti;
    }

    if (status == ERR_fixed_space)
    {
        if (pFontAttr->iDirection == 0)
            pFontAttr->sCoord.iX += advance;
        else if (pFontAttr->iDirection == 90)
            pFontAttr->sCoord.iY += advance;
        else if (pFontAttr->iDirection == 180)
            pFontAttr->sCoord.iX -= advance;
        else if (pFontAttr->iDirection == 270)
            pFontAttr->sCoord.iY -= advance;

        return 0;
    }

    if (FC_ISBITMAP(&fontcontext) && !status)
       {
        _ImgBuf sImage;
        SW16 X, Y;

        if (orientation == 180 || orientation == 270)
        {
            if (pFontAttr->iDirection == 0)
                pFontAttr->sCoord.iX += advance;
            else if (pFontAttr->iDirection == 90)
                pFontAttr->sCoord.iY += advance;
            else if (pFontAttr->iDirection == 180)
                pFontAttr->sCoord.iX -= advance;
            else if (pFontAttr->iDirection == 270)
                pFontAttr->sCoord.iY -= advance;
        }

        X = pFontAttr->sCoord.iX + pbm->xorigin / 16;
        Y = pFontAttr->sCoord.iY - pbm->yorigin / 16;
        sImage.iWidth     = pbm->black_width;
        sImage.iByteWidth = pbm->width;
        sImage.iHeight    = pbm->depth;
        sImage.pBuffer    = (UB8 *)pbm->bm;    // be aware of CHUNK size(8 or 16)

        if (pFontAttr->iRotation == 0)
            Y += (pFontAttr->iVertMulti * 3 + 3 >> 2) + 1;
        else if (pFontAttr->iRotation == 90)
            X -= (pFontAttr->iVertMulti * 3 + 3 >> 2) + 1;
        else if (pFontAttr->iRotation == 180)
            Y -= (pFontAttr->iVertMulti * 3 + 3 >> 2) + 1;
        else if (pFontAttr->iRotation == 270)
            X += (pFontAttr->iVertMulti * 3 + 3 >> 2) + 1;

        PutImage(pFontAttr->psImageBuffer, &sImage, X, Y, 0, pFontAttr->ePutWay);

        if (orientation == 0 || orientation == 90)
        {
            if (pFontAttr->iDirection == 0)
                pFontAttr->sCoord.iX += advance;
            else if (pFontAttr->iDirection == 90)
                pFontAttr->sCoord.iY += advance;
            else if (pFontAttr->iDirection == 180)
                pFontAttr->sCoord.iX -= advance;
            else if (pFontAttr->iDirection == 270)
                pFontAttr->sCoord.iY -= advance;
        }
    }
    return 0;
}

#endif

MLOCAL INTG DecodeCharID(TT_CHAR_INFO *pCharInfo, UB8 *pData, UL32 *CharID)
{
    INTG Length = 0;
    INTG Index;

    switch (pCharInfo->Type)
    {
        case TTF_TYPE_SINGLE_RAW:
            *CharID = *pData;
            Length  = 1;
            break;

        case TTF_TYPE_SINGLE_ENCODE:
            *CharID = *pData;
            for (Index = 0; EncodingTable && Index < EncodeTabSize; Index++)
            {
                if (EncodingTable[Index].Encode == *CharID)
                {
                    *CharID = EncodingTable[Index].Unicode;
                    break;
                }
            }
            Length = 1;
            break;

        case TTF_TYPE_SINGLE_LEFT:
        case TTF_TYPE_SINGLE_RIGHT:
        case TTF_TYPE_SINGLE_REMAP:
            *CharID = pCharInfo->Table[*pData];
            Length  = 1;
            break;

        case TTF_TYPE_DOUBLE_RAW:
            *CharID = (*pData) * 256 + *(pData + 1);
            Length  = 2;
            break;

        case TTF_TYPE_DOUBLE_ENCODE:
            *CharID = (*pData) * 256 + *(pData + 1);
            for (Index = 0; EncodingTable && Index < EncodeTabSize; Index++)
            {
                if (EncodingTable[Index].Encode == *CharID)
                {
                    *CharID = EncodingTable[Index].Unicode;
                    break;
                }
            }
            Length = 2;
            break;

        case TTF_TYPE_MULTI_RAW:
            if (*pData < 0x80)
            {
                *CharID = *pData;
                Length  = 1;
            }
            else
            {
                *CharID = (*pData) * 256 + *(pData + 1);
                Length  = 2;
            }
            break;

        case TTF_TYPE_MULTI_ENCODE:
            if (*pData < 0x80)
            {
                *CharID = *pData;
                for (Index = 0; EncodingTable && Index < EncodeTabSize; Index++)
                {
                    if (EncodingTable[Index].Encode == *CharID)
                    {
                        *CharID = EncodingTable[Index].Unicode;
                        break;
                    }
                }
                Length = 1;
            }
            else
            {
                *CharID = (*pData) * 256 + *(pData + 1);
                for (Index = 0; EncodingTable && Index < EncodeTabSize; Index++)
                {
                    if (EncodingTable[Index].Encode == *CharID)
                    {
                        *CharID = EncodingTable[Index].Unicode;
                        break;
                    }
                }
                Length = 2;
            }
            break;

        case TTF_TYPE_MULTI_BIG5:
            if (*pData < 0xA1)
            {
                *CharID = *pData;
                Length  = 1;
            }
            else
            {
                *CharID = (*pData - 0xA1) * 157;
                if (*(pData + 1) >= 0xA1)
                    *CharID += *(pData + 1) - 0xA1 + 0x3F;
                else
                    *CharID += *(pData + 1) - 0x40;

                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            break;

        case TTF_TYPE_MULTI_GB:
            if (*pData < 0x81)
            {
                *CharID = *pData;
                Length  = 1;
            }
            else
            {
                if (*pData <= 0xA0)
                {
                    *CharID = (*pData - 0x81) * 190;
                    if (*(pData + 1) >= 0x80)
                        *CharID += *(pData + 1) - 0x80 + 0x3f;
                    else
                        *CharID += *(pData + 1) - 0x40;
                }
                else if (*pData <= 0xA7)
                {
                    *CharID = (*pData - 0xA1) * 94;
                    *CharID += *(pData + 1) - 0xA1;
                    *CharID += (0xA0 - 0x80) * 190;
                }
                else
                {
                    *CharID = (*pData - 0xA8) * 190;
                    if (*(pData + 1) >= 0x80)
                        *CharID += *(pData + 1) - 0x80 + 0x3f;
                    else
                        *CharID += *(pData + 1) - 0x40;

                    *CharID += (0xA0 - 0x80) * 190 + (0xA7 - 0xA0) * 94;
                }
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            break;

        case TTF_TYPE_MULTI_SJIS:
            if (*pData >= 0x81 && *pData <= 0x84)
            {
                *CharID =  (*pData - 0x81) * 188;
                if (*(pData + 1) >= 0x80)
                    *CharID += *(pData + 1) - 0x80 + 0x3f;
                else
                    *CharID += *(pData + 1) - 0x40;

                *CharID += (0xDF - 0xA0);
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            else if (*pData >= 0x88 && *pData <= 0x9F)
            {
                *CharID = (*pData - 0x88) * 188;
                if (*(pData + 1) >= 0x80)
                    *CharID += *(pData + 1) - 0x80 + 0x3f;
                else
                    *CharID += *(pData + 1) - 0x40;

                *CharID += (0xDF - 0xA0) + (0x84 - 0x80) * 188;
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            else if (*pData >= 0xA1 && *pData <= 0xDF)
            {
                *CharID = *pData - 0xA1 ;
                *CharID = pCharInfo->Table[*CharID];
                Length  = 1;
            }
            else if (*pData >= 0xE0)
            {
                *CharID = (INTG)(*pData - 0xE0) * 188;
                if (*(pData + 1) >= 0x80)
                    *CharID += *(pData + 1) - 0x80 + 0x3f;
                else
                    *CharID += *(pData + 1) - 0x40;

                *CharID += (0xDF - 0xA0) + ((0x84 - 0x80) + (0x9F - 0x87)) * 188;
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            else
            {
                *CharID = *pData;
                Length  = 1;
            }
            break;

        case TTF_TYPE_MULTI_KSC:
            if (*pData >= 0xA1 && *pData <= 0xAC)
            {
                *CharID =  (*pData - 0xA1) * 94;
                *CharID += *(pData + 1) - 0xA1;
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            else if (*pData >= 0xB0 && *pData <= 0xC8)
            {
                *CharID = (*pData - 0xB0) * 94;
                *CharID += *(pData + 1) - 0xA1;
                *CharID += (0xAC - 0xA0) * 94;
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            else if (*pData >= 0xCA)
            {
                *CharID = (INTG)(*pData - 0xCA) * 94;
                *CharID += *(pData + 1) - 0xA1;
                *CharID += ((0xAC - 0xA0) + (0xC8 - 0xAF)) * 94;
                *CharID = pCharInfo->Table[*CharID];
                Length  = 2;
            }
            else
            {
                *CharID = *pData;
                Length  = 1;
            }
            break;

        case TTF_TYPE_MULTI_UTF8:
            if (*pData < 0x80)
            {
                *CharID = *pData;
                Length = 1;
            }
            else if (*pData >= 192 && *pData <= 223)
            {
                *CharID  = (INTG)(*(pData + 0) - 192) * 64;
                *CharID += (INTG)(*(pData + 1) - 128);
                Length = 2;
            }
            else if (*pData >= 224 && *pData <= 239)
            {
                *CharID  = (INTG)(*(pData + 0) - 224) * 4096;
                *CharID += (INTG)(*(pData + 1) - 128) * 64;
                *CharID += (INTG)(*(pData + 2) - 128);
                Length = 3;
            }

            // Monotype 4.7 does not support unicode over 0x10000
            else if (*pData >= 240 && *pData <= 247)
            {
            //    *CharID  = (INTG)(*(pData + 0) - 240) * 262144;
            //    *CharID += (INTG)(*(pData + 1) - 128) * 4096;
            //    *CharID += (INTG)(*(pData + 2) - 128) * 64;
            //    *CharID += (INTG)(*(pData + 3) - 128);
            /**/*CharID = 0;
                Length = 4;
            }
            else if (*pData >= 248 && *pData <= 251)
            {
            //    *CharID  = (INTG)(*(pData + 0) - 248) * 16777216;
            //    *CharID += (INTG)(*(pData + 1) - 128) * 262144;
            //    *CharID += (INTG)(*(pData + 2) - 128) * 4096;
            //    *CharID += (INTG)(*(pData + 3) - 128) * 64;
            //    *CharID += (INTG)(*(pData + 4) - 128);
            /**/*CharID = 0;
                Length = 5;
            }
            else if (*pData == 252 && *pData == 253)
            {
            //    *CharID  = (INTG)(*(pData + 0) - 252) * 1073741824;
            //    *CharID += (INTG)(*(pData + 1) - 128) * 16777216;
            //    *CharID += (INTG)(*(pData + 2) - 128) * 262144;
            //    *CharID += (INTG)(*(pData + 3) - 128) * 4096;
            //    *CharID += (INTG)(*(pData + 4) - 128) * 64;
            //    *CharID += (INTG)(*(pData + 5) - 128);
            /**/*CharID = 0;
                Length = 6;
            }

            // There is something wrong
            else
            {
            /**/*CharID = 0;
                Length = 1;
            }

            break;

        case TTF_TYPE_MULTI_UTF16BE:
            *CharID  = *(pData + 0) * 256;
            *CharID += *(pData + 1);
            Length = 2;

            // Monotype 4.7 does not support unicode over 0x10000
            if (*CharID >= 0xD800 && *CharID <= 0xDFFF)
            {
            //    *CharID  = (*CharID & 0x03FF) * 1024;
            //    *CharID += (*(pData + 2) & 0x03) * 256;
            //    *CharID += (*(pData + 3) & 0xFF);
            /**/*CharID = 0;
                Length  = 4;
            }
            break;

        case TTF_TYPE_MULTI_UTF16LE:
            *CharID  = *(pData + 0);
            *CharID += *(pData + 1) * 256;
            Length = 2;

            // Monotype 4.7 does not support unicode over 0x10000
            if (*CharID >= 0xD800 && *CharID <= 0xDFFF)
            {
            //    *CharID  = (*CharID & 0x03FF) * 1024;
            //    *CharID += (*(pData + 2) & 0xFF);
            //    *CharID += (*(pData + 3) & 0x03) * 256;
            /**/*CharID = 0;
                Length  = 4;
            }
            break;
    }
    return Length;
}

MLOCAL VOID RemapByTable(UB8 *pTarget, CONST UB8 *pSource, INTG Length, CONST UB8 *pTable, CONST UB8 *RemapTable)
{
    while (Length-- > 0)
        *pTarget++ = *(pTable + *(RemapTable + *pSource++));
    *pTarget = '\0';
}

MLOCAL TT_CHAR_INFO *GetCharInfo(_FontAttr *pFontAttr)
{
    if (fontcontext.ssnum == USER_CMAP)
    {
        if (fontcontext.user_platID == PID_MICROSOFT)
        {
            if ((fontcontext.user_specID == EID_SJIS) ||
                (fontcontext.user_specID == EID_GB2312) ||
                (fontcontext.user_specID == EID_BIG5) ||
                (fontcontext.user_specID == EID_KSC_WANSUNG) ||
                (fontcontext.user_specID == EID_KSC_JOHAB))
                return (TT_CHAR_INFO *)&MultiRawCharInfo;
        }
        return (TT_CHAR_INFO *)&SingleRawCharInfo;
    }
    else if (pFontAttr->eLanguage == LANG_TSPL)
        return (TT_CHAR_INFO *)&TsplCharInfo[pFontAttr->iCodePage];
#if defined(ZPL2)
    else if (pFontAttr->eLanguage == LANG_ZPL)
        return (TT_CHAR_INFO *)&ZplCharInfo[pFontAttr->iCodePage];
#endif
    else if (pFontAttr->eLanguage == LANG_DPL)
        return (TT_CHAR_INFO *)&SingleRawCharInfo;

    return  (TT_CHAR_INFO *)&OtherCharInfo;
}

INTG PreviewAcfaFont(_FontAttr *pFontAttr)
{
    TT_CHAR_INFO *pCharInfo;
      PIFBITMAP pbm = NULL;
    UL32 chId = 0;
    UL32 advance;
    UW16 status;
    UB8 *pString;
    UB8 StrBuf[2048];
    INTG StrLen;
    INTG Orientation;
    INTG i;

    CGIFfont_access(ROM_ACCESS);
#if DISK_FONTS
    if (pFontAttr->iFontType == AGFA_FONT_TYPE_DOWNLOAD)
        CGIFfont_access(DISK_ACCESS);
#endif

    if (!set_up_fontcontext(pFontAttr))
        return FALSE;

    /*
     * This function is called to change the current font parameters in effect to those
     * contained in the font context structure FONTCONTEXT. Character bitmaps will 
     * subsequently be generated and cached based on the values in the FONTCONTEXT structure.
     */

    status = CGIFfont(FSA &fontcontext);    /* API pass the fontcontext info to UFST */
    if (status)
    {
        SendPrintf("CGIFfont() error: %d\n", status);
        return FALSE;
    }

    pCharInfo = GetCharInfo(pFontAttr);

    pString = pFontAttr->pExp;
    StrLen = pFontAttr->ExpLength;
    if (IS_BIDI_TYPE(pCharInfo->Type))
    {
        FriBidiParType base = FRIBIDI_PAR_LTR;
        FriBidiChar in_us[1024], out_us[1024];
        UW16 *uni16 = (UW16 *)StrBuf;
        INTG len = 0;

        /* Charset to unicode */
        for (i = 0; i < StrLen; i++)
            i += DecodeCharID(pCharInfo, pString + i, (in_us + len++)) - 1;
        pCharInfo = (TT_CHAR_INFO *)&DoubleRawCharInfo;
        StrLen = len * 2;

        /* Create a bidi string */
        fribidi_log2vis(in_us, len, &base, out_us, NULL, NULL, NULL);
        for (i = 0; i < len; i++)
            *(uni16 + i) = cpu_to_be16(*(out_us + i));
        pString = StrBuf;
    }
#if defined(ZPL2)
    if (pCharInfo->Type == TTF_TYPE_SINGLE_REMAP)
    {
        RemapByTable(StrBuf, pString, StrLen, ZplCodePageTable[pFontAttr->iCodePage], pFontAttr->pRemapChar);
        pString = StrBuf;
    }
#endif

    Orientation = (360 - pFontAttr->iRotation + pFontAttr->iDirection) % 360;

    pFontAttr->iTextWidth  = 0;
    pFontAttr->iTextHeight = 0;

    for (i = 0; i < StrLen; i++)
    {
        i += DecodeCharID(pCharInfo, pString + i, &chId) - 1;
           status = CGIFchar(chId, &pbm, (SW16)0);

        if (pFontAttr->iFontType == AGFA_FONT_TYPE_DOWNLOAD)
            advance = (pFontAttr->iHoriMulti * pbm->escapement + (pbm->du_emx >> 1)) / pbm->du_emx;
        else
            advance = (pFontAttr->iHoriMulti * pbm->escapement + (8782 >> 1)) / 8782;

        if (Orientation == 0 || Orientation == 180)
        {
            pFontAttr->iTextWidth += advance;
            pFontAttr->iTextHeight = pFontAttr->iVertMulti;
        }
        else
        {
            pFontAttr->iTextWidth = pFontAttr->iHoriMulti;
            pFontAttr->iTextHeight += pFontAttr->iVertMulti;
        }
    }

#if DISK_FONTS
    CGIFbucket_purge(DELETEALL);
#endif

    return 0;
}

INTG AgfaOutText(_FontAttr *pFontAttr)
{
    TT_CHAR_INFO *pCharInfo;
    UL32 chId = 0;
    UW16 status;
    UB8 *pString;
    UB8 StrBuf[2048];
    INTG StrLen;
    INTG i;

    CGIFfont_access(ROM_ACCESS);
#if DISK_FONTS
    if (pFontAttr->iFontType == AGFA_FONT_TYPE_DOWNLOAD)
        CGIFfont_access(DISK_ACCESS);
#endif

    if (!set_up_fontcontext(pFontAttr))
        return FALSE;

    /*
     * This function is called to change the current font parameters in effect to those
     * contained in the font context structure FONTCONTEXT. Character bitmaps will 
     * subsequently be generated and cached based on the values in the FONTCONTEXT structure.
     */

    status = CGIFfont(FSA &fontcontext);    /* API pass the fontcontext info to UFST */
    if (status)
    {
        SendPrintf("CGIFfont() error: %d\n", status);
        return FALSE;
    }

    pCharInfo = GetCharInfo(pFontAttr);

    pString = pFontAttr->pExp;
    StrLen = pFontAttr->ExpLength;
    if (IS_BIDI_TYPE(pCharInfo->Type))
    {
        FriBidiParType base = FRIBIDI_PAR_LTR;
        FriBidiChar in_us[1024], out_us[1024];
        UW16 *uni16 = (UW16 *)StrBuf;
        INTG len = 0;

        /* Charset to unicode */
        for (i = 0; i < StrLen; i++)
            i += DecodeCharID(pCharInfo, pString + i, (in_us + len++)) - 1;
        pCharInfo = (TT_CHAR_INFO *)&DoubleRawCharInfo;
        StrLen = len * 2;

        /* Create a bidi string */
        fribidi_log2vis(in_us, len, &base, out_us, NULL, NULL, NULL);
        for (i = 0; i < len; i++)
            *(uni16 + i) = cpu_to_be16(*(out_us + i));
        pString = StrBuf;
    }
#if defined(ZPL2)
    if (pCharInfo->Type == TTF_TYPE_SINGLE_REMAP)
    {
        RemapByTable(StrBuf, pString, StrLen, ZplCodePageTable[pFontAttr->iCodePage], pFontAttr->pRemapChar);
        pString = StrBuf;
    }
#endif

    pFontAttr->iTextWidth = 0;
    pFontAttr->iTextHeight = 0;

    for (i = 0; i < StrLen; i++)
    {
        i += DecodeCharID(pCharInfo, pString + i, &chId) - 1;
        status = make_char_bitmap(chId, pFontAttr);
        if (status && (status != 69) && (status != 607))
            return FALSE;
    }

#if DISK_FONTS
    CGIFbucket_purge(DELETEALL);
#endif

    return 0;
}

#if defined(AGFA_FS) && DISK_FONTS

INTG open(FILECHAR *path, INTG access)
{
    INTG handle;
    if ((handle = Open(DRAM_DEVICE,  path, access)) == (-1))
    if ((handle = Open(FLASH_DEVICE, path, access)) == (-1))
        (handle = Open(CARD_DEVICE,  path, access));
    return handle;
}

INTG close(INTG handle)
{
    return Close(handle);
}

SL32 lseek(INTG handle, SL32 offset, INTG fromwhere)
{
    return Lseek(handle, offset, fromwhere);
}

INTG read(INTG handle, VOID *buf, UINTG len)
{
    return Read(handle, buf, len);
}

#endif

bitio.c   //

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* Copyright (C) 1989 - 1996, 1997 all rights reserved,
 * by Bayer Corp., Agfa Division, Wilmington, MA.
 *
 * This software is furnished under a license and may be used and
 * copied only in accordance with the terms of such license and with
 * the inclusion of the above copyright notice. This software or any
 * other copies thereof may not be provided or otherwise made
 * available to any other person except as allowed under license. No
 * title to and ownership of the software is hereby transferred.
 *
 * This information in this software is subject to change without notice
 */
/* $Header:   I:/BULL/URIP/RTS/rac/BITIO.C_V   1.21   Oct 08 2004 09:09:14   wuq  $ */
/* $Log:   I:/BULL/URIP/RTS/rac/BITIO.C_V  $
 * 
 *    Rev 1.21   Oct 08 2004 09:09:14   wuq
 * Check numberOfBits read in function MTX_BITIO_ReadValue().
 * 
 *    Rev 1.20   Sep 19 2003 16:00:46   WuQ
 * Bug fix of losing information of the last entry of loca table.
 * 
 *    Rev 1.19   Sep 11 2003 10:46:30   WuQ
 * Fix for Reading ahead in ACT (for AL).
 * 
 *    Rev 1.18   Aug 22 2003 09:22:04   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.17   Aug 13 2003 15:47:34   LynchR
 * Added error checking for memory allocation.
 * 
 *    Rev 1.16   Jun 20 2003 15:04:46   Galejs
 * get rid of asserts; VOID
 * 
 *    Rev 1.15   Sep 25 2002 15:51:08   WuQ
 * Changes for CCC
 * 
 *    Rev 1.14   Jun 12 2001 18:56:18   Galejs
 * data-type cleanup (+ use SIZEOF_LONG rather than NAT_ALIGN after all...)
 * 
 *    Rev 1.13   May 03 2001 20:44:50   Galejs
 * data-type cleanup
 * 
 *    Rev 1.12   Jan 15 2001 09:33:28   Song
 * Changed const to CONST, uppercase to lowercase #include files
 * 
 *    Rev 1.11   Dec 11 2000 18:30:16   Galejs
 * use more-UFSTish test of NAT_ALIGN in place of SIZEOF_LONG test
 * 
 *    Rev 1.10   Oct 16 2000 15:45:52   Al
 * ACT 2 changes
 * 
 *    Rev 1.9   Sep 21 2000 14:01:38   galejs
 * change ACT error handling (no setjmp / longjmp)
 * 
 *    Rev 1.8   Feb 07 2000 15:52:44   galejs
 * unsigned long -> UL32, long ->SL32
 * 
 *    Rev 1.7   Dec 09 1999 16:05:28   galejs
 * get rid of unused functions
 * 
 *    Rev 1.6   May 24 1999 15:09:38   galejs
 * make ACT reentrant
 * 
 *    Rev 1.5   04 Sep 1997 17:04:42   MARTIN
 * Modified references to AGFA Compressed TrueType (ACT).
 * 
 *    Rev 1.4   29 Aug 1997 09:06:42   JOE
 * Revised last change to assert() calls for portability.
 * Removed comment beginning with "//".
 * 
 *    Rev 1.3   28 Aug 1997 15:09:16   JOE
 * Changed all assert() calls to return a status in order to resolve
 * WATCOM compiler warnings.
 * In ACT_BITIO_WriteValue(), cast arg 2 of call to ACT_BITIO_output_bit()
 * to "int" to resolve WATCOM compiler error.
 * 
 *    Rev 1.2   15 Aug 1997 14:57:36   JOE
 * Added non-ANSI function declarations.
 * Changed the include filenames to lowercase.
 * 
 *    Rev 1.1   30 Jun 1997 20:16:36   MIKE
 * Fixed line endings with unix2dos utility
 * 
 *    Rev 1.0   04 Jun 1997 10:56:50   MARTIN
 * Initial revision.
 */

/*
 * File:                        bitio.cpp
 * First Version:                February 6, 1996
 * First Memory Version:        September 27, 1996 
 * First pure ANSI C version:     October 28, 1996
 *
 * 07-Feb-00 slg    Don't use "long" dcls (incorrect if 64-bit platform).
 * 7-21-00     swp    Rewrote the entire mess for CANONICAL
 * 12-Jun-01 slg    Data-type cleanup; put back SIZEOF_LONG test in place of
 *                    more-UFSTish (but incorrect) NAT_ALIGN test - oops... 
 *    
 */
#include "cgconfig.h"

#if ( TT_ROM_ACT ) || CCC  

#include "ufstport.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "shareinc.h"

#include "config.h"
#include "ra_mem.h"
#include "bitio.h"

CONST static UB8 mask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

/****************************************************************/
/****************************************************************/

/****************************************************************/
/*
* This performance of this next routine is vital to the runtime
* performance of ACT. If speed were not an issue we could use the
* following code:
*
*    UL32 MTX_BITIO_ReadValue( BITIO *t, SL32 numberOfBits )
*        {
*        UB8 *array = t->array;
*        SL32 index = t->index;
*        UL32 r = 0;
*    
*        while (numberOfBits--)
*            {
*            r <<= 1;
*            if (array[index >> 3] & mask[index & 7])
*                r |= 1;
*            index++;
*            }
*        t->index = index;
*        return r;
*        }
*
*
* But speed is an issue and on my box (PentiumII) the real code
* which follows is 3x faster in decoding an average file.
*
* It would be well worthwhile to have an assembler geek spend a
* few days optimizing this code -- or changing the algorithm to
* take advantage of specialized instructions like the 'bitfield'
* instructions of the Motorola 680X0 family.
*
*/

CONST static UL32 mask32[] = {
    0x00000000,    
    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
    };
        
/****************************************************************/
/* get the next <numberOfBits> bits from the bitarray <t> */
#if defined (ANSI_DEFS)
UL32 MTX_BITIO_ReadValue( BITIO *t, SL32 numberOfBits )
#else
UL32 MTX_BITIO_ReadValue( t, numberOfBits )
    BITIO *t;
    SL32 numberOfBits;
#endif
    {
    UL32 first,last,r,mask;
    UB8 *p;
    SL32 n,shift;
    SL32 numberOfBitsRead;

    if ( !numberOfBits )
        return 0;

    if ( t->index + numberOfBits > t->max)
    {
        if (t->index >= t->max)
            r = 0;
        else
        {
            numberOfBitsRead = t->max - t->index;
            r = MTX_BITIO_ReadValue(t, numberOfBitsRead );
            r <<= ( numberOfBits - numberOfBitsRead );
            t->index = t->max;
        }
    }
    else
    {
        first = t->index >> 3;
        r = t->index + numberOfBits - 1;
        last = r >> 3;
        n = 1 + last - first;

        shift = 7 - (r & 7);
        mask = mask32[numberOfBits];
        p = t->array + first;
    
        switch(n)
            {
            case 1:
                r = *p;
                r >>= shift;
                r &= mask;
                break;
            case 2:
                r = *p++;
                r = (r << 8) | *p;
                r >>= shift;
                r &= mask;
                break;
            case 3:
                r = *p++;
                r = (r << 8) | *p++;
                r = (r << 8) | *p;
                r >>= shift;
                r &= mask;
                break;
            case 4:
                r = *p++;
                r = (r << 8) | *p++;
                r = (r << 8) | *p++;
                r = (r << 8) | *p;
                r >>= shift;
                r &= mask;
                break;
            default: 
                /* We can never span more than 5 bytes with <= 32 bits, but
                * we can span 5 bytes with as few as 26 requested bits, eg:
                * [.......x][xxxxxxxx][xxxxxxxx][xxxxxxxx][x.......] */
#if SIZEOF_LONG >= 5

                /* which is no problem on machines with longs of 40+ bits */
                {
                unsigned long temp;        /* this declaration is correct as "unsigned long" - DON'T CHANGE! (sandra, 12 Jun 01) */

                temp = *p++;
                temp = (temp << 8) | *p++;
                temp = (temp << 8) | *p++;
                temp = (temp << 8) | *p++;
                temp = (temp << 8) | *p;
                temp >>= shift;
                r = (UL32)temp & mask;
                }
#else 
                /* which is rather ugly on a 32 bit machine ... fortunately 
                * spans of 5 are rather uncommon ... only 28 of 256 possible
                * fetches span 5 bytes.  Moreover, they all occur for tokens
                * with very low frequency - a 26 bit code spanning 5 bytes
                * will occur once in every 2**29 fetches; a 32 bit code which
                * spans 5 bytes will occur once in every 7*2**35 fetches.
                *
                * By the way: a 32 bit code would signify a token which had a
                * frequency of 1 in 2**32 in the data ,,, but which occured
                * at least twice (in order to be chosen a token) and since the
                * minimum token size is 2 bytes, this will occur only for files
                * which exceed 8 gigabytes uncompressed.
                *
                * Like I said ... rather uncommon.
                */
                first = numberOfBits/2;
                last = numberOfBits - first;
                r = MTX_BITIO_ReadValue(t,first);
                r = (r << last) | MTX_BITIO_ReadValue(t,last);
#endif /* SIZEOF_LONG >= 5  */
            
                break;
            }

            t->index += numberOfBits;
        }
        return r;
    }

#endif    /* #if ( TT_ROM_ACT ) || CCC */


#if ( TT_ROM_ACT )
/* the file header is byte aligned, hence the special cases */
/****************************************************************/
#if defined (ANSI_DEFS)
UL32 MTX_BITIO_Read8( BITIO *t )
#else
UL32 MTX_BITIO_Read8( t )
 BITIO *t;
#endif
    {
    UL32 r;
    SL32 index = t->index;
    UB8 *array = t->array;

    if (0 == (index & 7))
        {
        r = array[index >> 3];
        t->index += 8;
        }
    else
        r = MTX_BITIO_ReadValue(t,8);
    return r;
    }

/****************************************************************/
#if defined (ANSI_DEFS)
UL32 MTX_BITIO_Read32( BITIO *t )
#else
UL32 MTX_BITIO_Read32( t )
 BITIO *t;
#endif

    {
    UL32 r;
    SL32 index = t->index;
    UB8 *array = t->array;

    if (0 == (index & 7))
        {
        index >>= 3;
        r = array[index++];
        r = (r << 8) | array[index++];
        r = (r << 8) | array[index++];
        r = (r << 8) | array[index];
        t->index += 32;
        }
    else
        r = MTX_BITIO_ReadValue(t,32);
    return r;
    }

/* hopefully yopur compiler is smart enough to inline the following */
/****************************************************************/
#if defined (ANSI_DEFS)
UL32 MTX_BITIO_ftell( register BITIO *t )
#else
UL32 MTX_BITIO_ftell( t )
    register BITIO *t;
#endif
    {
    return t->index;
    }

/****************************************************************/
#if defined (ANSI_DEFS)
VOID MTX_BITIO_fseek( register BITIO *t, UL32 pos )
#else
VOID MTX_BITIO_fseek( t, pos )
 register BITIO *t;
 UL32 pos;
#endif
    {
    t->index = pos;
    }

/****************************************************************/

/****************************************************************/
#if defined (ANSI_DEFS)
BITIO *MTX_BITIO_Create(FSP ACT_MemHandler *mem, VOID *memPtr, SL32 memSize)
#else
BITIO *MTX_BITIO_Create(mem, memPtr, memSize)
    ACT_MemHandler *mem;
    VOID *memPtr;
    SL32 memSize;
#endif
    {


    BITIO *r;

    

    r = ACT_mem_malloc(FSA mem, sizeof(BITIO));
    if( !r )        /* Added error handler */ /* rjl 8/4/2003 - */
        return 0;
    r->array = memPtr;
    r->index = 0;
    r->max = memSize<<3;
    r->mem = mem;
    return r;
    }

/****************************************************************/
#if defined (ANSI_DEFS)
VOID MTX_BITIO_Destroy(FSP BITIO *t)
#else
VOID MTX_BITIO_Destroy(t)
    BITIO *t;
#endif
    {
    ACT_mem_free(FSA t->mem,t);
    }


/****************************************************************/
/************ the old version ***********************************/
/****************************************************************/


#endif /* TT_ROM_ACT */
 

bitio.h  //

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/rac/BITIO.H_V   1.12   Aug 22 2003 09:22:06   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/rac/BITIO.H_V  $
 * 
 *    Rev 1.12   Aug 22 2003 09:22:06   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.11   Jun 20 2003 14:57:00   Galejs
 * VOID
 * 
 *    Rev 1.10   Sep 23 2002 14:08:14   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.9   Jun 12 2001 13:44:50   Galejs
 * use UFST types rather than SHORT, CHAR, etc
 * 
 *    Rev 1.8   Oct 16 2000 15:45:54   Al
 *  
 *    Rev 1.7   Sep 21 2000 14:01:38   galejs
 * change ACT error handling (no setjmp / longjmp)
 * 
 *    Rev 1.6   Feb 07 2000 15:52:50   galejs
 * unsigned long -> UL32, long ->SL32
 * 
 *    Rev 1.5   Dec 09 1999 15:50:32   galejs
 * remove unused function prototypes, ReadOrWrite field in BITIO
 * 
 *    Rev 1.4   May 24 1999 15:10:16   galejs
 * make ACT reentrant
 * 
 *    Rev 1.3   13 Oct 1997 15:36:52   MARTIN
 * Renamed memory.h to ra_mem.h to fix name conflict on some compilers.
 * 
 *    Rev 1.2   04 Sep 1997 17:04:46   MARTIN
 * Modified references to AGFA Compressed TrueType (ACT).
 * 
 *    Rev 1.1   15 Aug 1997 15:23:50   JOE
 * Added non-ANSI function prototypes.
 * Changed the include filenames to lowercase.
 * 
 *    Rev 1.0   04 Jun 1997 11:05:58   MARTIN
 * Initial revision.
 */
/*
 * File:                        bitio.hpp
 * First Version:                February 6, 1996
 * First Memory Version:        September 27, 1996
 * First pure ANSI C version:     October 28, 1996
 *
 *    07-Feb-00  slg    Don't use "long" dcls (incorrect if 64-bit platform).
 *
 */

#ifndef __BITIO__
#define __BITIO__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    UB8 *array;    /* the array of BYTES */
    SL32 index;    /* next available bit index */
    SL32 max;        /* maximum bit index */
    SL32 high;        /* high water mark - for written arrays */
    ACT_MemHandler *mem;
    } BITIO;

#ifdef LINT_ARGS
/* read a value to the bitarray */
UL32 MTX_BITIO_ReadValue( BITIO *t, SL32 numberOfBits );
/* byte aligned special cases */
UL32 MTX_BITIO_Read32( BITIO *t);
UL32 MTX_BITIO_Read8( BITIO *t);

UL32 MTX_BITIO_ftell( register BITIO *t );
VOID MTX_BITIO_fseek( register BITIO *t, UL32 pos );
BITIO *MTX_BITIO_Create(FSP ACT_MemHandler *mem, VOID *memPtr, SL32 memSize);
VOID MTX_BITIO_Destroy(FSP BITIO *t);
#else
UL32 MTX_BITIO_ReadValue();
UL32 MTX_BITIO_Read32();
UL32 MTX_BITIO_Read8();
UL32 MTX_BITIO_ftell();
VOID MTX_BITIO_fseek();
BITIO *MTX_BITIO_Create();
VOID MTX_BITIO_Destroy();
#endif

#ifdef __cplusplus
}
#endif

#endif    /* __BITIO__ */
 

bitmap.c  ///

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

/* $Header:   I:/BULL/URIP/RTS/BMP/BITMAP.C_V   1.95   Nov 08 2004 14:54:26   doolittlej  $ */
/* $Log:   I:/BULL/URIP/RTS/BMP/BITMAP.C_V  $ 
 * 
 *    Rev 1.95   Nov 08 2004 14:54:26   doolittlej
 * Rearranged allocation in bitmap_dyn(), to do bitmap header first, in IFBITSPLIT section; also, keyed off of num_loops count to check if processing a space character before allocating bitmap.
 * 
 *    Rev 1.94   Nov 02 2004 08:21:32   DugganJ
 * In CGIFFtile_nzw_buf(), adjusted the way the nzw buffer
 * size is calculated to resolve crash and for consistency.
 * 
 * 
 *    Rev 1.93   Sep 27 2004 16:10:12   dugganj
 * Added multithread support.
 * 
 *    Rev 1.92   Sep 09 2004 16:58:22   galejss
 * MPR and NZW buffers now allocated from 3rd mem pool
 * 
 *    Rev 1.91   Aug 17 2004 17:50:46   galejss
 * call new HowMuchBiggerIsEffect function (centralized sizecheck for special effects)
 * 
 *    Rev 1.90   Apr 30 2004 13:59:14   GalejsS
 * IFBITSPLIT changes; IFBITMAP initialization changes; back out fix to #136 for now
 * 
 *    Rev 1.87   Oct 09 2003 12:52:48   IndrelR
 *    Rev 1.86   Oct 09 2003 12:50:48   IndrelR
 * Passed two vertical writing fields:  'topSideBearing' 
 * and 'advanceHeight' to IFBITMAP structure.
 * 
 *    Rev 1.85   Oct 03 2003 17:40:14   Galejs
 * in character(), make sure "usedEmbeddedBitmap" field is preserved
 * 
 *    Rev 1.84   Aug 21 2003 16:47:40   Galejs
 * update copyright notice
 * 
 *    Rev 1.83   Aug 20 2003 15:19:58   IndrelR
 * Added feature for processing XL bitmaps.
 * 
 *    Rev 1.82   Aug 20 2003 15:14:52   IndrelR
 *    Rev 1.81   Aug 20 2003 11:24:12   IndrelR
 * 
 *    Rev 1.80   Jul 21 2003 17:10:04   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.79   Jun 23 2003 13:42:00   Galejs
 * ufstport.h
 * 
 *    Rev 1.78   Dec 02 2002 18:01:54   Galejs
 * fix uninit vbl
 * 
 *    Rev 1.77   Oct 03 2002 18:12:16   Galejs
 * fix non-ANSI_DEFS compiler error
 * 
 *    Rev 1.76   Oct 01 2002 17:51:56   Galejs
 * return ERR_fixed_space from CGIFmakechar (bug # 49) (for keb)
 * 
 *    Rev 1.75   Sep 27 2002 18:29:18   Doolittl
 * Changes to TT_SCREENRES code to return fractional pixel advance information.
 * 
 *    Rev 1.74   Sep 25 2002 15:05:08   Galejs
 * tidying for FIX_CONTOURS changes (bug # 73) (for awr)
 * 
 *    Rev 1.73   Aug 14 2001 09:54:38   LynchR
 * Added support for special effects with embedded bitmaps
 * 
 *    Rev 1.72   27 Jul 2001 13:22:22   JOE
 * 
 * In bitmap_dyn(), checking for space character before calculating
 * new buffer sizes for special effects (by jfd/rl/fa).
 * 
 *    Rev 1.71   Jul 25 2001 16:10:54   LynchR
 * Fixed bouncing baseline for shadow when !SCALE_MATRIX.
 * Fixed bug in DoOutlineShadow.
 * 
 *    Rev 1.70   Jul 03 2001 14:21:02   LynchR
 * Added combined outline shadow effect.
 * 
 *    Rev 1.69   Jun 18 2001 20:41:16   Galejs
 * DoEffects reentrancy fix (+ minor compile warning fix)
 * 
 *    Rev 1.68   Jun 18 2001 15:06:42   LynchR
 * Added special effects.
 * 
 *    Rev 1.67   Jun 14 2001 15:10:32   Al
 * Fast fill- added a tran buffer to nzw buf
 * 
 *    Rev 1.66   04 Jun 2001 09:42:18   JOE
 * OpenType changes.
 * 
 *    Rev 1.65   May 03 2001 19:18:22   Galejs
 * data-type cleanup (+ EMBEDDED_BITMAPS conditonal compile)
 * 
 *    Rev 1.64   22 Jan 2001 14:31:08   JOE
 * In CGIFmakechar(), when testing for embedded bitmap processing,
 * check that outline is not being requested.
 * 
 *    Rev 1.63   Jan 10 2001 14:13:02   Song
 * Remove ctrl-z  and left align #ifdef
 * for SUN compiler.
 * 
 *    Rev 1.62   Nov 22 2000 16:52:48   Galejs
 * conditional-compile fixes for embedded bitmaps
 * 
 *    Rev 1.61   04 Oct 2000 08:50:22   JOE
 * Added function prototype for embedded_character().
 * In CGIFmakechar(), added embedded bitmap support.
 * 
 *    Rev 1.60   Mar 22 2000 14:48:06   galejs
 * in simple_character(), only initialize "or_buffer" if needed
 * 
 *    Rev 1.59   17 Mar 2000 11:52:26   JOE
 * Fixed comment (by ks).
 * 
 *    Rev 1.57   03 Feb 2000 15:34:24   AL
 * Changed SWP799 to WINDCOMP
 * 
 *    Rev 1.56   Jan 24 2000 12:40:56   galejs
 * don't use "top_bearing" field (for keb)
 * 
 *    Rev 1.55   24 Sep 1999 14:08:12   JOE
 * Corrections to last change (by swp).
 * 
 *    Rev 1.53   Aug 10 1999 15:12:08   galejs
 * include-file changes
 * 
 *    Rev 1.52   Jun 10 1999 15:57:04   galejs
 * If TT_SCREENRES is set, pass back non-linear charwidth
 * 
 *    Rev 1.51   27 Jan 1999 19:27:38   GALEJS
 * undo bmras_quadto() conditional compile (see raster.c)
 * 
 *    Rev 1.50   27 Jan 1999 14:38:12   MARTIN
 * Conditionally compile bmras_quadto based on TT_RDR || FCO_RDR.
 * 
 *    Rev 1.49   21 Jan 1999 14:06:42   GALEJS
 * remove unneeded bmras_cubeto() declaration
 * 
 *    Rev 1.48   12 Jan 1999 17:10:16   GALEJS
 * use CONST for read-only data; move EXTERN dcls
 * 
 *    Rev 1.47   31 Aug 1998 13:54:30   JOE
 * Modified for xl2.0 font processing support (by keb).
 * 
 *    Rev 1.46   22 Jun 1998 18:52:48   GALEJS
 * more reentrancy parms
 * 
 *    Rev 1.45   17 Jun 1998 16:30:44   GALEJS
 * add parm to render...() calls (for reentrancy)
 * 
 *    Rev 1.44   15 Jun 1998 17:15:54   GALEJS
 * no more MULTICALLER code; reentrancy parm-passing changes
 * 
 *    Rev 1.43   15 Apr 1998 16:49:56   GALEJS
 * chr_def_hdr into IF_STATE
 * 
 *    Rev 1.42   02 Apr 1998 19:00:36   GALEJS
 * "state" becomes if_state.state_bm, ras becomes if_state.ras
 * 
 *    Rev 1.41   27 Mar 1998 14:00:52   JOE
 * In CGIFmakechar(), calling Char_sz_space_metrics() to properly
 * load the fields of the IFBITMAP structure when processing a 
 * space character (by jwd).
 * 
 *    Rev 1.40   26 Mar 1998 16:07:10   JOE
 * Installed check in CGIFmakechar() for space character processing
 * (by jwd).
 * 
 *    Rev 1.39   24 Mar 1998 14:41:50   GALEJS
 * include-file changes
 * 
 *    Rev 1.38   04 Sep 1997 13:37:34   JOE
 * Removed all references to BJG_BOLD_P6 (by keb).
 * 
 *    Rev 1.37   03 Sep 1997 16:12:36   JOE
 * In bitmap_dyn(), if character() returns an "invalid_tile" error,
 * store the bitmap handle before returning.
 * 
 *    Rev 1.36   13 Aug 1997 08:40:16   JOE
 * In character(), moved check for inside-out tile after intersection of
 * app-supplied tile against entire bitmap. This resolves the banding
 * crashing problem.
 * 
 *    Rev 1.35   06 Aug 1997 14:10:08   MIKE
 * Change bmp_setRender() to VOID to resolve compiler warning
 * 
 *    Rev 1.34   30 Jul 1997 08:11:36   JOE
 * Changed bmras_quadto() prototype to EXTERN to resolve compiler error.
 * 
 *    Rev 1.33   16 Jul 1997 16:55:28   GALEJS
 * bmp_setRaster() needed for graymap as well as bitmap
 * 
 *    Rev 1.32   15 Jul 1997 14:47:50   AL
 * Put back global ras declaration
 * 
 *    Rev 1.31   15 Jul 1997 13:31:52   AL
 * Pseudo bold via outlines
 * 
 *    Rev 1.30   23 Jun 1997 13:02:48   MIKE
 * #include "nzwind.h"
 * 
 *    Rev 1.29   16 Jun 1997 19:22:02   GALEJS
 * "ras" declaration needed if NON_Z_WIND
 * 
 *    Rev 1.28   16 Jun 1997 14:21:12   AL
 * Can have GRAYSCALING without CGBITMAP
 * 
 *    Rev 1.27   24 Oct 1996 11:38:36   PVCSADMN
 * BJG revisions to enable char_size emboldening for PCL 6 emulation.
 * 
 *    Rev 1.26   23 Oct 1996 12:00:38   PVCSADMN
 * Added emboldening for PCL 6 emulation.
 * 
 *    Rev 1.25   05 Jan 1996 12:49:22   MERRILL
 * removed 5 warnings(c.f.MAX_BM & tile_in_part)
 * 
 *    Rev 1.23   06 Apr 1995 15:07:56   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.22   14 Feb 1995 20:49:22   MIKE
 * Reduce memory allocation for NZW buffer.
 * 
 *    Rev 1.21   03 Jun 1994 10:05:48   JOE
 * Changed all occurrences of ENTRY to CGENTRY to resolve conflict on
 * some compilers.
 * 
 *    Rev 1.20   22 Apr 1994 09:20:24   LISA
 * Modified copyright/disclaimer notice.
 * 
 *    Rev 1.19   06 Jan 1994 09:48:20   JOE
 * In compound_character(), restructured checks to determine if memory
 * requirements for compound parts are calculated correctly.
 * 
 *    Rev 1.18   15 Dec 1993 14:37:34   JOE
 * In compound_character(), if CHAR_SIZE, disabled memory check when
 * processing part 00 (already done earlier). In same routine, when 
 * processing parts 1 thru "n", changed calculation of "b.orb" to
 * "cc_buf " bm_size" to prevent memory overwrite.
 * 
 *    Rev 1.17   21 Sep 1993 15:15:58   JOE
 * In CGIFtile_nzw_buf()", corrected DBG1() statement ("size[1]"
 * becomes "*psize").
 * 
 *    Rev 1.16   15 Sep 1993 14:07:32   JOE
 * Added external declaration for "uLastCallerId" to resolve compiler error
 * when MULTICALLER is enabled.
 * 
 *    Rev 1.15   31 Aug 1993 14:12:54   AL
 * Added CGIFtile_nzw_buf()
 * 
 *    Rev 1.14   02 Aug 1993 14:28:52   MAIB
 * Changes to support multi-tasking
 * 
 *    Rev 1.13   29 Jul 1993 12:37:06   AL
 * More nzw changes
 * 
 *    Rev 1.12   27 Jul 1993 12:32:56   AL
 * Non-zero winding changes
 * 
 *    Rev 1.11   01 Jul 1993 14:18:12   MAIB
 * changed making_bold to non_z_wind
 * 
 *    Rev 1.10   17 May 1993 18:07:28   JOE
 * In simple_character(), when calling raster() and cgfill(), cast "bm->bm"
 * as LPUB8 due to change made in IFBITMAP structure.
 * 
 *    Rev 1.9   07 Apr 1993 11:50:48   JOE
 * Removed MAKE_BITMAP #define and all references to it.
 * 
 *    Rev 1.8   12 Feb 1993 16:55:04   JOE
 * Check for potential buffer overflow in compound_character() if CHAR_SIZE is
 * enabled.
 * 
 *    Rev 1.7   12 Feb 1993 11:01:16   JOE
 * VXWorks support.
 * 
 *    Rev 1.6   29 Jan 1993 09:22:44   JOE
 * In character(), saved em box size in "state.bm".
 * 
 *    Rev 1.5   22 Jan 1993 08:55:28   JOE
 * In CGIFmakechar(), removed escapement adjustment code because it is 
 * now done in MAKifbmheader (maker.c).
 * 
 *    Rev 1.4   20 Jan 1993 09:57:54   JOE
 * In character(), removed checking of "size" for overflow because it should
 * be done in application after call to CGIFchar_size().
 * 
 *    Rev 1.3   15 Jan 1993 13:27:40   JOE
 * If CHAR_SIZE, adjust escapement if master point size and x-scan 
 * resolution are not in IF 8782's.
 * 
 *    Rev 1.2   05 Jan 1993 15:43:38   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:30:22   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:32:48   LISA
 * Initial revision.
*/

/*---------------------------------------------------------------------
     23-Nov-90  awr   Created. Leveraged from maker.c
     8-Feb-91   awr   Changed name des2wrkbm() to des2bm()
     16-Apr-91  dET   Add squiping() function and made or buffer larger.
     19-May-91  awr   Squiping() prototype and bug fix.
      1-Jun-91  awr   HQ4 changes
      4-Jun-91  awr   cc merging under construction-- warning
     17-Jun-91  jfd   Moved "debug.h" after "port.h".
                      Moved "profile.h" after "port.h".
      4-Jul-91  awr   Tiling
     14-Aug-91  awr   In grow_and_merge(), filled in black_width & depth.
                      Disabled all calls to margin().
     20 Aug 91  ss    Added casts in simple_character() to eliminate warnings.
     24-Aug-91  awr   Moved function decls to include file
     27-Aug-91  bjg   Add special case handling for mirrored chars 
      1-Sep-91  awr   Included "bitmap.h"
      6-Sep-91  awr   Changed HEADERSIZE to BMHEADERSIZE
     19-Sep-91  jfd   In bitmap_tile(), when calculating tile_bm.xorigin
                      and tile_bm.yorigin, cast operand as LONG due to
                      change in type to LONG for xorigin and yorigin.
     12-Oct-91  awr   Missing pixel recovery and pseudo bold are no
                      longer mutually exclusive.
     18-Oct-91  jfd   Declare "scan_convert" conditionally based on
                      TILE.
     25-Oct-91  jfd   Changed declaration for "scan_convert" from GLOBAL
                      to EXTERN so as to resolve a linker error which
                      occurs if CHAR_SIZE is enabled.
     02-Feb-92   rs  Clean up compiler warnings.
      7-Mar-92  awr   Changed metrics() parameters
     03-Apr-92  rs    Portability cleanup (see port.h).
     04-Apr-92  awr   Changed calling sequence of find_part2whole()
     06-Apr-92  jfd   In bitmap(), conditionally compiled call to 
                      bitmap_ufst() (if PST1I ||  TT_RDR)
     08-Apr-92  rs    Modify 'simple_character()' to handle fixed space chars.
                      Do not call 'raster()' & 'fill()' if no contours based
                      upon 'if_state.num_loops' == 0.
                      Fix warnings in 'set_bitmap_memory()'.
      8 Apr 92  ss    In bitmap_ufst(), copy metrics generated earlier to
                      return with bitmap as expected by rest of code.
     10 Apr 92  ss    In bitmap_if(), don't do code that sets special_case.
     10-Apr-92  rs    Change 'special_case' to EXTERN, declared in 'maker.c'.
     12-Apr-92  awr   Moved in bitmap generating code from maker.
     19-Apr-92  awr   Combined CHAR_SIZE and CHAR_HANDLE tile code.
     21-Apr-92  jfd   Temporarily conditionally compiling entire module
                      based on CGBITMAP. Will optimize later!
     05-May-92  jfd   In bitmap_dyn(), changed "bmdim.x" to "state.bmdim.x"
                      when allocating bitmap buffer plus fluff.
      6 May 92  ss    In simple_character(), added casts to eliminate warnings
     12 May 92  jfd   Added #define for "MAX_CHARSIZE_SIZE" (size of buffer
                      used if CHAR_SIZE is enabled.
                      In character(), before calling clear_mem(), check if
                      size of tiled bitmap exceeds buffer size to avoid
                      writing outside of memory. This is necessary only
                      if CHAR_SIZE is enabled because bitmap_dyn()
                      previously checks for enough memory.
     29-May-92  jfd   Changed type "OLSTATS" to "CHAR_STATS" due to change 
                      in "ix.h".
      8-Jun-92  jfd   Removed all references to "olstats" and replaced
                      with "if_state.cs".
     21-Jun-92  awr   changed if_state.xlate and if_state.tbound to INTRs
                      Conditionally compiled portions
     19-Jun-92  jfd   In bitmap_dyn(), added special case for handling
                      space character.
      1-Jul-92  jfd   In compound_character(), when computing "if_state.xlate.y"
                      and "if_state.tbound.ur.y", use "trans_diff.y", not
                      "trans_diff.x".
      4-Jul-92  awr   Adjusted conditional compiles
     10 Jul 92  ss,awr In compound_character(), now set b.orb for CACHE and
                      CHAR_HANDLE code.
     14-Jul-92  awr   Changed call to make_gaso().
     22-Jul-92  awr   Preserve xlate and tbound in compund_character()
                      for part 0. Was getting trashed for compound characters
                      using tiling.
     05-Aug-92  jfd   Replaced calls to "clear_mem()" with MEMSET for
                      optimization.
     02-Sep-92  mby   Fixed bug in compound_char() ( CHAR_SIZE = 1 ).
                      or-buffer pointer was set incorrectly and either
                      clobbered the bm-header and crashed, or produced
                      garbled bitmaps.
     24-Oct-92  awr   Added MAKE_BITMAP define for timing tests
     14-Nov-92  rs    Port to Mac - fill() renamed to cgfill().
     05-Jan-93  jfd   ANSI C function declaration changes.
     20-Jan-93  jfd   In character(), removed checking of "size" for overflow
                      because it should be done in applcation after call to
                      CGIFchar_size(). Removed #define for MAX_CHARSIZE_SIZE.
     27-Jan-93  jfd   In character(), store em box size in "state.bm".
     08-Feb-93  jfd   VXWorks support.
     09-Feb-93  jfd   In compound_character(), if CHAR_SIZE, when processing
                      first part of a character, check for memory overflow
                      and disable missing pixel recovery if necessary
                      before calling character().
     07-Apr-93  jfd   Removed MAKE_BITMAP #define (Always assume TRUE).
     17-May-93  jfd   In simple_character(), when calling raster() and
                      cgfill(), cast "bm->bm" as LPUB8 due to change made
                      in IFBITMAP structure.
     01-Jul-93 maib  Changed making_bold to non_z_wind
     02-Jul-93 awr   Changes for improved non zero winding fill.  This
                     changed parameters for CGIFmakechar() and
                     CGIFtilebitMap()
    02-Aug-93 maib   Changed interface to prevent CGIFxxx() routines from calling
                     other CGIFxxx() routines, required for multi-tasking. also
                     added multicaller support code to CGIFxxx() routines
    30-Aug-93 awr    Added CGIFtile_nzw_buf()
     15-Sep-93 jfd   Added external declaratifon for "uLastCallerId" to
                     resolve compiler error when MULTICALLER is enabled.
     21-Sep-93 jfd   In CGIFtile_nzw_buf(), corrected printf() statement
                     ("size[1] becomes "*psize").
     09-Dec-93 jfd   In compound_character(), if CHAR_SIZE, disabled memory 
                     check when processing part 0 (already done earlier).
                     In same routine, when processing parts 1 thru "n",
                     changed calculation of "b.orb" to "cc_buf + bm_size"
                     to prevent memory overwrite.

  05-Jan-94 jfd/jwd  In compound_character(), restructured checks to determine
                     if memory requirements for compound parts are calculated
                     correctly.
  03-Jun-94 jfd      Changed all occurrences of ENTRY to CGENTRY to resolve
                     conflict on some compilers.
  14-Feb-95 mby   In bitmap_dyn() and CGIFtile_nzw_buf(), correct alignment
                  of NZW buffer and thus slightly reduce memory allocation.
  16-Jun-97 awr   Conditionally compile entire module on CGBITMAP. Moved
                  a lot of bitmap specific code out of raster into here.
  16-Jun-97 slg   "ras" still needed for NON_Z_WIND - add declaration at end
  23-Jun-97 mby   Added "include nzwind.h"
  15-Jul-97 awr   Pseudo bold via outlines.
  15-Jul-97 awr   Put back global ras declaration.
  16-Jul-97 slg   New section at start of file to declare things needed by
                  graymap as well as bitmap (ras, if_state, bmp_setRender())
  30-Jul-97 jfd   Changed bmras_quadto() prototype to EXTERN to resolve 
                  compiler error.
  06-Aug-97 mby   Change bmp_setRender() to VOID function to resolve compiler
                  warning.
  13-Aug-97 jfd   In character(), moved check for inside out tile after
                  intersection of app supplied tile against entire bitmap.
  03-Sep-97 jfd   In bitmap_dyn(), if character() returns an "invalid_tile"
                  error, store the handle to the IFBITMAP structure
                  before returning.
  03-Sep-97 keb   Removed references to BJG_BOLD_P6
  23-Mar-98    jwd   Installed check in CGIFmakechar() for space char processing;
                  no proc necessary if space char.
  27-Mar-98 jwd   In CGIFmakechar(), calling Char_sz_space_metrics()
                  to load IFBITMAP fields properly when processing a
                  space character.
  02-Apr-98 slg      "state" becomes if_state.state_bm, ras becomes if_state.ras.
  31-Aug-98 keb   modified for xl2.0 font processing support
  27-Jan-99 sbm      Conditionally compile bmras_quadto based on TT_RDR and FCO_RDR.
  10-Jun-99 slg      If TT_SCREENRES is set, pass back non-linear charwidth in character()
  06-Jul-99 swp   changes to rasterizer, enabled if SWP799 defined
  18-Jan-00 slg      Don't use "top_bearing" (vertical writing changes for keb)
  03-Feb-00 awr   Changed SWP799 to WINDCOMP
  15-Mar-00 ks    Make bmras_tbl local to bmp_setRender().
  22-Mar-00 slg      If "or_on" is not set, make "or_buffer" pointer NULL (rather
                    than initializing never-used pointer with an invalid value)
  28-Sep-00 jfd   Added function prototype for embedded_charater().
                  In CGIFmakechar(), added embedded bitmap support.
  22-Jan-01 jfd   In CGIFmakechar(), when testing for embedded bitmap 
                  processing, check that outline is not being requested.
  23-May-01 jfd   OpenType changes:
                  In render(), point to correct bucket.
  27-Jul-01 jfd/rl/fa In bitmap_dyn(), checking for space character
                  before calculating new buffer sizes.
  21-Aug-02 awr   Corrected names and comments in parameters of CGIFmakechar()
                  and CGIFtilebitMap(). Removed unused parameter from CGIFmakechar(),
                  it had already been removed from the documentation.
-----------------------------------------------------------------------*/


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

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

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

#include "shareinc.h"

#include "mixmodel.h"

/* the following declarations are needed for graymaps as well as bitmaps */
#if CGBITMAP || GRAYSCALING

/*----------------------*/
/*    bmp_setRender     */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID  bmp_setRender (FSP0)
#else   
GLOBAL VOID bmp_setRender ( )
#endif
{
    /* ks - Mar. 15, 2000 
    Make bmras_tbl local to this function */
    CONST OUT_TBL  bmras_tbl = {
        bmras_start_char,
        bmras_end_char,
        bmras_start_loop,
        bmras_end_loop,
        bmras_moveto,
        bmras_lineto,
        bmras_quadto,
#if PST1_RDR
        bmras_cubeto
#endif
    };

    DBG("bmp_setRender()\n");

    if_state.out = bmras_tbl;   /* set up for bitmaps */
    if_state.out_instance = &if_state.ras;
}

#endif   /* CGBITMAP || GRAYSCALING */


#if CGBITMAP            /* Conditionally compile rest of module */

#ifdef LINT_ARGS
MLOCAL UW16      render(FSP0);
MLOCAL UW16  simple_character(FSP PIFBITMAP, LPUB8, SW16VECTOR);
#if IF_RDR
MLOCAL SL32       tile_in_part(FSP SW16VECTOR, BOX);
MLOCAL UW16      compound_character(FSP0);
#endif
MLOCAL UW16      character(FSP0);
MLOCAL UW16      bitmap_dyn(FSP PHIFBITMAP);

#else   /* not LINTARGS */
MLOCAL UW16      render();
MLOCAL UW16      simple_character();
#if IF_RDR
MLOCAL SL32       tile_in_part();
MLOCAL UW16      compound_character();
#endif
MLOCAL UW16      character();
MLOCAL UW16      bitmap_dyn();
#endif


/*****************************************/
/*                                       */
/*      Raster Line Organizations        */
/*                                       */
/*****************************************/
#if (RASTER_ORG == EIGHT_BIT_CHUNK)

#if LEFT_TO_RIGHT_BIT_ORDER
CONST  CHUNK bit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
#else
CONST  CHUNK bit[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
#endif

#elif (RASTER_ORG == SIXTEEN_BIT_CHUNK)

#if LEFT_TO_RIGHT_BIT_ORDER
CONST  CHUNK bit[16] = { 0x8000, 0x4000, 0x2000, 0x1000,
                          0x0800, 0x0400, 0x0200, 0x0100,
                          0x0080, 0x0040, 0x0020, 0x0010,
                          0x0008, 0x0004, 0x0002, 0x0001};
#else
CONST  CHUNK bit[16] = { 0x0001, 0x0002, 0x0004, 0x0008, 
                          0x0010, 0x0020, 0x0040, 0x0080,
                          0x0100, 0x0200, 0x0400, 0x0800,
                          0x1000, 0x2000, 0x4000, 0x8000};
#endif

#elif (RASTER_ORG == THIRTYTWO_BIT_CHUNK)

#if LEFT_TO_RIGHT_BIT_ORDER
CONST  CHUNK bit[32] = { 0x80000000L, 0x40000000L, 0x20000000L, 0x10000000L,
                          0x08000000L, 0x04000000L, 0x02000000L, 0x01000000L,
                          0x00800000L, 0x00400000L, 0x00200000L, 0x00100000L,
                          0x00080000L, 0x00040000L, 0x00020000L, 0x00010000L,
                          0x00008000L, 0x00004000L, 0x00002000L, 0x00001000L,
                          0x00000800L, 0x00000400L, 0x00000200L, 0x00000100L,
                          0x00000080L, 0x00000040L, 0x00000020L, 0x00000010L,
                          0x00000008L, 0x00000004L, 0x00000002L, 0x00000001L};
#else
CONST  CHUNK bit[32] = { 0x00000001L, 0x00000002L, 0x00000004L, 0x00000008L,
                          0x00000010L, 0x00000020L, 0x00000040L, 0x00000080L,
                          0x00000100L, 0x00000200L, 0x00000400L, 0x00000800L,
                          0x00001000L, 0x00002000L, 0x00004000L, 0x00008000L,
                          0x00010000L, 0x00020000L, 0x00040000L, 0x00080000L,
                          0x00100000L, 0x00200000L, 0x00400000L, 0x00800000L,
                          0x01000000L, 0x02000000L, 0x04000000L, 0x08000000L,
                          0x10000000L, 0x20000000L, 0x40000000L, 0x80000000L};
#endif

#elif (RASTER_ORG == SIXTYFOUR_BIT_CHUNK)

#if LEFT_TO_RIGHT_BIT_ORDER
CONST  CHUNK bit[64] = {     0x8000000000000000,     0x4000000000000000,
                              0x2000000000000000,     0x1000000000000000,
                              0x0800000000000000,     0x0400000000000000,
                              0x0200000000000000,     0x0100000000000000,
                              0x0080000000000000,     0x0040000000000000,
                              0x0020000000000000,     0x0010000000000000,
                              0x0008000000000000,     0x0004000000000000,
                              0x0002000000000000,     0x0001000000000000,
                              0x0000800000000000,     0x0000400000000000,
                              0x0000200000000000,     0x0000100000000000,
                              0x0000080000000000,     0x0000040000000000,
                              0x0000020000000000,     0x0000010000000000,
                              0x0000008000000000,     0x0000004000000000,
                              0x0000002000000000,     0x0000001000000000,
                              0x0000000800000000,     0x0000000400000000,
                              0x0000000200000000,     0x0000000100000000,
                          0x80000000, 0x40000000, 0x20000000, 0x10000000,
                          0x08000000, 0x04000000, 0x02000000, 0x01000000,
                          0x00800000, 0x00400000, 0x00200000, 0x00100000,
                          0x00080000, 0x00040000, 0x00020000, 0x00010000,
                          0x00008000, 0x00004000, 0x00002000, 0x00001000,
                          0x00000800, 0x00000400, 0x00000200, 0x00000100,
                          0x00000080, 0x00000040, 0x00000020, 0x00000010, 
                          0x00000008, 0x00000004, 0x00000002, 0x00000001};
#else
CONST  CHUNK bit[64] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008,
                          0x00000010, 0x00000020, 0x00000040, 0x00000080,
                          0x00000100, 0x00000200, 0x00000400, 0x00000800,
                          0x00001000, 0x00002000, 0x00004000, 0x00008000,
                          0x00010000, 0x00020000, 0x00040000, 0x00080000,
                          0x00100000, 0x00200000, 0x00400000, 0x00800000,
                          0x01000000, 0x02000000, 0x04000000, 0x08000000,
                          0x10000000, 0x20000000, 0x40000000, 0x80000000,
                              0x0000000100000000,     0x0000000200000000,
                              0x0000000400000000,     0x0000000800000000,
                              0x0000001000000000,     0x0000002000000000,
                              0x0000004000000000,     0x0000008000000000,
                              0x0000010000000000,     0x0000020000000000,
                              0x0000040000000000,     0x0000080000000000,
                              0x0000100000000000,     0x0000200000000000,
                              0x0000400000000000,     0x0000800000000000,
                              0x0001000000000000,     0x0002000000000000,
                              0x0004000000000000,     0x0008000000000000,
                              0x0010000000000000,     0x0020000000000000,
                              0x0040000000000000,     0x0080000000000000,
                              0x0100000000000000,     0x0200000000000000,
                              0x0400000000000000,     0x0800000000000000,
                              0x1000000000000000,     0x2000000000000000,
                              0x4000000000000000,     0x8000000000000000};
#endif


#endif  /* RASTER_ORG == EIGHT_BIT_CHUNK */

/*--------------------*/
/*    missingPixel    */
/*--------------------*/
#if defined (ANSI_DEFS)
MLOCAL VOID
missingPixel(LPUB8 dstptr, SL32 width, SL32 depth, LPUB8 or_buffer)
#else
MLOCAL VOID
missingPixel(dstptr, width, depth, or_buffer)
    LPUB8  dstptr;
    SL32    width;   /* width of bitmap in bytes   */
    SL32    depth;   /* depth of bitmap in rasters */
    LPUB8  or_buffer;
#endif
{
    LPSB8      pbSrc;
    LPSB8      pbDes;
    SL32       tran_size, iw;
    LPCHUNK    chunkdptr;
    LPCHUNK    chunkorptr;
    
    /* Step 1, squip the or_buffer:
    *         "or" into the active bitmap area any
    *         pixels that have been set in the fluff portion
    *         of the or_buffer.
    */
    /* set pointers to top; src pointer to fluff and
    des pointer to or_buf */
    pbDes = (LPSB8)or_buffer;
    pbSrc = (LPSB8)or_buffer - width;
    
    for(iw=0;iw<width;iw++)
        *pbDes++ |= *pbSrc++;
    
    /* set pointers to bottom; src pointer to fluff and des pointer to or_buf */
    
    tran_size = (SL32)width * (SL32)depth;
    pbSrc = (LPSB8)or_buffer + (SL32)tran_size;
    pbDes = pbSrc - width;
    
    for(iw=0;iw<width;iw++)
        *pbDes++ |= *pbSrc++;
    
    /* Step 2:  Merge the or buffer into the final bitmap */
    
    chunkorptr  = (LPCHUNK)or_buffer;
    chunkdptr = (LPCHUNK)dstptr;    /* remember start of destination */
    tran_size >>= (CHUNK_SHIFT - 3);
    for(iw=0; iw < tran_size; iw++) *chunkdptr++ |= *chunkorptr++;
}
/*----------------------*/
/*   simple_character   */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  simple_character(FSP PIFBITMAP bm, LPUB8 orb, SW16VECTOR bmdim)
#else
MLOCAL UW16
simple_character(bm, orb, bmdim)
    PIFBITMAP  bm;
    LPUB8      orb;
    SW16VECTOR      bmdim;
#endif
{
    UW16       status;
    SL32       num_bytes;

    DBG("simple_character()\n");

  /*------------------------------------------------------------
   *  Make the character bitmap
   *    If there are no contours (ie space), do not call raster() or fill().
   *       Add 4/10/92 - rs
   */

    if (if_state.num_loops)
    {
        DBG("\nraster()\n");
        DBG1(" log_xpix %d\n", log_xpix);
        DBG2("  bmdim %d  %d\n", bmdim.x, bmdim.y);

        /* "or_buffer" is only used (deeper down) if "or_on" is set - so, fix
            a Purify error by setting "orb" to 0 otherwise (sandra, 20 Mar '00) */
        if(if_state.or_on)
        {
            /* clear out "or_buffer", if needed */
            num_bytes = (SL32)bmdim.x * (SL32)bmdim.y;
            MEMSET((LPUB8)orb, (SL32)0, (SL32)((SL32)num_bytes + (bmdim.x<<1)));
            if_state.ras.or_buffer   = orb+bmdim.x;
        }
        else
        {
            /* "or_buffer" not used - set its pointer to NULL */
            if_state.ras.or_buffer   = 0;
        }

        if_state.ras.tran_buffer = (LPUB8)bm->bm;
        if_state.ras.bmdim       = bmdim;
        if_state.ras.tsize = (SL32)if_state.ras.bmdim.x * (SL32)if_state.ras.bmdim.y;

#if NON_Z_WIND
#ifndef WINDCOMP
        if(if_state.non_z_wind)
            nz_init ( FSA &if_state.ras.nz_instance, if_state.nzw, if_state.ras.tran_run_ct, bmdim.y );
#endif /* WINDCOMP */
#endif /* NON_Z_WIND */

        status = render(FSA0);
        if(status)
        {
            DBG("raster() error\n");
            return status;
        }
        
#ifndef WINDCOMP
#if NON_Z_WIND
        if (if_state.non_z_wind)
        {
            status = nz_set_trans ( FSA &if_state.ras.nz_instance );
            if(status)
            {
                DBG("raster() error\n");
                return status;
            }
        }
        else
#endif /* NON_Z_WIND */
            cgfill(FSA (LPUB8)bm->bm, (LPUB8)bm->bm, (SL32)bm->width, (SL32)bm->depth,
                      if_state.ras.or_buffer);
            if(if_state.or_on)
                missingPixel((LPUB8)bm->bm, (SL32)bm->width, (SL32)bm->depth,
                                    if_state.ras.or_buffer);
#endif /* WINDCOMP */
    } /* if ( if_state.num_loops ) */

    DBG("part bitmap\n");

#ifdef AGFADEBUG
    print_bm(FSA bm);
#endif

    return SUCCESS;
}

#if IF_RDR
#define STAT_no_tile_intersect  16000
/*----------------------*/
/*     tile_in_part     */
/*----------------------*/
/*  1. Computes the subtile within the character part that we must build.
 *  2. Sets the global clip box "scan_convert.tb" used in raster().
 *  3. Returns FALSE if there is no intersection of the tile and the part.
 *     Returns TRUE otherwise.
 */
#if defined (ANSI_DEFS)
MLOCAL SL32   tile_in_part(FSP SW16VECTOR p2w, BOX part_box_pix)
#else
MLOCAL SL32
tile_in_part(p2w, part_box_pix)
    SW16VECTOR p2w;
    BOX        part_box_pix;
#endif
{

    DBG("tile_in_part()\n");
    DBG4("bm (pix):    (%d %d)   (%d, %d)\n",
                                                part_box_pix.ll.x,
                                                part_box_pix.ll.y,
                                                part_box_pix.ur.x,
                                                part_box_pix.ur.y);
  /* Translate tile back to part */
    if_state.tb.ll.x = if_state.tile_box.ll.x - p2w.x;
    if_state.tb.ll.y = if_state.tile_box.ll.y - p2w.y;
    if_state.tb.ur.x = if_state.tile_box.ur.x - p2w.x;
    if_state.tb.ur.y = if_state.tile_box.ur.y - p2w.y;
    DBG4("Tile within bm (pix):    (%d %d)   (%d, %d)\n",
                                                if_state.tb.ll.x,
                                                if_state.tb.ll.y,
                                                if_state.tb.ur.x,
                                                if_state.tb.ur.y);
#if 1  /* 08-26-97 jfd */
  /* intersect the boxes */
    if_state.tb.ll.x = MAX(if_state.tb.ll.x, part_box_pix.ll.x);
    if_state.tb.ll.y = MAX(if_state.tb.ll.y, part_box_pix.ll.y);
    if_state.tb.ur.x = MIN(if_state.tb.ur.x, part_box_pix.ur.x);
    if_state.tb.ur.y = MIN(if_state.tb.ur.y, part_box_pix.ur.y);
    DBG4("Tile intersect bm (pix):    (%d %d)   (%d, %d)\n",
                                                if_state.tb.ll.x,
                                                if_state.tb.ll.y,
                                                if_state.tb.ur.x,
                                                if_state.tb.ur.y);
#endif  /* 08-26-97 jfd */
  /* Return truth value of "tb is not empty" */

    return    (if_state.tb.ll.x < if_state.tb.ur.x)
           && (if_state.tb.ll.y < if_state.tb.ur.y);
}
/*----------------------*/
/*  compound_character  */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  compound_character(FSP0)
#else
MLOCAL UW16
compound_character()
#endif
{
    UW16           status = SUCCESS;
    UW16           pn;
    PCHR_DEF       cd;
    SW16VECTOR     p2w;
    SW16VECTOR     bmdim;     /* tile dim in bytes x rasters */
    SW16           black_width;
    MEM_HANDLE hbm=0;
    PIFBITMAP bm=0;
#if IFBITSPLIT
    MEM_HANDLE bmdatahandle=0;
    UL32 *bmdataptr=0;
#endif
    LPUB8 orb=0;
    SL32           num_bytes, bm_size;
    INTRVECTOR     trans_diff;

    BOOLEAN    save_or_on;

    DBG("\n\n\n\ncompound_character()\n");

    save_or_on = if_state.or_on;

  /*  Make first part of (possible compound) character in tile_bm. */

    cd = if_state.chr_def;

    cd->pix_bound.ur.x += cd->bmorigin.x;
    cd->pix_bound.ur.y += cd->bmorigin.y;
  /* find part's origin (0,0) in whole bitmap. We translated part 0
   * already by if_state.chr_def[0].bmorigin to align it with the overall bitmap
   */
    p2w.x = 0;
    p2w.y = 0;
    if(tile_in_part(FSA p2w, cd->pix_bound))
    {
        status = make_gaso(FSA 0,cd);
        if(status)
            return status;

      /*  Translate first part into position in overall bitmap  */

        trans_diff.x = (INTR)cd->bmorigin.x * (INTR)xpix;
        trans_diff.y = (INTR)cd->bmorigin.y * (INTR)ypix;

        if_state.xlate.x += trans_diff.x;
        if_state.xlate.y += trans_diff.y;

        if_state.tbound.ur.x += trans_diff.x;
        if_state.tbound.ur.y += trans_diff.y;

#if CHAR_SIZE
      /* Check for enough memory here  (02-09-93 jfd) */

        num_bytes = (SL32)if_state.bmdim.x * (SL32)if_state.bmdim.y;
        bm_size = num_bytes + (SL32)BMHEADERSIZE;

        if(!if_state.bmbufs_dyn)
              /* split up if_state.cc_buf: fixed buf allocated at start up */
        {
            if(if_state.or_on && (bm_size + num_bytes + 2*if_state.bmdim.x > if_state.cc_size))
                if_state.or_on = FALSE;
        }
#endif  /* CHAR_SIZE */

        status = simple_character(FSA if_state.bm, if_state.orb, if_state.bmdim);
        if(status)
            return status;

        if_state.xlate.x -= trans_diff.x;
        if_state.xlate.y -= trans_diff.y;

        if_state.tbound.ur.x -= trans_diff.x;
        if_state.tbound.ur.y -= trans_diff.y;
    }

  /*  Make remaining parts of compound character in compound
   *  character buffer and or them into tile_bm.
   */

    for(pn=1; pn<if_state.chr_def_hdr.num_parts; pn++)
    {
        cd++;
        p2w = if_state.chr_def[pn].bmorigin;  /* part's origin (0,0) in whole bm */
        if(tile_in_part(FSA p2w, cd->pix_bound))
        {
          /*  Adjust p2w. There are two adjustments:
           *      1. Origin of tile part is at tb.ll in entire part bitmap.
           *      2. Must include vector from entire to tile in whole bitmap.
           */
            p2w.x += if_state.tb.ll.x - if_state.tile_box.ll.x;
            p2w.y += if_state.tb.ll.y - if_state.tile_box.ll.y;
            DBG2("adjusted p2w: (%d, %d)\n", p2w.x, p2w.y);

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

          /*  Set up memory buffers  */

            black_width =
            bmdim.x = (if_state.tb.ur.x - if_state.tb.ll.x) + 1;
                                                       /* off transition */
            bmdim.y = (if_state.tb.ur.y - if_state.tb.ll.y);
            bmdim.x = (1 + (bmdim.x-1)/if_state.bit_map_width)
                                    * (if_state.bit_map_width >>3);
            DBG2("    alignment = %d, width in bytes %u\n",
                                       if_state.bit_map_width, bmdim.x);


            num_bytes = (SL32)bmdim.x * (SL32)bmdim.y;
            bm_size = num_bytes + (SL32)BMHEADERSIZE;
#if CACHE || CHAR_HANDLE
            if(if_state.bmbufs_dyn)
            {
#if IFBITSPLIT
            /* allocate the space for the actual bitmap data (bits) */
                bmdatahandle = CHARalloc(FSA num_bytes);
                if (bmdatahandle == NIL_MH)
{
//Send_String("bmdatahandle = CHARalloc aaaa\r\n");                
                    return ERR_bm_buff;
}                    

            /* allocate the IFBITMAP structure */
                hbm = (HIFBITMAP)CHARalloc(FSA (SL32)BMHEADERSIZE);
                if (hbm == (HIFBITMAP)NIL_MH)
                {
//Send_String("bmdatahandle = CHARalloc bbbb\r\n");
                    CHARfree(FSA bmdatahandle);
                    return ERR_bm_buff;
                }

                bm = (PIFBITMAP)MEMptr(hbm);
                MEMSET(bm, 0, BMHEADERSIZE);
                bmdataptr = (UL32 *)MEMptr(bmdatahandle);
                bm->bm = bmdataptr;        /* set pointer/handle to data in IFBITMAP structure */
                bm->datahandle = bmdatahandle;
#else
            /* allocate the space for IFBITMAP structure + bitmap data */
                hbm = (HIFBITMAP)CHARalloc(FSA bm_size);
                if (hbm == (HIFBITMAP)NIL_MH)
{
//Send_String("bmdatahandle = CHARalloc cccc\r\n");                
                    return ERR_bm_buff;
}                    
                bm = (PIFBITMAP)MEMptr(hbm);
                MEMSET(bm, 0, BMHEADERSIZE);
#endif
                orb =  if_state.orb;    /* ss-7/9/92 */
             }
#endif
#if CHAR_SIZE
            if(!if_state.bmbufs_dyn)
                  /* split up if_state.cc_buf: fixed buf allocated at start up */
            {
                bm = (PIFBITMAP)if_state.cc_buf;
                if(if_state.or_on)
                    orb =  if_state.cc_buf + bm_size;  /* 12-09-93 jfd */

                if((num_bytes > if_state.cc_size)
                  ||
                 (if_state.or_on && (num_bytes + 2*bmdim.x > if_state.cc_size)))
                {
                    DBG("    or_on bitmap > if_state.cc_size\n");
                    return ERR_bm_gt_oron;
                }
            }
#endif
            MEMSET((LPUB8)bm->bm, (SL32)0, (SL32)num_bytes);
            bm->width = bmdim.x;
            bm->depth = bmdim.y;
            bm->left_indent =
            bm->top_indent  = 0;
            bm->black_width = black_width - 1;   /* pixels */
            bm->black_depth = bmdim.y;

            status = simple_character(FSA bm, orb, bmdim);
            if(status)
            {
                if(if_state.bmbufs_dyn)
                {
#if IFBITSPLIT
                    if (bmdatahandle != NIL_MH)
                        CHARfree(FSA bmdatahandle);
#endif
                        CHARfree(FSA hbm);
                }
                goto done;
            }

            merge(FSA bm, if_state.bm, p2w);
            if (if_state.bmbufs_dyn)
            {
#if IFBITSPLIT
                if (bmdatahandle != NIL_MH)
                    CHARfree(FSA bmdatahandle);
#endif
                CHARfree(FSA hbm);
            }
        }

    }    /* end loop (pn=1 to num_parts) */

done:
    if_state.or_on = save_or_on;
    return status;
}
#endif  /* IF_RDR */

/*----------------------*/
/*    character         */
/*----------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  character(FSP0)
#else
MLOCAL UW16
character()
#endif
{
    SW16  black_width;
    SL32           size;

    DBG("character()\n");

  /* Intersect app supplied tile against entire bitmap */

    if(if_state.tile_box.ll.x < 0)
       if_state.tile_box.ll.x = 0;
    if(if_state.tile_box.ll.y < 0)
       if_state.tile_box.ll.y = 0;
    if(if_state.tile_box.ur.x > if_state.entire_bm.black_width)
       if_state.tile_box.ur.x = if_state.entire_bm.black_width;
    if(if_state.tile_box.ur.y > if_state.entire_bm.black_depth)
       if_state.tile_box.ur.y = if_state.entire_bm.black_depth;

/* at this point, tile_box is set correctly for a single part character
   (ufst) and could be copied right into if_state.tb  */

    if_state.tb = if_state.tile_box;

  /* Protect against app supplied inside out tile */

    if(if_state.tile_box.ll.x > if_state.tile_box.ur.x ||
       if_state.tile_box.ll.y > if_state.tile_box.ur.y )
        return ERR_invalid_tile;

  /*  Set up memory buffers  */

    black_width =
    if_state.bmdim.x = (if_state.tile_box.ur.x - if_state.tile_box.ll.x) + 1;   /* off transition */
    if_state.bmdim.y = (if_state.tile_box.ur.y - if_state.tile_box.ll.y);
    if_state.bmdim.x = (1 + (if_state.bmdim.x-1)/if_state.bit_map_width)
                            * (if_state.bit_map_width >>3);
    DBG2("    alignment = %d, width in bytes %u\n",
                                  if_state.bit_map_width, if_state.bmdim.x);

/*DYNAMIC  could set dynamic memory here for consistency in sizes
           with non dyn. Would only save spce. dimensions are the same
 */

    size = (SL32)if_state.bmdim.x * (SL32)if_state.bmdim.y;

  /*  Fill in bitmap header */

    MEMSET((LPUB8)if_state.bm->bm, (SL32)0, (SL32)size);
    if_state.bm->width       = if_state.bmdim.x;       /* byte width   */
    if_state.bm->depth       = if_state.bmdim.y;       /* raster depth */
    if_state.bm->left_indent =
    if_state.bm->top_indent  = 0;
    if_state.bm->black_width = black_width - 1;       /* pixel width */
    if_state.bm->black_depth = if_state.bmdim.y;               /* pixel depth */
    if_state.bm->xorigin     = if_state.entire_bm.xorigin
                              + (SL32)(((SL32)if_state.tile_box.ll.x << 4));
    if_state.bm->yorigin     = if_state.entire_bm.yorigin
            - ((SL32)((SL32)(if_state.entire_bm.depth - if_state.tile_box.ur.y)<< 4));
    if_state.bm->escapement  = if_state.entire_bm.escapement;


#if GET_VERTICAL_METRICS 
 if_state.bm->topSideBearing  = if_state.entire_bm.topSideBearing; 
 if_state.bm->advanceHeight  = if_state.entire_bm.advanceHeight; 
#endif  /*R.I. 07/10/03*/


#if TT_SCREENRES
    if_state.bm->pixelWidth     = if_state.entire_bm.pixelWidth;       /* jwd, 07/24/02 */
    if_state.bm->advanceWidth.x = if_state.entire_bm.advanceWidth.x;   /* jwd, 08/18/02 */
    if_state.bm->advanceWidth.y = if_state.entire_bm.advanceWidth.y;
#endif

#if EMBEDDED_BITMAPS && TT_RDR && CGBITMAP
    if_state.bm->usedEmbeddedBitmap     = if_state.entire_bm.usedEmbeddedBitmap;
#endif
    /* Store em box size   - 01-27-93 jfd */
    if_state.bm->du_emx      = if_state.entire_bm.du_emx;
    if_state.bm->du_emy      = if_state.entire_bm.du_emy;

#if IF_RDR
    if(if_state.fst_type == FC_IF_TYPE)
        return compound_character(FSA0);
    else
#endif
        return simple_character(FSA if_state.bm, if_state.orb, if_state.bmdim);
}
/*================================================================

The functions below are the entry points into this module.
Functions external to this module call these functions which then
set up internal parameters and buffers and then call the fucntion
"character()" above to build the character bitmap.


There are four entry functions:

    CGIFtilebitMap()
    CGIFmakechar()
    bitmap()
    bitmap_tile()

All of these entry functions do:

    1.  Set the tile box "if_state.tile_box"
    2.  Set the bitmap memory buffer structure "if_state.bmb"
    3.  Call the function above "character()".

The functions CGIFtilebitMap() and CGIFmakechar() supply the bitmap
memory and any auxillary buffers ("or" transitions or bold).  The functions
bitmap() and bitmap_tile() dynamically acquire any memory needed through
calls to CHARalloc() and CHARfree().
==================================================================*/
#if CHAR_SIZE
#if TILE
#if NON_Z_WIND
/*----------------------*/
/*   CGIFtile_nzw_buf   */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 CGENTRY CGIFFtile_nzw_buf(FSP PIFTILE piftile, LPSL32 psize)
#else
GLOBAL UW16 CGENTRY
CGIFFtile_nzw_buf(piftile, psize)
    PIFTILE    piftile;
    LPSL32      psize;
#endif /* ANSI_DEFS */
{
#ifdef WINDCOMP
    *psize = 0;
    return SUCCESS;
#else
    UW16 status = SUCCESS;

    if(if_state.non_z_wind)
    {
        *psize = (SL32)if_state.ras.tran_run_ct * (
                        (SL32)((sizeof(NZ_NODE) + MEM_ALIGN) & ~MEM_ALIGN)
                      + (SL32)(piftile->depth + 1) * (SL32)(sizeof(NZCOUNTER))
                                                 );
        if(*psize > (SL32)MAX_BM)
        {
            status = ERRnzw_mem_overflow;
            goto done;
        }
       DBG1("nzw buf size %ld\n", *psize);
    }
    else
        *psize = 0L;

done:
    return status;
#endif /* WINDCOMP */
}
#endif  /*  NON_Z_WIND  */

/*-----------------------*/
/*    CGIFFtilebitMap    */
/*-----------------------*/
/*   Make the bitmap tile in tile_bm.  */
#if defined (ANSI_DEFS)
GLOBAL UW16 CGENTRY CGIFFtilebitMap(FSP PIFTILE piftile, PIFBITMAP tile_bm,
    LPUB8 nzw_buf)
#else
GLOBAL UW16 CGENTRY
CGIFFtilebitMap(piftile, tile_bm, nzw_buf)
    PIFTILE    piftile;
    PIFBITMAP  tile_bm;            /* Final result goes here */
    LPUB8      nzw_buf;
#endif /* ANSI_DEFS */
{
    BOOLEAN    save_or_on;
    UW16       status;

    if_state.tile_on = 1;
    save_or_on = if_state.or_on;
    if_state.or_on=FALSE;
    if_state.bmbufs_dyn = FALSE;

    if_state.tile_box.ll.x = piftile->x;
    if_state.tile_box.ll.y = piftile->y;
    if_state.tile_box.ur.x = if_state.tile_box.ll.x + piftile->width;
    if_state.tile_box.ur.y = if_state.tile_box.ll.y + piftile->depth;

    if_state.bm  = tile_bm;
    if_state.orb = (LPUB8)0;
    if_state.nzw = nzw_buf;

    status = character(FSA0);

    if_state.or_on = save_or_on;
    return status;
}

#endif /* TILE */
/*-----------------------*/
/*    CGIFFmakechar      */
/*-----------------------*/
/*   Make the character bitmap in bm.  */
#if defined (ANSI_DEFS)
GLOBAL UW16 CGENTRY CGIFFmakechar(FSP PIFBITMAP bm, LPUB8 nzw_buf)
#else
GLOBAL UW16 CGENTRY
CGIFFmakechar(bm, nzw_buf)
    PIFBITMAP bm;             /* Final result goes here */
    LPUB8    nzw_buf;         /* non zero winding buffer */
#endif /* ANSI_DEFS */
{
    UW16 status;
#if SPECIAL_EFFECTS
    UW16 effectsStatus;
#endif
    DBG("\n\n\n\nCGIFmakechar()\n");

#if EMBEDDED_BITMAPS && TT_RDR && CGBITMAP
    if (!if_state.cs.format && if_state.BitmapEmbedded)    /* 01-22-01 jfd */
    {
        MEMCPY((LPSB8)bm, (LPSB8)&if_state.entire_bm, BMHEADERSIZE);
        embedded_character(FSA &if_state.pbucket->p.tt.embf,
            &if_state.pbucket->p.tt.emb, bm);
#if SPECIAL_EFFECTS
        effectsStatus = DoEffects( FSA bm );
        if( effectsStatus )
            return effectsStatus;
#endif
        return SUCCESS;
    }
#endif    /* EMBEDDED_BITMAPS && TT_RDR && CGBITMAP */

    /* No further processing necessary of space character. */
    /* of if char is DL Bitmap. jwd, 07/21/03.              */
    
#if PCLEO_RDR
    if (if_state.DLBmpInProcess)
    {
        ((PDLBITMAPPTR )bm )->DLBitmapPtr = if_state.PCL_BitMapCharPtr;
        return SUCCESS;
    }
#endif
    
    if (if_state.num_loops == 0)
    {
        Char_sz_space_metrics(FSA bm);
        return ERR_fixed_space;    /* was "return SUCCESS" */ /* keb 3/25 */
    }

#if OUTLINE
  /* Make an outline in the app's buffer if that's what the format says */
    if (if_state.cs.format) 
    {
      status = outbuffer(FSA (PIFOUTLINE)bm);
      return status;
    }
#endif

    if_state.tile_on = 0;
    if_state.bmbufs_dyn = FALSE;

    if_state.tile_box.ll.x =
    if_state.tile_box.ll.y = 0;
    if_state.tile_box.ur.x = if_state.entire_bm.black_width;
    if_state.tile_box.ur.y = if_state.entire_bm.black_depth;

    if_state.bm  = bm;
    if_state.orb = if_state.cc_buf;
    if_state.nzw = nzw_buf;

    status = character(FSA0);
    if (status)
    {
        return status;
    }
#if SPECIAL_EFFECTS
    effectsStatus = DoEffects( FSA bm );
    if( effectsStatus )
        return effectsStatus;
#endif
    return status;
}
#endif  /* CHAR_SIZE */


#if CACHE || CHAR_HANDLE
/*----------------------*/
/*    bitmap_dyn        */
/*----------------------*/
/*  This function is called by bitmap() and bitmap_tile() below.

    This function acquires and frees memory needed for bitmap construction
    through calls to CHARalloc() and CHARfree() and calls character() to
    actually build the character bitmap.  The steps are

    1. Acquire memory for the character bitmap and auxillary buffers and
       load references to the acquired memory in the bitmap buffer
        structure "if_state.bmb".
    2. Call character() to make the character bitmap.
    3. Free any auxillary buffers.  Normally, the character bitmap buffer
       is not freed but returned to the caller who is responsible for
       freeing it via CHARfree().  However, if character() returns an
       error, the character bitmap memory is also freed.
*/
#if defined (ANSI_DEFS)
MLOCAL UW16  bitmap_dyn(FSP PHIFBITMAP phbm)
#else
MLOCAL UW16
bitmap_dyn(phbm)
    PHIFBITMAP     phbm;        /* Final result goes here */
#endif
{
    UW16           status;
    SL32           size;

    DBG("bitmap_dyn()\n");
    /*-----------------------------------------------------
    *  Set up bitmap memory
    */
    
    /* Special case: 
    *     if space character, set "if_state.bmdim" to 0, get handle 
    *     and return!
    */
    
    if (!if_state.num_loops)  /* 6-19-92 */
        if_state.bmdim.x = if_state.bmdim.y = 0;  /* space character */
    else
    {
        if_state.bmdim.x = if_state.tile_box.ur.x - if_state.tile_box.ll.x + 1; /* off tran */
        if_state.bmdim.y = if_state.tile_box.ur.y - if_state.tile_box.ll.y;
        if_state.bmdim.x = (1 + (if_state.bmdim.x-1)/if_state.bit_map_width)
            * (if_state.bit_map_width >>3);
        DBG2("    alignment = %d, width in bytes %u\n",
            if_state.bit_map_width, if_state.bmdim.x);
    }
    
    
    /* Nil out the handles in order to make error clean up work */
    
    if_state.horb = NIL_MH;
    if_state.hnzw     = NIL_MH;
    if_state.hbm = (HIFBITMAP)NIL_MH;
    
#if SPECIAL_EFFECTS /* rjl 6/8/2001 - These calculations are made only if doing special effects, otherwise use defaults.*/
    
    /*This is where we add to the size of the character if they are doing special effects */

    size = HowMuchBiggerIsEffect(FSA if_state.num_loops, if_state.bmdim.x, if_state.bmdim.y);    
#else
    /* compute bitmap size. */

    size = (SL32)(if_state.bmdim.x) * ((SL32)if_state.bmdim.y);
#endif /* SPECIAL_EFFECTS */
    
    if(size > ((1 << MAX_BM_BITS) - 1)/*MAX_BM*/ - BMHEADERSIZE ) /* MAX_BM_SIZE */
        return ERR_bm_too_big;
           
    /*  Get a new IFBITMAP */

    /* If we are processing a bitmap font now, just point to the address */
    /* bubbled up from PCLchId2ptr(), and go. jwd, 07/21/03.             */

#if PCLEO_RDR
    if (if_state.DLBmpInProcess)
        {
        if_state.hbm = if_state.PCL_BitMapCharPtr;
        status = ERRDLBmpInProcess;
        goto done;
        }
    else
#endif
        {
#if IFBITSPLIT

    /* allocate the IFBITMAP structure */
    if_state.hbm = (HIFBITMAP)CHARalloc(FSA (SL32)BMHEADERSIZE);
    if(if_state.hbm == NIL_MH)
        goto error;

    if_state.bm = (PIFBITMAP)MEMptr(if_state.hbm);
    MEMSET(if_state.bm, 0, BMHEADERSIZE);

    if (if_state.num_loops)      /* Not for a space character. */
       {                         /* jwd, 11/8/04.              */
       /* allocate the space for the actual bitmap data (bits) */
       if_state.bmdatahandle = CHARalloc(FSA size);
       if(if_state.bmdatahandle == NIL_MH)
          goto error;

       if_state.bmdataptr = (UL32 *)MEMptr(if_state.bmdatahandle);
       if_state.bm->bm = if_state.bmdataptr;        /* set pointer/handle to data in IFBITMAP structure */
       if_state.bm->datahandle = if_state.bmdatahandle;
       }
#else
    /* allocate the space for IFBITMAP structure + bitmap data */
    if_state.hbm = (HIFBITMAP)CHARalloc(FSA (size + (SL32)BMHEADERSIZE));
    if(if_state.hbm == NIL_MH)
        goto error;
    if_state.bm = (PIFBITMAP)MEMptr(if_state.hbm);
    MEMSET(if_state.bm, 0, BMHEADERSIZE);
#endif
         }
    DBG1("bm buffer address: %lx\n", if_state.bm);
    
    /* Special case:
    *     if space character, load handle into "phbm" and return
    */
    
    if (!if_state.num_loops)  /* 6-19-92 */
    {
        *phbm = if_state.hbm;
#if 0
/* disable this memory-leak fix (bug # 136) for now - it may create an access violation later */
        /* free unused pre-allocated memory... keb 01/06/04 */
        if(if_state.state_bm.bmb.hbm != NIL_MH)
            CHARfree(FSA if_state.state_bm.bmb.hbm);
#endif
        return ERR_fixed_space;
    }
    
    /*  Add the number of bytes needed for a row (top and bottom fluff)
    *  times two so that missing pixel recovery will not overflow buffer
    *  and add to size of buffer.
    */
    if(if_state.or_on)
    {
        /* changed "bmdim.x" to "if_state.bmdim.x" - jfd 5-5-92 */
        if_state.horb = TEMPCHARalloc(FSA size + (if_state.bmdim.x << 1));  /* dET 16-Apr 91 */
        if(if_state.horb == NIL_MH)
            goto error;
        if_state.orb = (LPUB8)MEMptr(if_state.horb);  /* added casts -ss 8/20/91 */
        DBG1("or buffer address: %lx\n", if_state.orb);
    }
    
    if_state.nzw_size = 0L;
#if NON_Z_WIND
#ifndef WINDCOMP
    if(if_state.non_z_wind)
    {
        if_state.nzw_size = (SL32)if_state.ras.tran_run_ct * (
            (SL32)((sizeof(NZ_NODE) + MEM_ALIGN) & ~MEM_ALIGN)
            + ((SL32)if_state.bmdim.y + 1) * (SL32)(sizeof(NZCOUNTER))
            );
        
        DBG2("nzw: tran_run_ct %d    nzw_size  %ld\n",
            if_state.ras.tran_run_ct, if_state.nzw_size);
        if_state.hnzw = TEMPCHARalloc(FSA if_state.nzw_size);
        if (if_state.hnzw == NIL_MH)
            goto error;
        if_state.nzw = (LPUB8)MEMptr(if_state.hnzw);
        DBG1("non z wind buffer address: %lx\n", if_state.nzw);
    }
#endif /* WINDCOMP */
#endif /* NON_Z_WIND */
    
    goto good;
    
error:
#if IFBITSPLIT
    if(if_state.bmdatahandle != NIL_MH)
    {
        CHARfree(FSA if_state.bmdatahandle);
        if_state.bmdatahandle = NIL_MH;
    }
#endif
    if(if_state.hbm != NIL_MH)
    {
        CHARfree(FSA if_state.hbm);
        if_state.hbm = (HIFBITMAP)NIL_MH;
    }
    if(if_state.horb != NIL_MH)
    {
        TEMPCHARfree(FSA if_state.horb);
        if_state.horb = NIL_MH;
    }
    if(if_state.hnzw != NIL_MH)
    {
        TEMPCHARfree(FSA if_state.hnzw);
        if_state.hnzw = NIL_MH;
    }
    status = ERR_bm_buff;
    goto done;
    
good:
    
/*-----------------------------------------------------
*  Build the character bitmap
    */
    
    if_state.bmbufs_dyn = TRUE;
    status = character(FSA0);
    if(status && status != ERR_invalid_tile)  /* 09-02-97 jfd */
    {
#if IFBITSPLIT
        if(if_state.bmdatahandle != NIL_MH)
        {
            CHARfree(FSA if_state.bmdatahandle);
            if_state.bmdatahandle = NIL_MH;
        }
#endif
        CHARfree(FSA if_state.hbm);
        if_state.hbm = (HIFBITMAP)NIL_MH;
    }
    
    /*--------------------------------------------------------
    *  Free the auxillary buffers (for regular AND error cases)
    */
    if(if_state.horb != NIL_MH)
    {
        TEMPCHARfree(FSA if_state.horb);
        if_state.horb = NIL_MH;
    }
    if(if_state.hnzw != NIL_MH)
    {
        TEMPCHARfree(FSA if_state.hnzw);
        if_state.hnzw = NIL_MH;
    }
    
done:
    *phbm = if_state.hbm;
    return status;
}
#if TILE
/*----------------------*/
/*    bitmap_tile       */
/*----------------------*/
/*  Build a bitmap tile in memory dynamically allocated by CHARalloc().
 *  Return the handle of the bitmap tile.  Return NIL_MH if error.
 */
#if defined (ANSI_DEFS)
GLOBAL UW16  bitmap_tile(FSP PIFTILE piftile, PHIFBITMAP phbm)
#else
GLOBAL UW16
bitmap_tile(piftile, phbm)
    PIFTILE        piftile;
    PHIFBITMAP     phbm;        /* Final result goes here */
#endif
{
    UW16    status;
    BOOLEAN save_or_on;

    DBG("bitmap_tile()\n");
    if_state.tile_on = 1;
    save_or_on = if_state.or_on;
    if_state.or_on=FALSE;

    if_state.tile_box.ll.x = piftile->x;
    if_state.tile_box.ll.y = piftile->y;
    if_state.tile_box.ur.x = if_state.tile_box.ll.x + piftile->width;
    if_state.tile_box.ur.y = if_state.tile_box.ll.y + piftile->depth;

    status = bitmap_dyn(FSA phbm);

    if_state.or_on = save_or_on;
    return status;
}
#endif
/*----------------------*/
/*    bitmap            */
/*----------------------*/
/*  Build a bitmap in memory dynamically allocated by CHARalloc().
 *  Return the handle of the bitmap.  Return NIL_MH if error.
 */
#if defined (ANSI_DEFS)
GLOBAL UW16  bitmap(FSP PHIFBITMAP phbm)
#else   
GLOBAL UW16
bitmap(phbm)
    PHIFBITMAP  phbm;         /* Final result goes here */
#endif
{
    DBG("bitmap()\n");


    if_state.tile_on = 0;

    if_state.tile_box.ll.x =
    if_state.tile_box.ll.y = 0;
    if_state.tile_box.ur.x = if_state.entire_bm.black_width;
    if_state.tile_box.ur.y = if_state.entire_bm.black_depth;

    return bitmap_dyn(FSA phbm);
}
#endif /* CACHE || CHAR_HANDLE */
/*-------------------*/
/*       render      */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16 render ( FSP0 )
#else
MLOCAL UW16 render ( )
#endif
{
    UW16 status;
    PBUCKET pb = GET_pBUCKET(if_state.pbucket);                /* 05-23-01 jfd */

#if USE_JUMP_TABLES
        status = (*((PIF_FUNC_TBL)pb->pft)->render)    /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                 ( FSA if_state.out_instance,
                   pb,                                /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                   if_state.xlate.x,
                   if_state.xlate.y + (half_ypix<<if_state.right_shift));
#else
       switch (pb->fst_type)                        /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
       {
#if IF_RDR
          case FC_IF_TYPE:
             status = (ifrender (FSA if_state.out_instance,
                                  pb,                /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                                  if_state.xlate.x,
                                  if_state.xlate.y
                                      + (half_ypix<<if_state.right_shift)));
              break;
#endif
#if PST1_RDR
          case FC_PST1_TYPE:
             status = (psrender (FSA if_state.out_instance,
                                   pb,                /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                                   if_state.xlate.x,
                                   if_state.xlate.y
                                      + (half_ypix<<if_state.right_shift)));
              break;
#endif
#if TT_RDR
          case FC_TT_TYPE:
              status = (ttrender (FSA if_state.out_instance,
                                    pb,                /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                                    if_state.xlate.x,
                                    if_state.xlate.y
                                      + (half_ypix<<if_state.right_shift)));
              break;
#endif
#if FCO_RDR
          case FC_FCO_TYPE:
              status = (fco_render (FSA if_state.out_instance,
                                      pb,            /* changed 'if_state.pbucket' to 'pb'  05-23-01 jfd */
                                      if_state.xlate.x,
                                      if_state.xlate.y
                                       + (half_ypix<<if_state.right_shift)));
              break;
#endif
          default:
              status = (ERR_fst_type);
              break;
        }
#endif /* not USE_JUMP_TABLES */
    return status;
}
#endif /* CGBITMAP */

 

bmputl.c  //

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

/* $Header:   I:/BULL/URIP/RTS/BMP/BMPUTL.C_V   1.21   Aug 21 2003 16:47:40   Galejs  $ */
/* $Log:   I:/BULL/URIP/RTS/BMP/BMPUTL.C_V  $ 
 * 
 *    Rev 1.21   Aug 21 2003 16:47:40   Galejs
 * update copyright notice
 * 
 *    Rev 1.20   Jul 21 2003 17:11:14   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.19   Jun 23 2003 13:44:56   Galejs
 * ufstport.h
 * 
 *    Rev 1.18   May 03 2001 19:08:10   Galejs
 * data-type cleanup
 * 
 *    Rev 1.17   Aug 10 1999 14:41:20   galejs
 * include-file changes
 * 
 *    Rev 1.16   29 Jul 1999 16:58:02   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.15   12 Jan 1999 18:12:52   GALEJS
 * move EXTERN dcls
 * 
 *    Rev 1.14   22 Jun 1998 18:48:04   GALEJS
 * make Intellifont reentrant too
 * 
 *    Rev 1.13   15 Apr 1998 16:52:34   GALEJS
 * move chr_def_hdr into IF_STATE
 * 
 *    Rev 1.12   24 Mar 1998 14:43:36   GALEJS
 * include-file changes
 * 
 *    Rev 1.11   28 Jan 1998 11:48:04   AL
 * Moved gaso_pn to if_state for re-entrant
 * 
 *    Rev 1.10   15 Apr 1997 15:04:08   MIKE
 * LINT_ARGS replaces LINTARGS
 * 
 *    Rev 1.9   13 Jan 1997 08:36:46   DAVID
 * Removed ELASTIC_X and ELASTIC_Y option as part of project to trim ufst.
 * 
 *    Rev 1.8   06 Apr 1995 15:08:24   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.7   03 Jun 1994 08:46:24   JOE
 * In char_left_ref(), when calculating "orig_black_width", check if
 * character is a contourless character. If so, set to 0 rather than
 * using the "bound_box" data in the event that it is invalid.
 * 
 *    Rev 1.6   22 Apr 1994 09:20:48   LISA
 * Modified copyright/disclaimer notice.
 * 
 *    Rev 1.5   18 Apr 1994 08:17:16   JOE
 * Added comment in char_left_ref() describing fix for multi-part
 * characters with nonzero offset in first part.
 * 
 *    Rev 1.4   15 Apr 1994 16:23:14   JOE
 * 
 * Added new function char_left_ref().
 * Added arg to find_part2whole() function.
 * Made changes to fix floating accent problem.
 * 
 *    Rev 1.3   12 Feb 1993 11:04:22   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   05 Jan 1993 15:58:18   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:28:36   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:33:04   LISA
 * Initial revision.
*/
/* $Date:   Aug 21 2003 16:47:40  $ */
/* bmputl.c */

/* History                                                           */
/*    03-Oct-91 jfd  Removed #if TILE conditional around print_bm(). */
/*    10-Oct-91 rs   Modify 'translate_coords()' for bezier data &   */
/*                   Type 1 input.                                              */
/*    25-Oct-91 jfd  Instead of conditionally compiling entire file  */
/*                   based on CGBITMAP, conditionally compile based  */
/*                   on (CACHE || CHAR_SIZE || CHAR_HANDLE) to get   */
/*                   rid of link errors that occur if CGBITMAP is not*/
/*                   enabled.                                        */
/*    16-Jan-92 rs   Fix 'translate_coords() for PS type 1.          */
/*    23-Jan-92 awr  Removed translate_coords()                      */
/*    05-Feb-92 jfd  In print_bm(), changed format for x and y origins */
/*                   from "%d" to "%ld".                             */
/*    22-Mar-92 awr  Changed bitmap_dimensions() to take LONGs       */
/*                   Removed unused global tiling variables          */
/*    30-Mar-92 jfd  In bitmap_dimensions(), fixed DBG2 statement      */
/*                   to print "x" and "y" instead of "ur.x" and "ur.y" */
/*    03-Apr-92 rs   Portability cleanup (see port.h).                */
/*    04-Apr-92 awr  Changed calling sequence of find_part2whole()   */
/*    12-Apr-92 awr  Moved translation calcs from manipulate() to    */
/*                   make_gaso()                                     */
/*    18-Apr-92 awr  Removed clip_tile()                             */
/*     2-May-92 awr  Moved if_state.tt initialization from           */
/*                   manipualte() to make_gaso()                     */
/*    14-Jun-92 awr  Changed types of xlate and tbound to INTRs      */
/*    3-Jul-92  awr  Moved structs_are_equal() to comp_pix.c         */
/*                   Fixed test in make_gaso()... was big slow down  */
/*   11-Aug-92  jfd  Trying macro MDES2BM for optimization.          */
/*                   Included imath.h.                                          */
/*   16-Aug-92  rs   Fix nested comment.                                    */
/*   19-Aug-92  awr  In make_gaso(), only return prematurely if      */
/*                   processing a simple character.                  */
/*   15-Sep-92  jfd  Conditionally compile the following routines    */
/*                   based on IF_RDR:                                */
/*                   union_bound_boxes(), find_part2whole(),         */
/*                   make_gaso().                                    */
/*   16-Sep-92  jfd  Removed GLOBAL declarations for "entire_bm" and */
/*                   "entire_tt". They are now being declared GLOBAL */
/*                   in maker.c.                                     */
/*                   Changed declaration for "gaso_pn" from GLOBAL   */
/*                   to EXTERN. It is now declared GLOBAL in         */
/*                   comp_pix.                                       */
/*   15-Nov-92  rs   Port to Macintosh - use ANSI_DEFS on functions  */
/*   05-Jan-93  jfd  ANSI C function declaration changes             */
/*   08-Feb-93  jfd  VXWorks support.                                */
/*   13-Apr-94  awr  Added new function char_left_ref().             */
/*                   Added arg to find_part2whole() function.        */
/*                   Made changes to fixfloating accent problem.     */
/*   15-Apr-94  jfd  Added arg go char_left_ref() - y offset.        */
/*   27-May-94  jfd  In char_left_ref(), when calculating            */
/*                   "orig_black_width", check if character is a     */
/*                   contourless character. If so, set to 0 rather   */
/*                   than using the "bound_box" information in the   */
/*                   event that it is invalid.                       */
/*   13-Jan-97  dlk  Remover ELASTIC_X and ELASTIC_Y as part of pro-
 *                   ject to trim ufst.
 *   14-Apr-97  mby  Replaced "LINTARGS" with "LINT_ARGS".
 *   28-Jan-98  awr  moved gaso_pn to if_state for re-entrant
 *   28-July-99 ks   Changed DEBUG compiler directive to AGFADEBUG. 
 *-------------------------------------------------------------------*/


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

#include <stdio.h>

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

#include "shareinc.h"

#include "imath.h"


#if IF_RDR
/*----------------------*/
/*      make_gaso       */
/*----------------------*/
/*  Make a Grid aligned, Scaled Outline. Keep track of the current
 *  gaso and don't remake if not necessary.
 */

#if defined (ANSI_DEFS)
GLOBAL UW16  make_gaso(FSP SL32 pn, PCHR_DEF cd)
#else
GLOBAL UW16
make_gaso(pn, cd)
    SL32 pn;
    PCHR_DEF    cd;
#endif
{
    UW16 status;

    DBG("make_gaso()\n");

    if(pn == if_state.gaso_pn && pn == 0)  /* 8-19-92 */
        return SUCCESS;


    if_state.gaso_pn = -1;   /* make invalid in case we fail */

    status = DArd_char(FSA cd);
    if (status)
        return status;

  /*  Set translation for scaling to working fop space. Resulting outline
   *  can end up in any quadrant
   */

    if_state.tt.x = if_state.tt.y = 0;

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

  /*  Compute the translation
   *  from working space to working bitmap space for cc base.
   */

#if INTR_SIZE == 16
    DBG4("work buffer bounds:  (%d, %d)   (%d, %d)\n",
                                        if_state.tbound.ll.x,
                                        if_state.tbound.ll.y,
                                        if_state.tbound.ur.x,
                                        if_state.tbound.ur.y);
#else
    DBG4("work buffer bounds:  (%ld, %ld)   (%ld, %ld)\n",
                                        if_state.tbound.ll.x,
                                        if_state.tbound.ll.y,
                                        if_state.tbound.ur.x,
                                        if_state.tbound.ur.y);
#endif

  /*  NOTE: the grid alignment is correct whether x_min and y_min
   *  are positive or negative becase "&" always truncates to the left.
   *  The reason for rounding the two different ways is that after
   *  translating by tt, we want
   *      XFLOOR  (tt.x + tbound.ll.x + x.half_pixel) = 0
   *      YCEILING(tt.y + tbound.ll.y + y.half_pixel) = 1
   *
   *  This requires that:
   *
   *      -x.half_pixel <= tt.x + tbound.ll.x <  x.half_pixel
   *      -y.half_pixel <  tt.y + tbound.ll.y <= y.half_pixel
   */

    if_state.xlate.x =   -((if_state.tbound.ll.x + if_state.x.half_pixel)
                                      & if_state.x.grid_align);
    if_state.xlate.y =   ((-if_state.tbound.ll.y + if_state.y.half_pixel)
                                      & if_state.y.grid_align);

  /*  Compute working bitmap bounding box: assumes we will
   *  translate by if_state.tt
   */

    if_state.tbound.ll.x += if_state.xlate.x;
    if_state.tbound.ll.y += if_state.xlate.y;
    if_state.tbound.ur.x += if_state.xlate.x;
    if_state.tbound.ur.y += if_state.xlate.y;

  /* tt must by SW16 and is used for Intellifont translation before
   * resolution is increased to INTR
   */
    if_state.tt.x = (SW16)if_state.xlate.x;
    if_state.tt.y = (SW16)if_state.xlate.y;
    DBG2("    if_state.tt.x = %d   if_state.tt.y = %d\n",
                    if_state.tt.x, if_state.tt.y);

    if_state.tbound.ll.y += (INTR)if_state.y.half_pixel;
    if_state.tbound.ur.y += (INTR)if_state.y.half_pixel;

#if INTR_SIZE == 16
    DBG4(" bm fops bounding box (%d,%d)   (%d,%d)\n\n",
                                                    if_state.tbound.ll.x,
                                                    if_state.tbound.ll.y,
                                                    if_state.tbound.ur.x,
                                                    if_state.tbound.ur.y);
#else
    DBG4(" bm fops bounding box (%ld,%ld)   (%ld,%ld)\n\n",
                                                    if_state.tbound.ll.x,
                                                    if_state.tbound.ll.y,
                                                    if_state.tbound.ur.x,
                                                    if_state.tbound.ur.y);
#endif

    if_state.gaso_pn = pn;    /* current grid aligned scaled outline */
    return SUCCESS;
}


/*----------------------*/
/*   union_bound_boxes  */
/*----------------------*/
/*  Translate the src bounding box by (dx, dy) and then merge it
 *  with the destination bounding box. Return result in the
 *  destination bounding box.
 */
#if defined (ANSI_DEFS)
GLOBAL VOID union_bound_boxes(PBOX dst, PBOX src, SW16 dx, SW16 dy)
#else
GLOBAL VOID
union_bound_boxes(dst, src, dx, dy)
    PBOX dst, src;
    SW16 dx, dy;
#endif /* ANSI_DEFS */
{
    dst->ll.x = MIN(dst->ll.x, dx + src->ll.x);
    dst->ll.y = MIN(dst->ll.y, dy + src->ll.y);
    dst->ur.x = MAX(dst->ur.x, dx + src->ur.x);
    dst->ur.y = MAX(dst->ur.y, dy + src->ur.y);
}

/*----------------------*/
/* bitmap_dimensions    */
/*----------------------*/
/*
Calculate the width and depth of a bit map in (bytes x pixels)
given the upper right corner in fops. The lower left corner is
assumed to be (1,1) in fops.


    The "final" outline that is rasterized is still in "fops"- fractional
    output pixels. The outline has been translated so as to be close to the
    the axis of the first quadrant. It is then translated 1/2 pixel up
    to make protect againts "widows" and "flats" in curves. The result
    of all of this is that if SW16DVECTOR ll is the lower left corner of
    the resulting fop bounding box, then

            -0.5 pixel <= ll.x <  0.5 pixel
               0       <  ll.y <= 1


    The width calculated is the resulting black width. The charcter
    transition array will be one bit wider to include the rightmost
    off transition.

*/

/*----------------------*/
/*    chr_left_ref      */
/*----------------------*/
/*  This function may only be called for quadrant rotations.
 *  Returned value is not really a box, but two vectors.  The vector ll of
 *  of the box is the new location in design space of the left reference
 *  baseline.  This new location takes into account chages in black width
 *  that cause the left side bearing to change.  It is calculated off the
 *  inverse image of the bitmap so that des2bm() maps it to it's bitmap
 *  location in the bitmap.
 *
 *  The vector ur is the vector from this new origin in design space to the
 *  pre-image in design space of the lower left pixel of the bitmap.
 */
#if defined (ANSI_DEFS)
GLOBAL BOX char_left_ref(FSP SW16VECTOR org, BOX pixBound, SW16 yoff)
#else
GLOBAL BOX char_left_ref(org, pixBound, yoff)
    SW16VECTOR org;
    BOX pixBound;
    SW16 yoff;
#endif
{
    BOX retVal;
    SW16VECTOR prell, preur, dll, dur;
    SW16 orig_lsb, new_lsb;
    SW16VECTOR new_org;    /* character origin (design units)        */

    DBG("char_left_ref()\n");
    DBG2("org %d %d\n", org.x, org.y);
    DBG2("pixBound %d %d\n", pixBound.ll.x, pixBound.ll.y);
    DBG2("          %d %d\n", pixBound.ur.x, pixBound.ur.y);

    pixBound.ur.x <<= log_xpix; 
    pixBound.ur.y <<= log_ypix; 
    /*  assume pixBound.ll is (0,0) */

    prell = inv_des2bm(FSA pixBound.ll);
    preur = inv_des2bm(FSA pixBound.ur);
    DBG2("prell %d %d\n", prell.x, prell.y);
    DBG2("preur %d %d\n", preur.x, preur.y);

    if(prell.x < preur.x)
    {
        dll.x = prell.x;
        dur.x = preur.x;
    }
    else
    {
        dll.x = preur.x;
        dur.x = prell.x;
    }
    if(prell.y < preur.y)
    {
        dll.y = prell.y;
        dur.y = preur.y;
    }
    else
    {
        dll.y = preur.y;
        dur.y = prell.y;
    }

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

    orig_lsb = if_state.bound_box.ll.x - org.x;

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

        if (if_state.num_loops)
           orig_black_width = if_state.bound_box.ur.x
                            - if_state.bound_box.ll.x;
        else
           orig_black_width = 0;

        new_black_width  = dur.x - dll.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 = dll.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  */
    /*  Using "yoff" to adjust new_org should fix bug for multipart   */
    /*  characters with nonzero offset in first part.   -jfd 4/15/94  */      
/*
    if( if_state.chr_def->offset.y )
       new_org.y -= if_state.chr_def->offset.y;
*/
    new_org.y -= yoff;


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

    retVal.ll = new_org;

    retVal.ur.x = prell.x - new_org.x;
    retVal.ur.y = prell.y - new_org.y;

    DBG2("retVal %d %d\n", retVal.ll.x, retVal.ll.y);
    DBG2("       %d %d\n", retVal.ur.x, retVal.ur.y);

    return retVal;
}
/*----------------------*/
/*   find_part2whole    */
/*----------------------*/
/* calculate pixel address in destination bitmap of pixel
 * origin (0,0) in compound part bitmap
 */
#if defined (ANSI_DEFS)
GLOBAL SW16VECTOR find_part2whole(FSP SW16VECTOR wholeOrg,
                                          SW16VECTOR tt, PCHR_DEF cd)
#else
GLOBAL SW16VECTOR
find_part2whole(wholeOrg, tt, cd)
    SW16VECTOR wholeOrg;
    SW16VECTOR tt;       /* translation for part  */
    PCHR_DEF   cd;
#endif
{
    SW16VECTOR ctt;       /* translation for part  */
    SW16VECTOR des_tran;
    SW16VECTOR p2w;

    DBG("find_part2whole()\n");
    DBG2("wholeOrg %d %d\n", wholeOrg.x, wholeOrg.y);
    DBG2("pix_bound %d %d\n", cd->pix_bound.ll.x, cd->pix_bound.ll.y);
    DBG2("          %d %d\n", cd->pix_bound.ur.x, cd->pix_bound.ur.y);

  /* des_tran = design unit translation to move compound part so
   * in design space so that it is positioned correctly with respect
   * to the other parts.
   */
    if(!if_state.quadrant)  /* arbitrary rotation */
    {
    des_tran.x = if_state.chr_def_hdr.origin.x-(if_state.escape_box.ll.x - cd->offset.x);
    des_tran.y = if_state.chr_def_hdr.origin.y-(if_state.escape_box.ll.y - cd->offset.y);
        ctt = if_state.tt;       /* save translation of part */
    }
    else
    {
        BOX foo;
        foo = char_left_ref(FSA if_state.escape_box.ll, cd->pix_bound, (SW16)0);
        des_tran.x = wholeOrg.x + cd->offset.x + foo.ur.x;
        des_tran.y = wholeOrg.y + cd->offset.y + foo.ur.y;
        ctt.x = ctt.y = 0;
    }
    DBG2("des_tran = %d %d\n", des_tran.x, des_tran.y);


  /*  Must grid align des_tran. */

    pixel_align (FSAvoid des_tran.x, &if_state.x, R_TWO_I);
    des_tran.x = if_state.value;
    pixel_align (FSAvoid des_tran.y, &if_state.y, R_TWO_I);
    des_tran.y = if_state.value;
    DBG2("grid aligned des_tran = %d %d\n", des_tran.x, des_tran.y);

    if_state.tt = tt;        /* restore translation for whole */
#if defined MDES2BM
    p2w = MDES2BM(des_tran);  /* part to whole translate */
#else
    p2w = des2bm(FSA des_tran);  /* part to whole translate */
#endif /* defined MDES2BM */
    p2w.x -= ctt.x;
    p2w.y -= ctt.y;
    DBG2("p2w in fops = %d %d\n", p2w.x, p2w.y);

    p2w.x = XFLOOR(p2w.x);
    p2w.y = YFLOOR(p2w.y);
    DBG2("p2w in pixels = %d %d\n", p2w.x, p2w.y);

    return p2w;
}
#endif  /* IF_RDR */


#ifdef AGFADEBUG
#if defined (ANSI_DEFS)
GLOBAL VOID  print_bm(FSP PIFBITMAP bm)
#else
GLOBAL VOID
print_bm(bm)
    PIFBITMAP bm;
#endif
{
    DBG3("    width(bytes) x depth:     %d x %d = %ld bytes\n",
                 bm->width, bm->depth, (SL32)bm->width * (SL32)bm->depth);
    DBG2("    left_indent, top_indent   %d %d\n", bm->left_indent,
                                                  bm->top_indent);
    DBG2("    black_width, black_depth  %d %d\n", bm->black_width,
                                                  bm->black_depth);
    DBG2("    xorigin, yorigin          %ld %ld\n", bm->xorigin,
                                                    bm->yorigin);
}
#endif    /* AGFADEBUG */

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值