bmputl.txt ///
/* 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 */
bold.txt
/* Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved. */
/* $Header: I:/BULL/URIP/RTS/COR/BOLD.C_V 1.15 Aug 21 2003 17:03:30 Galejs $ */
/* $Log: I:/BULL/URIP/RTS/COR/BOLD.C_V $
*
* Rev 1.15 Aug 21 2003 17:03:30 Galejs
* update copyright notice
*
* Rev 1.14 Jul 21 2003 17:24:42 Galejs
* reentrancy / debug fixes
*
* Rev 1.13 Jun 19 2003 18:35:48 Galejs
* get rid of TEST_INTERSECT option
*
* Rev 1.12 Aug 13 1999 14:36:58 galejs
* include-file changes; MSDOS becomes UFST_MSDOS
*
* Rev 1.11 22 Jun 1998 18:56:28 GALEJS
* make Intellifont reentrant too
*
* Rev 1.10 15 Jun 1998 16:04:30 GALEJS
* include-file changes
*
* Rev 1.9 15 Apr 1998 18:01:34 GALEJS
* dup_points[] in IF_STATE now
*
* Rev 1.8 02 Apr 1998 19:11:16 GALEJS
* move externs to if_state
*
* Rev 1.7 24 Mar 1998 15:10:24 GALEJS
* include-file changes
*
* Rev 1.6 06 Apr 1995 15:10:50 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.5 22 Apr 1994 09:27:54 LISA
* Modified copyright/disclaimer notice for 1994.
*
* Rev 1.4 08 Dec 1993 18:59:42 ROB
* No change.
*
* Rev 1.3 12 Feb 1993 11:28:10 JOE
* VXWorks support.
*
* Rev 1.2 07 Jan 1993 10:47:36 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 09:37:06 LISA
* Made change to Log keyword
*
* Rev 1.0 10 Dec 1992 08:37:14 LISA
* Initial revision.
*/
/* $Date: Aug 21 2003 17:03:30 $ */
/* bold.c */
/*
*
*
* History
*
* 28-Jul-90 awr created
* 12-Oct-90 tbh In bold(), computing point of intersection "dp->x",
* "dp->y" differently in the event that both X and Y
* skeletal data do not exist for a duplicate point.
* 15-Oct-90 awr In intersect(), check that intersection point does
* not exceed bounding box
* 30-Jan-91 dET added function prototyping for MSC.
* 31-Jan-91 dET Modify for MSC multi-model compilation.
* 3-Feb-91 awr Removed nx(), ny() function declarations,
* updated copyright.
* Changed initialization call from np_init_char() to
* init_xy_tran().
* 5-Feb-91 awr Conditionally compiled whole module on BOLD.
* Added #include "cgconfig.h"
* 8-Feb-91 awr Removed EXTERN x_skel[] and y_skel[] and made
* parameters of bold().
* 6-Apr-91 awr Changed intersect calculations to floating point
* Removed long math code to lmath.c.
* 8-Apr-91 jfd In intersect(), call printf() only if MSC.
* 1-Jun-91 awr HQ4 changes
* 17-Jun-91 jfd Moved "debug.h" after "port.h".
* Moved "profile.h" after "port.h".
* 24-Aug-91 awr Moved function decls to include file
* 19 Sep 91 ss Added casts for compare to -1 to eliminate warnings on SUN.
* 03-Apr-92 rs Portability cleanup (see port.h).
* 16-Aug-92 rs Change define from MSC to MSDOS.
* Fix use of '-1' for UB8 & UW16.
* 15-Sep-92 jfd Conditionally entire module based on IF_RDR.
* 14-Nov-92 rs Port to Mac - ANSI function definitions using ANSI_DEFS,
* rename bold() to cgbold().
* 07-Jan-93 jfd ANSI C function declaration changes.
* 08-Feb-93 jfd VXWorks support.
* 15-Apr-98 slg Move dup_points[] into IF_STATE.
*/
/*-------------------------------------------------------------*/
/* b o l d i n t e r s e c t */
#include "cgconfig.h"
#if IF_RDR
#if BOLD /* whole module is conditionally compiled on BOLD */
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include "ufstport.h"
#include "dbg_ufst.h"
#include "shareinc.h"
#include "imath.h"
#include "adj_skel.h"
#ifdef LINT_ARGS
MLOCAL BOOLEAN no_intersect(FSP PDUP_POINTS);
MLOCAL BOOLEAN intersect(FSP SW16,SW16,SW16,SW16,SW16,SW16,SW16,SW16,PDUP_POINTS);
MLOCAL VOID set_tran(FSP PTRAN, UW16, UW16);
MLOCAL VOID find_in_scale_seg(FSP UW16, LPUW16, PTRAN, LPUB8, LPUB8);
MLOCAL VOID find_out_scale_seg(FSP UW16,LPUW16, PTRAN, LPUB8, LPUB8);
#endif /* LINT_ARGS */
#if defined (ANSI_DEFS)
MLOCAL BOOLEAN no_intersect(FSP PDUP_POINTS dp)
#else
MLOCAL BOOLEAN
no_intersect(dp)
PDUP_POINTS dp;
#endif
{
DBG(" lines do not intersect\n");
dp->xsk0 = 255;
dp->xsk1 = 255;
dp->ysk0 = 255;
dp->ysk1 = 255;
return FALSE; /* lines don't intersect */
}
#if defined (ANSI_DEFS)
MLOCAL BOOLEAN intersect(FSP SW16 xi0, SW16 yi0, SW16 xi1, SW16 yi1,
SW16 xo0, SW16 yo0, SW16 xo1, SW16 yo1, PDUP_POINTS dp)
#else
MLOCAL BOOLEAN
intersect(xi0, yi0, xi1, yi1, xo0, yo0, xo1, yo1, dp)
SW16 xi0, yi0, xi1, yi1, xo0, yo0, xo1, yo1;
PDUP_POINTS dp;
#endif /* ANSI_DEFS */
{
FPNUM a0, b0, c0, a1, b1, c1;
FPNUM det;
FPNUM x_det, y_det;
SW16 x, y;
DBG("intersect()\n");
DBG4(" (%d, %d) (%d, %d)\n", xi0, yi0, xi1, yi1);
DBG4(" (%d, %d) (%d, %d)\n", xo0, yo0, xo1, yo1);
/* For the two lines, determine equations of the form:
*
* a0*x + b0*y = c0
* a1*x + b1*y = c1
*/
if_state.fpmath_error = 0;
a0 = fpint2fp((SL32)(yi1 - yi0));
b0 = fpint2fp((SL32)(xi0 - xi1));
c0 = fpint2fp((SL32)xi0*(SL32)yi1 - (SL32)yi0*(SL32)xi1);
a1 = fpint2fp((SL32)(yo1 - yo0));
b1 = fpint2fp((SL32)(xo0 - xo1));
c1 = fpint2fp((SL32)xo0*(SL32)yo1 - (SL32)yo0*(SL32)xo1);
/* Solve equations using determinants */
det = fpsub(fpmul(a0, b1), fpmul(a1, b0));
if(fpiszero(det))
return no_intersect(FSA dp);
x_det = fpsub(fpmul(c0, b1), fpmul(c1, b0)); /* c0*b1 - c1*b0 */
y_det = fpsub(fpmul(a0, c1), fpmul(a1, c0)); /* a0*c1 - a1*c0 */
x = fp2word(fpdiv(x_det, det));
y = fp2word(fpdiv(y_det, det));
/* Check that we do not exceed bounding box (10-15-90 awr) */
if(if_state.fpmath_error || (x < if_state.bound_box.ll.x)
|| (if_state.bound_box.ur.x < x)
|| (y < if_state.bound_box.ll.y)
|| (if_state.bound_box.ur.y < y))
return no_intersect(FSA dp);
dp->x = x;
dp->y = y;
DBG2(" intersection (%d, %d)\n", dp->x, dp->y);
return TRUE;
}
#if defined (ANSI_DEFS)
MLOCAL VOID set_tran (FSP PTRAN td, UW16 first_skel_ind, UW16 last_skel_ind)
#else
MLOCAL VOID
set_tran(td, first_skel_ind, last_skel_ind)
PTRAN td;
UW16 first_skel_ind, last_skel_ind;
#endif /* ANSI_DEFS */
{
PADJUSTED_SKEL skel0, skel1;
skel0 = td->skel + td->sct + first_skel_ind;
skel1 = td->skel + td->sct + last_skel_ind;
td->new0 = skel0->adjusted;
td->new1 = skel1->adjusted;
td->num = td->new1 - td->new0;
td->old0 = skel0->original;
td->old1 = skel1->original;
td->den = td->old1 - td->old0;
if(!td->den) td->num = td->den = 1;
td->half_den = td->den / 2;
DBG2("new0 %d new1 %d\n", td->new0, td->new1);
DBG2("old0 %d old1 %d\n", td->old0, td->old1);
DBG2("num %d den %d\n\n\n",td->num,td->den);
}
/* 10-12-90 tbh Added argument "pskelMinus1" to find_in_scale_seg() */
#if defined (ANSI_DEFS)
MLOCAL VOID find_in_scale_seg(FSP UW16 coord_index, LPUW16 s2c_base, PTRAN td,
LPUB8 pskel, LPUB8 pskelMinus1)
#else
MLOCAL VOID
find_in_scale_seg(coord_index, s2c_base, td, pskel, pskelMinus1)
UW16 coord_index;
LPUW16 s2c_base;
PTRAN td; /* ptr to x or y transform data */
LPUB8 pskel, pskelMinus1; /* 10-12-90 tbh */
#endif /* ANSI_DEFS */
{
UW16 i;
LPUW16 p;
UW16 first_skel_ind, last_skel_ind;
DBG1("find_in_scale_seg(%u)\n", coord_index);
DBG1(" nsk = %u\n", td->nsk);
for(i=0, p=s2c_base + td->sct; i<td->nsk; i++, p++)
{
DBG1(" %u\n", *p);
if(*p >= coord_index)
{
DBG(" found it\n");
break;
}
}
if(i==0 || i==td->nsk) /* scale seg = last skel to first skel */
{
first_skel_ind = td->nsk - 1;
last_skel_ind = 0;
}
else
{
first_skel_ind = i - 1;
last_skel_ind = i;
}
DBG2(" first_skel_ind %u last_skel_ind %u\n",
first_skel_ind, last_skel_ind);
*pskel = 0xff; /* -1 */ /* 255 */
*pskelMinus1 = (UB8)(td->sct + first_skel_ind); /* 10-12-90 tbh */
if(i<td->nsk)
if(*p == coord_index)
*pskel = (UB8)(td->sct + last_skel_ind);
set_tran(FSA td, first_skel_ind, last_skel_ind);
}
/* 10-12-90 tbh Added argument "pskelPlus1" to find_out_scale_seg() */
#if defined (ANSI_DEFS)
MLOCAL VOID find_out_scale_seg(FSP UW16 coord_index, LPUW16 s2c_base, PTRAN td,
LPUB8 pskel, LPUB8 pskelPlus1)
#else
MLOCAL VOID
find_out_scale_seg(coord_index, s2c_base, td, pskel, pskelPlus1)
UW16 coord_index;
LPUW16 s2c_base;
PTRAN td; /* ptr to x or y transform data */
LPUB8 pskel, pskelPlus1; /* 10-12-90 tbh */
#endif /* ANSI_DEFS */
{
UW16 i;
LPUW16 p;
UW16 first_skel_ind, last_skel_ind;
DBG1("find_out_scale_seg(%u)\n", coord_index);
DBG1(" nsk = %u\n", td->nsk);
i=td->nsk-1;
for(p=s2c_base + td->sct + i; i>0; i--, p--)
{
DBG1(" %u\n", *p);
if(*p <= coord_index)
{
DBG(" found it\n");
break;
}
}
if(i==(UW16)-1 || i==td->nsk-1) /* scale seg = last skel to first skel */
{
first_skel_ind = td->nsk - 1;
last_skel_ind = 0;
}
else
{
first_skel_ind = i;
last_skel_ind = i + 1;
}
DBG2(" first_skel_ind %u last_skel_ind %u\n",
first_skel_ind, last_skel_ind);
*pskel = 0xff; /* -1 */ /* 255 */
*pskelPlus1 = (UB8)(td->sct + last_skel_ind); /* 10-12-90 tbh */
if(i != (UW16)(-1)) /* should this be '!= (UW16)(-1)' ?? was '>=0' */
if(*p == coord_index)
*pskel = (UB8)(td->sct + first_skel_ind);
set_tran(FSA td, first_skel_ind, last_skel_ind);
}
#if defined (ANSI_DEFS)
GLOBAL VOID cgbold(FSP PADJUSTED_SKEL x_skel, PADJUSTED_SKEL y_skel)
#else
GLOBAL VOID
cgbold(x_skel, y_skel)
PADJUSTED_SKEL x_skel, y_skel;
#endif /* ANSI_DEFS */
{
PDUP_POINTS dp;
LOOP loop; /* current loop */
UW16 loopct;
UW16 id; /* coordinate index of duplicate point in loop */
UW16 ncoords;
LPUW16 x_s2c_base;
LPUW16 y_s2c_base;
UW16 k;
UB8 xskPlus1, yskPlus1, xskMinus1, yskMinus1; /* 10-12-90 tbh */
SW16VECTOR i0, i1, o0, o1;
DBG("bold()\n");
/* Initialize */
dp = if_state.dup_points;
init_xy_tran(FSA x_skel, y_skel); /* initialize for skeletal interpolation */
if_state.x_tran.sct = 0;
if_state.y_tran.sct = 0;
x_s2c_base = if_state.xskel.skel_to_contr;
y_s2c_base = if_state.yskel.skel_to_contr;
DBG1(" number of loops = %d\n", if_state.num_loops);
first_loop(FSA0);
for(loopct = 0; loopct < if_state.num_loops; loopct++)
{
if(dp->loop == (UW16)-1) break;
DBG("\n\n\nN e x t L o o p\n");
if_state.x_tran.nsk = *(if_state.x_tran.num_skel_loop++);
if_state.y_tran.nsk = *(if_state.y_tran.num_skel_loop++);
next_loop(FSA &loop);
ncoords = loop.ncoords;
while(dp->loop == loopct)
{
/* set id = index of first duplicate point */
id = dp->coord_index; /* index of second duplicate point */
if(id == 0)
id = ncoords - 1; /* index of point just before */
else
id--;
/* find incoming scaling segment */
find_in_scale_seg(FSA id, x_s2c_base, &if_state.x_tran, &dp->xsk0, &xskMinus1); /* 10-12-90 tbh */
find_in_scale_seg(FSA id, y_s2c_base, &if_state.y_tran, &dp->ysk0, &yskMinus1); /* 10-12-90 tbh */
/* compute incoming line segment */
if(id == 0)
k = ncoords - 1;
else
k = id - 1;
i0 = *(loop.cv + k); /* coordinate points */
i1 = *(loop.cv + id);
DBG4(" in old: (%d, %d) (%d, %d)\n", i0.x, i0.y, i1.x, i1.y);
i0 = nxy(FSA i0);
i1 = nxy(FSA i1);
DBG4(" in new: (%d, %d) (%d, %d)\n", i0.x, i0.y, i1.x, i1.y);
/* find outgoing scaling segment */
id = dp->coord_index; /* index of second duplicate point */
find_out_scale_seg(FSA id, x_s2c_base, &if_state.x_tran, &dp->xsk1, &xskPlus1); /* 10-12-90 tbh */
find_out_scale_seg(FSA id, y_s2c_base, &if_state.y_tran, &dp->ysk1, &yskPlus1); /* 10-12-90 tbh */
/* 10-12-90 tbh The following code was added */
if ( ( (dp->xsk0 == 255) /* if no x-skel at this duplicate . . */
&&
(dp->xsk1 == 255)
) /* and contour is not horizontal . . */
&&
( ((y_skel+dp->ysk1)->original != (y_skel+yskPlus1)->original)
||
((y_skel+dp->ysk1)->original != (y_skel+yskMinus1)->original)
)
)
{
if (dp->ysk0 == 255) dp->y = (y_skel+dp->ysk1)->adjusted;
else if (dp->ysk1 == 255) dp->y = (y_skel+dp->ysk0)->adjusted;
else dp->y = ((y_skel+dp->ysk1)->adjusted + (y_skel+dp->ysk0)->adjusted + 1) >> 1;
}
else if
( ( (dp->ysk0 == 255) /* if no y-skel at this duplicate . . */
&&
(dp->ysk1 == 255)
) /* and contour is not vertical . . */
&&
( ((x_skel+dp->xsk1)->original != (x_skel+xskPlus1)->original)
||
((x_skel+dp->xsk1)->original != (x_skel+xskMinus1)->original)
)
)
{
if (dp->xsk0 == 255) dp->x = (x_skel+dp->xsk1)->adjusted;
else if (dp->xsk1 == 255) dp->x = (x_skel+dp->xsk0)->adjusted;
else dp->x = ((x_skel+dp->xsk1)->adjusted + (x_skel+dp->xsk0)->adjusted + 1) >> 1;
}
else
{
/* compute outgoing line segment */
k = id + 1;
if(k == ncoords)
k = 0;
o0 = *(loop.cv + k); /* coordinate points */
o1 = *(loop.cv + id);
DBG4(" out old: (%d, %d) (%d, %d)\n",
o0.x, o0.y, o1.x, o1.y);
o0 = nxy(FSA o0);
o1 = nxy(FSA o1);
DBG4(" out new: (%d, %d) (%d, %d)\n",
o0.x, o0.y, o1.x, o1.y);
/* compute intersection of incomming and outgoing line segments */
intersect(FSA i0.x, i0.y, i1.x, i1.y, o0.x, o0.y, o1.x, o1.y, dp);
}
/* move to next duplicate point */
dp++;
} /* while(dp->loop == loopct) */
if_state.x_tran.sct += if_state.x_tran.nsk;
if_state.y_tran.sct += if_state.y_tran.nsk;
} /* end of character */
/* Change skeletal points */
for(dp = if_state.dup_points; dp->loop != (UW16)-1; dp++)
{
if(dp->xsk0 != 255) (x_skel+dp->xsk0)->adjusted = dp->x;
if(dp->xsk1 != 255) (x_skel+dp->xsk1)->adjusted = dp->x;
if(dp->ysk0 != 255) (y_skel+dp->ysk0)->adjusted = dp->y;
if(dp->ysk1 != 255) (y_skel+dp->ysk1)->adjusted = dp->y;
}
}
#endif /* BOLD */
#endif /* IF_RDR */
bucket.c //
/*
* Copyright (C) 2005 Monotype Imaging Inc. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/DA/BUCKET.C_V 1.141 Dec 14 2004 14:17:46 galejss $ */
/* $Log: I:/BULL/URIP/RTS/DA/BUCKET.C_V $
*
* Rev 1.141 Dec 14 2004 14:17:46 galejss
* make all DBG calls 16-bit-compatible
*
* Rev 1.140 Nov 29 2004 17:36:56 jardima
* added code for the memory fund check
*
* Rev 1.139 Nov 08 2004 14:37:38 DugganJ
* Corrected printf() call in print_bucket_status().
*
*
* Rev 1.138 Oct 26 2004 11:23:10 dugganj
* Multithread changes.
*
* Rev 1.137 Sep 27 2004 16:27:44 dugganj
* Added multithread support.
*
* Rev 1.136 Aug 10 2004 16:48:40 galejss
* changes for runtime no-symset-mapping option
*
* Rev 1.135 Jul 16 2004 17:42:58 galejss
* changes for IF disk/rom support; copy ttc_index field only if current font is TT
*
* Rev 1.134 Jun 04 2004 16:18:56 GalejsS
* change type of "pathname" to FILECHAR (fix compiler warnings)
*
* Rev 1.133 Nov 10 2003 13:41:16 Joe
* In BUCKfree(), calling MEMSET to reset "if_state.cur_loc_fc" whenever a
* bucket is freed.
*
* Rev 1.132 Oct 17 2003 16:53:40 Galejs
* remove obsolete MEM_DUMP_INT code; compile fixes for PRINT_BUCKETS option
*
* Rev 1.131 Aug 26 2003 10:28:34 Joe
* In BUCKfind(), added fix for unbound pcleos.
*
* Rev 1.130 Aug 22 2003 08:52:46 LynchR
* Updated coppyright notice.
*
* Rev 1.129 Aug 21 2003 13:58:18 IndrelR
* Added feature for processing XL bitmaps.
*
* Rev 1.128 Aug 20 2003 11:25:40 IndrelR
* Rev 1.127 Aug 08 2003 17:14:26 Galejs
* fix link error for FIpath with DISKROM utility
*
* Rev 1.126 Jul 28 2003 17:22:12 Galejs
* add new all-FSTs no-plugins option; extend IXopen_file to PST1 as well
*
* Rev 1.125 Jul 07 2003 11:47:02 Galejs
* DYNAMIC_FONTS option is only relevant if IF_RDR
*
* Rev 1.124 Jun 19 2003 18:37:56 Galejs
* clean up debugging options
*
* Rev 1.123 Dec 02 2002 11:14:58 Galejs
* BUCKfree() needs to be global now, not static
*
* Rev 1.122 Nov 26 2002 17:59:04 Galejs
* fix uninit-vbl compiler warning; conditional include of unistd.h
*
* Rev 1.121 Oct 03 2002 09:51:44 Joe
* In BUCKfind(), fixed bug which was resulting in wrong bucket being
* chosen when switching from RAW_GLYPH mode to a non-Asian
* encoded symbolset.
*
* Rev 1.120 Sep 30 2002 14:12:34 WuQ
* Changes for CCC font
*
* Rev 1.119 Sep 24 2002 11:44:02 Doolittl
* Correction for CGIFfont_purge(); In BUCKfind(), == goes back to !=.
*
* Rev 1.118 Sep 23 2002 20:48:04 Galejs
* add DIMM_DISK option (bug # 92) (for awr)
*
* Rev 1.117 Sep 23 2002 15:18:20 Galejs
* fix possibly-uninitialized-vbl warnings (part of bug # 76)
*
* Rev 1.116 Sep 06 2002 17:22:48 Galejs
* centralize #if-TT includes
*
* Rev 1.115 Aug 19 2002 16:15:42 Joe
* Added disable-plugins support for stroke fonts
* in BUCKfind().
*
* Rev 1.114 24 Aug 2001 14:02:52 JOE
* DISK / ROM changes (by jwd).
*
* Rev 1.113 Jun 28 2001 18:52:08 Galejs
* fix DYNAMIC_FONTS conditional compile
*
* Rev 1.112 Jun 15 2001 18:15:54 Galejs
* add #if-PLUGINS conditional compile
*
* Rev 1.111 04 Jun 2001 10:05:56 JOE
* OpenType changes.
*
* Rev 1.110 01 Jun 2001 07:21:50 AOF
* Doc's fixes!
*
* Rev 1.0 01 Jun 2001 07:21:32 AOF
* Initial revision.
*
* Rev 1.109 May 21 2001 18:51:22 Galejs
* get rid of "rom_length" for CFF_ROM
*
* Rev 1.108 May 03 2001 20:02:08 Galejs
* data-type cleanup (+ remove AGFATOOLS)
*
* Rev 1.107 Jan 12 2001 20:59:30 Galejs
* get rid of control-z yet again
*
* Rev 1.106 12 Jan 2001 16:02:00 JOE
* In BUCKfind(), made some bucket recognition changes.
*
* Rev 1.105 Jan 10 2001 14:17:12 Song
* Remove ctrl-z
*
* Rev 1.104 18 Dec 2000 13:32:24 JOE
* In BUCKfind(), changed the bucket search test to accomodate TrueType
* collection fonts.
*
* Rev 1.103 Dec 14 2000 19:00:50 Galejs
* integrate fix for TTC files (for ks)
*
* Rev 1.102 Dec 04 2000 15:54:44 Galejs
* use new is_it_Asian() macro rather than explicit Asian-symbolset tests
*
* Rev 1.101 Nov 28 2000 18:47:52 Galejs
* get_tt_ids() doesn't need reentancy parameter
*
* Rev 1.100 Nov 21 2000 09:34:46 Joe
* In BUCKfind(), moved closing brace
* inside ASIAN_ENCODING block to resolve
* compiler error.
*
* Rev 1.99 Nov 20 2000 16:10:42 Joe
* Added support for 'set cmap tables' functionality.
*
* Rev 1.98 Feb 02 2000 13:17:58 galejs
* bugfixes in IXopen_file (for jd), & BUCKfind (for ks)
*
* Rev 1.97 Jan 28 2000 15:32:10 galejs
* use PATHNAMELEN (from port.h) rather than MAXNAME for buffersize
*
* Rev 1.96 Jan 24 2000 13:02:18 galejs
* get rid of "entityACT" field
*
* Rev 1.95 Dec 10 1999 16:04:54 galejs
* get rid of TT_ROM1 code
*
* Rev 1.94 Nov 15 1999 12:27:58 galejs
* set "ttc_index" field in TT_BUCK from FC
*
* Rev 1.93 Aug 16 1999 12:14:04 galejs
* include-file changes; BUCKfree() becomes MLOCAL
*
* Rev 1.92 24 Jun 1999 13:32:52 JOE
* In BUCKfind(), made changes to bucket searching due to moving the
* get_tt_ids() call from CGIFfont() to ttload...().
*
* Rev 1.91 26 Jan 1999 11:32:42 JOE
* Revised handling of extern_font variable to allow FORMAT16
* and ASIAN_ENCODING independence (by jwd).
*
* Rev 1.90 21 Jan 1999 13:48:08 GALEJS
* standardize #include tests
*
* Rev 1.89 12 Jan 1999 18:22:40 GALEJS
* move EXTERN dcls
*
* Rev 1.88 06 Aug 1998 15:47:58 AL
* CFF Rom support
*
* Rev 1.87 28 Jul 1998 10:28:42 DAVID
* Added EXTERN BOOLEAN declaration for 'ps_is_same()' to eliminate
* compiler warning and return of wrong type.
*
* Rev 1.86 22 Jul 1998 16:36:34 AL
* Removed extra settings of platformID, specificID and languageID from
* BUCKfind
*
* Rev 1.85 20 Jul 1998 15:17:24 AL
* Multiple master and CFF support
*
* Rev 1.84 22 Jun 1998 17:56:22 GALEJS
* pcleo.h in shareinc.h now
*
* Rev 1.83 17 Jun 1998 16:35:28 GALEJS
* add arg to load/unload_font() calls (for reentrancy)
*
* Rev 1.82 15 Jun 1998 15:59:08 GALEJS
* reentrancy parm-passing changes
*
* Rev 1.81 11 May 1998 13:57:30 JOE
* Removed condition which included 'ttroment.h' based on TT_ROM_ACT
* being enabled (by keb).
*
* Rev 1.80 15 Apr 1998 17:45:32 GALEJS
* symbolset in IF_STATE
*
* Rev 1.79 14 Apr 1998 18:35:08 GALEJS
* move fontindex into IF_STATE
*
* Rev 1.78 02 Apr 1998 18:29:06 GALEJS
* max_open_files now in if_state
*
* Rev 1.77 30 Mar 1998 12:06:00 GALEJS
* move all MLOCALs into if_state
*
* Rev 1.76 04 Mar 1998 16:48:14 JOE
* Removed CTRL-Z at end of file.
*
* Rev 1.75 03 Mar 1998 16:09:14 JOE
* Added AGFATOOLS (by dah).
*
* Rev 1.74 10 Feb 1998 17:13:22 GALEJS
* only use pathname for Disk modes
*
* Rev 1.73 04 Feb 1998 01:13:32 DAVID
* In BUCKfind() added code to copy fcCur.ExtndFlags word to
* b->fc_ExtndFlags in two places - for support of HP4000 emulation.
*
* Rev 1.72 30 Jan 1998 16:32:42 GALEJS
* delete unused TT plugin options; #-files vbls only needed if DISK
*
* Rev 1.71 04 Sep 1997 17:03:42 MARTIN
* Modified references to AGFA Compressed TrueType (ACT).
*
* Rev 1.70 04 Jun 1997 17:19:38 DAVID
* In BUCKfind(), added WANSUNG and JOHAB encoding support to ASIAN_
* ENCODINGs.
*
* Rev 1.69 30 May 1997 09:50:16 MARTIN
* Added TrueType ROM ACT (compressed random access).
*
* Rev 1.68 28 Apr 1997 20:11:58 MIKE
* Conditionally compiled if_state.if_init_face
*
* Rev 1.67 11 Mar 1997 14:04:06 MIKE
* Changed TT plugin augmentation logic to disregard state of FC_PCL6_EMU
*
* Rev 1.66 14 Jan 1997 17:14:18 DAVID
* Removed MULTIFORMAT option as part of project to trim ufst.
*
* Rev 1.65 13 Jan 1997 15:49:02 DAVID
* Removed CONVERGENT_FONTS option as part of project to trim ufst.
*
* Rev 1.64 02 Jan 1997 17:51:46 DAVID
* Added languageID, and langId fields to help distinguish betweeen
* GB and BIG5 encoded Asian fonts.
*
* Rev 1.63 14 Nov 1996 20:36:14 MIKE
* In BUCKfind(), don't set cur_ssnum=0 if search_lvl > 0
*
* Rev 1.62 04 Oct 1996 09:16:40 JOE
* Removed CTRL-Z at end of file.
*
* Rev 1.61 01 Oct 1996 16:46:00 JOE
* Included CACHE.H (needed for PFONT typedef in DLL.H).
*
* Rev 1.60 25 Sep 1996 11:49:40 MIKE
* For DYNAMIC_FONTS/ROM fixed bug in BUCKfind() - bucket search loop
*
* Rev 1.59 16 Sep 1996 17:22:10 MIKE
* Assign (bucket)->fc_format before calling load_font()
*
* Rev 1.57 30 Aug 1996 17:47:02 MIKE
* Changed test for fco_pluginSearchPath(). Added b->fc_format.
*
* Rev 1.56 27 Jun 1996 09:59:44 DBK
* Made ifdef changes based on NO_SYMSET_MAPPING
*
* Rev 1.54 14 Jun 1996 16:59:44 JOE
* Changed "//" comment delimiter to "slash-asterisk ... asterisk-slash".
*
* Rev 1.53 13 Jun 1996 17:00:26 JWD
* Revised handling of extern_font flag, to implement format16 support
*
* Rev 1.52 16 May 1996 14:41:54 MIKE
* Made 2/27/96 change conditional on TT_RDR = 1
*
* Rev 1.50 22 Apr 1996 17:55:36 MIKE
* OS9 support.
*
* Rev 1.49 29 Feb 1996 10:05:06 MIKE
* Repeat call to ttload_font if insufficient memory. Add BUFpurgeBUCK().
*
* Rev 1.48 06 Dec 1995 13:48:14 MIKE
* Fix bug in while loop in BUFalloc()
*
* Rev 1.47 05 Dec 1995 15:05:28 MERRILL
* quiet BC4 warnings
*
* Rev 1.46 19 Jun 1995 15:33:52 MIKE
* BUCKfind() should call SYMnoMap() for PCLEO with !b->usePlugins
*
* Rev 1.45 06 Apr 1995 15:14:14 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.44 17 Dec 1994 17:56:24 JOE
* In BUCKfind(), if TFS was a pcleo, need to load symbolset first
* and last character in order to locate the character in the
* FCO plugins.
*
* Rev 1.43 15 Dec 1994 16:53:46 MIKE
* Return error if "buck_search_lvl" too large (BUCKfind)
*
* Rev 1.42 02 Dec 1994 21:26:02 YAN
* KSC.
*
* Rev 1.41 30 Nov 1994 11:02:52 JOE
* In BUCKfind(), if FCO_RDR is enabled, always set up FCO plugins
* regardless of fst type.
*
* Rev 1.40 09 Nov 1994 16:21:22 BJG/DBK
* In BUCKfind(), added braces following "if" statement to correct
* improper bucket searching algorithm.
*
* Rev 1.39 15 Sep 1994 20:44:24 MIKE
* In BUCKfind() for FCO plugins, set font_type.
*
* Rev 1.37 02 Sep 1994 12:58:34 MIKE
* In BUCKfind() set up plugin faces for FCO_RDR.
*
* Rev 1.36 05 Aug 1994 13:39:32 MIKE
* Added FCO changes from 1.25.1.2
*
* Rev 1.35 29 Apr 1994 16:10:36 JOE
* In BUCKfind(), only call IXopen_file() for TT data for which we
* have a path.
*
* Rev 1.34 22 Apr 1994 15:39:02 JOE
* Changed conditional compile statement prior to including <hif.h>
* to #if (_AM29K && !UNIX) to resolve UNIX Metaware compiler error.
*
* Rev 1.33 22 Apr 1994 15:12:00 JOE
* In BUCKfind(), when calling xxload_font(), cast first arg as LPSB8.
*
* Rev 1.32 22 Apr 1994 13:54:40 LISA
* Made modifications to copyright/disclaimer notice.
*
* Rev 1.31 30 Mar 1994 11:45:54 JOE
* In BUCKfind(), if processing TT, after finding bucket, call IXopen_file()
* in the event that the TT file was closed due to num_open_files exceeding
* max_open_files.
*
* Rev 1.30 29 Mar 1994 10:08:02 JOE
* Changed conditional compile for IXopen_file() and IXclose_file()
* to include TT_RDR too.
* Modified IXopen_file() for TT support.
*
* Rev 1.29 09 Feb 1994 12:07:14 JOE
* More _AM29K changes.
*
* Rev 1.28 03 Feb 1994 15:30:20 MIKE
* Change fontindex.awtsub_on to if_state.awtsub_on.
*
* Rev 1.27 02 Feb 1994 09:05:18 JOE
* AM29K changes.
*
* Rev 1.26 19 Jan 1994 08:57:48 JOE
* In BUCKfind(), conditionally compiled code which stores platform and
* specific IDs based on TT_RDR to resolve compiler error.
*
* Rev 1.25 05 Jan 1994 18:12:18 ROB
* Add support for "GB" encoding.
*
* Rev 1.24 08 Dec 1993 19:00:00 ROB
* General cleanup for MSDOS, FLAT, OS2.
*
* Rev 1.23 07 Dec 1993 15:20:08 JOE
*
* In BUCKfind(), for KANJI TT fonts, set platform ID and specific ID
* from "symbolset" data (loaded by cgif_Font() ).
* Changed conditional compile statement for OS2 support.
*
* Rev 1.22 01 Dec 1993 08:52:38 JOE
*
* Changed KANJI_ENCODING to ASIAN_ENCODING.
*
* Rev 1.21 30 Nov 1993 14:48:56 ROB
* Add BIG5 support and TCA hooks.
*
* Rev 1.20 18 Nov 1993 13:34:34 MIKE
* In BUCKfind() set platId & specId to 0 in the TT bucket, if plugins disable
*
* Rev 1.19 11 Nov 1993 16:32:16 JOE
* In BUCKfind(), added UNICODE changes for KANJI support (platformID
* set to 3 instead of 1).
*
* Rev 1.18 23 Sep 1993 20:26:28 MIKE
* Before setting up plugin search path, test pbucket->usePlugins
*
* Rev 1.17 23 Sep 1993 19:29:32 MIKE
* BUCKfind() changes.
*
* Rev 1.16 12 Aug 1993 11:08:18 MIKE
* For CONVERGENT_FONTS: change IF plugin search path setup in BUCKfind().
*
* Rev 1.15 10 Aug 1993 15:33:54 JOE
* In BUCKfind(), conditionally compiled call to ifload_font() based on IF_RDR.
* In BUCKfree(), conditionally compiled call to ifunload_font() bsd on IF_RDR.
* In BUCKfree(), changed statement "return (fst_type)" to "return"
* because BUCKfree() returns VOID.
*
* Rev 1.14 15 Jul 1993 11:55:46 MIKE
* Convergent font changes -- see comments.
*
* Rev 1.13 01 Jul 1993 15:21:40 JOE
*
* EUC KANJI support.
*
* Rev 1.12 30 Jun 1993 08:54:56 JOE
* In BUCKfind(), conditionally compiling test for JIS or SJIS encoding
* based on KANJI_ENCODING.
*
* Rev 1.11 29 Jun 1993 14:49:52 JOE
* In BUCKfind(), storing 1 for platformID and specificID if using JIS or
* SJIS encoding.
*
* Rev 1.10 28 Jun 1993 14:08:32 JOE
*
* In BUCKfind(), when searching for bucket, generalized code which
* determines whether TFS font has changed.
*
* Rev 1.9 24 Jun 1993 14:21:00 JOE
*
* In BUCKfind(), if processing KANJI fonts, check encoding value in
* addition to pathname before determining that TFS font has not changed.
* This fixes a bug when switching from JIS to SJIS encoding and vice versa.
*
* Rev 1.8 03 May 1993 17:07:16 MIKE
* Fix ROM problem in bucket search algorithm in BUCKfind().
*
* Rev 1.7 22 Apr 1993 11:18:04 MIKE
* BUCKfind - support IF dynamic fonts (has_path, etc.).
* IXopen_file() - dynamic font support (don't call buildpath()).
*
* Rev 1.6 13 Apr 1993 13:26:14 JOE
* In BUCKfree(), conditionally compiled calls to psunload_font() and
* ttunload_font() if !USE_JUMP_TABLES. In BUCKfind(), conditionally compiled
* calls to psload_font() and ttload_font() if !USE_JUMP_TABLES.
*
* Rev 1.5 29 Mar 1993 10:50:00 ROB
* Kanji cleanup.
*
* Rev 1.4 11 Mar 1993 15:06:08 MAIB
* Initial changes to support Asian character encoding (TrueType 1st pass)
*
* Rev 1.3 12 Feb 1993 13:36:58 JOE
* VXWorks support.
*
* Rev 1.2 06 Jan 1993 16:05:36 JOE
* ANSI C function declaration changes.
*
* Rev 1.1 14 Dec 1992 15:47:30 LISA
* Made change to Log keyword
*
* Rev 1.0 09 Dec 1992 15:38:52 LISA
* Initial revision.
*/
/* $Date: Dec 14 2004 14:17:46 $ */
/* bucket.c */
/*
*
*
* History
*
* 24-Aug-90 awr Initialize BUCKET's "my_handle" field in BUCKnew()
* 03-Dec-90 awr In BUCKfree(), reset if_init_face (last face processed
* by if_init())
* 7 Jan 91 ss Added PCLEO_RDR support
* 24-Jan-91 jfd As a result of removing the "name_off" field from
* the INDEX_ENTRY structure (#if ROM), conditionally
* compile the DBG5 statement in IXfind_bucket().
* 28-Jan-91 tnc Window-ized file "close" and "read".
* 28-Jan-91 jfd Made size arg of MEMalloc() LONG
* 30-Jan-91 dET Added function prototyping for MSC
* 31-Jan-91 dET Modify for MSC multi-model compilation.
* 4-Feb-91 awr Split off from ix.c
* 8-Feb-91 awr Added dll.h to declare functions.
* 15-Feb-91 awr changed IXfind_bucket() name to BUCKfind()
* 23-Feb-91 awr removed reference to hfi by adding calls to
* FIpath() and FIentry().
* 23-Feb-91 awr Moved BUCKET defund logic from mem.c
* 04-Mar-91 jfd Conditionally declared FIpath (#if !ROM).
* 06-Mar-91 jfd Removed BUCKdefund().
* 09-Apr-91 dET Added BUFdump routines for aid in debugging.
* 17-Jun-91 jfd Moved "debug.h" after "port.h".
* Moved "cgconfig.h" before "port.h".
* 24 Jun 91 ss Conditionally compile io.h based on system type.
* Added prototypes for BUCK,BUF...() when not LINT_ARGS.
* 3-Jan-92 awr Removed font_open field from BUCKET
* Removed BUCKnew(); coded inline.
* 15-Jan-92 jfd Added functofin prototype for IXset_search_path().
* 17 Jan 92 ss In BUCKfind() made test for matching to an existing
* bucket more strict.
* 29-Jan-92 rs Move IF_FUNC_TBL from cgif.c for URIP ptrs.
* 07-Mar-92 rs Remove duplicate global 'pras' (in cgif.c).
* 8-Mar-92 awr Added core font substitution for PS and TT
* 03-Apr-92 rs Portability cleanup (see port.h).
* 23 Apr 92 ss In BUCKfind(), reordered initial setup code based
* on buck_search_lvl which wraps in the PS,TT specific
* code instead of duplicating it.
* - Improved test for matching typeface in bucket search
* to the one requested in fontindex.
* - Changed test for buck_search_lvl==MAX_UWORD to ==0.
* No longer using MAX_UWORD to determine a non-IF type.
* Added items set when have a TFS round (buck_search_lvl
* == 0).
* - Changed name fontindex.num_levels to .num_searches.
* 6-Jul-92 jfd Added "ifget_width" to iffunc_tbl structure.
* Added "psget_width" to psfunc_tbl structure.
* Added "ttget_width" to ttfunc_tbl structure.
* 9-Jul-92 jfd Conditionally compiled "ifget_width", "psget_width"
* and "ttget_width" based on WIDTHS.
* 21-Jul-92 awr Conditional compile changes.
* 28-Jul-92 ss In BUCKfind(), initialize tfnum to 0; if not IF font
* and ROM is true, has_path = FALSE.
* 05-Aug-92 jfd Replaced calls to "clear_mem()" with MEMSET for
* optimization.
* Included "mixmodel.h" and "string.h".
* 16-Aug-92 rs #defined 'MEM_DUMP' = 0 if not already defined.
* 14-Sep-92 jfd Conditionally compiled table iffunc_tbl{} based on
* IF_RDR.
* In BUCKfind(), conditionally compiled case clause
* which stores pointer to IF function table based on
* IF_RDR.
* 16-Sep-92 jfd Conditionally compile routines IXopen_file() and
* IXclose_file() based on IF_RDR.
* 28-Sep-92 awr Changed BUCKfind() parameters.
* Changed FIentry() parameter.
* 10-Oct-92 rs Implement USE_JUMP_TABLES feature for overlays.
* 13-Oct-92 mby Changed BUCKfind() for TT: platformID & specificID.
* Set has_path = TRUE, if TT_TTPLUGIN && not ROM font
* 26-Oct-92 jfd In BUCKfind(), before storing "platId" and "specId"
* into TT bucket, check if bucket is a TT bucket.
* In same routine, storing "cur_ssnum" into bucket
* structure at same time that other fields are loaded.
* 06-Nov-92 jfd In BUCKfind(), moved closing brace to line following
* #endif for (IF_RDR || PS_IFPLUG || TT_IFPLUG). This
* fixes a compiler error if compiling for TT only.\
* 15-Nov-92 rs Port to Macintosh - #include <unix.h>, casting in call
* to load_font().
* 22-Nov-92 rs Port to Macintosh - prototype for set_tt_universal().
* 06-Jan-93 jfd ANSI C function declaration changes.
* 08-Feb-93 jfd VXWorks support.
* 11-Mar-93 maib began support for jis and shift jis character encoding.
* 27-Mar-93 rs Add defines for KANJI_ENCODING, JIS_ENCODING &
* SJIS_ENCODING per cgconfig.h.
* 13-Apr-93 jfd In BUCKfree(), conditionally compiled calls to
* psunload_font() and ttunload_font() if !USE_JUMP_TABLES.
* in BUCKfind(), conditionally compiled calls to
* psload_font() and ttload_font() if !USE_JUMP_TABLES.
* 10-Apr-93 mby DYNAMIC_FONTS: IXopen_file() builds pathname differently.
* In BUCKfind(), has_path can be true for IF; BUCKET->dynIFActive.
* 30-Apr-93 mby Fix ROM problem in BUCKfind() bucket search algorithm.
* 24-Jun-93 jfd In BUCKfind(), if processing KANJI fonts, check
* encoding value in addition to pathname before
* determining that TFS font has not changed. This
* fixes a bug when switching from JIS to SJIS encoding
* and vice versa.
* 28-Jun-93 jfd In BUCKfind(), when searching for bucket, generalize
* the code. For PS, TT, KANJI, or IF using dynamic
* fonts, the symbolset is checked in addition to the
* pathname before determining that TFS font has not
* changed.
* 29-Jun-93 jfd In BUCKfind(), storing 1 for platformID and specificID
* if using JIS or SJIS encoding.
* 30-Jun-93 jfd In BUCKfind(), conditionally compiling test for
* JIS or SJIS encoding based on KANJI_ENCODING.
* 30-Jun93 jfd/gy EUC KANJI support.
* 13-Jul-93 mby Conditionally compiled set_tt_universal() based on
* TT_TTPLUG and TT_TTPLUG_IF.
* Modified TT plugin font selection for TT_TTPLUG_IF.
* Added debug routine print_buckets().
* 10-Aug-93 jfd In BUCKfind(), conditionally compile call to
* ifload_font() based on IF_RDR.
* In BUCKfree(), conditionally compile call to
* ifunload_font() based on IF_RDR.
* In BUCKfree(), changed "return (ERR_fst_type);"
* to "return" because BUCKfree() returns VOID.
* 12-Aug-93 mby For CONVERGENT_FONTS: change plugin search path setup
* in BUCKfind().
* 22-Sep-93 mby Add default case to switch(fontindex.plug_type)
* Set usePlugins boolean in bucket. ROM1 support.
* 11-Nov-93 gy In BUCKfind(), added UNICODE changes for KANJI
* support (platformID set to 3 instead of 1).
* 18-Nov-93 mby In BUCKfind() set platId and specId to 0 in the TrueType
* bucket if if_state.usePlugins is 0.
* 23-Nov-93 rs Add BIG5 & TCA to KANJI_ENCODING support.
* 01-Dec-93 jfd Changed KANJI_ENCODING to ASIAN_ENCODING.
* 03-Dec-93 jfd In BUCKfind(), for KANJI fonts, set platform ID and
* and specificID from "symbolset" data (loaded by
* cgif_Font() ).
* 07-Dec-93 rs Changed conditional compile statement for OS2.
* 08-Dec-93 rs General cleanup - MSDOS & OS2.
* 05-Jan-94 rs Add support for "GB" encoding.
* 19-Jan-94 jfd In BUCKfind(), conditionally compiled block of code
* which stores platform ID and specific ID based on
* TT_RDR.
* 27-Jan-94 jfd Conditionally compiled #include for fcntl.h
* (if !(_AM29K && UNIX) ).
* 02-Feb-94 mby Change fontindex.awtsub_on to if_state.awtsub_on.
* 09-Feb-94 jfd Including "hif.h" if _AM29K.
* 28-Mar-94 jfd Change conditional compile for IXopen_file() and
* IXclose_file() to include TT_RDR too.
* Modified IXopen_file() for TT support.
* 30-Mar-94 jfd In BUCKfind(), if processing TT, after finding
* bucket, call IXopen_file() in the event that
* the TT file was closed due to num_open_files
* exceeding max_open_files.
* 22-Apr-94 dbk In BUCKfind(), when calling xxload_font(), cast
* first arg as LPSB8.
* jfd Changed conditional compile statement prior to
* including <hif.h> to #if (_AM29K && !UNIX) to
* resolve UNIX Metaware compiler error.
* 29-Apr-94 jfd In BUCKfind(), only call IXopen_file() for TT data
* for which we have a path .
* 09-Nov-94 bg/dbk In BUCKfind(), added braces following "if" statement
* to correct improper bucket searching algorithm.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* FCO Changes from 1.25.1.2:
* 15-Mar-94 mby Added fco_func_tbl structure for FCO function calls.
* In BUCKfind(), cur_font_hdr = fontindex.FCObject for
* FCO font type.
* 26-May-94 mby Change fontindex.FCObject to if_state.FCObject.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 02-Sep-94 mby In BUCKfind() set up plugin faces for FCO_RDR.
* 08-Sep-94 mby Add missing break statement.
* 15-Sep-94 mby In BUCKfind() for FCO plugins, set font_type.
* 28-Nov-94 jfd In BUCKfind(), if FCO_RDR is enabled, always set
* up FCO plugins regardless of fst type.
* 15-Dec-94 mby In BUCKfind() for FCO_RDR, if "buck_search_lvl"
* argument too large, return ERR_no_cgnum.
* 17-Dec-94 jfd In BUCKfind(), if TFS was a pcleo, need to load
* symbolset first and last character in order to
* locate the character in the FCO plugins.
* 06-Jun-95 mby In BUCKfind() for plugin search path, if TFS is PCLEO
* or PCLETTO and !(b->usePlugins), call SYMnoMap(),
* not SYMnew().
* 06-Dec-95 mby Fix bug in BUFalloc() - restore v46 code.
* 27-Feb-96 mby In BUCKfind() repeat call to load_font (TT only) to fix
* memory fragmentation in BUFFER pool.
* Add BUFpurgeBUCK() function to remove all font buckets.
* 22-Apr-96 mby Conditionalize <fcntl.h> for OS9 port.
* 16-May-96 mby Made 2/27/96 change conditional on TT_RDR.
* 13-Jun-96 jwd Revised handling of extern_font flag, to implement
* format16 support.
* 17-Jun-96 dbk Made ifdef changes based on NO_SYMSET_MAPPING.
* 26-Aug-96 mby In BUCKfind(), removed "b->rom_font"; added "b->fc_format".
* b->fc_format has to be set every time we call BUCKfind()
* to keep it uptodate.
* Changed test for calling fco_pluginSearchPath().
* 16-Sep-96 mby Assignment of (bucket)->fc_format must be made in 2 places
* -- before load_font() & before fco_pluginSearchPath().
* Code cleanup: added calls to BUFfree().
* 25-Sep-96 mby Fixed bug in bucket search loop in BUCKfind() - for
* DYNAMIC_FONTS && ROM make sure fst_type is FC_IF_TYPE.
* 01-Oct-96 jfd Included CACHE.H (needed for PFONT typedef in DLL.H).
* 14-Nov-96 mby In BUCKfind(), buck_search_lvl > 0 (plugins), set
* cur_ssnum = fontindex.cur_ssnum INSTEAD OF 0.
* 01-Jan-97 dlk Added tt_langId field and languageID to help distinguish
* between GB and BIG5 encoded Asian fonts.
* 13-Jan-97 dlk Removed CONVERGENT_FONTS option as part of project to
* trim ufst.
* 14-Jan-97 dlk Removed MULTIFORMAT option as part of project to trim ufst.
* 11-Mar-97 mby In BUCKfind() modified test for calling fco_pluginSearchPath()
* to ignore state of FC_PCL6_EMU in fontcontext.format
* 28-Apr-97 mby In BUCKinit(), conditionally compiled if_state.if_init_face.
* 29-May-97 sbm Add TT_ROM_ACT functionality.
* 04-Jun-97 dlk In BUCKfind() added WANSUNG and JOHAB Korean encoding sup-
* port to lists of ASIAN_ENCODINGs.
* 30-Jan-98 slg Delete code for unused TT plugin options; number-of-files
* vbls are only needed for DISK cases.
* 04-Feb-98 dlk In BUCKfind() added code to copy fcCur.ExtndFlags word to
* b->fc_ExtndFlags -n two places - for support of HP4000
* emulation.
* 10-Feb-98 slg can't use pathname if ROM mode
* 02-Mar-98 dah Added AGFATOOLS to allow ROM simulation
* 30-Mar-98 slg Move all MLOCALs into IF_STATE, use "shareinc.h".
* 02-Apr-98 slg Move max_open_files into IF_STATE.
* 11-may-98 keb removed condition which included 'ttroment.h' based on
* TT_ROM_ACT being enabled
* 28-Jul-98 dlk Added EXTERN BOOLEAN declaration for 'ps_is_same()' to
* eliminate compiler warning and return BOOLEAN instead of
* int.
* 25-Jan-99 jwd Revised handling of extern_font variable to allow FORMAT16
* and ASIAN_ENCODING independence
* 24-Jun-99 jfd In BUCKfind(), made changes to bucket searching
* due to moving the get_tt_ids() call from CGIFFont()
* to ttload...().
* 28-Jan-00 slg Use PATHNAMELEN (from port.h) rather than locally-defined (and
* incorrect) MAXNAME; replace !ROM tests by DISK_FONTS.
* 02-Feb-00 slg Integrate bugfix for ks ("extern_font" setting in BUCKfind);
* change conditional compile in IXopen_file for jd (disk/ROM).
* 13-Nov-00 jfd In BUCKfind(), before searching for bucket, call get_tt_ids()
* to derive platform ID and specific ID.
* In same function, when checking for a matching bucket, check for
* a match on platform ID and specific ID.
* 21-Nov-00 jfd In BUCKfind(), moved closing brace inside ASIAN_ENCODING
* block to resolve compiler error.
* 14-Dec-00 slg Sign in Kimberley's TTC bugfix (previously, we were not
* distinguishing between different TTC indices when looking up
* TT chars, so chars from one index were returned for others).
* 18-Dec-00 jfd In BUCKfind(), changed the bucket search testing to
* accomodate TrueType collection fonts.
* 12-Jan-01 jfd In BUCKfind(), added bucket recognition changes.
* 23-May-01 jfd OpenType changes:
* In BUCKfree(), free OTCFF bucket if applicable.
* In BUCKfind(), initialize new BUCKET fields.
* In same function, create new BUCKET if processing an OpenType CFF font
* and call psload_font() to load.
* 31-May-01 jwd In BUCKfind(), corrected purge bucket code (used by CGIFfont_purge()).
* 24-Aug-01 jwd DISK / ROM changes.
* 19-Aug-02 jfd Added disable-plugins support for stroke fonts in BUCKfind().
* 15-Aug-02 awr Added DIMM_DISK
* 03-Oct-02 jfd In BUCKfind(), fixed bug which was resulting in wrong bucket being
* chosen when switching from RAW_GLYPH mode to a non-Asian encoded symbolset.
* 10-Nov-03 jfd In BUCKfree(), calling MEMSET to reset "if_state.cur_loc_fc" whenever a
* bucket is freed.
*
*/
#include <string.h>
#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>
#include "cgconfig.h"
#include "ufstport.h"
#if MAYBE_FCNTL_H
#include <fcntl.h>
#endif
#if MAYBE_FCNTL_HIF_H
#include <fcntl.h>
#include <hif.h> /* 2-7-94 jfd */
#endif
#if MAYBE_IO_H
#include <io.h>
#endif
#if MAYBE_UNISTD_H
#include <unistd.h>
#endif
#include "dbg_ufst.h"
#include "shareinc.h"
#include "mixmodel.h"
#include "segments.h"
#include "dll.h"
#ifdef LINT_ARGS
VOID BUCKfree(FSP HBUCKET);
#else /* NOT LINT_ARGS */
VOID BUCKfree();
#endif
#if (USE_JUMP_TABLES)
/*
URIP function interface tables - 1 for each font type
*/
#if IF_RDR
MLOCAL IF_FUNC_TBL iffunc_tbl = {
ifload_font,
ifunload_font,
ifset_trans,
ifset_char,
ifmake_gaso_and_stats,
ifrender
#if WIDTHS
,ifget_width
#endif /* WIDTHS */
};
#endif /* IF_RDR */
#if PST1_RDR
MLOCAL IF_FUNC_TBL psfunc_tbl = {
psload_font,
psunload_font,
psset_trans,
psset_char,
psmake_gaso_and_stats,
psrender
#if WIDTHS
,psget_width
#endif /* WIDTHS */
};
#endif /* PST1_RDR */
#if TT_RDR
MLOCAL IF_FUNC_TBL ttfunc_tbl = {
ttload_font,
ttunload_font,
ttset_trans,
ttset_char,
ttmake_gaso_and_stats,
ttrender
#if WIDTHS
,ttget_width
#endif /* WIDTHS */
};
#endif /* TT_RDR */
#if FCO_RDR
MLOCAL IF_FUNC_TBL fco_func_tbl = {
fco_load_font,
fco_unload_font,
fco_set_trans,
fco_set_char,
fco_make_gaso_and_stats,
fco_render
#if WIDTHS
,fco_get_width
#endif /* WIDTHS */
};
#endif /* FCO_RDR */
#endif /* USE_JUMP_TABLES */
/*-------------------------------------------------------------*/
#if DISK_FONTS && (IF_RDR || TT_RDR || PST1_RDR)
/*-------------------*/
/* IXclose_file */
/*-------------------*/
/* Close buckets file if it's open and decrement
* global count of open files.
*/
#if defined (ANSI_DEFS)
GLOBAL VOID IXclose_file(FSP PBUCKET b)
#else
GLOBAL VOID
IXclose_file(b)
PBUCKET b;
#endif
{
if(b->fh != -1)
{
#if DIMM_DISK
if(b->fc_ExtndFlags & EF_DIMM_DISK_TYPE)
dd_close(b);
else
#endif
CLOSE(b->fh);
b->fh = -1;
if_state.num_open_files--;
}
}
/*-------------------*/
/* IXopen_file */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 IXopen_file(FSP PINDEX_ENTRY ix, PBUCKET bucket)
#else
GLOBAL UW16
IXopen_file(ix, bucket)
PINDEX_ENTRY ix;
PBUCKET bucket;
#endif
{
HBUCKET hb;
PBUCKET b;
FILECHAR pathname[PATHNAMELEN];
if(bucket->fh != -1)
return SUCCESS; /* file is already open */
/* Make sure too many files aren't open */
while(if_state.num_open_files >= if_state.max_open_files)
{
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b; /* lru BUCKET in lru list */
while(hb != if_state.pserver->hBUCKlru)
{
b = (PBUCKET)MEMptr(hb);
if(b->fh != -1)
{
IXclose_file(FSA b);
break;
}
hb = b->link.b; /* previous BUCKET in the list */
}
if(hb == if_state.pserver->hBUCKlru)
{
DBG(" couldn't close file\n");
return ERR_IXopen_file;
}
}
/* Open the file */
#if IF_DISK /* changed from IF_RDR to resolve FIpath DISKROM link error - sandra, 8 Aug 03 */
if (bucket->fst_type == FC_IF_TYPE)
{
#if DYNAMIC_FONTS
if (bucket->dynIFActive)
STRCPY(pathname, bucket->pathname);
else
#endif
buildpath (pathname, if_state.typePath, FIpath(FSA ix));
}
#endif /* IF_DISK */
#if TT_RDR
if (bucket->fst_type == FC_TT_TYPE)
STRCPY(pathname, bucket->pathname);
#endif
#if PST1_RDR
if (bucket->fst_type == FC_PST1_TYPE)
STRCPY(pathname, bucket->pathname);
#endif
#if DIMM_DISK
if(bucket->fc_ExtndFlags & EF_DIMM_DISK_TYPE)
dd_open(bucket);
else
#endif
{
if((bucket->fh = OPEN(pathname, O_READFLAGS)) == -1)
{
DBG1(" Open lib file failed. pathname = %s\n", pathname);
return ERR_open_lib;
}
}
if_state.num_open_files++;
return SUCCESS;
}
#endif /* DISK_FONTS && (IF_RDR || TT_RDR || PST1_RDR) */
/*-------------------*/
/* BUCKinit */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 BUCKinit(FSP0)
#else
GLOBAL UW16
BUCKinit()
#endif
{
#if DISK_FONTS
if_state.num_open_files = 0; /* number of open library files */
#endif
#if IF_RDR
if_state.if_init_face = 0; /* Last face processed by if_init() */
#endif
/* 06-28-04 jfd Only initialize the BUCKET lru once */
if (if_state.pserver->MTinitstate & not_BUCKlru)
{
if_state.pserver->hBUCKlru = MEMalloc(FSA BUFFER_POOL, (SL32)sizeof(DLL));
if(!(if_state.pserver->hBUCKlru))
return ERRmem;
dll_null(FSA if_state.pserver->hBUCKlru); /* Set BUCKET lru to empty. */
if_state.pserver->MTinitstate &= ~not_BUCKlru;
}
return SUCCESS;
}
/*-------------------*/
/* BUCKexit */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID BUCKexit(FSP0)
#else
GLOBAL VOID
BUCKexit()
#endif
{
#if UFST_MULTITHREAD
PBUCKET b;
HBUCKET hb;
HBUCKET next_hb;
UL32 thread_id;
#endif
if(if_state.pserver->MTinitstate & not_BUCKlru) return; /* bucket LRU list not initialized */
#if UFST_MULTITHREAD
thread_id = get_thread_id(FSA0);
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f; /* first BUCKET in lru list */
while(hb != if_state.pserver->hBUCKlru)
{
b = (PBUCKET)MEMptr(hb);
next_hb = b->link.f;
BUCKfree(FSA hb);
hb = next_hb; /* next BUCKET in the list */
}
if (!if_state.pserver->client_count)
{
if (dll_empty(FSA if_state.pserver->hBUCKlru))
{
MEMfree(FSA BUFFER_POOL, if_state.pserver->hBUCKlru);
if_state.pserver->MTinitstate |= not_BUCKlru; /* set not initialized bit */
}
}
#else
while(!dll_empty(FSA if_state.pserver->hBUCKlru))
BUCKfree(FSA ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b);
MEMfree(FSA BUFFER_POOL, if_state.pserver->hBUCKlru);
if_state.pserver->MTinitstate |= not_BUCKlru; /* set not initialized bit */
#endif
}
#if FCO_RDR
/*-------------------*/ /* This function is almost the same as */
/* BUFpurgeBUCK */ /* BUCKexit but does not remove 'hBUCKlru'. */
/*-------------------*/
/* Arguments: none
* Called by: CGIFfco_Open
* Notes: CGIFfco_Open allocates permanent memory in the BUFFER pool for the
* FCO. To avoid fragmentation, use BUFpurgeBUCK to remove all buckets.
*/
#if defined (ANSI_DEFS)
GLOBAL VOID BUFpurgeBUCK(FSP0)
#else
GLOBAL VOID BUFpurgeBUCK()
#endif
{
#if UFST_MULTITHREAD
PBUCKET b;
HBUCKET hb;
HBUCKET next_hb;
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f; /* first BUCKET in lru list */
while(hb != if_state.pserver->hBUCKlru)
{
b = (PBUCKET)MEMptr(hb);
next_hb = b->link.f;
BUCKfree(FSA hb);
hb = next_hb; /* next BUCKET in the list */
}
#else
while(!dll_empty(FSA if_state.pserver->hBUCKlru))
BUCKfree(FSA ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b);
#endif
}
#endif /* FCO_RDR */
/*-------------------*/
/* BUCKfree */
/*-------------------*/
#if defined (ANSI_DEFS)
VOID BUCKfree(FSP HBUCKET hb)
#else
VOID
BUCKfree(hb)
HBUCKET hb;
#endif
{
PBUCKET b;
#if UFST_MULTITHREAD
UW16 status;
#endif
b = ((PBUCKET)MEMptr(hb));
#if UFST_MULTITHREAD
status = remove_thread_id_from_list(FSA b->thread_ids);
if (!thread_list_is_empty(FSA b->thread_ids))
return;
b->locked = FALSE;
#endif
#if USE_JUMP_TABLES
(*((PIF_FUNC_TBL)b->pft)->unload_font) (FSA b);
#else
switch (b->fst_type)
{
#if IF_RDR
case FC_IF_TYPE:
ifunload_font (FSA b);
break;
#endif
#if PST1_RDR
case FC_PST1_TYPE:
psunload_font (FSA b);
break;
#endif
#if TT_RDR
case FC_TT_TYPE:
ttunload_font (FSA b);
break;
#endif
#if FCO_RDR
case FC_FCO_TYPE:
fco_unload_font (FSA b);
break;
#endif
default:
/* return (ERR_fst_type); */
return;
}
#endif /* USE_JUMP_TABLES */
MEMSET (&if_state.cur_loc_fc, '\0', sizeof (FONTCONTEXT));
/* Reset system copy of fontcontext too. */
MEMSET (&if_state.pserver->cur_loc_fc, '\0', sizeof (FONTCONTEXT));
dll_remove(FSA hb); /* remove from active lru list */
#if TT_RDR && CFF_RDR /* 05-23-01 jfd */
if ( B_ISOTCFF(b) )
BUFfree(FSA ((PBUCKET)(b->potcff))->my_handle);
#endif /* TT_RDR && CFF_RDR */
BUFfree(FSA hb);
}
#if TT_TTPLUG
/* TT Plugins are in TrueType format. */
/*-------------------*/
/* CGIFtt_universal */
/*-------------------*/
/* This function defines the current font as set by the last call
* to CGIFfont() as a plugin font.
*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFtt_universal (FSP LPUB8 ptr, SL32 rom_font)
#else
UW16 CGENTRY CGIFtt_universal (ptr, rom_font)
LPUB8 ptr;
SL32 rom_font;
#endif /* ANSI_DEFS */
{
if_state.ttplug_font_type = FC_TT_TYPE;
if(rom_font)
{
if_state.ttplug_font_type |= FC_ROM_TYPE;
if_state.tt_fnt_hdr = ptr;
}
else
{
#if DISK_FONTS
if(STRLEN((FILECHAR *)ptr) >= PATHNAMELEN)
return ERRlong_font_name;
STRCPY(if_state.tt_universal, (FILECHAR *)ptr);
if_state.tt_fnt_hdr = (LPUB8)if_state.tt_universal;
#endif
}
return SUCCESS;
}
#endif /* TT_TTPLUG */
#if UFST_MULTITHREAD
#if defined (ANSI_DEFS)
GLOBAL UW16 add_thread_id_to_list(FSP LPUL32 ids)
#else
GLOBAL UW16 add_thread_id_to_list(ids)
LPUL32 ids;
#endif
{
UW16 ctr = 0;
UW16 status = SUCCESS;
UL32 thread_id = get_thread_id(FSA0);
/* Add id of current thread to list */
while (ctr < MAX_THREADS && ids[ctr] != -1L)
{
if (ids[ctr] == thread_id)
return status;
ctr++;
}
if (ctr < MAX_THREADS)
ids[ctr] = thread_id;
else
status = ERR_max_threads_exceeded;
return status;
}
#if defined (ANSI_DEFS)
GLOBAL UW16 remove_thread_id_from_list(FSP LPUL32 ids)
#else
GLOBAL UW16 remove_thread_id_from_list(ids)
LPUL32 ids;
#endif
{
UW16 ctr = 0;
UW16 status = SUCCESS;
UL32 thread_id = get_thread_id(FSA0);
while (ctr < MAX_THREADS && ids[ctr] != thread_id)
ctr++;
/* Remove id of current thread from thread list */
if (ctr < MAX_THREADS)
MEMCPY((LPSB8)&ids[ctr], (LPSB8)&ids[ctr+1], (MAX_THREADS - ctr - 1) * sizeof(UL32));
else
status = ERR_thread_not_found_in_list;
return status;
}
#if defined (ANSI_DEFS)
GLOBAL BOOLEAN thread_list_is_empty(FSP LPUL32 ids)
#else
GLOBAL BOOLEAN thread_list_is_empty(ids)
LPUL32 ids;
#endif
{
UW16 ctr = 0;
while (ctr < MAX_THREADS && ids[ctr] == -1L)
ctr++;
/* Return TRUE if bucket "pb"'s thread list is empty */
return (ctr < MAX_THREADS) ? FALSE : TRUE;
}
#if defined (ANSI_DEFS)
GLOBAL BOOLEAN only_thread_in_list(FSP LPUL32 ids, UL32 thread_id)
#else
GLOBAL BOOLEAN only_thread_in_list(ids, thread_id)
LPUL32 ids;
UL32 thread_id;
#endif
{
UW16 ctr = 0;
while (ctr < MAX_THREADS && ids[ctr] != -1L)
ctr++;
/* Return TRUE is thread_id is the only thread in list */
return (ctr == 1 && ids[0] == thread_id) ? TRUE : FALSE;
}
#if defined (ANSI_DEFS)
GLOBAL VOID print_bucket_status(FSP0)
#else
GLOBAL VOID print_bucket_status()
#endif
{
PBUCKET b;
HBUCKET hb;
UW16 ctr;
printf("\n print_bucket_status()");
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f; /* first BUCKET in lru list */
while(hb != if_state.pserver->hBUCKlru)
{
b = (PBUCKET)MEMptr(hb);
printf("\n bucket %lx:", b);
if (b->locked)
{
printf(" locked by: ");
ctr = 0;
while (ctr < MAX_THREADS)
{
if (b->thread_ids[ctr] != -1L)
printf(" [%d]=%8x", ctr, b->thread_ids[ctr]);
ctr++;
}
}
else
printf(" unlocked!!!");
hb = b->link.f; /* next BUCKET in the list */
}
printf("\n");
}
#endif
/*-------------------*/
/* BUCKfind */
/*-------------------*/
/* Inputs: buck_search_level == 0 buck_search_level > 0
* fontindex.cur_tf_num
* cur_ssnum
* font_type
* has_path
* cur_pix
* cur_font_hdr
* pathname
* symbolset.tt_platID
* symbolset.tt_specID
* symbolset.tt_langID
*/
#if defined (ANSI_DEFS)
GLOBAL UW16 BUCKfind(FSP SL32 buck_search_lvl, SL32 purge_bucket, PPBUCKET p_bucket)
#else
GLOBAL UW16
BUCKfind(buck_search_lvl, purge_bucket, p_bucket)
SL32 buck_search_lvl;
SL32 purge_bucket;
PPBUCKET p_bucket;
#endif
{
SL32 tfnum=0;
UW16 cur_ssnum=0;
HBUCKET hb, hb0;
PBUCKET b = NULL;
UW16 status;
BOOLEAN has_path=FALSE;
LPUB8 cur_font_hdr=0;
SL32 font_type=0;
#if (DYNAMIC_FONTS && IF_ROM)
SL32 rom_font;
#endif
SL32 extern_font=0; /* Changed from BOOLEAN 6/13/96 jwd, FMT 16. */
UW16 fst_type=0;
#if UFST_MULTITHREAD
int thread_id = get_thread_id(FSA0);
#endif
DBG1("BUCKfind(%ld)\n", buck_search_lvl);
if( buck_search_lvl == 0 ) /* Typeface Sensitive level */
{
tfnum = if_state.fontindex.cur_tf_num;
cur_ssnum = if_state.fontindex.cur_ssnum;
font_type = if_state.fontindex.font_type;
has_path = if_state.fontindex.has_path;
#if (DYNAMIC_FONTS && IF_ROM)
rom_font = (SL32)(font_type & FC_ROM_TYPE);
#endif
/* extern_font = ((font_type & FC_EXTERN_TYPE) == FC_EXTERN_TYPE) +
((font_type & EF_FORMAT16_TYPE) == EF_FORMAT16_TYPE);
*/
/* ks - Fixed reported error - Jan 26, 2000 */
/* Need to setup extern_font based on bitmap/scalable check as well. */
/* Revisit to optimize/make constants. jwd, 07/21/03. */
if ( FC_ISXLFONT(&if_state.fcCur))
{
#if PCLEO_RDR
if (if_state.DLBmpInProcess)
extern_font = PCL_BITMAP_FONT;
else
#endif
extern_font = (((font_type & FC_EXTERN_TYPE) == FC_EXTERN_TYPE) + /* keb 8/99 */
((EF_FONTTYPE_MASK & EF_XLFONT_TYPE) == EF_XLFONT_TYPE) + 1);
}
else
{
#if PCLEO_RDR
if (if_state.DLBmpInProcess)
extern_font = PCL_BITMAP_FONT;
else
#endif
extern_font = ((font_type & FC_EXTERN_TYPE) == FC_EXTERN_TYPE) +
((font_type & EF_FORMAT16_TYPE) == EF_FORMAT16_TYPE);
}
fst_type = font_type & FC_FONTTYPE_MASK;
switch (fst_type)
{
#if IF_RDR
case FC_IF_TYPE:
if_state.fontindex.pix = if_state.fontindex.cur_pix; /* IF disk or ROM */
#if DYNAMIC_FONTS
if (if_state.fontindex.cur_pix) /* If cur_pix is valid, then the TFS */
has_path = FALSE; /* is in if.fnt. Even if there if a */
#endif /* pathname, ignore it. */
break;
#endif /* IF_RDR */
default: break;
} /* switch (fst_type) */
#if DISK_FONTS
if (has_path)
cur_font_hdr = (LPUB8)if_state.fontindex.pathname;
else
#endif
cur_font_hdr = if_state.fontindex.cur_font_hdr;
#if FCO_RDR
if (fst_type == FC_FCO_TYPE)
cur_font_hdr = (LPUB8)MEMptr(if_state.pserver->FCObject);
#endif
} /* if( buck_search_lvl == 0 ) */
#if PLUGINS
else /* loading a plugin, buck_search_level > 0 */
{
has_path = FALSE;
switch( if_state.fontindex.plug_type )
{
#if (IF_RDR || PS_IFPLUG)
case FC_IF_TYPE: /* Intellifont plugins */
{
if_state.fontindex.pix = FIentry( FSA buck_search_lvl - 1 );
tfnum = if_state.fontindex.pix->tfnum;
font_type = FC_IF_TYPE; /* disk based */
cur_font_hdr = (LPUB8)NULL;
/* I don't think this test needs to be #if IF_ROM, but... (sandra, 17 Jun 04) */
#if ROM
/* if ROM is enabled, we assume ROM plugins for IF */
font_type |= FC_ROM_TYPE;
#endif
break;
}
#endif /* (IF_RDR || PS_IFPLUG) */
#if (TT_RDR && TT_TTPLUG)
case FC_TT_TYPE: /* TrueType plugins */
{
font_type = if_state.ttplug_font_type;
tfnum = 0;
cur_font_hdr = if_state.tt_fnt_hdr;
if ( !(font_type & FC_ROM_TYPE) )
has_path = TRUE;
break;
}
#endif /* TT_RDR && TT_TTPLUG */
#if FCO_RDR /* If FCO_RDR is enabled, plug_type will ALWAYS be set to FCO_TYPE */
case FC_FCO_TYPE: /* MicroType plugins */
{
font_type = FC_FCO_TYPE;
cur_font_hdr = (LPUB8)MEMptr(if_state.pserver->FCO_PluginH);
tfnum = if_state.fontindex.fcoSearchPath[buck_search_lvl-1];
break;
/* NOTE [ mby 09-25-96 ]: tfnum is not strictly correct;
* it should have the index number in the lower word AND
* the FCO handle in upper word. But this is a benign bug
* for now. */
}
#endif /* FCO_RDR */
default:
return ERR_no_cgnum;
} /* switch if_state.fontindex.plug_type */
/* For any type of plugins, break out details of plugin font.
*/
cur_ssnum = if_state.fontindex.cur_ssnum; /* code in tt_if.c fc_if.c */
/* checks b->cur_ssnum == UNICODE - mby 11-14-96 */
extern_font = ((font_type & FC_EXTERN_TYPE) == FC_EXTERN_TYPE);
fst_type = font_type & FC_FONTTYPE_MASK;
#if (DYNAMIC_FONTS && IF_ROM)
rom_font = (SL32)(font_type & FC_ROM_TYPE);
#endif
}
#endif /* PLUGINS */
/* Search for BUCKET */
hb0 = hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f; /* first BUCKET in lru list */
while(hb != if_state.pserver->hBUCKlru)
{
b = (PBUCKET)MEMptr(hb);
/* Search algorithm:
* - For TrueType, compare platform ID, spec ID
* (if using an ASIAN encoding scheme, compare ssnum)
* - For TT, PS, IF (dynamic): if there's a pathname, compare to
* b->pathname
* - For DYNAMIC/ROM, compare cur_font_hdr
* - Else compare tfnum, symbol set, font_hdr, and font_type.
*/
#if TT_RDR
if (fst_type == FC_TT_TYPE)
{
/* TFS search and no plugins */
if (buck_search_lvl == 0 && !if_state.usePlugins)
{
if (b->p.tt.platId != 0 || b->p.tt.specId != 0)
goto Bf1; /* match failed */
}
#if PLUGINS
/* !TFS search and TT plugins */
else if (buck_search_lvl > 0 && if_state.fontindex.plug_type == FC_TT_TYPE)
{
if (b->p.tt.platId != TT_PLUGPLID || b->p.tt.specId != TT_PLUGSPID)
goto Bf1; /* match failed */
}
#endif /* PLUGINS */
#if ASIAN_ENCODING
/* TFS search and no ASIAN encoding */
else if (buck_search_lvl == 0 && (is_it_Asian(cur_ssnum) || is_it_Asian(b->cur_ssnum)) )
{
if (b->cur_ssnum != cur_ssnum)
goto Bf1; /* match failed */
if ( FC_ISUSERCMAPTBL(&if_state.fcCur) )
{
/* If user has specified a platform ID and specific ID,
* test for a match with the current bucket
*/
if (b->p.tt.platId != if_state.fcCur.user_platID ||
b->p.tt.specId != if_state.fcCur.user_specID)
goto Bf1; /* match failed */
}
} /* 11-21-00 jfd */
#endif /* ASIAN_ENCODING */
/* All other cases */
else
{
if (b->p.tt.platId != if_state.symbolset.tt_platID ||
b->p.tt.specId != if_state.symbolset.tt_specID)
goto Bf1; /* match failed */
}
}
#endif /* TT_RDR */
#if PST1_RDR
if ((fst_type == FC_PST1_TYPE) && (b->fst_type == FC_PST1_TYPE))
{
BOOLEAN filesmatch = FALSE;
#if DISK_FONTS
if(has_path && b->has_path)
filesmatch = (STRNCMP((FILECHAR *)cur_font_hdr,
b->pathname, PATHNAMELEN) == 0);
else if(!has_path && !b->has_path)
#endif
filesmatch = (b->cur_font_hdr == cur_font_hdr);
if(!filesmatch)
goto Bf1;
if(!ps_is_same(FSA b))
goto Bf1;
}
#endif /* PST1_RDR */
#if DISK_FONTS
if (has_path)
{
if(b->has_path)
{
if( STRNCMP((FILECHAR *)cur_font_hdr, b->pathname, PATHNAMELEN) == 0
#if TT_RDR
/*
* For TT collections, match on index number too.
*/
&& ( (fst_type == FC_TT_TYPE && (b->p.tt.ttc_index == if_state.fcCur.ttc_index))
|| (fst_type != FC_TT_TYPE))
#endif /* TT_RDR */
)
{
b->cur_ssnum = cur_ssnum;
break; /* We have a match! (pathname + symset) */
}
}
}
else
#endif /* DISK_FONTS */
#if (DYNAMIC_FONTS && IF_ROM)
if ( (fst_type == FC_IF_TYPE) && (tfnum == 0) && rom_font )
{
if (b->cur_font_hdr == cur_font_hdr)
break; /* We have a match! (DYNAMIC/ROM, IF format) */
}
else
#endif /* DYNAMIC_FONTS && IF_ROM */
/*** Test if this is our bucket ***/
if( (b->tfnum == tfnum ) &&
(b->cur_ssnum == cur_ssnum ) &&
(b->cur_font_hdr == cur_font_hdr) &&
#if TT_RDR /* 12-18-00 jfd */
/*
* For TT collections, match on index number too.
*/
( (b->fst_type == FC_TT_TYPE && (b->p.tt.ttc_index == if_state.fcCur.ttc_index))
|| (b->fst_type != FC_TT_TYPE) )
&&
#endif /* TT_RDR */
(b->font_type == font_type))
break;
#if (TT_RDR || PST1_RDR)
Bf1:
#endif
if(hb == hb0) /* if first bucket in lru list, */
{
#if UFST_MULTITHREAD
status = remove_thread_id_from_list(FSA b->thread_ids);
if (thread_list_is_empty(FSA b->thread_ids))
b->locked = FALSE; /* unlock */
#else
b->locked = FALSE; /* unlock */
#endif
}
hb = b->link.f; /* next BUCKET in the list */
} /* bucket search loop */
if(purge_bucket)
{
if(hb != if_state.pserver->hBUCKlru) /* found it; changed != to == */
{
#if UFST_MULTITHREAD
status = remove_thread_id_from_list(FSA b->thread_ids);
if (thread_list_is_empty(FSA b->thread_ids))
#endif
BUCKfree(FSA hb); /* jwd, 5/31/01. */
/* Back to !=. jwd, 09/23/02. */
}
return SUCCESS;
}
if(hb != if_state.pserver->hBUCKlru)
{ /* found it */
/* Make BUCKET most recently used */
DBG(" search succeeded\n");
#if TT_DISK
if (fst_type == FC_TT_TYPE)
{
if(b->has_path) /* 4-29-94 jfd */
{
status = IXopen_file(FSA (PINDEX_ENTRY)NULL, b);
if (status)
return status;
}
}
#endif
if(hb != hb0) /* if not already first in list... */
{
b->locked =TRUE;
#if UFST_MULTITHREAD
status = add_thread_id_to_list(FSA b->thread_ids);
#endif
dll_remove(FSA hb);
dll_after(FSA if_state.pserver->hBUCKlru, hb);
}
#if UFST_MULTITHREAD
else
status = add_thread_id_to_list(FSA b->thread_ids);
#endif
}
else /* not found */
{
SL32 againFlag = 1; /* to fix fragmentation in BUFpool memory */
DBG(" search failed- making new BUCKET\n");
#if TT_RDR
TryAgain:
#endif
hb = (HBUCKET)BUFalloc(FSA (SL32)sizeof(BUCKET));
if(!(hb))
return ERR_no_buck_mem;
b = (PBUCKET)MEMptr(hb);
MEMSET((LPUB8)b, (SL32)0, (SL32)sizeof(BUCKET) );
b->my_handle = hb; /* remember who I am for freeing */
b->fh = -1; /* no open file */
b->tfnum = tfnum;
b->bucket_num = 0; /* set to default */
b->font_type = font_type;
b->fc_format = if_state.fcCur.format; /* copy of fontcontext.format word */
b->fc_ExtndFlags = if_state.fcCur.ExtndFlags;
/* copy of fontcontext.ExtndFlags word */
b->fst_type = fst_type;
b->extern_font = extern_font;
b->cur_font_hdr = cur_font_hdr;
b->cur_ssnum = cur_ssnum;
b->usePlugins = if_state.usePlugins;
#if TT_RDR
/* only copy ttc_index if CURRENT font is a TT font */
if (FC_ISTT(&if_state.fcCur))
b->p.tt.ttc_index = if_state.fcCur.ttc_index;
#endif /* TT_RDR */
#if DISK_FONTS
#if DYNAMIC_FONTS && IF_RDR
/* test was #if ROM - I believe this is correct, but... (sandra, 17 Jun 04) */
#if IF_ROM
b->dynIFActive = (fst_type == FC_IF_TYPE) && !extern_font && cur_font_hdr;
/* If dynamic, cur_font_hdr points to a font in ROM. */
#else
b->dynIFActive = (fst_type == FC_IF_TYPE) && has_path;
#endif
#endif /* DYNAMIC_FONTS && IF_RDR */
b->has_path = has_path;
if(has_path)
STRCPY(b->pathname, (FILECHAR *)cur_font_hdr);
#if CFF_RDR && TT_RDR /* 05-23-01 jfd */
b->potcff = (PBUCKET)0;
b->otcff_font = FALSE;
#endif /* CFF_RDR && TT_RDR */
#endif /* DISK_FONTS */
#if UFST_MULTITHREAD
MEMSET(b->thread_ids, (UL32)-1L, MAX_THREADS * sizeof(UL32));
#endif
#if USE_JUMP_TABLES
switch (b->fst_type)
{
case FC_IF_TYPE:
#if IF_RDR /* should this be one line up? (sandra, 28 Jun 04) */
DBG(" fst_type = Intellifont\n");
b->pft = &iffunc_tbl;
break;
#endif
#if PST1_RDR
case FC_PST1_TYPE:
DBG(" fst_type = PostScript\n");
b->pft = &psfunc_tbl;
break;
#endif
#if TT_RDR
case FC_TT_TYPE:
DBG(" fst_type = TrueType\n");
b->pft = &ttfunc_tbl;
break;
#endif /* TT_RDR */
#if FCO_RDR
case FC_FCO_TYPE:
DBG(" fst_type = Font Collection Object\n");
b->pft = &fco_func_tbl;
break;
#endif /* FCO_RDR */
default:
BUFfree(FSA hb);
return ERR_fst_type;
}
status =
((*((PIF_FUNC_TBL)b->pft)->load_font)(FSA (PFONT_DES)cur_font_hdr, b));
#else /* !USE_JUMP_TABLES */
switch (b->fst_type)
{
#if IF_RDR
case FC_IF_TYPE:
status = ifload_font (FSA (LPSB8)cur_font_hdr, b);
break;
#endif
#if PST1_RDR
case FC_PST1_TYPE:
status = psload_font (FSA (LPSB8)cur_font_hdr, b);
break;
#endif
#if TT_RDR
case FC_TT_TYPE:
status = ttload_font (FSA (LPSB8)cur_font_hdr, b);
break;
#endif
#if FCO_RDR
case FC_FCO_TYPE:
status = fco_load_font (FSA (LPSB8)cur_font_hdr, b);
break;
#endif
default:
BUFfree(FSA hb); /* added 09-16-96 */
return (ERR_fst_type);
}
#endif /* USE_JUMP_TABLES */
if (status)
{
DBG(" load_font() failed in BUCKfind()\n");
BUFfree(FSA hb);
#if TT_RDR
if (status == ERR_TT_MEMFAIL && againFlag) { /* Low Memory */
/* Check for TrueType BUFalloc failure. Then try again.
* The 1st call to load_font should free all the other
* buckets; hence the 2nd time around might work. */
againFlag = 0;
goto TryAgain;
}
#endif
return status;
}
else
dll_after(FSA if_state.pserver->hBUCKlru, hb); /* link at start of BUCKET lru list */
#if TT_RDR && CFF_RDR /* 05-23-01 jfd */
/* If processing an OpenType CFF font, create the CFF bucket. */
if (B_ISOTCFF(b))
{
PBUCKET otcff_b = NULL;
HBUCKET otcff_hb;
otcff_hb = (HBUCKET)BUFalloc(FSA (SL32)sizeof(BUCKET));
if(!(otcff_hb))
return ERR_no_buck_mem;
otcff_b = (PBUCKET)MEMptr(otcff_hb);
MEMSET((LPUB8)otcff_b, (int)0, (int)sizeof(BUCKET) );
otcff_b->my_handle = otcff_hb; /* remember who I am for freeing */
otcff_b->bucket_num = 0; /* set to default */
otcff_b->fst_type = FC_PST1_TYPE;
otcff_b->extern_font = extern_font;
otcff_b->cur_ssnum = cur_ssnum;
otcff_b->cur_font_hdr = cur_font_hdr;
otcff_b->p.ps.cft.CFFTableOffset = b->p.tt.CFFTableOffset;
otcff_b->p.ps.cft.CFFTableSize = b->p.tt.CFFTableSize;
otcff_b->otcff_font = TRUE;
otcff_b->fh = b->fh;
otcff_b->tfnum = b->tfnum;
otcff_b->font_type = b->font_type;
otcff_b->fc_format = b->fc_format;
otcff_b->fc_ExtndFlags = b->fc_ExtndFlags;
otcff_b->usePlugins = b->usePlugins;
#if USE_JUMP_TABLES
DBG(" fst_type = PostScript\n");
otcff_b->pft = &psfunc_tbl;
status =
((*((PIF_FUNC_TBL)otcff_b->pft)->load_font)(FSA (PFONT_DES)cur_font_hdr, otcff_b));
#else /* !USE_JUMP_TABLES */
status = psload_font (FSA (LPSB8)cur_font_hdr, otcff_b);
#endif /* USE_JUMP_TABLES */
if (status)
{
DBG(" load_font() failed in BUCKfind()\n");
BUFfree(FSA otcff_hb);
b->potcff = (PBUCKET)0;
return status;
}
b->potcff = otcff_b;
}
#endif /* TT_RDR && CFF_RDR */
} /* bucket not found; made a new bucket. */
/* Copy of fontcontext.format word. MUST do this here
* in case we skipped the bucket-not-found code block.
*/
b->fc_format = if_state.fcCur.format;
/* Copy of fontcontext.ExtndFlags word. MUST do this here
* in case we skipped the bucket-not-found code block.
*/
b->fc_ExtndFlags = if_state.fcCur.ExtndFlags;
#if PLUGINS
/* If have only determined up to TFS level, now determine plugins. */
#if FCO_RDR
/* If FCO_RDR is enabled, always use FCO plugins regardless of fst type.
*/
if (if_state.fontindex.fcoMakeNewSrchPath)
{
if_state.fontindex.plug_type = FC_FCO_TYPE;
fco_pluginSearchPath(FSA b, if_state.fontindex.fcoSearchPath,
&if_state.fontindex.num_searches);
if_state.fontindex.fcoMakeNewSrchPath = 0;
#if PCLEO_RDR
/* If TFS was a pcleo, need to load symbolset first and last
* character in order to locate the character in the FCO plugins */
if (if_state.fcCur.format & FC_EXTERN_TYPE && (b->cur_ssnum != DL_SYMSET))
{
if (!b->usePlugins) /* mby, 6-06-95 */
{
if (!SYMnoMap(FSA if_state.fcCur.font_hdr, if_state.fcCur.format)) {
BUFfree(FSA hb); /* added 09-16-96 */
return ERR_IXnew_ss;
}
}
else if (FC_SSMAP(&if_state.fcCur))
{
if (!SYMnew(FSA if_state.fcCur.ssnum, if_state.fcCur.format)) {
BUFfree(FSA hb); /* added 09-16-96 */
return ERR_IXnew_ss;
}
}
}
#endif /* PCLEO_RDR */
} /* endif (if_state.fontindex.fcoMakeNewSrchPath) */
#else /* ~FCO_RDR */
if(if_state.fontindex.num_searches <= 1 && b->usePlugins) /* setup plugin search path */
{
if_state.fontindex.plug_type = 0xFFFF; /* Invalid type */
#if TT_TTPLUG
/* also make sure global disable-all-plugins bit is OFF (i.e. plugins are enabled) */
if(fst_type == FC_TT_TYPE && !FC_NOPLUGINS(&if_state.fcCur))
{
#if STIK
fs_GlyphInfoType *fsg = (fs_GlyphInfoType *)MEMptr(b->p.tt.buffInfo);
/* Do not augment stik fonts with plugins */
/* for CCC font */
if (!(IS_STIK_FONT(fsg) && FC_STIKNOPLUGINS(&if_state.fcCur)))
#endif /* STIK */
{
if_state.fontindex.plug_type = FC_TT_TYPE;
if_state.fontindex.num_searches++; /* added another search level */
}
}
#endif /* TT_TTPLUG */
#if (IF_RDR || PS_IFPLUG) /* Intellifont plugins */
/* also make sure global disable-all-plugins bit is OFF (i.e. plugins are enabled) */
if( !FC_NOPLUGINS(&if_state.fcCur) &&
((fst_type == FC_IF_TYPE) ||
((fst_type == FC_PST1_TYPE) && PS_IFPLUG) ))
{
/* A quick rundown:
if AWT font substitution is on, then pass bits in awt header to
IXset_search_path().
else pass bits in b->bucket_num to IXset_search_path().
if B_PLUGIN_TYPE_TT is set, then use the TT plugin
*/
{
{
if_state.fontindex.plug_type = FC_IF_TYPE;
status = IXset_search_path(FSA b->bucket_num);
if (status)
return status;
}
}
}
#endif /* (IF_RDR || PS_IFPLUG) Intellifont plugins */
} /* if (if_state.fontindex.num_searches <= 1) */
#endif /* FCO_RDR */
#endif /* PLUGINS */
b->locked = TRUE;
{
#if UFST_MULTITHREAD
status = add_thread_id_to_list(FSA b->thread_ids);
#endif
}
if_state.pbucket = b;
*p_bucket = b;
return SUCCESS;
} /* BUCKfind */
/*------------------------------------------------------------------*/
/* B u f f e r M e m o r y M a n a g e m e n t */
/*------------------*/
/* BUFalloc */
/*------------------*/
/* Acquire size SB8s. Free lru BUCKETs if need be */
#if defined (ANSI_DEFS)
GLOBAL MEM_HANDLE BUFalloc(FSP SL32 size)
#else
GLOBAL MEM_HANDLE
BUFalloc(size)
SL32 size;
#endif
{
MEM_HANDLE hbuf;
HBUCKET hb;
#if UFST_MULTITHREAD
PBUCKET b;
HBUCKET next_hb;
#endif
/* AJ - added for memory fund check*/
if (size > if_state.pserver->mem_fund[BUFFER_POOL])
return NIL_MH;
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b;
while ( (hbuf=MEMalloc(FSA BUFFER_POOL, size)) == NIL_MH
#if UFST_MULTITHREAD
&& hb != if_state.pserver->hBUCKlru
#endif
)
{
if(dll_empty(FSA if_state.pserver->hBUCKlru)) return NIL_MH;
#if UFST_MULTITHREAD
b = (PBUCKET)MEMptr(hb);
next_hb = b->link.b;
if (thread_list_is_empty(FSA b->thread_ids))
BUCKfree(FSA hb);
hb = next_hb; /* next BUCKET in the list */
#else
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b;
if(((PBUCKET)MEMptr(hb))->locked) return NIL_MH;
/* Only the most recently used BUCKET can be locked. */
BUCKfree(FSA hb); /* free lru BUCKET */
#endif
}
return hbuf;
}
/*------------------*/
/* BUFfree */
/*------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID BUFfree(FSP MEM_HANDLE h)
#else
GLOBAL VOID
BUFfree(h)
MEM_HANDLE h;
#endif
{
MEMfree(FSA BUFFER_POOL, h);
}
#if PRINT_BUCKETS
print_buckets(FSP0)
{
HBUCKET hb;
PBUCKET b;
hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f; /* first BUCKET in lru list */
while(hb != if_state.pserver->hBUCKlru)
{
b = (PBUCKET)MEMptr(hb);
hb = b->link.f; /* next BUCKET in the list */
printf("bucket %lx: tfnum = %ld bucket_num = %04X\n", b, b->tfnum, b->bucket_num);
printf(" font_type = %04X, extern_font = %d, cur_ssnum = %04X\n", b->font_type, b->extern_font, b->cur_ssnum);
printf(" has_path = %d", b->has_path);
#if DISK_FONTS
if (b->has_path)
printf(" pathname = %s", b->pathname);
#endif
printf("\n");
}
}
#endif
cache.c
/*
* Copyright (C) 2005 Monotype Imaging Inc. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/DEP/CACHE.C_V 1.54 Dec 14 2004 15:47:36 galejss $ */
/* $Log: I:/BULL/URIP/RTS/DEP/CACHE.C_V $
*
* Rev 1.54 Dec 14 2004 15:47:36 galejss
* make all DBG calls 16-bit-compatible
*
* Rev 1.53 Nov 30 2004 11:34:20 jardima
* Memory fund check added to TEMPCHARalloc
*
* Rev 1.52 Nov 29 2004 17:36:38 jardima
* added code for memory fund check
*
* Rev 1.51 Oct 26 2004 11:32:44 dugganj
* Multithreading changes.
*
* Rev 1.50 Oct 14 2004 11:46:56 galejss
* NEW_POOL becomes CHARGEN_POOL
*
* Rev 1.49 Oct 13 2004 08:08:40 dugganj
* Corrected !ANSI_DEFS function declaration for
* CACfont_free().
*
* Rev 1.48 Oct 01 2004 14:41:52 azimaf
* added new function CACfont_free to handle
* freeing the CASHE pool
*
* Rev 1.47 Sep 27 2004 16:14:30 dugganj
* Added multithread support.
*
* Rev 1.46 Sep 23 2004 09:17:18 dugganj
* Fixed incorrect SUN declarations for functions
* TEMPCHARalloc() and TEMPCHARfree().
*
* Rev 1.45 Sep 09 2004 16:56:12 galejss
* add TEMPCHARalloc / free functions (which use new 3rd memory pool NEW_POOL)
*
* Rev 1.44 Aug 10 2004 14:08:28 galejss
* new USE_ASIAN_CACHE test
*
* Rev 1.43 Jul 16 2004 13:31:58 galejss
* changes for extended disk/rom support; BOOLEAN type cleanup
*
* Rev 1.42 Apr 26 2004 17:28:56 GalejsS
* support for below-the-line IFBITSPLIT option; fix incorrect scope of conditional compile for char-by-ref
*
* Rev 1.41 Oct 17 2003 16:35:58 Galejs
* compile fixes for MEM_TRACE, ASIAN_HASH_TRACE options
*
* Rev 1.40 Aug 22 2003 08:57:08 LynchR
* Updated copyright notice.
*
* Rev 1.39 Jul 11 2003 12:12:18 Galejs
* replace cache_by_ref_mode tests with CACHE_BY_REF tests
*
* Rev 1.38 Jun 19 2003 18:56:14 Galejs
* move debug flags into header files; get rid of NON_IF_FONT
*
* Rev 1.37 Jun 12 2003 16:12:08 Joe
* Added "cache-by-reference" support.
*
* Rev 1.36 Oct 01 2002 12:25:32 Galejs
* add cast for chId
*
* Rev 1.35 Sep 30 2002 13:13:58 Galejs
* 32-bit charcode support (for rjl)
*
* Rev 1.34 Sep 23 2002 15:24:54 Galejs
* fix possibly-uninitialized-vbl warnings (part of bug # 76)
*
* Rev 1.33 May 03 2001 20:13:12 Galejs
* data-type cleanup
*
* Rev 1.32 Mar 29 2000 13:48:50 galejs
* fix massively messed-up indents
*
* Rev 1.31 27 Mar 2000 14:55:36 JOE
* CACHE with NO_SYMSET_MAPPING fix (by jwd).
*
* Rev 1.30 Aug 18 1999 17:25:40 galejs
* FONT becomes cacheFONT (to resolve conflict with customer's typedef)
*
* Rev 1.29 Aug 17 1999 11:40:10 galejs
* include-file changes
*
* Rev 1.28 12 Jan 1999 18:31:48 GALEJS
* move EXTERN dcls
*
* Rev 1.27 22 Jun 1998 18:21:10 GALEJS
* more reentrancy parm changes (compressed-cache)
*
* Rev 1.26 15 Jun 1998 14:32:30 GALEJS
* reentrancy changes (parm-passing, CHARalloc(), CHARfree())
*
* Rev 1.25 01 Apr 1998 19:11:34 GALEJS
* move all GLOBALs to IF_STATE; CAChdr_font() interface change
*
* Rev 1.24 30 Mar 1998 12:11:20 GALEJS
* move 2 MLOCALs into if_state, delete 1 unused MLOCAL
*
* Rev 1.23 24 Mar 1997 11:44:16 MIKE
* Fixed CACinsert() for grayscale
*
* Rev 1.22 16 Oct 1996 16:38:24 JOE
* In CACinsert(), before calculating size of character, test whether
* processing bitmap or outline.
*
* Rev 1.21 04 Oct 1996 09:10:10 JOE
* Removed CTRL-Z at end of file.
*
* Rev 1.20 01 Oct 1996 16:40:44 JOE
* Implemented new ASIAN cache architecture.
*
* Rev 1.19 24 Jan 1996 17:24:54 AL
* Compressed cache
*
* Rev 1.18 05 Dec 1995 13:27:16 MERRILL
* cleaned up warnings for borland4.0
*
* Rev 1.17 07 Apr 1995 08:36:32 LISA
* Changed copyright from Miles Inc. to Bayer Corp.
*
* Rev 1.16 13 Feb 1995 15:10:08 JOE
* In FNTfree(), when freeing the hash table, removed call to dll_remove()
* because it is unnecessary and was causing an infinite loop.
*
* Rev 1.15 26 Jan 1995 16:22:44 JOE
* ASIAN cache manager changes:
* In CACinsert(), check if MEMalloc() call failed before inserting character in hash list.
* In CACfont() and CAChdr_font(), return error if not enough cache memory for hash list.
* In FNTfree(), free hash table.
*
* Rev 1.14 26 Sep 1994 09:37:44 JOE
* In CAChdr_purge(), reset similar_fonts_purged flag before
* looping thru every font.
*
* Rev 1.13 20 Sep 1994 11:50:06 JOE
* In CAChdr_font(), conditionally compiled statements which reference
* "font_hdr" field of fontcontext to resolve compiler error.
* In same function, returning ERRfont_hdr_purge error if this function
* iis not supported.
*
* Rev 1.12 11 Sep 1994 09:02:48 JOE
* Added new functions CAChdr_purge() and CAChdr_font().
*
* Rev 1.11 05 Aug 1994 20:17:52 MIKE
* Added FCO changes from 1.8.1.1
*
* Rev 1.10 21 Apr 1994 15:43:10 LISA
* Made modifications to copyright/disclaimer notice.
*
* Rev 1.9 25 Jan 1994 10:45:08 MAIB
* Created a two-byte character code caching scheme, conditionally compiled
* on ASIAN_ENCODING
*
* Rev 1.8 01 Nov 1993 13:09:56 MAIB
* Additional check for current font added
*
* Rev 1.7 29 Oct 1993 17:27:58 MAIB
* Fixed condition missed in CACfont() optimization
*
* Rev 1.6 25 Oct 1993 10:58:52 MAIB
* Optimizations for cache access and font access in place
*
* Rev 1.5 06 May 1993 16:09:36 MIKE
* In CACfont() change "has_path" condition from NON_IF_FONT to
* PST1_DISK || TT_DISK || (DYNAMIC_FONTS && IF_DISK).
* has_path is true for IF disk + dynamic font.
*
* Rev 1.4 12 Feb 1993 19:38:28 MIKE
* Application Generated Bitmap support: in BMfree() call
* app_free_character() to clear char from cache.
*
* Rev 1.3 12 Feb 1993 13:55:46 JOE
* VXWorks support.
*
* Rev 1.2 14 Jan 1993 13:55:32 LISA
* Removeed CtrlZ character from end of file
*
* Rev 1.1 11 Dec 1992 15:31:42 LISA
* Made change to Log keyword
*
* Rev 1.0 09 Dec 1992 15:25:46 LISA
* Initial revision.
*/
/* cache.c */
/*
*
* History
*
* 29-Jul-90 awr changed conditional compile on MEMstat() from DEBUG
* to MEM_TRACE
* 05-Aug-90 awr added bitMapCount in FONTCONTEXT to improve cache
* performance. If last bitmap is freed from a font
* and it's not the current font, then the font is freed.
* 20-Nov-90 jfd Compiling all routines conditionally based on CACHE;
* Added #include "cgconfig.h".
* 04-Dec-90 jfd Moved "include" statement for "cgconfig.h" to line
* following "port.h"
* 28-Jan-91 jfd Made size arg of BMnew() LONG
* Made size arg of MEMalloc() LONG
* 30-Jan-91 dET Added function prototyping for MSC.
* 31-Jan-91 dET Modify for MSC multi-model compilation.
* 3-Feb-90 awr Split BMnew() into CACalloc() and CACinsert()
* changed make_char() for memory callbacks
* changed mem_avail[] to a LONG.
* 8-Feb-91 awr Added dll.h to declare functions.
* Moved FNTfree() call in CGIFfont() to start of
* FNTfind().
* Renamed FNTfind() to CACfont().
* Removed BMnew()- no longer used.
* 05-Mar-91 jfd Added new routine CACpurge().
* 06-Mar-91 jfd In CACexit(), free list headers.
* Changed CACdefund() to BOOLEAN and am calling
* CACExit() if necessary.
* 09-Apr-91 dET Added print_fnt_lru() and cac_dump routines for aid
* in debugging.
* 17-Jun-91 jfd Moved "debug.h" after "port.h".
* Moved "cgconfig.h" before "port.h".
* 26 Jun 91 ss Added not LINT_ARGS prototype for FNTfree().
* 18-Aug-91 awr Added htileBM to keep track of tile bm memory
* 28-Aug-91 jfd Added function prototype for purge_page() and
* (*free)() to resolve compiler warnings.
* 29-Aug-91 jfd In CACfont(), replaced call to structs_are_equal()
* with call to FCis_equal().
* 25-Sep-91 jfd In CACpurge(), changed type of argument from
* "FONTCONTEXT *" to "PFONTCONTEXT" to get rid of
* compiler warning.
* 28-Seo-91 awr Use CGIFinitstate to signal whether cache is
* initialized and protect against out of sequence
* calls to CACinit() or CACexit()
* 14-Feb-92 jfd Included "mixmodel.h".
* 26-Feb-92 jfd In CACfont(), conditionally compiled all references
* to "fc->font_hdr" based on EXTERN_FONT.
* Included <string.h> dur to STRNCMP call.
* 03-Apr-92 rs Portability cleanup (see port.h).
* 05-Apr-92 rs Fix CACfont - always said font was found after call
* to 'FCis_equal()'.
* 12 May 92 ss Changed conditional compiles based on EXTERN_FONT
* to (PST1I || TT_RDR) since EXTERN_FONT is used
* elsewhere to mean PCLEO.
* 08-Jul-92 rs Code cleanup.
* 21-Jul-92 awr Conditional compile changes.
* 05-Aug-92 jfd Replaced calls to FCis_equal() with MEMCMP for
* optimization.
* 04-Sep-92 jfd In CACfont(), moved setting of "has_path" outside
* of "for" loop to ensure thatit is set properly.
* 17-Nov-92 rs Add ANSI function definitions base on ANSI_DEFS.
* 08-Feb-93 jfd VXWorks support.
* 09-Feb-93 mby Application Generated Bitmap support: in BMfree() call
* app_free_character() to clear character from cache.
* 05-May-93 mby In CACfont() change has_path condition from NON_IF_FONT
* to PST1_DISK || TT_DISK || (DYNAMIC_FONTS && IF_DISK)
* Set has_path if dynamic font and IF disk.
* 25-Oct-93 maib Conditionally left out CACaccess, now inline in CGIFchar.
* Optimized CACfont for multi-threading
* 29-Oct-93 maib Fixed optimization when same fontcontext passed
* 01-Nov-93 maib Made sure to check for valid pfontCur before comparing
* fontcontexts
* 25-Jan-94 maib Included new cache accessing scheme for ASIAN_ENCODING
* 30-Aug-94 jfd Added new functions CAChdr_purge() and
* CAChdr_font().
* 20-Sep-94 jfd In CAChdr_font(), conditionally compiled statement
* which references "font_hdr" field of fontcontext
* to resolve compiler error.
* In same function, returning ERRhdr_font_purge error
* if this function is not supported.
* 23-Sep-94 jfd In CAChdr_purge(), reset similar_fonts_purged
* before looping thru every font.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* FCO Changes from 1.8.1.1:
* 15-Jun-94 mby In CACfont() has_path = 0 if fst type is FCO.
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* 26-Jan-95 jfd Made the following changes to ASIAN_ENCODING
* version of cache manager:
* In CACinsert(), check if MEMalloc() call failed
* before inserting character in hash list.
* In CACfont() and CAChdr_font(), return error if
* there is not enough cache memory for hash list.
* In FNTfree(), free hash table.
* 13-Feb-95 jfd In FNTtree(), when freeing the hash table, removed
* call to dll_remove() because it is unnecessary.
* 01-Oct-96 jfd Implemented new Asian cache architecture.
* Added option for Asian hash trace.
* Deleted obsolete function CACaccess().
* Replaced function CAChashLookup() with CACbmLookup().
* 16-Oct-96 jfd In CACinsert(), before calculating size of character,
* test whether processing bitmap or outline.
* 24-Mar-97 mby In CACinsert() correctly calculate size of grayscale
* char, which was not happening.
* Fixed a few warnings; removed BorlandC #pragma.
* 20-Mar-98 slg "MLOCAL fcCur" set but never used - delete
* 24-Mar-98 slg Move MLOCALs hFNTlru, hBigBM into if_state
* 01-Apr-98 slg Move all GLOBALs into IF_STATE. Also - add 2nd parm to
* CAChdr_font() = ptr to "similar_fonts_purged" flag.
* 15-Jun-98 slg Same version of CHARfree() for CACHE and non-CACHE;
* Add non-CACHE version of CHARalloc();
* parameter-passing changes for reentrancy
* 24-Mar-00 jwd Cache w/ NO_SYMSET_MAPPING fix.
* 12-Jun-03 jfd Added "cache-by-reference" support.
*
*/
#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"
#include "dll.h"
#if CACHE
#ifdef LINT_ARGS
MLOCAL VOID BMfree(FSP HIFBITMAP);
MLOCAL VOID FNTfree(FSP HIFFONT);
#if DEFUND
MLOCAL VOID purge_page(FSP UW16, MEM_HANDLE, VOID (*)(FSP MEM_HANDLE));
#endif /* DEFUND */
GLOBAL UW16 CAChdr_purge(FSP PFONTCONTEXT);
MLOCAL UW16 CAChdr_font (FSP PFONTCONTEXT, UW16*);
#if ASIAN_ENCODING && ASIAN_HASH_TRACE
GLOBAL VOID hash_trace(FSP PFONT);
#endif
#else /* not LINT_ARGS */
MLOCAL VOID FNTfree(); /* added -ss 6/26/91 */
#if DEFUND
MLOCAL VOID purge_page();
#endif /* DEFUND */
GLOBAL UW16 CAChdr_purge();
MLOCAL UW16 CAChdr_font ();
#if ASIAN_ENCODING && ASIAN_HASH_TRACE
GLOBAL VOID hash_trace();
#endif
#endif /* LINT_ARGS */
/*
* 9/24/96 jfd
* return a MEM_HANDLE to the IFBITMAP for a particular
* character ID, look in the font passed
*/
#if USE_ASIAN_CACHE
#if defined (ANSI_DEFS)
GLOBAL MEM_HANDLE CACbmLookup(FSP PFONT pf, UL32 chId)
#else
GLOBAL MEM_HANDLE
CACbmLookup(pf, chId)
PFONT pf;
UL32 chId;
#endif
{
#if USE_LOW_BYTE
UB8 row = (chId & 0x00ff);
#else
UB8 row = ((chId & 0xff00) >> 8);
#endif
MEM_HANDLE hItem = pf->hash_table[row];
PIFBITMAP pifb;
/*
* hrowDLL is a handle to the first IFBITMAP of a list of IFBITMAPS
* for the particular row. traverse each IFBITMAP item to determine
* if the character has been previously cached. if found, return the
* handle to the IFBITMAP item. if not found, return null...
*/
while (hItem != NIL_MH)
{
pifb = (PIFBITMAP)MEMptr(hItem);
if ((UL32)(pifb->index) == chId)
return hItem;
hItem = pifb->f;
}
return (MEM_HANDLE)0L;
}
#endif /* USE_ASIAN_CACHE */
/*
* 1/25/94 maib
* return a MEM_HANDLE to the hash list item for a particular
* character ID, look in the font passed
*/
/*----------------------*/
/* BMfree */
/*----------------------*/
/* Free an IFBITMAP. Remove all references to this bitmap. References can
* be from FONTs or from hBigBM.
*/
#if defined (ANSI_DEFS)
MLOCAL VOID BMfree(FSP HIFBITMAP hbm)
#else
MLOCAL VOID
BMfree(hbm)
HIFBITMAP hbm; /* handle of IFBITMAP that is to be freed */
#endif
{
PIFBITMAP bm;
HIFFONT hf;
PFONT f;
#if IFBITSPLIT
BOOLEAN in_two_parts = TRUE;
#endif
if(hbm == if_state.hBigBM)
if_state.hBigBM = (HIFBITMAP)0L;
bm = (PIFBITMAP)MEMptr(hbm); /* Recover pointer to the IFBITMAP */
/* Remove the reference to the IFBITMAP from the font. If there are
* no more bitmaps in the font and the font is not the current font
* then free up the font also.
*/
hf = bm->hiffont; /* handle to my FONT owner */
f = (PFONT)MEMptr(hf);
#if IFBITSPLIT && OUTLINE
/* outline memory is NOT declared in two parts (unlike bitmap & graymap memory) */
if (FC_ISOUTLINE(&f->fc))
in_two_parts = FALSE;
#endif
/*
* 1/25/94 maib
* new caching scheme for asian encoding
*/
#if USE_ASIAN_CACHE
remove_from_list(FSA hbm, f); /* moved here from after "dll_remove(hbm)" */
#else
*(f->hbuf+bm->index) = (HIFBITMAP)0L; /* forget about me */
#endif /* USE_ASIAN_CACHE */
if(!(--f->bitmapCount) && (hf != if_state.hfontCur))
FNTfree(FSA hf);
dll_remove(FSA hbm); /* Remove IFBITMAP from lru list */
#if ALIEN_BITS
if (FC_ISAPPGEN( &(f->fc) ))
{
app_free_character(hbm);
return;
}
#endif /* ALIEN_BITS */
#if IFBITSPLIT
if (in_two_parts)
{
IFBITMAP *pbm;
pbm = (IFBITMAP *)MEMptr(hbm);
MEMfree(FSA CACHE_POOL, pbm->datahandle); /* Free the IFBITMAP memory */
}
#endif
MEMfree(FSA CACHE_POOL, hbm); /* Free the IFBITMAP memory */
}
/*----------------------*/
/* CACinsert */
/*----------------------*/
/* Insert the character whose handle is hbm into the current font
* at index chId.
* ASSUMES that hfontCur and pfontCur are valid.
* Returns a handle to the cached bitmap which may be different than
* the input handle if cache compression is used. In that case, the
* caller should not rely on the input handle to be valid.
*/
#if defined (ANSI_DEFS)
GLOBAL HIFBITMAP CACinsert(FSP HIFBITMAP hbm, UL32 chId)
#else
GLOBAL HIFBITMAP
CACinsert(hbm, chId)
HIFBITMAP hbm;
UL32 chId;
#endif
{
PIFBITMAP bm;
#if OUTLINE
PIFOUTLINE out;
#endif
HIFBITMAP retval;
SL32 size=0; /* size of bitmap/outline/graymap */
retval = hbm;
bm = (PIFBITMAP)MEMptr(hbm);
if (FC_ISBITMAP(&(if_state.pfontCur->fc)))
{
size = (SL32)bm->width * (SL32)bm->depth;
}
#if GRAYSCALING
else if (FC_ISGRAY(&(if_state.pfontCur->fc)))
{
size = bm->size;
}
#endif
#if OUTLINE
else
{
out = (PIFOUTLINE)MEMptr(hbm);
size = (SL32)out->size * (SL32)out->depth;
}
#endif
#if COMPRESSED_CACHE
{
HIFBITMAP hcmp;
PIFBITMAP pbuf;
UW16 status;
if(!FC_ISBITMAP(&if_state.pfontCur->fc)) /* only compress bitmaps */
goto cache_it;
/* Make sure current fonts decompression IFBITMAP is at least
* as big as the one we are inserting. If not, reallocate a
* bigger one.
*/
if(if_state.pfontCur->hifbm == NIL_MH)
{
if_state.pfontCur->hifbm = (HIFBITMAP)CHARalloc(FSA (SL32)BMHEADERSIZE+size);
if(if_state.pfontCur->hifbm == NIL_MH)
goto cache_it; /* cache the incomming character as is */
pbuf = if_state.pfontCur->pifbm = (PIFBITMAP)MEMptr(if_state.pfontCur->hifbm);
if_state.pfontCur->size = size;
}
else
pbuf = if_state.pfontCur->pifbm;
if(if_state.pfontCur->size < size)
{
MEMfree(FSA CACHE_POOL,if_state.pfontCur->hifbm); /* free the one we've outgrown */
if_state.pfontCur->hifbm = (HIFBITMAP)CHARalloc(FSA (SL32)BMHEADERSIZE+size);
if(if_state.pfontCur->hifbm == NIL_MH)
goto cache_it; /* cache the incomming character as is */
pbuf = if_state.pfontCur->pifbm = (PIFBITMAP)MEMptr(if_state.pfontCur->hifbm);
if_state.pfontCur->size = size;
}
status = compress_ifbitmap(FSA bm, pbuf, &hcmp);
if(status==SUCCESS)
{
#define TEST_COMPRESSED_CACHE 0 /* set to 1 to test */
#if TEST_COMPRESSED_CACHE
{
UW16 status;
UB8 *p, *q;
SL32 size;
PIFBITMAP pcmp;
pcmp = (PIFBITMAP)MEMptr(hcmp);
status = decompress_ifbitmap(FSA pcmp, if_state.pfontCur->pifbm);
if(status && status != ERRcmpr_notcompressed) /* error */
goto test_bad;
size = (SL32)BMHEADERSIZE + (SL32)bm->width * (SL32)bm->depth;
p = (UB8*)bm;
q = (UB8*)if_state.pfontCur->pifbm;
while(size--)
if(*p++ != *q++)
goto test_good;
test_bad:
printf("Decompressed bitmap differs from compressed bitmap\n");
exit(9);
}
test_good:
#endif
/* Copy the full bitmap into the buffer ifbitmap */
{
UB8 *p, *q;
SL32 size;
size = (SL32)bm->width * (SL32)bm->depth;
*if_state.pfontCur->pifbm = *bm; /* header */
p = (UB8*)&bm->bm[0];
q = (UB8*)&if_state.pfontCur->pifbm->bm[0];
while(size--)
*q++ = *p++;
}
MEMfree(FSA CACHE_POOL, hbm);
hbm = hcmp;
bm = (PIFBITMAP)MEMptr(hbm); /* Recover pointer */
retval = if_state.pfontCur->hifbm;
size = bm->size; /* size of compressed data */
}
/* else we just leave the old memory handle */
}
cache_it:
#endif /* COMPRESSED_CACHE */
/* If memory block is too big to cache, remember it in hBigBM.
* It will be freed on the next call to CHARalloc().
* (If using "cache-by-reference" method, don't treat large bitmaps any differently.)
*/
#if !CACHE_BY_REF
if(size > (SL32)if_state.max_char_size)
if_state.hBigBM = hbm;
#endif /* !CACHE_BY_REF */
/* make least recently used */
bm->notmru = 0; /* Keep CACaccess() from calling me again */
dll_after(FSA if_state.pserver->hBMlru, hbm); /* link at start of IFBITMAP lru list */
/* Remember my new owner so that I can remove all references to
* myself if I have to be reclaimed. Tell new owner there's one more
* of us bitmaps.
*/
bm->index = chId;
bm->hiffont = if_state.hfontCur;
if_state.pfontCur->bitmapCount++;
/* Insert bitmap handle in current FONT table */
/*
* 1/25/94 maib
* new caching scheme for asian encoding
*/
#if USE_ASIAN_CACHE
insert_at_head_of_list(FSA hbm, if_state.pfontCur);
#else
*(if_state.pfontCur->hbuf + chId) = hbm;
#endif /* USE_ASIAN_CACHE */
return retval;
}
/* I F B I T M A P */
/*========================================================================*/
/* F O N T */
/*----------------------*/
/* FNTfree */
/*----------------------*/
/* Free a currently active FONT and associated IFBITMAPs */
#if defined (ANSI_DEFS)
MLOCAL VOID FNTfree(FSP HIFFONT hf)
#else
MLOCAL VOID
FNTfree(hf)
HIFFONT hf; /* Handle of FONT to be freed */
#endif
{
PFONT f; /* Pointer to FONT to be freed */
#if !USE_ASIAN_CACHE
PHIFBITMAP phbm;
#endif
SW16 i;
/* Clear cache state pointers if this is the current font. Leave
* the current FONTCONTEXT
*/
if(hf == if_state.hfontCur)
{
if_state.hfontCur = (HIFFONT)0;
if_state.pfontCur = (PFONT)0;
}
f = (PFONT)MEMptr(hf); /* Recover pointer */
#if ASIAN_ENCODING && ASIAN_HASH_TRACE /* added 8/20/96 dlk */
hash_trace(FSA f);
#endif /* ASIAN_ENCODING && ASIAN_HASH_TRACE */
#if COMPRESSED_CACHE
if(f->hifbm != NIL_MH)
MEMfree(FSA CACHE_POOL, f->hifbm);
#endif
/* Free each IFBITMAP in the font. Bump the font's bitmapCount by 1 so
* that it won't go to 0 when the last bitmap is freed. Otherwise,
* BMfree() will try to free me.
*/
f->bitmapCount++; /* One more than I really have */
/*
* 1/25/94 maib
* new caching scheme for asian encoding
*/
#if USE_ASIAN_CACHE
/*
* just make sure all cached bitmaps are accessed here, the
* actual cleanup, for both the bitmap and hash list item,
* is done within BMfree...
* traverse each row, and each column w/in each row...
*/
{
MEM_HANDLE hItem, cur_hItem;
IFBITMAP *pifb;
for (i = 0; i < HASHMAX; i++)
{
hItem = f->hash_table[i]; /* handle to an IFBITMAP */
while (hItem) /* free bitmaps until NULL handle is reached */
{
/* get the next item in the list before it is freed */
pifb = (PIFBITMAP)MEMptr(hItem);
cur_hItem = hItem;
hItem = pifb->f;
BMfree(FSA cur_hItem);
}
}
}
#else
phbm = f->hbuf; /* start of array of bitmap handles */
for(i = 0; i<SSMAX; i++)
{
if (*phbm) BMfree(FSA *phbm);
phbm++;
}
#endif /* USE_ASIAN_CACHE */
dll_remove(FSA hf); /* Remove FONT from lru list */
MEMfree(FSA CACHE_POOL, hf); /* Free the FONT memory */
}
/*-------------------*/
/* CACfont */
/*-------------------*/
/* Find the active FONT that matches the given FONTCONTEXT. If no
* match, then create a new FONT.
*/
#if defined (ANSI_DEFS)
GLOBAL UW16 CACfont(FSP PFONTCONTEXT fc)
#else
GLOBAL UW16
CACfont(fc)
PFONTCONTEXT fc;
#endif
{
HIFFONT hf;
PFONT f;
HIFBITMAP hbm;
PIFBITMAP bm;
#if UFST_MULTITHREAD
UW16 status;
#endif
#if DISK_FONTS
BOOLEAN has_path;
#if ROM
has_path = FALSE;
#else
has_path = (!FC_ISEXTERN(fc) && !fc->font_id); /* PS, TT disk, IF dynamic */
if (FC_ISFCO(fc))
has_path = FALSE;
#endif /* ROM */
#endif /* DISK_FONTS */
/*
* 10/25/93 maib
* in an attempt to optimize CACfont, do not perform any changes if
* the fontcontext passed is identical to what the cache believes is
* the current font's fontcontext. ie. there is no need to make the
* font the most current if this already is true...
*/
if (if_state.pfontCur &&
!MEMCMP((LPSB8)fc, (LPSB8)&if_state.pfontCur->fc, sizeof(FONTCONTEXT)))
{
#if DISK_FONTS
if (has_path)
{
if (STRNCMP((FILECHAR *)fc->font_hdr, if_state.pfontCur->pathname, PATHNAMELEN) == 0)
#if UFST_MULTITHREAD
{
/* Add this thread to FNT's list of referenced threads */
status = add_thread_id_to_list(FSA if_state.pfontCur->thread_ids);
if (status)
return ERR_max_threads_exceeded;
return SUCCESS;
}
#else
return SUCCESS;
#endif
}
else
#endif /* DISK_FONTS */
#if UFST_MULTITHREAD
{
/* Add this thread to FNT's list of referenced threads */
status = add_thread_id_to_list(FSA if_state.pfontCur->thread_ids);
if (status)
return ERR_max_threads_exceeded;
return SUCCESS;
}
#else
return SUCCESS;
#endif
}
/* Free old FONT if it has no bitmaps */
if(if_state.pfontCur)
if(!if_state.pfontCur->bitmapCount) FNTfree(FSA if_state.hfontCur);
/* Set cache state to no valid FONT in case we fail */
if_state.pfontCur = (PFONT)0;
if_state.hfontCur = (HIFFONT)0;
/* Search active fonts for a match with
* the user's device font context
*/
for(hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->f; hf != if_state.pserver->hFNTlru; hf = f->link.f)
{
f = (PFONT)MEMptr(hf);
if (!MEMCMP((LPSB8)fc, (LPSB8)&f->fc, sizeof(FONTCONTEXT)))
{
#if DISK_FONTS
if (has_path)
{
if(STRNCMP((FILECHAR *)fc->font_hdr, f->pathname, PATHNAMELEN) == 0)
break;
}
else
#endif
break;
}
}
if(hf != if_state.pserver->hFNTlru)
{
/* Make FONT most recently used */
dll_remove(FSA hf);
dll_after(FSA if_state.pserver->hFNTlru, hf);
}
else
{
/* No active FONT matches the app's FONTCONTEXT. Make a new FONT */
SW16 i;
#if !USE_ASIAN_CACHE
PHIFBITMAP phbm;
#endif
/* Allocate a new FONT */
hf = (HIFFONT)CHARalloc(FSA (SL32)sizeof(cacheFONT));
if(!(hf))
return ERR_no_font;
/* Make new FONT most recently used */
dll_after(FSA if_state.pserver->hFNTlru, hf);
/* Initialize font data. */
f = (PFONT)MEMptr(hf); /* Recover pointer */
f->fc = *fc; /* Copy FONTCONTEXT to new FONT */
#if DISK_FONTS
if(has_path)
STRCPY(f->pathname, (FILECHAR *)fc->font_hdr);
#endif
f->bitmapCount = 0; /* No character IFBITMAPs are cached yet */
#if UFST_MULTITHREAD
/* Initialize thread list and add this thread to it. */
MEMSET(f->thread_ids, (UL32)-1L, MAX_THREADS * sizeof(UL32));
#endif
#if COMPRESSED_CACHE
f->hifbm = NIL_MH;
#endif
/*
* 1/25/94 maib
* new caching scheme for asian encoding
*/
#if USE_ASIAN_CACHE
for (i = 0; i < HASHMAX; i++)
{
/*
* each row of array is initially empty
*/
f->hash_table[i] = (MEM_HANDLE)NIL_MH;
}
#else
phbm = f->hbuf; /* point to list of IFBITMAP handles */
for(i=0; i < SSMAX; i++)
*phbm++ = (HIFBITMAP)0L;
#endif /* USE_ASIAN_CACHE */
} /* end make a new FONT */
#if UFST_MULTITHREAD
/* Add this thread to FNT's list of referenced threads */
status = add_thread_id_to_list(FSA f->thread_ids);
#endif
/* Set all IFBITMAPs' notmru flags to 1 indicating that they have not
* been moved to the front of the lru list during calls to CGIFchar() for
* the current FONT. CGIFchar() checks the notmru flag for the IFBITMAP
* it is about to return. If it is 1, then a call is made to BMmru()
* above to move the IFBITMAP to the head of the lru list making it
* "most recently used". At that time the notmru flag is cleared so that
* it will be moved to the head of the list only once during a sequence
* of calls to CGIFchar() for a given FONT. This is to keep CGIFchar()'s
* performance up. All IFBITMAPs that need to have their
* notmru flags set are at the beginning of the lru list.
*/
hbm = ((PDLL)MEMptr(if_state.pserver->hBMlru))->f; /* first IFBITMAP in lru list */
while(hbm != if_state.pserver->hBMlru)
{
bm = (PIFBITMAP)MEMptr(hbm);
if(bm->notmru) break;
bm->notmru = 1;
hbm = bm->link.f; /* next IFBITMAP in the list */
}
/* Set cache state for current font */
if_state.pfontCur = f;
if_state.hfontCur = hf;
return SUCCESS;
}
/*--------------------*/
/* CAChdr_font */
/*--------------------*/
/* Find the active FONT that matches the given FONTCONTEXT. If no
* match, then create a new FONT.
*/
#if defined (ANSI_DEFS)
MLOCAL UW16 CAChdr_font(FSP PFONTCONTEXT fc, UW16 *fonts_purged)
#else
MLOCAL UW16
CAChdr_font(fc, fonts_purged)
UW16 *fonts_purged;
PFONTCONTEXT fc;
#endif
{
HIFFONT hf;
PFONT f;
HIFBITMAP hbm;
PIFBITMAP bm;
#if UFST_MULTITHREAD
UW16 status;
#endif
#if DISK_FONTS
BOOLEAN has_path;
#if ROM
has_path = FALSE;
#else
has_path = (!FC_ISEXTERN(fc) && !fc->font_id); /* PS, TT disk, IF dynamic */
#endif /* ROM */
#endif
/*
* 10/25/93 maib
* in an attempt to optimize CACfont, do not perform any changes if
* the fontcontext's font_hdr passed is identical to what the cache believes is
* the current font's fontcontext's font_hdr. ie. there is no need to make the
* font the most current if this already is true...
*/
if (if_state.pfontCur &&
((LPSB8)fc->font_hdr == (LPSB8)if_state.pfontCur->fc.font_hdr))
{
#if DISK_FONTS
if (has_path)
{
if (STRNCMP((FILECHAR *)fc->font_hdr, if_state.pfontCur->pathname, PATHNAMELEN) == 0)
{
#if UFST_MULTITHREAD
/* Add this thread to FNT's list of referenced threads */
status = add_thread_id_to_list(FSA if_state.pfontCur->thread_ids);
#endif
*fonts_purged = FALSE;
return SUCCESS;
}
}
else
#endif /* DISK_FONTS */
{
#if UFST_MULTITHREAD
/* Add this thread to FNT's list of referenced threads */
status = add_thread_id_to_list(FSA if_state.pfontCur->thread_ids);
#endif
*fonts_purged = FALSE;
return SUCCESS;
}
}
/* Free old FONT if it has no bitmaps */
if(if_state.pfontCur)
if(!if_state.pfontCur->bitmapCount) FNTfree(FSA if_state.hfontCur);
/* Set cache state to no valid FONT in case we fail */
if_state.pfontCur = (PFONT)0;
if_state.hfontCur = (HIFFONT)0;
/* Search active fonts for a match with
* the user's device font context's font_hdr
*/
for(hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->f; hf != if_state.pserver->hFNTlru; hf = f->link.f)
{
f = (PFONT)MEMptr(hf);
if ((LPSB8)fc->font_hdr == (LPSB8)f->fc.font_hdr)
{
#if DISK_FONTS
if (has_path)
{
if(STRNCMP((FILECHAR *)fc->font_hdr, f->pathname, PATHNAMELEN) == 0)
break;
}
else
#endif
break;
}
}
if(hf != if_state.pserver->hFNTlru)
{
/* Make FONT most recently used */
dll_remove(FSA hf);
dll_after(FSA if_state.pserver->hFNTlru, hf);
*fonts_purged = FALSE;
}
else
{
/* No active FONT matches the app's FONTCONTEXT's font_hdr. Make a new FONT */
SW16 i;
#if !USE_ASIAN_CACHE
PHIFBITMAP phbm;
#endif
*fonts_purged = TRUE;
/* Allocate a new FONT */
hf = (HIFFONT)CHARalloc(FSA (SL32)sizeof(cacheFONT));
if(!(hf))
return ERR_no_font;
/* Make new FONT most recently used */
dll_after(FSA if_state.pserver->hFNTlru, hf);
/* Initialize font data. */
f = (PFONT)MEMptr(hf); /* Recover pointer */
f->fc = *fc; /* Copy FONTCONTEXT to new FONT */
#if DISK_FONTS
if(has_path)
STRCPY(f->pathname, (FILECHAR *)fc->font_hdr);
#endif
f->bitmapCount = 0; /* No character IFBITMAPs are cached yet */
#if UFST_MULTITHREAD
/* Initialize thread list and add this thread to it. */
MEMSET(f->thread_ids, (UL32)-1L, MAX_THREADS * sizeof(UL32));
#endif
/*
* 1/25/94 maib
* new caching scheme for asian encoding
*/
#if USE_ASIAN_CACHE
for (i = 0; i < HASHMAX; i++)
{
/*
* each row of array is initially empty
*/
f->hash_table[i] = (MEM_HANDLE)NIL_MH;
}
#else
phbm = f->hbuf; /* point to list of IFBITMAP handles */
for(i=0; i < SSMAX; i++)
*phbm++ = (HIFBITMAP)0L;
#endif /* USE_ASIAN_CACHE */
} /* end make a new FONT */
#if UFST_MULTITHREAD
/* Add this thread to FNT's list of referenced threads */
status = add_thread_id_to_list(FSA f->thread_ids);
#endif
/* Set all IFBITMAPs' notmru flags to 1 indicating that they have not
* been moved to the front of the lru list during calls to CGIFchar() for
* the current FONT. CGIFchar() checks the notmru flag for the IFBITMAP
* it is about to return. If it is 1, then a call is made to BMmru()
* above to move the IFBITMAP to the head of the lru list making it
* "most recently used". At that time the notmru flag is cleared so that
* it will be moved to the head of the list only once during a sequence
* of calls to CGIFchar() for a given FONT. This is to keep CGIFchar()'s
* performance up. All IFBITMAPs that need to have their
* notmru flags set are at the beginning of the lru list.
*/
hbm = ((PDLL)MEMptr(if_state.pserver->hBMlru))->f; /* first IFBITMAP in lru list */
while(hbm != if_state.pserver->hBMlru)
{
bm = (PIFBITMAP)MEMptr(hbm);
if(bm->notmru) break;
bm->notmru = 1;
hbm = bm->link.f; /* next IFBITMAP in the list */
}
/* Set cache state for current font */
if_state.pfontCur = f;
if_state.hfontCur = hf;
return SUCCESS;
}
#if MEM_TRACE
#if defined (ANSI_DEFS)
MLOCAL VOID print_fnt_lru(FSP0)
#else
MLOCAL VOID
print_fnt_lru()
#endif
{
HIFFONT hf;
PFONT f;
/* Search active fonts and print
*/
for(hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->f; hf != if_state.pserver->hFNTlru; hf = f->link.f)
{
f = (PFONT)MEMptr(hf);
DBG3("%ld: %d %d\n", f->fc.font_id,f->fc.point_size, f->bitmapCount);
DBG3("%ld: %d %d\n", f->fc.font_id,f->fc.s.m1.em_depth, f->bitmapCount);
}
}
#endif
/*----------------------*/
/* CACinit */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 CACinit(FSP0)
#else
GLOBAL UW16
CACinit()
#endif
{
if(!(if_state.CGIFinitstate & not_cac))
return ERR_CACinit; /* already initialized */
/* Set cache state to no valid FONT */
if_state.pfontCur = (PFONT)0;
if_state.hfontCur = (HIFFONT)0;
#if TILE
if_state.htileBM = NIL_MH; /* Handle of last made tile part */
#endif
/* Get doubly linked list headers. These must be handles */
/* 06-28-04 jfd Only have to initialize the IFBITMAP lru once */
if (if_state.pserver->MTinitstate & not_BMlru)
{
if_state.pserver->hBMlru = MEMalloc(FSA CACHE_POOL, (SL32)sizeof(DLL));
if(!(if_state.pserver->hBMlru))
return ERR_CACinit;
dll_null(FSA if_state.pserver->hBMlru); /* Set IFBITMAP lru to empty. */
if_state.pserver->MTinitstate &= ~not_BMlru;
}
/* 06-28-04 jfd Only have to initialize the FONT lru once */
if (if_state.pserver->MTinitstate & not_FNTlru)
{
if_state.pserver->hFNTlru = MEMalloc(FSA CACHE_POOL, (SL32)sizeof(DLL));
if(!(if_state.pserver->hFNTlru))
{
MEMfree(FSA CACHE_POOL, if_state.pserver->hBMlru);
return ERR_CACinit;
}
dll_null(FSA if_state.pserver->hFNTlru); /* Set FONT lru list to empty. */
if_state.pserver->MTinitstate &= ~not_FNTlru;
}
if_state.hBigBM = (HIFBITMAP)0L; /* No big character yet */
if_state.CGIFinitstate &= ~not_cac; /* turn off not initialized bit */
return SUCCESS;
}
/*----------------------*/
/* CACexit */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID CACexit(FSP0)
#else
GLOBAL VOID
CACexit()
#endif
{
DBG("\n\nCACexit()\n");
if(if_state.CGIFinitstate & not_cac) return; /* cache not initialized */
if (if_state.pserver->MTinitstate & not_FNTlru) return; /* FNT lru list not initialized */
if (if_state.pserver->MTinitstate & not_BMlru) return; /* BM lru list not initialized */
{
#if UFST_MULTITHREAD
PFONT f;
HIFFONT hf;
HIFFONT next_hf;
UL32 thread_id;
thread_id = get_thread_id(FSA0);
hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->b;
while(hf != if_state.pserver->hFNTlru)
{
f = (PFONT)MEMptr(hf);
next_hf = f->link.b;
if (only_thread_in_list(FSA f->thread_ids, thread_id))
FNTfree(FSA hf);
hf = next_hf;
}
#else
/* Free all FONTs */
while(!dll_empty(FSA if_state.pserver->hFNTlru))
FNTfree(FSA ((PDLL)MEMptr(if_state.pserver->hFNTlru))->b);
#endif
#if UFST_MULTITHREAD
if (!if_state.pserver->client_count)
{
#endif
/* free list headers */
MEMfree(FSA CACHE_POOL, if_state.pserver->hFNTlru);
MEMfree(FSA CACHE_POOL, if_state.pserver->hBMlru);
if_state.pserver->MTinitstate |= not_FNTlru; /* set not initialized bit */
if_state.pserver->MTinitstate |= not_BMlru; /* set not initialized bit */
#if UFST_MULTITHREAD
}
#endif
}
#if TILE
if(if_state.htileBM)
{
#if IFBITSPLIT
IFBITMAP *pbm;
pbm = (IFBITMAP *)MEMptr(if_state.htileBM);
MEMfree(FSA CACHE_POOL, pbm->datahandle); /* Free the IFBITMAP memory */
#endif
MEMfree(FSA CACHE_POOL, if_state.htileBM);
if_state.htileBM = NIL_MH;
}
#endif
if_state.CGIFinitstate |= not_cac; /* set not initialized bit */
#if MEM_TRACE
MEMstat(FSA CACHE_POOL);
#endif
}
/*------------------*/
/* CACpurge */
/*------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 CACpurge(FSP PFONTCONTEXT fc)
#else
GLOBAL UW16
CACpurge(fc)
PFONTCONTEXT fc;
#endif
{
#if UFST_MULTITHREAD
PFONT f;
#endif
UW16 status;
status = CACfont(FSA fc);
if (status)
return status;
#if UFST_MULTITHREAD
f = (PFONT)MEMptr(if_state.hfontCur);
status = remove_thread_id_from_list(FSA f->thread_ids);
if (thread_list_is_empty(FSA f->thread_ids))
#endif
FNTfree(FSA if_state.hfontCur);
return SUCCESS;
}
/*-----------------------*/
/* CACfont_free */
/*-----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 CACfont_free(FSP HIFFONT hf)
#else
GLOBAL UW16
CACfont_free(hf)
HIFFONT hf;
#endif
{
#if UFST_MULTITHREAD
PFONT f;
UW16 status;
f = (PFONT)MEMptr(hf);
status = remove_thread_id_from_list(FSA f->thread_ids);
if (thread_list_is_empty(FSA f->thread_ids))
#endif
FNTfree(FSA hf);
return SUCCESS;
}
/*-----------------------*/
/* CAChdr_purge */
/*-----------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 CAChdr_purge(FSP PFONTCONTEXT fc)
#else
GLOBAL UW16
CAChdr_purge(fc)
PFONTCONTEXT fc;
#endif
{
UW16 status;
UW16 similar_fonts_purged;
#if UFST_MULTITHREAD
PFONT f;
#endif
similar_fonts_purged = FALSE;
while (!similar_fonts_purged)
{
status = CAChdr_font(FSA fc, &similar_fonts_purged);
if (status)
return status;
#if UFST_MULTITHREAD
f = (PFONT)MEMptr(if_state.hfontCur);
status = remove_thread_id_from_list(FSA f->thread_ids);
if (thread_list_is_empty(FSA f->thread_ids))
#endif
FNTfree(FSA if_state.hfontCur);
}
return SUCCESS;
}
/*------------------------------------------------------------------*/
/* C a c h e M e m o r y M a n a g e m e n t */
#if DEFUND
/* If DEFUND is enabled, we may get called via the CGIFdefund()
* function to relinquish all use of a particlular ufst memory
* page. CACdefund() is called in this case. If the linked list
* headers need to be freed, we just call CACexit() to clear out the
* whole cache and return TRUE so that CGIFdefund() will call CACinit()
* once it has disposed of the page.
*/
/*----------------*/
/* purge_page */
/*----------------*/
/* Search all entries in the least recently used list whose handle is
* "lru". If any entry has been allocated from the memory block "page",
* then free it using the function "free".
*/
#if defined (ANSI_DEFS)
MLOCAL VOID purge_page (FSP UW16 page, MEM_HANDLE lru, VOID (*free)(FSP MEM_HANDLE))
#else
MLOCAL VOID
purge_page(page, lru, free)
UW16 page;
MEM_HANDLE lru; /* handle of lru list */
#ifdef LINT_ARGS
VOID (*free)(MEM_HANDLE);
#else
VOID (*free)(); /* function that frees members of lru list */
#endif
#endif /* (ANSI_DEFS) */
{
MEM_HANDLE hp, hnext;
hp = ((PDLL)MEMptr(lru))->f;
while(hp != lru)
{
hnext = ((PDLL)MEMptr(hp))->f;
if(PAGE(hp) == page)
(*free)(FSA hp);
hp = hnext;
}
}
/*----------------------*/
/* CACdefund */
/*----------------------*/
/* Free all BITMAPs and FONTs that are part of memory page "page". */
#if defined (ANSI_DEFS)
GLOBAL BOOLEAN CACdefund (FSP UW16 page)
#else
GLOBAL BOOLEAN
CACdefund(page)
UW16 page;
#endif
{
#if UFST_MULTITHREAD
if (if_state.pserver->client_count > 1) /* 10-25-04 jfd - was 0 */
return FALSE;
#endif
purge_page(FSA page, if_state.pserver->hFNTlru, FNTfree); /* Free FONTs using this page */
purge_page(FSA page, if_state.pserver->hBMlru, BMfree); /* Free BITMAPs using this page */
if((PAGE(if_state.pserver->hFNTlru) == page) || (PAGE(if_state.pserver->hBMlru) == page))
{
CACexit(FSA0);
return TRUE;
}
else
return FALSE;
}
#endif /* DEFUND */
/*----------------------*/
/* CHARalloc */
/*----------------------*/
/* Acquire cache memory, freeing character bitmaps if need be.
* Return a handle to the memory.
*/
#if defined (ANSI_DEFS)
GLOBAL MEM_HANDLE CHARalloc (FSP SL32 size)
#else
GLOBAL MEM_HANDLE
CHARalloc(size)
SL32 size;
#endif
{
MEM_HANDLE h;
/* AJ - memory fund check*/
if (size > if_state.pserver->mem_fund[CACHE_POOL])
return NIL_MH;
/* Free up big character IFBITMAP if any */
if (if_state.hBigBM)
BMfree(FSA if_state.hBigBM);
#if TILE
if(if_state.htileBM)
{
#if IFBITSPLIT
IFBITMAP *pbm;
pbm = (IFBITMAP *)MEMptr(if_state.htileBM);
MEMfree(FSA CACHE_POOL, pbm->datahandle); /* Free the IFBITMAP memory */
#endif
MEMfree(FSA CACHE_POOL, if_state.htileBM);
if_state.htileBM = NIL_MH;
}
#endif
while( (h = MEMalloc(FSA CACHE_POOL, (SL32)size)) == NIL_MH )
{
#if MEM_TRACE
MEMstat(FSA CACHE_POOL);
#endif
if(dll_empty(FSA if_state.pserver->hBMlru))
{
#if MEM_TRACE
print_fnt_lru(FSA0);
#endif
return (MEM_HANDLE)0;
}
else
{
#if CACHE_BY_REF
/* If using "cache-by-reference" method, loop through unreferenced characters
* to reacquire cache memory and try again.
*/
HIFBITMAP hbm;
PIFBITMAP bm;
/* Loop thru the LRU list (starting at the end with the LRU
* character) and free unreferenced characters.
*/
hbm = ((PDLL)MEMptr(if_state.pserver->hBMlru))->b;
while(hbm != if_state.pserver->hBMlru)
{
bm = (PIFBITMAP)MEMptr(hbm);
if (bm->ref_counter == 0)
{
BMfree(FSA hbm);
break;
}
hbm = bm->link.b;
}
if (hbm == if_state.pserver->hBMlru)
break;
#else
BMfree(FSA ((PDLL)MEMptr(if_state.pserver->hBMlru))->b ); /* free lru IFBITMAP */
#endif /* CACHE_BY_REF */
}
}
return h;
}
#if MEM_TRACE
#if defined (ANSI_DEFS)
GLOBAL SL32 CACdump (FSP UW16 print)
#else
GLOBAL SL32
CACdump(print)
UW16 print;
#endif
{
HIFFONT hf;
PFONT f;
HIFBITMAP hbm;
PIFBITMAP bm;
SL32 size;
SL32 total = 0L;
SL32 bmTotal = 0L;
SL32 ftTotal = 0L;
if(print) DBG("FONTS\n");
for(hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->f; hf != if_state.pserver->hFNTlru; hf = f->link.f)
{
f = (PFONT)MEMptr(hf);
size = *((LPSL32)((LPSB8)f - 4));
total += size;
ftTotal += size;
if(print) DBG4("Handle %6lx Pointer %Fp Bitmapcount %3d Size %5ld\n",
hf, f, f->bitmapCount, size);
}
if(print)// DBG1("FONT totals = %ld\n", ftTotal);
{
sprintf(cTempBuffer,"FONT totals = %ld\n", ftTotal);
Send_String(cTempBuffer);
}
if(print)DBG("BITMAPS\n");
hbm = ((PDLL)MEMptr(if_state.pserver->hBMlru))->f; /* first IFBITMAP in lru list */
while(hbm != if_state.pserver->hBMlru)
{
bm = (PIFBITMAP)MEMptr(hbm);
size = *((LPSL32)((LPSB8)bm - 4));
total += size;
bmTotal += size;
if(print) DBG4("Handle %6lx Pointer %Fp size %5ld charcode %ld\n",
hbm, bm, size, bm->index);
hbm = bm->link.f; /* next IFBITMAP in the list */
}
if(print) DBG1("BITMAP totals %ld\n", bmTotal);
return total;
}
#endif /* MEM_TRACE */
#if ASIAN_ENCODING && ASIAN_HASH_TRACE /* added 8/20/96 dlk */
/******************************/
/* HASH_TRACE */
/******************************/
#if defined (ANSI_DEFS)
GLOBAL VOID hash_trace(FSP PFONT pf)
#else
GLOBAL VOID
hash_trace(pf)
PFONT pf;
#endif /* ANSI_DEFS */
{
SL32 i; /* loop index to rows */
SL32 j; /* loop counter */
SL32 atemp;
SL32 xCount; /* scaled down count of '*' to print */
SL32 totalItemCount;
SL32 r; /* rows per output page */
SL32 pageNumber; /* printed page number counter */
SL32 hItemCount[HASHMAX]; /* holds number of cached bitmaps per row */
SL32 row;
MEM_HANDLE hItem;
PIFBITMAP pifb;
totalItemCount = 0;
r = 86; /* set this to the number of rows to print on each page */
for(row = 0; row < HASHMAX; row++)
{
hItemCount[row] = 0;
hItem = pf->hash_table[row];
while(hItem != NIL_MH)
{
#if CACHE_BY_REF
pifb = (PIFBITMAP)MEMptr(hItem);
hItemCount[row] += pifb->ref_counter;
#else
hItemCount[row]++;
pifb = (PIFBITMAP)MEMptr(hItem);
#endif /* CACHE_BY_REF */
hItem = pifb->f;
} /* end of while to count hash items in this row */
totalItemCount = totalItemCount + hItemCount[row];
} /* end of checking all rows */
pageNumber = 0;
for(i = 0; i < HASHMAX; i++)
{
if((i == 0)|(i == r)|(i == 2*r)|(i == 3*r)|(i == 4*r)|(i == 5*r)|(i == 6*r))
{
pageNumber++;
printf("\f"); /* start a new page of output */
printf("\n ASIAN_ENCODING: HASH TABLE -- Utilization / Distribution Chart (PAGE: %d)", pageNumber);
#if DISK_FONTS
printf(" font %s", pf->pathname);
#endif
printf("\n | Item | 100 200 300 400 500 600 700 800 900 1000|");
printf("\n Row | Count | | | | | | | | | | | | | | | | | | | | | |");
printf("\n=====|=======|=========|=========|=========|=========|=========|=========|=========|=========|=========|=========|=|");
} /* end of new page header */
xCount = hItemCount[i];
atemp = xCount % 10;
xCount = xCount / 10;
if(atemp) xCount++;
if((hItemCount[i] / 10) > 100) xCount = 101;
printf("\n %4d|%7d|", i, hItemCount[i]);
for(j = 1; j <= xCount; j++) printf("X");
for(j = 1; j <= (101 - xCount); j++) printf(".");
printf("|");
if((i == (r-1))|(i == ((2*r)-1))|(i == ((3*r)-1))|(i == ((4*r)-1))|(i == ((5*r)-1))|(i == ((6*r)-1)))
{
printf("\n=====|=======|=========|=========|=========|=========|=========|=========|=========|=========|=========|=========|=|");
} /* end of page footer */
} /* end of rows to print */
printf("\n=====|=======|=========|=========|=========|=========|=========|=========|=========|=========|=========|=========|=|");
printf("\n");
printf("\n*** END OF CHART *** Total Count Of Cached Items = %d", totalItemCount);
} /* end of hash_trace() */
#endif /* ASIAN_ENCODING && ASIAN_HASH_TRACE */ /* added 8/20/96 dlk */
#if CACHE_BY_REF
/* New "cache-by-reference" freeing method */
/*-----------------------*/
/* CGIFFfree_by_ref */
/*-----------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfree_by_ref (FSP PIFBITMAP pifb)
#else
UW16 CGENTRY
CGIFFfree_by_ref(pifb)
PIFBITMAP pifb;
#endif
{
HIFFONT hf;
PFONT f;
MEM_HANDLE hItem;
UL32 chId;
HIFFONT uhf;
uhf = pifb->hiffont;
chId = pifb->index;
/* Search every cached font for font containing character to free */
for (hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->f, f = (PFONT)MEMptr(hf);
hf != if_state.pserver->hFNTlru && hf != uhf;
hf = f->link.f)
{
f = (PFONT)MEMptr(hf);
}
if (hf == if_state.pserver->hFNTlru)
return ERR_char_not_cached; /* font containing character to free is not cached */
/* Found font. Search font for character to free */
f = (PFONT)MEMptr(hf);
#if USE_ASIAN_CACHE
hItem = CACbmLookup(FSA f, chId);
#else
hItem = *(f->hbuf + chId);
#endif
/* If character exists in cache, decrement reference count. */
if (hItem)
{
PIFBITMAP pb;
pb = (PIFBITMAP)MEMptr(hItem);
if (pb->ref_counter)
pb->ref_counter--;
else
return ERR_char_not_cached;
/* If no more references exist for character ... */
if (!pb->ref_counter)
{
SL32 size = 0;
/* If character should not have been cached due to its large size, free it */
if (FC_ISBITMAP(&f->fc))
size = (SL32)pb->width * (SL32)pb->depth;
#if GRAYSCALING
else if (FC_ISGRAY(&f->fc))
size = pb->size;
#endif
#if OUTLINE
else
{
PIFOUTLINE pout;
pout = (PIFOUTLINE)pifb;
size = (SL32)pout->size * (SL32)pout->depth;
}
#endif
if (size > (SL32)if_state.max_char_size)
BMfree(FSA hItem);
}
}
return SUCCESS;
}
#endif /* CACHE_BY_REF */
#else /* not CACHE */
#if defined (ANSI_DEFS)
GLOBAL MEM_HANDLE CHARalloc (FSP SL32 size)
#else
GLOBAL MEM_HANDLE
CHARalloc(size)
SL32 size;
#endif
{
return ( MEMalloc(FSA CACHE_POOL, (size)) );
}
#endif /* CACHE */
/* (used by both CACHE and non-CACHE cases) */
/*----------------------*/
/* CHARfree */
/*----------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID CHARfree (FSP MEM_HANDLE h)
#else
GLOBAL VOID
CHARfree(h)
MEM_HANDLE h;
#endif
{
MEMfree(FSA CACHE_POOL, h);
}
/* allocate / free from new memory pool (for per-char temporary data) */
#if defined (ANSI_DEFS)
GLOBAL MEM_HANDLE TEMPCHARalloc (FSP SL32 size)
#else
GLOBAL MEM_HANDLE
TEMPCHARalloc(size)
SL32 size;
#endif
{
/* AJ memory fund check */
if (size <= if_state.pserver->mem_fund[CHARGEN_POOL])
return ( MEMalloc(FSA CHARGEN_POOL, (size)) );
else
return NIL_MH;
}
#if defined (ANSI_DEFS)
GLOBAL VOID TEMPCHARfree (FSP MEM_HANDLE h)
#else
GLOBAL VOID
TEMPCHARfree(h)
MEM_HANDLE h;
#endif
{
MEMfree(FSA CHARGEN_POOL, h);
}
canon.txt ///
/*
* Copyright (C) 2005 Monotype Imaging Inc. All rights reserved.
*/
/* $Header: I:/BULL/URIP/RTS/RAC/CANON.C_V 1.11 Dec 13 2004 15:53:42 galejss $ */
/* $Log: I:/BULL/URIP/RTS/RAC/CANON.C_V $
*
* Rev 1.11 Dec 13 2004 15:53:42 galejss
* make all DBG calls 16-bit-compatible
*
* Rev 1.10 Jun 04 2004 17:22:48 GalejsS
* fix 3 compile warnings (signed-unsigned assignment mismatches)
*
* Rev 1.9 Aug 22 2003 09:22:06 LynchR
* Updated copyright notice.
*
* Rev 1.8 Aug 13 2003 15:46:02 LynchR
* Added error checking for memory allocations.
*
* Rev 1.7 Jul 21 2003 17:40:50 Galejs
* reentrancy / debug fixes
*
* Rev 1.6 Jun 20 2003 15:02:58 Galejs
* get rid of asserts; debug cleanup; VOID
*
* Rev 1.5 Jan 03 2003 13:58:10 Galejs
* fixes for tiny ACT-compressed files (for awr)
*
* Rev 1.4 Jun 12 2001 16:39:10 Galejs
* use UFST types rather than SHORT, CHAR, etc
*
* Rev 1.3 May 03 2001 20:47:12 Galejs
* data-type cleanup
*
* Rev 1.2 Jan 15 2001 09:41:34 Song
* changed DEBUG to AGFADEBUG, uppercae to lowercase for #include files
*
* Rev 1.1 Oct 20 2000 10:56:44 Galejs
* return ERR_bad_ACT_version if old ACT format opened
*
* Rev 1.0 Oct 20 2000 08:35:40 Pvcsadmn
* Original (by awr)
*
*/
#include "cgconfig.h"
#if TT_ROM_ACT /* conditional compile entire module */
#include "ufstport.h"
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* memcpy */
#include "shareinc.h"
#include "dbg_ufst.h"
#include "ra_mem.h"
#include "bitio.h"
#include "radecomp.h" /* BYTE_CACHE_INTERVAL */
static SL32 get_next_token(FSP ACT_RA_DECOMP *r);
#ifdef AGFADEBUG
/****************************************************************/
/* print a number in binary ... a printf("%b") ... */
#if defined (ANSI_DEFS)
VOID print_code(UL32 code, SL32 len)
#else
VOID print_code(code, len)
UL32 code;
SL32 len;
#endif
{
UL32 m;
if (len)
{
m = 1 << (len-1);
while (m)
{
putchar( (code & m) ? '1' : '0');
m >>= 1;
}
putchar(' ');
}
}
#endif
/****************************************************************/
/****************************************************************/
/* given a RAC3 file in memory, readin all the necessary glop
* to facilitate decoding a file
*
* code assumes that a UB8 pointer can be any address
* if NOT, you will need to allocate and readin the BYTES
* Also you'll need to free them in MTX_RA_DECOMP_Destroy
*
* NB: this handles BOTH inferred and explicit offsets
* even though <write_canonical_header> can only do inferred
* offsets at this time.
*/
#if defined (ANSI_DEFS)
ACT_RA_DECOMP *ACT_RA_DECOMP_Create(FSP ACT_MemHandler *mem, UB8 *data )
#else
ACT_RA_DECOMP *ACT_RA_DECOMP_Create(mem, data )
ACT_MemHandler *mem;
UB8 *data;
#endif
{
BITIO *bio;
ACT_RA_DECOMP *r;
SL32 offset_length; /* length in bytes of each offset entry. 0 => inferred offsets */
SL32 *p,i,n,offset,crumbs;
SL32 fsize = 0; /*** bytes in the compressed file ... ***/
DBG("***** reading *****\n");
/* verify 'RAC3' signature */
if (data[0] != 'R' || data[1] != 'A' || data[2] != 'C' || data[3] != 3)
{
DBG("*** not a RAC3 data image ***\n");
mem->err = ERR_bad_ACT_version;
return 0;
}
/* get compressed file size */
fsize = data[4];
fsize = (fsize << 8) | data[5];
fsize = (fsize << 8) | data[6];
fsize = (fsize << 8) | data[7];
r = (ACT_RA_DECOMP*) ACT_mem_malloc(FSA mem, sizeof(ACT_RA_DECOMP));
if( !r ) /* Added error handler */ /* rjl 8/4/2003 - */
return 0;
r->mem = mem;
/* create BITIO and skip signature and compressed file size */
bio = MTX_BITIO_Create(FSA mem, data, fsize);
if( !bio ) /* Added error handler */ /* rjl 8/4/2003 - */
goto error;
MTX_BITIO_fseek(bio,8<<3);
r->bio = bio;
/* Initialize the Huffman code lookup table */
for (i=0; i<TABLE_SIZE; i++)
r->token_bits_table[i] = 0; /* means no entry for code i */
r->token_num_table[0] = -1; /* means table not built */
/* read uncompressed file size */
r->unCompressedByteCount = MTX_BITIO_Read32(bio);
/* read number of tokens */
r->num_tokens = MTX_BITIO_Read32(bio);
/* establish pointer to lengths[] -- and skip the data */
offset = MTX_BITIO_ftell(bio);
r->lengths = data + (offset >> 3);
offset += (r->num_tokens << 3);
MTX_BITIO_fseek(bio,offset);
/* read in the offset_length */
offset_length = MTX_BITIO_Read8(bio);
/* allocate and calculate or read the offsets */
n = r->num_tokens;
p = r->offsets = (SL32 *)ACT_mem_malloc(FSA mem, n * 4);
if( !p ) /* Added error handler */ /* rjl 8/4/2003 - */
goto error;
if (offset_length == 0)
{
/* infer the offsets of the non_overlapping token strings from their lengths */
p[0] = 0;
for (i=1; i<r->num_tokens; i++)
p[i] = p[i-1] + r->lengths[i-1];
}
else
{
/* read in the offsets of the overlapping token strings */
offset_length <<= 3;
for (i=0; i<r->num_tokens; i++)
p[i] = MTX_BITIO_ReadValue(r->bio,offset_length);
}
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
DBG("offsets\n");
for (i=0; i<r->num_tokens; i++)
DBG2("%ld: %ld\n",i,r->offsets[i]);
}
#endif /* AGFADEBUG */
/* read total string data length */
n = r->string_len = MTX_BITIO_Read32(bio);
DBG1("r->string_len=%ld\n",r->string_len);
/* establish pointer to string[] -- and skip the data */
offset = MTX_BITIO_ftell(bio);
r->string = data + (offset >> 3);
offset += (r->string_len<<3);
MTX_BITIO_fseek(bio,offset);
/* read number of canonical huffman code groups */
r->num_groups = MTX_BITIO_Read8(bio);
DBG1("r->num_groups=%ld\n",r->num_groups);
/* establish pointer to bits[] -- and skip the data */
offset = MTX_BITIO_ftell(bio);
r->bits = data + (offset>>3);
offset += (r->num_groups<<3);
MTX_BITIO_fseek(bio,offset);
/* allocate and read in firsts[] */
n = r->num_groups;
r->firsts = (UL32 *)ACT_mem_malloc(FSA mem, n * 4);
p = (SL32 *)r->firsts;
if( !p ) /* Added error handler */ /* rjl 8/4/2003 - */
goto error;
while (n--)
*p++ = MTX_BITIO_Read32(bio);
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
SL32 i;
DBG("firsts[] = ");
for (i=0; i<r->num_groups; i++)
print_code(r->firsts[i], r->bits[i]);
DBG("\n");
}
#endif /* AGFADEBUG */
/* allocate and read in lasts[] */
n = r->num_groups;
r->lasts = (UL32 *)ACT_mem_malloc(FSA mem, n * 4);
p = (SL32 *)r->lasts;
if( !p ) /* Added error handler */ /* rjl 8/4/2003 - */
goto error;
while (n--)
*p++ = MTX_BITIO_Read32(bio);
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
SL32 i;
DBG("lasts[] = ");
for (i=0; i<r->num_groups; i++)
print_code(r->lasts[i], r->bits[i]);
DBG("\n");
}
#endif /* AGFADEBUG */
/* calculate next_mask to keep rightmost MAX bits */
if(r->bits[r->num_groups-1] == 32)
r->next_mask = 0xFFFFFFFF;
else
r->next_mask = (1 << r->bits[r->num_groups-1]) - 1;
/* allocate and calculate tokens[] */
n = r->num_groups;
p = r->tokens = (SL32 *)ACT_mem_malloc(FSA mem, n * 4);
if( !p ) /* Added error handler */ /* rjl 8/4/2003 - */
goto error;
p[0] = 0;
for (i=1; i<n; i++)
p[i] = p[i-1] + 1 + (r->lasts[i-1] - r->firsts[i-1]);
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
SL32 i;
DBG("tokens[] = ");
for (i=0; i<r->num_groups; i++)
DBG1("%ld ",r->tokens[i]);
DBG("\n");
}
#endif /* AGFADEBUG */
/* read crumbs (size of bitMarks and deltaBytes arrays) */
crumbs = MTX_BITIO_Read32(bio);
/* bitMarks[] */
r->bitMarks = &bio->array[bio->index>>3]; /* point at the ROM, we'll decode the LONGs on the fly */
bio->index += 32*crumbs;
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
SL32 i;
DBG("bitMarks[] =");
for (i=0; i<crumbs; i++)
{
UL32 bitMark;
UB8 *p = &r->bitMarks[4*i];
bitMark = *p++;
bitMark = (bitMark<<8) | *p++;
bitMark = (bitMark<<8) | *p++;
bitMark = (bitMark<<8) | *p++;
DBG1("%ld ",bitMark);
}
DBG("\n");
}
#endif /* AGFADEBUG */
/* establish pointer to deltaBytes[] */
n = crumbs;
offset = MTX_BITIO_ftell(bio);
r->deltaBytes = data + (offset>>3);
offset += n<<3;
MTX_BITIO_fseek(bio,offset);
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
SL32 i;
DBG("deltaBytes[] =");
for (i=0; i<crumbs; i++)
DBG1("%d ",r->deltaBytes[i]);
DBG("\n");
}
#endif /* AGFADEBUG */
/* read token_offset */
r->token_offset = MTX_BITIO_Read32(bio);
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
DBG1("token_offset = %ld\n",r->token_offset);
fflush(stdout);
}
#endif /* AGFADEBUG */
MTX_TTC_InitCoordEncoding();
return r;
error:
ACT_RA_DECOMP_Destroy(FSA r );
return 0;
}
/****************************************************************/
#if defined (ANSI_DEFS)
VOID ACT_RA_DECOMP_Destroy(FSP ACT_RA_DECOMP *t)
#else
VOID ACT_RA_DECOMP_Destroy(t)
ACT_RA_DECOMP *t;
#endif
{
ACT_mem_free(FSA t->mem,t->firsts);
ACT_mem_free(FSA t->mem,t->lasts);
ACT_mem_free(FSA t->mem,t->tokens);
ACT_mem_free(FSA t->mem,t->offsets);
MTX_BITIO_Destroy(FSA t->bio );
ACT_mem_free(FSA t->mem, t );
}
/****************************************************************/
/* from current position (assuming someone else has done the
* MTX_BITIO_fseek() and read in <next>) get the next token
* number and refresh <next>.
*/
/****************************************************************/
#ifdef AGFADEBUG
/* build the table by decoding codes */
#if defined (ANSI_DEFS)
static old_build_token_table(FSP ACT_RA_DECOMP *r)
#else
static old_build_token_table(r)
ACT_RA_DECOMP *r;
#endif
{
SL32 lo,hi,mid;
UL32 first;
UL32 last;
UL32 next;
SL32 drop;
SL32 i,token_num;
UB8 n;
UB8 max = TABLE_BITS;
for (i=0; i<TABLE_SIZE; i++)
{
/* binary search for <i> in first/last */
lo = 0;
hi = r->num_groups-1;
while (lo <= hi)
{
mid = (lo + hi)/2;
n = r->bits[mid];
drop = max - n;
next = i >> drop;
first = r->firsts[mid];
last = r->lasts[mid];
if (next < first)
hi = mid-1;
else if (next > last)
lo = mid+1;
else
{
token_num = r->tokens[mid] + (next - first);
r->token_num_table[i] = token_num;
r->token_bits_table[i] = n;
break;
}
}
}
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
DBG("code bits token_num\n");
for (i=0; i<TABLE_SIZE; i++)
{
print_code(i,TABLE_BITS);
DBG2("%4d %9ld\n",r->token_bits_table[i],r->token_num_table[i]);
}
fflush(stdout);
}
#endif
}
#endif /* AGFADEBUG */
/****************************************************************/
/* here is the faster one ... always the same (I think) */
#if defined (ANSI_DEFS)
static build_token_table(FSP ACT_RA_DECOMP *r)
#else
static build_token_table(r)
ACT_RA_DECOMP *r;
#endif
{
SL32 i,j,k,bits,count,num,token,index;
#ifdef AGFADEBUG
/* do it the old fashioned way */
old_build_token_table(FSA r);
DBG("*** checking for errors in (fast) build_token_table()\n");
#endif /* AGFADEBUG */
for (i=0,index=0; (index < TABLE_SIZE) && (i < r->num_groups) && (r->bits[i] <= TABLE_BITS); i++)
{
bits = r->bits[i];
count = 1 << (TABLE_BITS - bits);
num = 1 + r->lasts[i] - r->firsts[i];
token = r->tokens[i];
for (j=0,token=r->tokens[i]; (index < TABLE_SIZE) && (j<num); j++,token++)
{
for (k=0; (index < TABLE_SIZE) && (k < count); k++)
{
#ifdef AGFADEBUG
/* and compare with the fast way */
if (r->token_num_table[index] != token)
DBG2("*** token_num_table[%ld] != %ld\n",index,token);
if (r->token_bits_table[index] != bits)
DBG2("*** token_bits_table[%ld] != %ld\n",index,bits);
#endif /* AGFADEBUG */
r->token_num_table[index] = token;
r->token_bits_table[index] = (UB8)bits;
index++;
}
}
}
r->slowGroup = i; /* first group not completely contained in the table */
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
{
DBG("code bits token_num\n");
for (i=0; i<TABLE_SIZE; i++)
{
print_code(i,TABLE_BITS);
DBG2("%4d %9ld\n",r->token_bits_table[i],r->token_num_table[i]);
}
fflush(stdout);
}
#endif /* AGFADEBUG */
}
/****************************************************************/
#define NEXT_MASK (1<<TABLE_BITS)-1
#if defined (ANSI_DEFS)
static SL32 get_next_token(FSP ACT_RA_DECOMP *r)
#else
static SL32 get_next_token(r)
ACT_RA_DECOMP *r;
#endif
{
SL32 lo,hi,mid;
UL32 first;
UL32 last;
UL32 next;
UL32 rest;
SL32 bitsNeeded;
SL32 drop;
SL32 token_num;
UB8 n;
UB8 max;
/* do we need to build the token table ? */
if (r->token_num_table[0] < 0)
build_token_table(FSA r);
next = r->next;
/* ? possible && legitimate entry in the table */
if (r->token_bits_table[next])
{
n = r->token_bits_table[next];
token_num = r->token_num_table[next];
next <<= n;
next |= MTX_BITIO_ReadValue(r->bio,n);
next &= NEXT_MASK;
r->next = next;
return token_num;
}
else
{
/* not in table ... binary search the longer length groups */
max = r->bits[r->num_groups-1];
bitsNeeded = max - TABLE_BITS;
if (bitsNeeded > 0)
r->next = (next << bitsNeeded) | MTX_BITIO_ReadValue(r->bio, bitsNeeded);
else if (bitsNeeded < 0)
{
r->next >>= -bitsNeeded;
r->bio->index += bitsNeeded;
}
lo = r->slowGroup;
hi = r->num_groups-1;
while (lo <= hi)
{
mid = (lo + hi)/2;
n = r->bits[mid];
drop = max - n;
next = r->next >> drop;
first = r->firsts[mid];
last = r->lasts[mid];
if (next < first)
hi = mid-1;
else if (next > last)
lo = mid+1;
else
{
token_num = r->tokens[mid] + (next - first);
bitsNeeded = TABLE_BITS - max + n; /* to get TABLE_BITS bits into next */
if(bitsNeeded > 0)
{
r->next <<= bitsNeeded;
rest = MTX_BITIO_ReadValue(r->bio,bitsNeeded);
r->next |= rest;
}
else if(bitsNeeded<0)
{
r->next >>= -bitsNeeded;
r->bio->index += bitsNeeded ;
}
r->next &= NEXT_MASK;
return token_num;
}
}
/* This can't happen, we got a bad token number */
return 0; /* to keep the compiler happy */
}
}
/****************************************************************/
/* return the next token's string pointer and set its length */
#if defined (ANSI_DEFS)
SB8 *ReadSymbol(FSP ACT_RA_DECOMP *t, SL32 *len )
#else
SB8 *ReadSymbol(t, len )
ACT_RA_DECOMP *t;
SL32 *len;
#endif
{
SL32 n;
SB8 *r;
n = get_next_token(FSA t);
#ifdef AGFADEBUG
if (UFST_get_debug(FSA0))
DBG1("index=%ld ",n);
#endif /* AGFADEBUG */
*len = t->lengths[n];
r = (SB8*)(t->string + t->offsets[n]);
return r;
}
/****************************************************************/
#endif /* TT_ROM_ACT */